Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/preferences.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
artifacts:
base_dir: ~/repos/vaults/code-artifacts
base_dir: ~/ai-artifacts
editors:
- extensions: '*.md'
name: Webstorm
Expand Down
14 changes: 7 additions & 7 deletions packages/agents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ Project-level values take precedence over global. An explicitly empty value at t

#### `artifacts`

| Key | Type | Default | Description |
| ------------------------- | ------ | --------- | ---------------------------------------------------------------------------------------------------------- |
| `artifacts.base_dir` | string | `~/.ai` | Root directory for all generated artifacts (chats, plans, devlogs, tickets, runs). Supports `~` expansion. |
| `artifacts.paths.chats` | string | `chats` | Subdirectory name for chat artifacts, relative to the project artifact directory. |
| `artifacts.paths.devlogs` | string | `devlogs` | Subdirectory name for devlog artifacts. |
| `artifacts.paths.plans` | string | `plans` | Subdirectory name for plan artifacts. |
| Key | Type | Default | Description |
| ------------------------- | ------ | ---------------- | ---------------------------------------------------------------------------------------------------------- |
| `artifacts.base_dir` | string | `~/ai-artifacts` | Root directory for all generated artifacts (chats, plans, devlogs, tickets, runs). Supports `~` expansion. |
| `artifacts.paths.chats` | string | `chats` | Subdirectory name for chat artifacts, relative to the project artifact directory. |
| `artifacts.paths.devlogs` | string | `devlogs` | Subdirectory name for devlog artifacts. |
| `artifacts.paths.plans` | string | `plans` | Subdirectory name for plan artifacts. |

#### `repository`

Expand Down Expand Up @@ -183,7 +183,7 @@ project:
ticket_prefix: '#'

artifacts:
base_dir: ~/repos/vaults/code-artifacts
base_dir: ~/ai-artifacts
paths:
chats: chats
devlogs: devlogs
Expand Down
4 changes: 2 additions & 2 deletions packages/agents/content/skills/_data/artifact-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Standards for AI-generated artifact storage, naming, and lifecycle.

## Directory structure

All artifacts live under a configurable base directory (`base_dir`, default `~/.ai`). Use `get-session-context` to resolve `artifact_base_dir`:
All artifacts live under a configurable base directory (`base_dir`, default `~/ai-artifacts`). Use `get-session-context` to resolve `artifact_base_dir`:

