@mindfoldhq/trellis 0.5.0-beta.16 → 0.5.0-beta.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -98
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +1 -29
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +92 -5
- package/dist/commands/update.js.map +1 -1
- package/dist/configurators/antigravity.d.ts.map +1 -1
- package/dist/configurators/antigravity.js +2 -8
- package/dist/configurators/antigravity.js.map +1 -1
- package/dist/configurators/claude.d.ts.map +1 -1
- package/dist/configurators/claude.js +3 -9
- package/dist/configurators/claude.js.map +1 -1
- package/dist/configurators/codebuddy.d.ts.map +1 -1
- package/dist/configurators/codebuddy.js +2 -2
- package/dist/configurators/codebuddy.js.map +1 -1
- package/dist/configurators/codex.d.ts.map +1 -1
- package/dist/configurators/codex.js +2 -7
- package/dist/configurators/codex.js.map +1 -1
- package/dist/configurators/copilot.d.ts.map +1 -1
- package/dist/configurators/copilot.js +2 -9
- package/dist/configurators/copilot.js.map +1 -1
- package/dist/configurators/cursor.d.ts.map +1 -1
- package/dist/configurators/cursor.js +2 -2
- package/dist/configurators/cursor.js.map +1 -1
- package/dist/configurators/droid.d.ts.map +1 -1
- package/dist/configurators/droid.js +2 -2
- package/dist/configurators/droid.js.map +1 -1
- package/dist/configurators/gemini.d.ts.map +1 -1
- package/dist/configurators/gemini.js +2 -2
- package/dist/configurators/gemini.js.map +1 -1
- package/dist/configurators/index.d.ts.map +1 -1
- package/dist/configurators/index.js +13 -11
- package/dist/configurators/index.js.map +1 -1
- package/dist/configurators/kilo.d.ts.map +1 -1
- package/dist/configurators/kilo.js +2 -8
- package/dist/configurators/kilo.js.map +1 -1
- package/dist/configurators/kiro.d.ts.map +1 -1
- package/dist/configurators/kiro.js +2 -2
- package/dist/configurators/kiro.js.map +1 -1
- package/dist/configurators/opencode.d.ts.map +1 -1
- package/dist/configurators/opencode.js +3 -3
- package/dist/configurators/opencode.js.map +1 -1
- package/dist/configurators/pi.d.ts.map +1 -1
- package/dist/configurators/pi.js +9 -4
- package/dist/configurators/pi.js.map +1 -1
- package/dist/configurators/qoder.d.ts.map +1 -1
- package/dist/configurators/qoder.js +2 -2
- package/dist/configurators/qoder.js.map +1 -1
- package/dist/configurators/shared.d.ts +21 -2
- package/dist/configurators/shared.d.ts.map +1 -1
- package/dist/configurators/shared.js +32 -3
- package/dist/configurators/shared.js.map +1 -1
- package/dist/configurators/windsurf.d.ts.map +1 -1
- package/dist/configurators/windsurf.js +2 -8
- package/dist/configurators/windsurf.js.map +1 -1
- package/dist/constants/paths.d.ts +2 -0
- package/dist/constants/paths.d.ts.map +1 -1
- package/dist/constants/paths.js +2 -0
- package/dist/constants/paths.js.map +1 -1
- package/dist/migrations/manifests/0.5.0-beta.17.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.18.json +9 -0
- package/dist/templates/codex/skills/finish-work/SKILL.md +41 -109
- package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +73 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/add-project-local-conventions.md +83 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +54 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +81 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +57 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +78 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +83 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +79 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +48 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +55 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +68 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +80 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +51 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +102 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +101 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workflow.md +75 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workspace-memory.md +71 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +79 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +69 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +59 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +74 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +83 -0
- package/dist/templates/common/commands/finish-work.md +34 -10
- package/dist/templates/common/index.d.ts +22 -2
- package/dist/templates/common/index.d.ts.map +1 -1
- package/dist/templates/common/index.js +53 -4
- package/dist/templates/common/index.js.map +1 -1
- package/dist/templates/common/skills/brainstorm.md +3 -0
- package/dist/templates/copilot/prompts/finish-work.prompt.md +44 -112
- package/dist/templates/markdown/agents.md +8 -0
- package/dist/templates/opencode/plugins/inject-subagent-context.js +20 -5
- package/dist/templates/opencode/plugins/inject-workflow-state.js +6 -1
- package/dist/templates/pi/extensions/trellis/index.ts.txt +499 -51
- package/dist/templates/shared-hooks/inject-workflow-state.py +6 -1
- package/dist/templates/trellis/scripts/common/task_store.py +4 -16
- package/dist/templates/trellis/scripts/common/tasks.py +4 -1
- package/dist/templates/trellis/workflow.md +59 -3
- package/dist/utils/template-hash.d.ts.map +1 -1
- package/dist/utils/template-hash.js +19 -1
- package/dist/utils/template-hash.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Skills, Commands, Prompts, And Workflows
|
|
2
|
+
|
|
3
|
+
Skills and commands are textual entry points for user interaction with Trellis. Different platforms use different names, but their core purpose is the same: tell the AI how to enter the Trellis flow when the user expresses a certain intent.
|
|
4
|
+
|
|
5
|
+
## Conceptual Differences
|
|
6
|
+
|
|
7
|
+
| Type | Trigger mode | Best for |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| skill | AI auto-match or explicit user mention | Long-term capabilities, workflow rules, modification guides. |
|
|
10
|
+
| command | Explicit user invocation | Clear operation entry points such as continue and finish-work. |
|
|
11
|
+
| prompt | Explicit user invocation or platform selection | Similar to command, but in a platform prompt format. |
|
|
12
|
+
| workflow | Explicit user selection or platform auto-match | Guides the main session when no sub-agent/hook exists. |
|
|
13
|
+
|
|
14
|
+
Trellis workflow skills usually share one semantic set: brainstorm, before-dev, check, update-spec, break-loop. Multi-file built-in skills such as `trellis-meta` use layered references.
|
|
15
|
+
|
|
16
|
+
## Common Paths
|
|
17
|
+
|
|
18
|
+
| Platform | Common entries |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| Claude Code | `.claude/skills/`, `.claude/commands/` |
|
|
21
|
+
| Cursor | `.cursor/skills/`, `.cursor/commands/` |
|
|
22
|
+
| OpenCode | `.opencode/skills/`, `.opencode/commands/` |
|
|
23
|
+
| Codex | `.agents/skills/`, `.codex/skills/` |
|
|
24
|
+
| Kilo | `.kilocode/skills/`, `.kilocode/workflows/` |
|
|
25
|
+
| Kiro | `.kiro/skills/` |
|
|
26
|
+
| Gemini CLI | `.gemini/skills/`, `.gemini/commands/` |
|
|
27
|
+
| Antigravity | `.agent/skills/`, `.agent/workflows/` |
|
|
28
|
+
| Windsurf | `.windsurf/skills/`, `.windsurf/workflows/` |
|
|
29
|
+
| Qoder | `.qoder/skills/`, `.qoder/commands/` |
|
|
30
|
+
| CodeBuddy | `.codebuddy/skills/`, `.codebuddy/commands/` |
|
|
31
|
+
| GitHub Copilot | `.github/skills/`, `.github/prompts/` |
|
|
32
|
+
| Factory Droid | `.factory/skills/`, `.factory/commands/` |
|
|
33
|
+
| Pi Agent | `.pi/skills/` |
|
|
34
|
+
|
|
35
|
+
In a user project, use the files actually generated by init as authoritative.
|
|
36
|
+
|
|
37
|
+
## Skill Structure
|
|
38
|
+
|
|
39
|
+
A common skill is a directory:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
trellis-meta/
|
|
43
|
+
├── SKILL.md
|
|
44
|
+
└── references/
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`SKILL.md` should tell the AI:
|
|
48
|
+
|
|
49
|
+
- When to use this skill.
|
|
50
|
+
- Which reference to read first for the current task.
|
|
51
|
+
- What not to do.
|
|
52
|
+
|
|
53
|
+
References hold longer explanations so the entry file does not contain everything.
|
|
54
|
+
|
|
55
|
+
## Command/Prompt/Workflow Structure
|
|
56
|
+
|
|
57
|
+
Commands, prompts, and workflows are usually single files. Their content should include:
|
|
58
|
+
|
|
59
|
+
- When to use it.
|
|
60
|
+
- Which `.trellis/` files to read.
|
|
61
|
+
- Which scripts to run.
|
|
62
|
+
- How to report after completion.
|
|
63
|
+
|
|
64
|
+
They should not store task state; task state belongs in `.trellis/tasks/` and `.trellis/.runtime/`.
|
|
65
|
+
|
|
66
|
+
## Local Change Scenarios
|
|
67
|
+
|
|
68
|
+
| User need | Edit location |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| Change AI auto-trigger rules | The corresponding skill's frontmatter description. |
|
|
71
|
+
| Change user command behavior | The corresponding command/prompt/workflow file. |
|
|
72
|
+
| Add a project-local skill | Platform skill directory, or shared `.agents/skills/`. |
|
|
73
|
+
| Let multiple platforms share one capability | Write equivalent skills in each platform skill directory, or use the `.agents/skills/` shared layer on platforms that support it. |
|
|
74
|
+
| Change finish/continue entry points | Platform commands/prompts/workflows. |
|
|
75
|
+
|
|
76
|
+
## Modification Principles
|
|
77
|
+
|
|
78
|
+
1. **Keep entry files short; references carry long content**. This matters especially for multi-file skills like `trellis-meta`.
|
|
79
|
+
2. **Make trigger descriptions specific**. A description that is too broad can mis-trigger; one that is too narrow may not trigger.
|
|
80
|
+
3. **Keep the same semantics consistent across platforms**. File formats can differ, but behavior descriptions should match.
|
|
81
|
+
4. **Put project-specific capabilities in local skills**. Do not put team-private flows into public `trellis-meta`.
|
|
82
|
+
|
|
83
|
+
If the user only wants local AI to know one more project rule, usually create a project-local skill or update `.trellis/spec/` instead of changing a Trellis built-in workflow skill.
|
|
@@ -1,28 +1,48 @@
|
|
|
1
1
|
# Finish Work
|
|
2
2
|
|
|
3
|
-
Wrap up the current session.
|
|
3
|
+
Wrap up the current session: archive the active task (and any other completed-but-unarchived tasks the user wants to clean up) and record the session journal. Code commits are NOT done here — those happen in workflow Phase 3.4 before you invoke this command.
|
|
4
4
|
|
|
5
|
-
## Step 1:
|
|
5
|
+
## Step 1: Survey current state
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
{{PYTHON_CMD}} ./.trellis/scripts/get_context.py --mode record
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This prints:
|
|
12
|
+
|
|
13
|
+
- **My active tasks** — review whether any besides the current one are actually done (code merged, AC met) and should be archived this round.
|
|
14
|
+
- **Git status** — quick visual on what's dirty.
|
|
15
|
+
- **Recent commits** — you'll need their hashes in Step 4 for `--commit`.
|
|
8
16
|
|
|
9
|
-
|
|
17
|
+
If `--mode record` surfaces other completed tasks not tied to the current session, surface them to the user with a one-shot confirmation: "These N tasks look done — archive them too in this round? [y/N]". Default is no; the current active task is always archived in Step 3 regardless.
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
## Step 2: Sanity check — working tree must be clean
|
|
12
20
|
|
|
13
|
-
|
|
21
|
+
Run:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
git status --porcelain
|
|
25
|
+
```
|
|
14
26
|
|
|
15
|
-
|
|
27
|
+
Filter out paths under `.trellis/workspace/` and `.trellis/tasks/` — those are managed by `add_session.py` and `task.py archive` auto-commits and will appear dirty as part of this skill's own work.
|
|
16
28
|
|
|
17
|
-
|
|
29
|
+
If anything else is dirty (any path outside those two prefixes), **stop and bail out** with:
|
|
18
30
|
|
|
19
|
-
|
|
31
|
+
> "Working tree has uncommitted code changes. Return to workflow Phase 3.4 to commit them before running `{{CMD_REF:finish-work}}`."
|
|
32
|
+
|
|
33
|
+
Do NOT run `git commit` here. Do NOT prompt the user to commit. The user goes back to Phase 3.4 and the AI drives the batched commit there.
|
|
34
|
+
|
|
35
|
+
## Step 3: Archive task(s)
|
|
20
36
|
|
|
21
37
|
```bash
|
|
22
38
|
{{PYTHON_CMD}} ./.trellis/scripts/task.py archive <task-name>
|
|
23
39
|
```
|
|
24
40
|
|
|
25
|
-
|
|
41
|
+
At minimum: the current active task (if any). Plus any extra tasks the user confirmed in Step 1. Each archive produces a `chore(task): archive ...` commit via the script's auto-commit.
|
|
42
|
+
|
|
43
|
+
If there is no active task and the user did not confirm any cleanup archives, skip this step.
|
|
44
|
+
|
|
45
|
+
## Step 4: Record session journal
|
|
26
46
|
|
|
27
47
|
```bash
|
|
28
48
|
{{PYTHON_CMD}} ./.trellis/scripts/add_session.py \
|
|
@@ -30,3 +50,7 @@ Append a session entry (auto-handles journal rotation, line count, index update)
|
|
|
30
50
|
--commit "hash1,hash2" \
|
|
31
51
|
--summary "Brief summary"
|
|
32
52
|
```
|
|
53
|
+
|
|
54
|
+
Use the work-commit hashes produced in Phase 3.4 (visible in Step 1's `Recent commits` list, or via `git log --oneline`) for `--commit`. Do not include the archive commit hashes from Step 3. This produces a `chore: record journal` commit.
|
|
55
|
+
|
|
56
|
+
Final git log order: `<work commits from 3.4>` → `chore(task): archive ...` (one or more) → `chore: record journal`.
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Directory structure:
|
|
8
8
|
* common/
|
|
9
|
-
* ├── commands/
|
|
10
|
-
*
|
|
9
|
+
* ├── commands/ # Templates that stay as slash commands
|
|
10
|
+
* ├── skills/ # Single-file templates that become auto-triggered skills
|
|
11
|
+
* └── bundled-skills/ # Multi-file built-in skills with references/assets
|
|
11
12
|
*/
|
|
12
13
|
export interface CommonTemplate {
|
|
13
14
|
/** Template name without extension (e.g., "start", "before-dev") */
|
|
@@ -15,6 +16,18 @@ export interface CommonTemplate {
|
|
|
15
16
|
/** Raw content with {{placeholders}} — must be resolved before writing */
|
|
16
17
|
content: string;
|
|
17
18
|
}
|
|
19
|
+
export interface CommonBundledSkillFile {
|
|
20
|
+
/** POSIX path relative to the skill directory, e.g. "references/core.md" */
|
|
21
|
+
relativePath: string;
|
|
22
|
+
/** Raw content with {{placeholders}} — must be resolved before writing */
|
|
23
|
+
content: string;
|
|
24
|
+
}
|
|
25
|
+
export interface CommonBundledSkill {
|
|
26
|
+
/** Skill directory name, e.g. "trellis-meta" */
|
|
27
|
+
name: string;
|
|
28
|
+
/** Files that must be written under the skill directory */
|
|
29
|
+
files: CommonBundledSkillFile[];
|
|
30
|
+
}
|
|
18
31
|
/**
|
|
19
32
|
* Get all command templates (stay as slash commands on all platforms).
|
|
20
33
|
* Results are cached after first call.
|
|
@@ -25,4 +38,11 @@ export declare function getCommandTemplates(): CommonTemplate[];
|
|
|
25
38
|
* Results are cached after first call.
|
|
26
39
|
*/
|
|
27
40
|
export declare function getSkillTemplates(): CommonTemplate[];
|
|
41
|
+
/**
|
|
42
|
+
* Get all multi-file built-in skills.
|
|
43
|
+
*
|
|
44
|
+
* These are copied as complete skill directories so references and assets stay
|
|
45
|
+
* lazy-loadable instead of being flattened into one oversized SKILL.md.
|
|
46
|
+
*/
|
|
47
|
+
export declare function getBundledSkillTemplates(): CommonBundledSkill[];
|
|
28
48
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/common/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/common/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAuBH,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,KAAK,EAAE,sBAAsB,EAAE,CAAC;CACjC;AAOD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,EAAE,CAMtD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,EAAE,CAMpD;AAuCD;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,kBAAkB,EAAE,CAM/D"}
|
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Directory structure:
|
|
8
8
|
* common/
|
|
9
|
-
* ├── commands/
|
|
10
|
-
*
|
|
9
|
+
* ├── commands/ # Templates that stay as slash commands
|
|
10
|
+
* ├── skills/ # Single-file templates that become auto-triggered skills
|
|
11
|
+
* └── bundled-skills/ # Multi-file built-in skills with references/assets
|
|
11
12
|
*/
|
|
12
|
-
import { readdirSync, readFileSync } from "node:fs";
|
|
13
|
-
import { dirname, join } from "node:path";
|
|
13
|
+
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
14
|
+
import { dirname, join, relative, sep } from "node:path";
|
|
14
15
|
import { fileURLToPath } from "node:url";
|
|
15
16
|
const __filename = fileURLToPath(import.meta.url);
|
|
16
17
|
const __dirname = dirname(__filename);
|
|
@@ -30,6 +31,7 @@ function listMarkdownFiles(dir) {
|
|
|
30
31
|
// Cached results — files don't change during a CLI run
|
|
31
32
|
let cachedCommands;
|
|
32
33
|
let cachedSkills;
|
|
34
|
+
let cachedBundledSkills;
|
|
33
35
|
/**
|
|
34
36
|
* Get all command templates (stay as slash commands on all platforms).
|
|
35
37
|
* Results are cached after first call.
|
|
@@ -52,4 +54,51 @@ export function getSkillTemplates() {
|
|
|
52
54
|
}));
|
|
53
55
|
return cachedSkills;
|
|
54
56
|
}
|
|
57
|
+
function listDirectories(dir) {
|
|
58
|
+
try {
|
|
59
|
+
return readdirSync(join(__dirname, dir))
|
|
60
|
+
.filter((entry) => statSync(join(__dirname, dir, entry)).isDirectory())
|
|
61
|
+
.sort();
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function toPosixRelativePath(root, filePath) {
|
|
68
|
+
return relative(root, filePath).split(sep).join("/");
|
|
69
|
+
}
|
|
70
|
+
function listBundledSkillFiles(skillDir) {
|
|
71
|
+
const root = join(__dirname, "bundled-skills", skillDir);
|
|
72
|
+
const files = [];
|
|
73
|
+
function walk(dir) {
|
|
74
|
+
for (const entry of readdirSync(dir)) {
|
|
75
|
+
const fullPath = join(dir, entry);
|
|
76
|
+
const stat = statSync(fullPath);
|
|
77
|
+
if (stat.isDirectory()) {
|
|
78
|
+
walk(fullPath);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
files.push({
|
|
82
|
+
relativePath: toPosixRelativePath(root, fullPath),
|
|
83
|
+
content: readFileSync(fullPath, "utf-8"),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
walk(root);
|
|
89
|
+
return files.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get all multi-file built-in skills.
|
|
93
|
+
*
|
|
94
|
+
* These are copied as complete skill directories so references and assets stay
|
|
95
|
+
* lazy-loadable instead of being flattened into one oversized SKILL.md.
|
|
96
|
+
*/
|
|
97
|
+
export function getBundledSkillTemplates() {
|
|
98
|
+
cachedBundledSkills ??= listDirectories("bundled-skills").map((name) => ({
|
|
99
|
+
name,
|
|
100
|
+
files: listBundledSkillFiles(name),
|
|
101
|
+
}));
|
|
102
|
+
return cachedBundledSkills;
|
|
103
|
+
}
|
|
55
104
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/common/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/common/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -57,6 +57,9 @@ Before any Q&A, ensure a task exists. If none exists, create one immediately.
|
|
|
57
57
|
TASK_DIR=$(python3 ./.trellis/scripts/task.py create "brainstorm: <short goal>" --slug <auto>)
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
+
Use a slug without a date prefix. `task.py create` adds the `MM-DD-`
|
|
61
|
+
directory prefix automatically.
|
|
62
|
+
|
|
60
63
|
Create/seed `prd.md` immediately with what you know:
|
|
61
64
|
|
|
62
65
|
```markdown
|
|
@@ -1,157 +1,89 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Trellis Copilot prompt: Finish Work
|
|
2
|
+
description: "Trellis Copilot prompt: Finish Work — survey + archive task + record session journal"
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
# Finish Work
|
|
5
|
+
# Finish Work
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Wrap up the current session: archive the active task (and any other completed-but-unarchived tasks the user wants to clean up) and record the session journal. Code commits are NOT done here — those happen in workflow Phase 3.4 before you invoke this prompt.
|
|
8
8
|
|
|
9
|
-
**Timing**: After
|
|
9
|
+
**Timing**: After Phase 3.4 (Commit changes) — when the working tree is already clean.
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
### 1. Code Quality
|
|
13
|
+
## Step 1: Survey current state
|
|
16
14
|
|
|
17
15
|
```bash
|
|
18
|
-
|
|
19
|
-
pnpm lint
|
|
20
|
-
pnpm type-check
|
|
21
|
-
pnpm test
|
|
16
|
+
python3 ./.trellis/scripts/get_context.py --mode record
|
|
22
17
|
```
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
- [ ] `pnpm type-check` passes with no type errors?
|
|
26
|
-
- [ ] Tests pass?
|
|
27
|
-
- [ ] No `console.log` statements (use logger)?
|
|
28
|
-
- [ ] No non-null assertions (the `x!` operator)?
|
|
29
|
-
- [ ] No `any` types?
|
|
30
|
-
|
|
31
|
-
### 1.5. Test Coverage
|
|
32
|
-
|
|
33
|
-
Check if your change needs new or updated tests (see `.trellis/spec/unit-test/conventions.md`):
|
|
34
|
-
|
|
35
|
-
- [ ] New pure function �?unit test added?
|
|
36
|
-
- [ ] Bug fix �?regression test added in `test/regression.test.ts`?
|
|
37
|
-
- [ ] Changed init/update behavior �?integration test added/updated?
|
|
38
|
-
- [ ] No logic change (text/data only) �?no test needed
|
|
39
|
-
|
|
40
|
-
### 2. Code-Spec Sync
|
|
41
|
-
|
|
42
|
-
**Code-Spec Docs**:
|
|
43
|
-
- [ ] Does `.trellis/spec/backend/` need updates?
|
|
44
|
-
- New patterns, new modules, new conventions
|
|
45
|
-
- [ ] Does `.trellis/spec/frontend/` need updates?
|
|
46
|
-
- New components, new hooks, new patterns
|
|
47
|
-
- [ ] Does `.trellis/spec/guides/` need updates?
|
|
48
|
-
- New cross-layer flows, lessons from bugs
|
|
49
|
-
|
|
50
|
-
**Key Question**:
|
|
51
|
-
> "If I fixed a bug or discovered something non-obvious, should I document it so future me (or others) won't hit the same issue?"
|
|
52
|
-
|
|
53
|
-
If YES -> Update the relevant code-spec doc.
|
|
54
|
-
|
|
55
|
-
### 2.5. Code-Spec Hard Block (Infra/Cross-Layer)
|
|
56
|
-
|
|
57
|
-
If this change touches infra or cross-layer contracts, this is a blocking checklist:
|
|
58
|
-
|
|
59
|
-
- [ ] Spec content is executable (real signatures/contracts), not principle-only text
|
|
60
|
-
- [ ] Includes file path + command/API name + payload field names
|
|
61
|
-
- [ ] Includes validation and error matrix
|
|
62
|
-
- [ ] Includes Good/Base/Bad cases
|
|
63
|
-
- [ ] Includes required tests and assertion points
|
|
19
|
+
This prints:
|
|
64
20
|
|
|
65
|
-
**
|
|
66
|
-
|
|
67
|
-
|
|
21
|
+
- **My active tasks** — review whether any besides the current one are actually done (code merged, AC met) and should be archived this round.
|
|
22
|
+
- **Git status** — quick visual on what's dirty.
|
|
23
|
+
- **Recent commits** — you'll need their hashes in Step 4 for `--commit`.
|
|
68
24
|
|
|
69
|
-
|
|
25
|
+
If `--mode record` surfaces other completed tasks not tied to the current session, surface them to the user with a one-shot confirmation: "These N tasks look done — archive them too in this round? [y/N]". Default is no; the current active task is always archived in Step 3 regardless.
|
|
70
26
|
|
|
71
|
-
|
|
27
|
+
## Step 2: Sanity check — working tree must be clean
|
|
72
28
|
|
|
73
|
-
|
|
74
|
-
- [ ] Output schema updated?
|
|
75
|
-
- [ ] API documentation updated?
|
|
76
|
-
- [ ] Client code updated to match?
|
|
29
|
+
Run:
|
|
77
30
|
|
|
78
|
-
|
|
31
|
+
```bash
|
|
32
|
+
git status --porcelain
|
|
33
|
+
```
|
|
79
34
|
|
|
80
|
-
|
|
35
|
+
Filter out paths under `.trellis/workspace/` and `.trellis/tasks/` — those are managed by `add_session.py` and `task.py archive` auto-commits and will appear dirty as part of this prompt's own work.
|
|
81
36
|
|
|
82
|
-
|
|
83
|
-
- [ ] Schema file updated?
|
|
84
|
-
- [ ] Related queries updated?
|
|
85
|
-
- [ ] Seed data updated (if applicable)?
|
|
37
|
+
If anything else is dirty (any path outside those two prefixes), **stop and bail out** with:
|
|
86
38
|
|
|
87
|
-
|
|
39
|
+
> "Working tree has uncommitted code changes. Return to workflow Phase 3.4 to commit them before running `/finish-work`."
|
|
88
40
|
|
|
89
|
-
|
|
41
|
+
Do NOT run `git commit` here. Do NOT prompt the user to commit. The user goes back to Phase 3.4 and the AI drives the batched commit there.
|
|
90
42
|
|
|
91
|
-
|
|
92
|
-
- [ ] Error handling works at each boundary?
|
|
93
|
-
- [ ] Types are consistent across layers?
|
|
94
|
-
- [ ] Loading states handled?
|
|
43
|
+
## Step 3: Archive task(s)
|
|
95
44
|
|
|
96
|
-
|
|
45
|
+
```bash
|
|
46
|
+
python3 ./.trellis/scripts/task.py archive <task-name>
|
|
47
|
+
```
|
|
97
48
|
|
|
98
|
-
|
|
99
|
-
- [ ] Edge cases tested?
|
|
100
|
-
- [ ] Error states tested?
|
|
101
|
-
- [ ] Works after page refresh?
|
|
49
|
+
At minimum: the current active task (if any). Plus any extra tasks the user confirmed in Step 1. Each archive produces a `chore(task): archive ...` commit via the script's auto-commit.
|
|
102
50
|
|
|
103
|
-
|
|
51
|
+
If there is no active task and the user did not confirm any cleanup archives, skip this step.
|
|
104
52
|
|
|
105
|
-
##
|
|
53
|
+
## Step 4: Record session journal
|
|
106
54
|
|
|
107
55
|
```bash
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
git status
|
|
113
|
-
git diff --name-only
|
|
114
|
-
|
|
115
|
-
# 3. Based on changed files, check relevant items above
|
|
56
|
+
python3 ./.trellis/scripts/add_session.py \
|
|
57
|
+
--title "Session Title" \
|
|
58
|
+
--commit "hash1,hash2" \
|
|
59
|
+
--summary "Brief summary"
|
|
116
60
|
```
|
|
117
61
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
## Common Oversights
|
|
62
|
+
Use the work-commit hashes produced in Phase 3.4 (visible in Step 1's `Recent commits` list, or via `git log --oneline`) for `--commit`. Do not include the archive commit hashes from Step 3. This produces a `chore: record journal` commit.
|
|
121
63
|
|
|
122
|
-
|
|
123
|
-
|-----------|-------------|-------|
|
|
124
|
-
| Code-spec docs not updated | Others don't know the change | Check .trellis/spec/ |
|
|
125
|
-
| Spec text is abstract only | Easy regressions in infra/cross-layer changes | Require signature/contract/matrix/cases/tests |
|
|
126
|
-
| Migration not created | Schema out of sync | Check db/migrations/ |
|
|
127
|
-
| Types not synced | Runtime errors | Check shared types |
|
|
128
|
-
| Tests not updated | False confidence | Run full test suite |
|
|
129
|
-
| Console.log left in | Noisy production logs | Search for console.log |
|
|
64
|
+
Final git log order: `<work commits from 3.4>` → `chore(task): archive ...` (one or more) → `chore: record journal`.
|
|
130
65
|
|
|
131
66
|
---
|
|
132
67
|
|
|
133
68
|
## Relationship to Other Commands
|
|
134
69
|
|
|
135
70
|
```
|
|
136
|
-
Development Flow:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
71
|
+
Development Flow (workflow.md Phase 3):
|
|
72
|
+
3.1 Quality verification
|
|
73
|
+
3.2 Debug retrospective (on demand)
|
|
74
|
+
3.3 Spec update
|
|
75
|
+
3.4 Commit changes -> AI drafts batched commits, user confirms
|
|
76
|
+
3.5 Wrap-up -> /finish-work (this prompt: survey + archive + journal)
|
|
77
|
+
|
|
141
78
|
Debug Flow:
|
|
142
|
-
Hit bug -> Fix -> / -> Knowledge capture
|
|
143
|
-
|
|
|
144
|
-
Deep analysis
|
|
79
|
+
Hit bug -> Fix -> /break-loop -> Knowledge capture
|
|
145
80
|
```
|
|
146
81
|
|
|
147
|
-
-
|
|
148
|
-
-
|
|
149
|
-
- `/` - Deep analysis after debugging
|
|
82
|
+
- `/finish-work` — survey + archive + record session (this prompt)
|
|
83
|
+
- `/break-loop` — deep analysis after debugging
|
|
150
84
|
|
|
151
85
|
---
|
|
152
86
|
|
|
153
87
|
## Core Principle
|
|
154
88
|
|
|
155
|
-
> **
|
|
156
|
-
|
|
157
|
-
Complete work = Code + Docs + Tests + Verification
|
|
89
|
+
> **Finish-work is pure bookkeeping.** Code is already committed before this runs. If the working tree is dirty, this prompt refuses to proceed.
|
|
@@ -16,6 +16,14 @@ If you're using Codex or another agent-capable tool, additional project-scoped h
|
|
|
16
16
|
- `.agents/skills/` — reusable Trellis skills
|
|
17
17
|
- `.codex/agents/` — optional custom subagents
|
|
18
18
|
|
|
19
|
+
## Subagents
|
|
20
|
+
|
|
21
|
+
- ALWAYS wait for all subagents to complete before yielding.
|
|
22
|
+
- Spawn subagents automatically when:
|
|
23
|
+
- Parallelizable work (e.g., install + verify, npm test + typecheck, multiple tasks from plan)
|
|
24
|
+
- Long-running or blocking tasks where a worker can run independently.
|
|
25
|
+
- Isolation for risky changes or checks
|
|
26
|
+
|
|
19
27
|
Managed by Trellis. Edits outside this block are preserved; edits inside may be overwritten by a future `trellis update`.
|
|
20
28
|
|
|
21
29
|
<!-- TRELLIS:END -->
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* global process */
|
|
1
2
|
/**
|
|
2
3
|
* Trellis Context Injection Plugin
|
|
3
4
|
*
|
|
@@ -259,6 +260,19 @@ function shellQuote(value) {
|
|
|
259
260
|
return `'${String(value).replace(/'/g, "'\\''")}'`
|
|
260
261
|
}
|
|
261
262
|
|
|
263
|
+
function powershellQuote(value) {
|
|
264
|
+
return `'${String(value).replace(/'/g, "''")}'`
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function buildTrellisContextPrefix(contextKey, hostPlatform = process.platform) {
|
|
268
|
+
if (hostPlatform === "win32") {
|
|
269
|
+
// OpenCode's Windows Bash tool runs through PowerShell, not a POSIX shell.
|
|
270
|
+
return `$env:TRELLIS_CONTEXT_ID = ${powershellQuote(contextKey)}; `
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return `export TRELLIS_CONTEXT_ID=${shellQuote(contextKey)}; `
|
|
274
|
+
}
|
|
275
|
+
|
|
262
276
|
function getBashCommandKey(args) {
|
|
263
277
|
if (!args || typeof args !== "object") return null
|
|
264
278
|
if (typeof args.command === "string") return "command"
|
|
@@ -271,7 +285,8 @@ function commandStartsWithTrellisContext(command) {
|
|
|
271
285
|
return (
|
|
272
286
|
/^TRELLIS_CONTEXT_ID\s*=/.test(firstCommand) ||
|
|
273
287
|
/^export\s+TRELLIS_CONTEXT_ID\s*=/.test(firstCommand) ||
|
|
274
|
-
/^env\s+(?:[^\s=]+\s+)*TRELLIS_CONTEXT_ID\s*=/.test(firstCommand)
|
|
288
|
+
/^env\s+(?:[^\s=]+\s+)*TRELLIS_CONTEXT_ID\s*=/.test(firstCommand) ||
|
|
289
|
+
/^\$env:TRELLIS_CONTEXT_ID\s*=/i.test(firstCommand)
|
|
275
290
|
)
|
|
276
291
|
}
|
|
277
292
|
|
|
@@ -279,7 +294,7 @@ function commandStartsWithTrellisContext(command) {
|
|
|
279
294
|
* OpenCode TUI may not expose OPENCODE_RUN_ID to Bash. The plugin hook still
|
|
280
295
|
* receives session identity, so inject it into Bash commands before execution.
|
|
281
296
|
*/
|
|
282
|
-
function injectTrellisContextIntoBash(ctx, input, output) {
|
|
297
|
+
function injectTrellisContextIntoBash(ctx, input, output, hostPlatform) {
|
|
283
298
|
const args = output?.args
|
|
284
299
|
const commandKey = getBashCommandKey(args)
|
|
285
300
|
if (!commandKey) return false
|
|
@@ -291,7 +306,7 @@ function injectTrellisContextIntoBash(ctx, input, output) {
|
|
|
291
306
|
const contextKey = ctx.getContextKey(input)
|
|
292
307
|
if (!contextKey) return false
|
|
293
308
|
|
|
294
|
-
args[commandKey] =
|
|
309
|
+
args[commandKey] = `${buildTrellisContextPrefix(contextKey, hostPlatform)}${command}`
|
|
295
310
|
return true
|
|
296
311
|
}
|
|
297
312
|
|
|
@@ -300,7 +315,7 @@ function injectTrellisContextIntoBash(ctx, input, output) {
|
|
|
300
315
|
// (packages/opencode/src/plugin/index.ts — `for ([_, fn] of Object.entries(mod)) await fn(input)`);
|
|
301
316
|
// the previous `{ id, server }` object shape failed with
|
|
302
317
|
// `TypeError: fn is not a function` in 1.2.x.
|
|
303
|
-
export default async ({ directory }) => {
|
|
318
|
+
export default async ({ directory, platform: hostPlatform = process.platform }) => {
|
|
304
319
|
const ctx = new TrellisContext(directory)
|
|
305
320
|
debugLog("inject", "Plugin loaded, directory:", directory)
|
|
306
321
|
|
|
@@ -311,7 +326,7 @@ export default async ({ directory }) => {
|
|
|
311
326
|
|
|
312
327
|
const toolName = input?.tool?.toLowerCase()
|
|
313
328
|
if (toolName === "bash") {
|
|
314
|
-
if (injectTrellisContextIntoBash(ctx, input, output)) {
|
|
329
|
+
if (injectTrellisContextIntoBash(ctx, input, output, hostPlatform)) {
|
|
315
330
|
debugLog("inject", "Injected TRELLIS_CONTEXT_ID into Bash command")
|
|
316
331
|
}
|
|
317
332
|
return
|
|
@@ -81,7 +81,12 @@ const FALLBACK_BREADCRUMBS = {
|
|
|
81
81
|
"Per-turn only; does not carry forward; do NOT invent an override the " +
|
|
82
82
|
"user did not say.",
|
|
83
83
|
completed:
|
|
84
|
-
"
|
|
84
|
+
"Code committed via Phase 3.4; run `/trellis:finish-work` to wrap up " +
|
|
85
|
+
"(archive task + record session).\n" +
|
|
86
|
+
"If you reach this state with uncommitted code, return to Phase 3.4 " +
|
|
87
|
+
"first — `/finish-work` refuses to run on a dirty working tree.\n" +
|
|
88
|
+
"`task.py archive` deletes runtime session files that point at the " +
|
|
89
|
+
"archived task.",
|
|
85
90
|
}
|
|
86
91
|
|
|
87
92
|
/**
|