```
{base_dir}/
Expand Down Expand Up @@ -53,7 +53,7 @@ Multiple runs per ticket (restarts, separate review cycles) each get their own r

### Persistent export destination

Artifacts under `{base_dir}/` are ephemeral when `base_dir` is a git-ignored path (the default). In worktrees, they are lost on deletion. The `export-ai-artifacts.sh` script copies them to `~/.ai/projects/{project-slug}/` for long-term retention, preserving the same directory structure. Exported artifacts are immutable (first export wins).
Artifacts under `{base_dir}/` are ephemeral when `base_dir` is a git-ignored path (the default). In worktrees, they are lost on deletion. The `export-ai-artifacts.sh` script copies them to `~/ai-artifacts/projects/{project-slug}/` for long-term retention, preserving the same directory structure. Exported artifacts are immutable (first export wins).

## Path resolution

Expand Down
52 changes: 26 additions & 26 deletions packages/agents/content/skills/get-session-context/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,21 @@ Example: branch `MAC-130/agents/feat/branch-manifest` produces `.agents/MAC-130-
"project_slug": "configs-macos",
"default_branch": "origin/main",
"branch_name": "MAC-130/agents/feat/branch-manifest",
"artifact_base_dir": "/Users/william/.ai",
"artifact_base_dir": "{artifact_base_dir}",
"artifact_paths": { "chats": "chats", "devlogs": "devlogs", "plans": "plans" },
"created_at": "2026-02-25T19:43:00Z"
}
```

| Field | Type | Description |
| ------------------- | ------------------ | ----------------------------------------------------------------------------------------- |
| `ticket_id` | `string` or `null` | Ticket ID extracted from branch name, or `null` if not derivable |
| `project_slug` | `string` | Project slug for artifact namespacing |
| `default_branch` | `string` | Full remote reference for the default branch (e.g., `origin/main`) |
| `branch_name` | `string` | Raw branch name as it appears in `gitStatus` |
| `artifact_base_dir` | `string` | Resolved absolute path for artifact storage (from preferences or default `~/.ai`) |
| `artifact_paths` | `object` | Category suffix paths relative to the project directory (defaults: chats, devlogs, plans) |
| `created_at` | `string` | ISO 8601 UTC timestamp of when the manifest was created |
| Field | Type | Description |
| ------------------- | ------------------ | ------------------------------------------------------------------------------------------ |
| `ticket_id` | `string` or `null` | Ticket ID extracted from branch name, or `null` if not derivable |
| `project_slug` | `string` | Project slug for artifact namespacing |
| `default_branch` | `string` | Full remote reference for the default branch (e.g., `origin/main`) |
| `branch_name` | `string` | Raw branch name as it appears in `gitStatus` |
| `artifact_base_dir` | `string` | Resolved absolute path for artifact storage (from preferences or default `~/ai-artifacts`) |
| `artifact_paths` | `object` | Category suffix paths relative to the project directory (defaults: chats, devlogs, plans) |
| `created_at` | `string` | ISO 8601 UTC timestamp of when the manifest was created |

## Resolution order

Expand Down Expand Up @@ -121,7 +121,7 @@ If the fields are absent, default to `origin/main`.

#### Artifact base directory

Extract `artifacts.base_dir` from `{prefs}`. If not found, use default: `~/.ai`.
Extract `artifacts.base_dir` from `{prefs}`. If not found, use default: `~/ai-artifacts`.

Expand `~` using the home directory inferred from the `Working directory:` field in the system prompt environment block (e.g., if the working directory is `/Users/william/repos/myproject`, the home directory is `/Users/william`).

Expand Down Expand Up @@ -190,7 +190,7 @@ Branch: `MAC-130/agents/feat/branch-manifest`
"project_slug": "configs-macos",
"default_branch": "origin/main",
"branch_name": "MAC-130/agents/feat/branch-manifest",
"artifact_base_dir": "/Users/william/.ai",
"artifact_base_dir": "{artifact_base_dir}",
"artifact_paths": { "chats": "chats", "devlogs": "devlogs", "plans": "plans" },
"created_at": "2026-02-25T00:00:00Z"
}
Expand All @@ -211,7 +211,7 @@ Branch: `PT-456/fix/login-redirect`
"project_slug": "example-project",
"default_branch": "origin/main",
"branch_name": "PT-456/fix/login-redirect",
"artifact_base_dir": "/Users/william/.ai",
"artifact_base_dir": "{artifact_base_dir}",
"artifact_paths": { "chats": "chats", "devlogs": "devlogs", "plans": "plans" },
"created_at": "2026-02-25T00:00:00Z"
}
Expand All @@ -232,7 +232,7 @@ Branch: `mac-147`
"project_slug": "configs-macos",
"default_branch": "origin/main",
"branch_name": "mac-147",
"artifact_base_dir": "/Users/william/.ai",
"artifact_base_dir": "{artifact_base_dir}",
"artifact_paths": { "chats": "chats", "devlogs": "devlogs", "plans": "plans" },
"created_at": "2026-02-27T00:00:00Z"
}
Expand All @@ -254,7 +254,7 @@ Branch: `experiment/try-new-parser`
"project_slug": "example-project",
"default_branch": "origin/main",
"branch_name": "experiment/try-new-parser",
"artifact_base_dir": "/Users/william/.ai",
"artifact_base_dir": "{artifact_base_dir}",
"artifact_paths": { "chats": "chats", "devlogs": "devlogs", "plans": "plans" },
"created_at": "2026-02-25T00:00:00Z"
}
Expand All @@ -277,7 +277,7 @@ Produces the same ticket ID as the slash-separated variant. Separators `_` and `
"project_slug": "configs-macos",
"default_branch": "origin/main",
"branch_name": "MAC-130_agents_feat_branch-manifest",
"artifact_base_dir": "/Users/william/.ai",
"artifact_base_dir": "{artifact_base_dir}",
"artifact_paths": { "chats": "chats", "devlogs": "devlogs", "plans": "plans" },
"created_at": "2026-02-25T00:00:00Z"
}
Expand All @@ -298,7 +298,7 @@ Branch: `NMR-567.2/fix/regression`
"project_slug": "example-project",
"default_branch": "origin/main",
"branch_name": "NMR-567.2/fix/regression",
"artifact_base_dir": "/Users/william/.ai",
"artifact_base_dir": "{artifact_base_dir}",
"artifact_paths": { "chats": "chats", "devlogs": "devlogs", "plans": "plans" },
"created_at": "2026-02-25T00:00:00Z"
}
Expand All @@ -319,7 +319,7 @@ Branch: `MAC-200`
"project_slug": "example-project",
"default_branch": "origin/main",
"branch_name": "MAC-200",
"artifact_base_dir": "/Users/william/.ai",
"artifact_base_dir": "{artifact_base_dir}",
"artifact_paths": { "chats": "chats", "devlogs": "devlogs", "plans": "plans" },
"created_at": "2026-02-25T00:00:00Z"
}
Expand All @@ -341,7 +341,7 @@ Branch: `a-1-test`
"project_slug": "example-project",
"default_branch": "origin/main",
"branch_name": "a-1-test",
"artifact_base_dir": "/Users/william/.ai",
"artifact_base_dir": "{artifact_base_dir}",
"artifact_paths": { "chats": "chats", "devlogs": "devlogs", "plans": "plans" },
"created_at": "2026-02-25T00:00:00Z"
}
Expand All @@ -366,7 +366,7 @@ Preferences: `project.ticket_prefix: MAC-`
"project_slug": "configs-macos",
"default_branch": "origin/main",
"branch_name": "147/feat/improve-parser",
"artifact_base_dir": "/Users/william/.ai",
"artifact_base_dir": "{artifact_base_dir}",
"artifact_paths": { "chats": "chats", "devlogs": "devlogs", "plans": "plans" },
"created_at": "2026-02-28T00:00:00Z"
}
Expand All @@ -391,7 +391,7 @@ Preferences: no `project.ticket_prefix` configured
"project_slug": "example-project",
"default_branch": "origin/main",
"branch_name": "42_fix_login-redirect",
"artifact_base_dir": "/Users/william/.ai",
"artifact_base_dir": "{artifact_base_dir}",
"artifact_paths": { "chats": "chats", "devlogs": "devlogs", "plans": "plans" },
"created_at": "2026-02-28T00:00:00Z"
}
Expand All @@ -416,7 +416,7 @@ Preferences: `project.ticket_prefix: '#'`
"project_slug": "codeassembly",
"default_branch": "origin/main",
"branch_name": "152",
"artifact_base_dir": "/Users/william/.ai",
"artifact_base_dir": "{artifact_base_dir}",
"artifact_paths": { "chats": "chats", "devlogs": "devlogs", "plans": "plans" },
"created_at": "2026-03-03T00:00:00Z"
}
Expand All @@ -425,21 +425,21 @@ Preferences: `project.ticket_prefix: '#'`
#### 12. Custom artifact base directory (relative path)

Branch: `MAC-200/feat/new-feature`
Preferences: `artifacts.base_dir: .ai`
Preferences: `artifacts.base_dir: ai-artifacts`
Working directory: `/Users/william/repos/myproject`

**Derivation trace:**

1. Ticket ID: `MAC-200`.
2. `artifacts.base_dir` is `.ai` (relative). Resolve against working directory: `/Users/william/repos/myproject/.ai`.
2. `artifacts.base_dir` is `ai-artifacts` (relative). Resolve against working directory: `/Users/william/repos/myproject/ai-artifacts`.

```json
{
"ticket_id": "MAC-200",
"project_slug": "myproject",
"default_branch": "origin/main",
"branch_name": "MAC-200/feat/new-feature",
"artifact_base_dir": "/Users/william/repos/myproject/.ai",
"artifact_base_dir": "/Users/william/repos/myproject/ai-artifacts",
"artifact_paths": { "chats": "chats", "devlogs": "devlogs", "plans": "plans" },
"created_at": "2026-03-17T00:00:00Z"
}
Expand All @@ -450,7 +450,7 @@ Working directory: `/Users/william/repos/myproject`
- **Corrupt manifest**: If a manifest file exists but contains invalid JSON, delete it and fall through to derivation to produce a new file.
- **Stale-schema manifest**: If a manifest file exists with valid JSON but is missing required fields (e.g., `artifact_base_dir`, `artifact_paths`), delete it and fall through to derivation. This occurs once per branch when the schema evolves.
- **Detached HEAD**: If `gitStatus` does not indicate an active branch (no `Current branch:` line or empty value), return an error message. Do not attempt derivation.
- **Missing preferences**: If `.agents/preferences.yaml` cannot be read, use `~/.agents/preferences.yaml`. If that is also unavailable, use defaults: `project_slug` from the working directory name, `default_branch` as `origin/main`, `artifact_base_dir` as `~/.ai` (expanded to absolute).
- **Missing preferences**: If `.agents/preferences.yaml` cannot be read, use `~/.agents/preferences.yaml`. If that is also unavailable, use defaults: `project_slug` from the working directory name, `default_branch` as `origin/main`, `artifact_base_dir` as `~/ai-artifacts` (expanded to absolute).
- **Author-prefixed branches**: Branch names like `wthorsen/MAC-130` are not matched for ticket ID extraction (the ticket ID must be at the start). The ticket ID will be `null`. (The ticket ID is visually present but not at position zero; extracting it would require a separate enhancement.)

## Constraints
Expand Down
2 changes: 1 addition & 1 deletion packages/agents/content/skills/orchestrate/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ Prefix the status line with a colored emoji for visual distinction:
}
```

When omitted (the normal case), `init_run` resolves the artifact base directory automatically from preferences (`artifacts.base_dir` in `.agents/preferences.yaml` then `~/.agents/preferences.yaml`, defaulting to `~/.ai`). An optional `baseDir` parameter can be passed as an explicit override, but the skill does not need to pass it under normal circumstances.
When omitted (the normal case), `init_run` resolves the artifact base directory automatically from preferences (`artifacts.base_dir` in `.agents/preferences.yaml` then `~/.agents/preferences.yaml`, defaulting to `~/ai-artifacts`). An optional `baseDir` parameter can be passed as an explicit override, but the skill does not need to pass it under normal circumstances.

**Success path:** Store the returned `{ runDir, runId, ticketId, timestamp }` as context variables. Set `{mcp-available}` = `true`. `{run-dir}` is the canonical artifact directory for all subsequent file writes and MCP calls. The returned `ticketId` is the resolved value (provided or auto-generated). Initialize `{seq} = 1`.

Expand Down
Loading