@mindfoldhq/trellis 0.6.3 → 0.6.5
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/dist/cli/index.js +1 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/channel/messages.js +1 -1
- package/dist/commands/channel/supervisor.d.ts.map +1 -1
- package/dist/commands/channel/supervisor.js +34 -2
- package/dist/commands/channel/supervisor.js.map +1 -1
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +1 -0
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +23 -11
- package/dist/commands/update.js.map +1 -1
- package/dist/configurators/codex.d.ts.map +1 -1
- package/dist/configurators/codex.js +1 -15
- package/dist/configurators/codex.js.map +1 -1
- package/dist/configurators/index.d.ts.map +1 -1
- package/dist/configurators/index.js +25 -9
- package/dist/configurators/index.js.map +1 -1
- package/dist/configurators/kiro.d.ts +4 -2
- package/dist/configurators/kiro.d.ts.map +1 -1
- package/dist/configurators/kiro.js +12 -3
- package/dist/configurators/kiro.js.map +1 -1
- package/dist/configurators/pi.d.ts.map +1 -1
- package/dist/configurators/pi.js +14 -4
- package/dist/configurators/pi.js.map +1 -1
- package/dist/configurators/shared.d.ts +0 -19
- package/dist/configurators/shared.d.ts.map +1 -1
- package/dist/configurators/shared.js +12 -32
- package/dist/configurators/shared.js.map +1 -1
- package/dist/configurators/trae.d.ts +17 -0
- package/dist/configurators/trae.d.ts.map +1 -0
- package/dist/configurators/trae.js +42 -0
- package/dist/configurators/trae.js.map +1 -0
- package/dist/configurators/zcode.js +3 -3
- package/dist/configurators/zcode.js.map +1 -1
- package/dist/migrations/manifests/0.6.4.json +9 -0
- package/dist/migrations/manifests/0.6.5.json +9 -0
- package/dist/templates/codex/skills/brainstorm/SKILL.md +19 -1
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +1 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +2 -2
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +2 -0
- package/dist/templates/common/skills/brainstorm.md +19 -1
- package/dist/templates/copilot/prompts/brainstorm.prompt.md +19 -1
- package/dist/templates/kiro/agents/trellis.json +34 -0
- package/dist/templates/kiro/hooks/trellis-workflow-state.kiro.hook +14 -0
- package/dist/templates/kiro/index.d.ts +16 -2
- package/dist/templates/kiro/index.d.ts.map +1 -1
- package/dist/templates/kiro/index.js +13 -3
- package/dist/templates/kiro/index.js.map +1 -1
- package/dist/templates/pi/agents/trellis-check.md +1 -1
- package/dist/templates/pi/agents/trellis-implement.md +1 -1
- package/dist/templates/pi/agents/trellis-research.md +1 -1
- package/dist/templates/pi/extensions/trellis/index.ts.txt +84 -8
- package/dist/templates/shared-hooks/index.d.ts +9 -3
- package/dist/templates/shared-hooks/index.d.ts.map +1 -1
- package/dist/templates/shared-hooks/index.js +14 -3
- package/dist/templates/shared-hooks/index.js.map +1 -1
- package/dist/templates/shared-hooks/inject-workflow-state.py +52 -7
- package/dist/templates/shared-hooks/session-start.py +13 -0
- package/dist/templates/trae/agents/trellis-check.md +108 -0
- package/dist/templates/trae/agents/trellis-implement.md +103 -0
- package/dist/templates/trae/agents/trellis-research.md +137 -0
- package/dist/templates/trae/hooks.json +27 -0
- package/dist/templates/trae/index.d.ts +15 -0
- package/dist/templates/trae/index.d.ts.map +1 -0
- package/dist/templates/trae/index.js +15 -0
- package/dist/templates/trae/index.js.map +1 -0
- package/dist/templates/trellis/scripts/common/active_task.py +2 -0
- package/dist/templates/trellis/scripts/common/cli_adapter.py +37 -11
- package/dist/templates/trellis/scripts/common/task_store.py +1 -0
- package/dist/templates/trellis/workflow.md +22 -20
- package/dist/types/ai-tools.d.ts +4 -4
- package/dist/types/ai-tools.d.ts.map +1 -1
- package/dist/types/ai-tools.js +16 -0
- package/dist/types/ai-tools.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.0",
|
|
3
|
+
"enabled": true,
|
|
4
|
+
"name": "trellis-workflow-state",
|
|
5
|
+
"description": "Inject Trellis workflow state on each prompt",
|
|
6
|
+
"when": {
|
|
7
|
+
"type": "promptSubmit"
|
|
8
|
+
},
|
|
9
|
+
"then": {
|
|
10
|
+
"type": "runCommand",
|
|
11
|
+
"command": "{{PYTHON_CMD}} .kiro/hooks/inject-workflow-state.py",
|
|
12
|
+
"timeout": 30
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
* Kiro templates
|
|
3
3
|
*
|
|
4
4
|
* Kiro uses pure JSON agent definitions, not Markdown.
|
|
5
|
-
*
|
|
5
|
+
* CLI agents embed hooks in their JSON (`hooks.agentSpawn`,
|
|
6
|
+
* `hooks.userPromptSubmit`); the IDE surface reads standalone `.kiro.hook`
|
|
7
|
+
* JSON files (`when`/`then` schema).
|
|
6
8
|
*
|
|
7
9
|
* Directory structure:
|
|
8
10
|
* kiro/
|
|
9
|
-
*
|
|
11
|
+
* ├── agents/ # Agent definitions (JSON) — main `trellis` + 3 sub-agents
|
|
12
|
+
* └── hooks/ # IDE `.kiro.hook` definitions (JSON)
|
|
10
13
|
*/
|
|
11
14
|
import { type AgentTemplate } from "../template-utils.js";
|
|
12
15
|
export type { AgentTemplate };
|
|
@@ -15,4 +18,15 @@ export type { AgentTemplate };
|
|
|
15
18
|
* Content contains {{PYTHON_CMD}} placeholder that must be resolved before writing.
|
|
16
19
|
*/
|
|
17
20
|
export declare const getAllAgents: () => AgentTemplate[];
|
|
21
|
+
export interface IdeHookTemplate {
|
|
22
|
+
/** Filename (e.g. "trellis-workflow-state.kiro.hook") */
|
|
23
|
+
name: string;
|
|
24
|
+
/** Raw JSON content; contains {{PYTHON_CMD}} placeholder. */
|
|
25
|
+
content: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get all Kiro IDE hook templates (`*.kiro.hook` JSON files).
|
|
29
|
+
* Content contains {{PYTHON_CMD}} placeholder that must be resolved before writing.
|
|
30
|
+
*/
|
|
31
|
+
export declare const getIdeHooks: () => IdeHookTemplate[];
|
|
18
32
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/kiro/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/kiro/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAChF,YAAY,EAAE,aAAa,EAAE,CAAC;AAM9B;;;GAGG;AACH,eAAO,MAAM,YAAY,QAAO,aAAa,EAAsB,CAAC;AAEpE,MAAM,WAAW,eAAe;IAC9B,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,QAAO,eAAe,EAGqB,CAAC"}
|
|
@@ -2,17 +2,27 @@
|
|
|
2
2
|
* Kiro templates
|
|
3
3
|
*
|
|
4
4
|
* Kiro uses pure JSON agent definitions, not Markdown.
|
|
5
|
-
*
|
|
5
|
+
* CLI agents embed hooks in their JSON (`hooks.agentSpawn`,
|
|
6
|
+
* `hooks.userPromptSubmit`); the IDE surface reads standalone `.kiro.hook`
|
|
7
|
+
* JSON files (`when`/`then` schema).
|
|
6
8
|
*
|
|
7
9
|
* Directory structure:
|
|
8
10
|
* kiro/
|
|
9
|
-
*
|
|
11
|
+
* ├── agents/ # Agent definitions (JSON) — main `trellis` + 3 sub-agents
|
|
12
|
+
* └── hooks/ # IDE `.kiro.hook` definitions (JSON)
|
|
10
13
|
*/
|
|
11
14
|
import { createTemplateReader } from "../template-utils.js";
|
|
12
|
-
const { listJsonAgents } = createTemplateReader(import.meta.url);
|
|
15
|
+
const { listFiles, readTemplate, listJsonAgents } = createTemplateReader(import.meta.url);
|
|
13
16
|
/**
|
|
14
17
|
* Get all Kiro agent templates (JSON format).
|
|
15
18
|
* Content contains {{PYTHON_CMD}} placeholder that must be resolved before writing.
|
|
16
19
|
*/
|
|
17
20
|
export const getAllAgents = () => listJsonAgents();
|
|
21
|
+
/**
|
|
22
|
+
* Get all Kiro IDE hook templates (`*.kiro.hook` JSON files).
|
|
23
|
+
* Content contains {{PYTHON_CMD}} placeholder that must be resolved before writing.
|
|
24
|
+
*/
|
|
25
|
+
export const getIdeHooks = () => listFiles("hooks")
|
|
26
|
+
.filter((f) => f.endsWith(".kiro.hook"))
|
|
27
|
+
.map((f) => ({ name: f, content: readTemplate(`hooks/${f}`) }));
|
|
18
28
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/kiro/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/kiro/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,oBAAoB,EAAsB,MAAM,sBAAsB,CAAC;AAGhF,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,oBAAoB,CACtE,MAAM,CAAC,IAAI,CAAC,GAAG,CAChB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAoB,EAAE,CAAC,cAAc,EAAE,CAAC;AASpE;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,GAAsB,EAAE,CACjD,SAAS,CAAC,OAAO,CAAC;KACf,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;KACvC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: trellis-check
|
|
3
3
|
description: |
|
|
4
4
|
Code quality check expert. Reviews changes against Trellis specs, fixes issues directly, and verifies quality gates.
|
|
5
|
-
tools:
|
|
5
|
+
tools: read, write, edit, bash, find, grep
|
|
6
6
|
---
|
|
7
7
|
# Check Agent
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: trellis-implement
|
|
3
3
|
description: |
|
|
4
4
|
Code implementation expert. Understands Trellis specs and requirements, then implements features. No git commit allowed.
|
|
5
|
-
tools:
|
|
5
|
+
tools: read, write, edit, bash, find, grep
|
|
6
6
|
---
|
|
7
7
|
# Implement Agent
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: trellis-research
|
|
3
3
|
description: |
|
|
4
4
|
Code and technical research expert. Finds relevant files, patterns, docs, and persists findings to the current task's research/ directory.
|
|
5
|
-
tools:
|
|
5
|
+
tools: read, write, bash, find, grep
|
|
6
6
|
---
|
|
7
7
|
# Research Agent
|
|
8
8
|
|
|
@@ -31,11 +31,13 @@ interface SubagentInput {
|
|
|
31
31
|
interface AgentConfig {
|
|
32
32
|
model?: string;
|
|
33
33
|
thinking?: string;
|
|
34
|
+
tools?: string[];
|
|
34
35
|
fallbackModels: string[];
|
|
35
36
|
}
|
|
36
37
|
interface PiRunConfig {
|
|
37
38
|
model?: string;
|
|
38
39
|
thinking?: string;
|
|
40
|
+
tools?: string[];
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
// ── Lazy-load pi-tui (avoid failing top-level imports) ─────────────────
|
|
@@ -81,6 +83,10 @@ const MAX_PARALLEL_PROMPTS = 6;
|
|
|
81
83
|
const ABORT_KILL_GRACE_MS = 1500;
|
|
82
84
|
const SESSION_OVERVIEW_TIMEOUT_MS = 1500;
|
|
83
85
|
const THROTTLE_MS = 500;
|
|
86
|
+
const FIRST_REPLY_NOTICE = `<first-reply-notice>
|
|
87
|
+
First visible reply: say once in Chinese that Trellis SessionStart context is loaded, then answer directly.
|
|
88
|
+
This notice is one-shot: do not repeat it after the first assistant reply in the same session.
|
|
89
|
+
</first-reply-notice>`;
|
|
84
90
|
|
|
85
91
|
// ── State types ───────────────────────────────────────────────────────
|
|
86
92
|
type RunStatus = "pending" | "running" | "succeeded" | "failed" | "cancelled";
|
|
@@ -654,8 +660,8 @@ function resolveRunCfg(
|
|
|
654
660
|
agentSuffixThinking ??
|
|
655
661
|
normalize(inheritedThinking);
|
|
656
662
|
if (baseModel && thinking && thinking !== "off")
|
|
657
|
-
return { model: `${baseModel}:${thinking}`, thinking };
|
|
658
|
-
return { model: baseModel || rawModel, thinking };
|
|
663
|
+
return { model: `${baseModel}:${thinking}`, thinking, tools: agentCfg.tools };
|
|
664
|
+
return { model: baseModel || rawModel, thinking, tools: agentCfg.tools };
|
|
659
665
|
}
|
|
660
666
|
|
|
661
667
|
function buildPiArgs(cfg: PiRunConfig): string[] {
|
|
@@ -669,6 +675,8 @@ function buildPiArgs(cfg: PiRunConfig): string[] {
|
|
|
669
675
|
);
|
|
670
676
|
else if (cfg.thinking && cfg.thinking !== "off")
|
|
671
677
|
args.push("--thinking", cfg.thinking);
|
|
678
|
+
if (cfg.tools && cfg.tools.length > 0)
|
|
679
|
+
args.push("--tools", cfg.tools.join(","));
|
|
672
680
|
return args;
|
|
673
681
|
}
|
|
674
682
|
|
|
@@ -762,6 +770,16 @@ function parseAgentFM(c: string): AgentConfig {
|
|
|
762
770
|
}
|
|
763
771
|
i--;
|
|
764
772
|
}
|
|
773
|
+
} else if (k === "tools") {
|
|
774
|
+
// Pi tool names are lowercase (read, bash, edit, write, grep, find, ls).
|
|
775
|
+
// Normalize to lowercase so mixed-case frontmatter still matches.
|
|
776
|
+
if (v.trim()) {
|
|
777
|
+
cfg.tools = v
|
|
778
|
+
.trim()
|
|
779
|
+
.split(",")
|
|
780
|
+
.map((s) => s.trim().replace(/^["']|["']$/g, "").toLowerCase())
|
|
781
|
+
.filter(Boolean);
|
|
782
|
+
}
|
|
765
783
|
}
|
|
766
784
|
}
|
|
767
785
|
return cfg;
|
|
@@ -862,12 +880,12 @@ function workflowBreadcrumb(root: string, key: string | null): string {
|
|
|
862
880
|
}
|
|
863
881
|
|
|
864
882
|
// ── Session Overview ───────────────────────────────────────────────────
|
|
865
|
-
function
|
|
883
|
+
function runContextScript(root: string, key: string | null, args: string[]): string {
|
|
866
884
|
const script = join(root, ".trellis", "scripts", "get_context.py");
|
|
867
885
|
if (!exists(script)) return "";
|
|
868
886
|
try {
|
|
869
887
|
const py = process.platform === "win32" ? "python" : "python3";
|
|
870
|
-
const result = spawnSync(py, [script], {
|
|
888
|
+
const result = spawnSync(py, [script, ...args], {
|
|
871
889
|
cwd: root,
|
|
872
890
|
env: key ? { ...process.env, TRELLIS_CONTEXT_ID: key } : process.env,
|
|
873
891
|
encoding: "utf-8",
|
|
@@ -876,12 +894,44 @@ function sessionOverview(root: string, key: string | null): string {
|
|
|
876
894
|
});
|
|
877
895
|
if (result.status !== 0) return "";
|
|
878
896
|
const stdout = (result.stdout ?? "").trim();
|
|
879
|
-
return stdout
|
|
897
|
+
return stdout;
|
|
880
898
|
} catch {
|
|
881
899
|
return "";
|
|
882
900
|
}
|
|
883
901
|
}
|
|
884
902
|
|
|
903
|
+
function sessionOverview(root: string, key: string | null): string {
|
|
904
|
+
const stdout = runContextScript(root, key, []);
|
|
905
|
+
return stdout ? `<session-overview>\n${stdout}\n</session-overview>` : "";
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
function workflowOverview(root: string, key: string | null): string {
|
|
909
|
+
const stdout = runContextScript(root, key, [
|
|
910
|
+
"--mode",
|
|
911
|
+
"phase",
|
|
912
|
+
"--platform",
|
|
913
|
+
"pi",
|
|
914
|
+
]);
|
|
915
|
+
return stdout ? `<trellis-workflow>\n${stdout}\n</trellis-workflow>` : "";
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
function buildStartupContext(
|
|
919
|
+
root: string,
|
|
920
|
+
key: string | null,
|
|
921
|
+
overview: string,
|
|
922
|
+
): string {
|
|
923
|
+
const workflow = workflowOverview(root, key);
|
|
924
|
+
return [
|
|
925
|
+
"<session-context>\nTrellis compact SessionStart context. Use it to orient the session; load details on demand.\n</session-context>",
|
|
926
|
+
FIRST_REPLY_NOTICE,
|
|
927
|
+
overview,
|
|
928
|
+
workflow,
|
|
929
|
+
"<ready>\nUse the current workflow state to decide whether to create, continue, or skip a Trellis task.\n</ready>",
|
|
930
|
+
]
|
|
931
|
+
.filter(Boolean)
|
|
932
|
+
.join("\n\n");
|
|
933
|
+
}
|
|
934
|
+
|
|
885
935
|
function buildContext(root: string, agent: string, key: string | null): string {
|
|
886
936
|
const dir = readTaskDir(root, key);
|
|
887
937
|
if (!dir)
|
|
@@ -1372,6 +1422,16 @@ export default function trellisExtension(pi: {
|
|
|
1372
1422
|
};
|
|
1373
1423
|
return turnCache;
|
|
1374
1424
|
};
|
|
1425
|
+
const startupKeys = new Set<string>();
|
|
1426
|
+
const getStartupCtx = (
|
|
1427
|
+
k: string | null,
|
|
1428
|
+
turn: { ov: string },
|
|
1429
|
+
): string => {
|
|
1430
|
+
const key = k ?? "default";
|
|
1431
|
+
if (startupKeys.has(key)) return "";
|
|
1432
|
+
startupKeys.add(key);
|
|
1433
|
+
return buildStartupContext(root, k, turn.ov);
|
|
1434
|
+
};
|
|
1375
1435
|
|
|
1376
1436
|
// Toggle only the latest subagent native card; do not use Pi global tool expansion.
|
|
1377
1437
|
const toggleDetail = (ctx: PiExtensionContext) => {
|
|
@@ -1550,7 +1610,7 @@ export default function trellisExtension(pi: {
|
|
|
1550
1610
|
pi.on?.("session_start", (event, ctx) => {
|
|
1551
1611
|
getKey(event, ctx);
|
|
1552
1612
|
ctx?.ui?.notify?.(
|
|
1553
|
-
"Trellis project context is available. Use /trellis-
|
|
1613
|
+
"Trellis project context is available. Use /trellis-start to bootstrap or /trellis-continue to resume.",
|
|
1554
1614
|
"info",
|
|
1555
1615
|
);
|
|
1556
1616
|
});
|
|
@@ -1585,13 +1645,29 @@ export default function trellisExtension(pi: {
|
|
|
1585
1645
|
return { isError: true };
|
|
1586
1646
|
return undefined;
|
|
1587
1647
|
});
|
|
1648
|
+
pi.on?.("input", (event, ctx) => {
|
|
1649
|
+
const k = getKey(event, ctx);
|
|
1650
|
+
const ev = event as { text?: string };
|
|
1651
|
+
if (typeof ev.text !== "string" || !ev.text.trim())
|
|
1652
|
+
return { action: "continue" };
|
|
1653
|
+
const { wf, ov } = getTurnCtx(k);
|
|
1654
|
+
const injection = [wf, ov].filter(Boolean).join("\n\n");
|
|
1655
|
+
if (!injection) return { action: "continue" };
|
|
1656
|
+
return {
|
|
1657
|
+
action: "transform",
|
|
1658
|
+
text: [ev.text, injection].join("\n\n"),
|
|
1659
|
+
};
|
|
1660
|
+
});
|
|
1588
1661
|
pi.on?.("before_agent_start", (event, ctx) => {
|
|
1589
1662
|
const k = getKey(event, ctx);
|
|
1590
1663
|
const cur = (event as { systemPrompt?: string }).systemPrompt ?? "";
|
|
1591
1664
|
const ctxText = buildContext(root, "trellis-implement", k);
|
|
1592
|
-
const
|
|
1665
|
+
const turn = getTurnCtx(k);
|
|
1666
|
+
const startup = getStartupCtx(k, turn);
|
|
1593
1667
|
return {
|
|
1594
|
-
systemPrompt: [cur, ctxText, wf, ov]
|
|
1668
|
+
systemPrompt: [cur, startup, ctxText, turn.wf, turn.ov]
|
|
1669
|
+
.filter(Boolean)
|
|
1670
|
+
.join("\n\n"),
|
|
1595
1671
|
};
|
|
1596
1672
|
});
|
|
1597
1673
|
pi.on?.("context", (event, ctx) => {
|
|
@@ -12,7 +12,7 @@ export interface HookScript {
|
|
|
12
12
|
content: string;
|
|
13
13
|
}
|
|
14
14
|
export type SharedHookName = "session-start.py" | "inject-shell-session-context.py" | "inject-workflow-state.py" | "inject-subagent-context.py";
|
|
15
|
-
export type SharedHookPlatform = "claude" | "cursor" | "codex" | "gemini" | "qoder" | "copilot" | "codebuddy" | "droid" | "kiro";
|
|
15
|
+
export type SharedHookPlatform = "claude" | "cursor" | "codex" | "gemini" | "qoder" | "copilot" | "codebuddy" | "droid" | "kiro" | "trae";
|
|
16
16
|
/**
|
|
17
17
|
* Which shared hooks each platform actually invokes. Single source of truth
|
|
18
18
|
* for shared-hook distribution — both `writeSharedHooks` (runtime install)
|
|
@@ -29,8 +29,14 @@ export type SharedHookPlatform = "claude" | "cursor" | "codex" | "gemini" | "qod
|
|
|
29
29
|
* Class-2 (pull-based) platforms (codex, copilot, gemini, qoder) can't
|
|
30
30
|
* have hooks mutate sub-agent prompts — their sub-agents load context
|
|
31
31
|
* via a prelude instead.
|
|
32
|
-
* - Kiro supports
|
|
33
|
-
*
|
|
32
|
+
* - Kiro supports per-turn + spawn hooks on both surfaces (per the official
|
|
33
|
+
* docs https://kiro.dev/docs/cli/hooks/): the CLI custom agent declares
|
|
34
|
+
* `hooks.userPromptSubmit` + `hooks.agentSpawn`, and the IDE declares a
|
|
35
|
+
* `.kiro.hook` with `when.type=promptSubmit`. So Kiro ships
|
|
36
|
+
* `session-start.py` (agentSpawn overview), `inject-workflow-state.py`
|
|
37
|
+
* (per-turn breadcrumb), and `inject-subagent-context.py` (sub-agent
|
|
38
|
+
* spawn). The scripts emit a plain-text Kiro branch — Kiro adds a hook's
|
|
39
|
+
* stdout directly to the conversation context (no JSON envelope).
|
|
34
40
|
* - Claude Code `statusLine` is intentionally not installed by default.
|
|
35
41
|
* Users can add their own statusLine command in `.claude/settings.json`,
|
|
36
42
|
* or opt in to the Trellis one via `trellis init --with-statusline`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/shared-hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GACtB,kBAAkB,GAClB,iCAAiC,GACjC,0BAA0B,GAC1B,4BAA4B,CAAC;AAEjC,MAAM,MAAM,kBAAkB,GAC1B,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,OAAO,GACP,SAAS,GACT,WAAW,GACX,OAAO,GACP,MAAM,CAAC;AAEX
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/shared-hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GACtB,kBAAkB,GAClB,iCAAiC,GACjC,0BAA0B,GAC1B,4BAA4B,CAAC;AAEjC,MAAM,MAAM,kBAAkB,GAC1B,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,OAAO,GACP,SAAS,GACT,WAAW,GACX,OAAO,GACP,MAAM,GACN,MAAM,CAAC;AAEX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAC3C,kBAAkB,EAClB,SAAS,cAAc,EAAE,CAgC1B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,UAAU,EAAE,CAWnD;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,kBAAkB,GAC3B,UAAU,EAAE,CAGd"}
|
|
@@ -29,8 +29,14 @@ function readTemplate(relativePath) {
|
|
|
29
29
|
* Class-2 (pull-based) platforms (codex, copilot, gemini, qoder) can't
|
|
30
30
|
* have hooks mutate sub-agent prompts — their sub-agents load context
|
|
31
31
|
* via a prelude instead.
|
|
32
|
-
* - Kiro supports
|
|
33
|
-
*
|
|
32
|
+
* - Kiro supports per-turn + spawn hooks on both surfaces (per the official
|
|
33
|
+
* docs https://kiro.dev/docs/cli/hooks/): the CLI custom agent declares
|
|
34
|
+
* `hooks.userPromptSubmit` + `hooks.agentSpawn`, and the IDE declares a
|
|
35
|
+
* `.kiro.hook` with `when.type=promptSubmit`. So Kiro ships
|
|
36
|
+
* `session-start.py` (agentSpawn overview), `inject-workflow-state.py`
|
|
37
|
+
* (per-turn breadcrumb), and `inject-subagent-context.py` (sub-agent
|
|
38
|
+
* spawn). The scripts emit a plain-text Kiro branch — Kiro adds a hook's
|
|
39
|
+
* stdout directly to the conversation context (no JSON envelope).
|
|
34
40
|
* - Claude Code `statusLine` is intentionally not installed by default.
|
|
35
41
|
* Users can add their own statusLine command in `.claude/settings.json`,
|
|
36
42
|
* or opt in to the Trellis one via `trellis init --with-statusline`
|
|
@@ -62,7 +68,12 @@ export const SHARED_HOOKS_BY_PLATFORM = {
|
|
|
62
68
|
"inject-workflow-state.py",
|
|
63
69
|
"inject-subagent-context.py",
|
|
64
70
|
],
|
|
65
|
-
kiro: [
|
|
71
|
+
kiro: [
|
|
72
|
+
"session-start.py",
|
|
73
|
+
"inject-workflow-state.py",
|
|
74
|
+
"inject-subagent-context.py",
|
|
75
|
+
],
|
|
76
|
+
trae: ["session-start.py", "inject-workflow-state.py"],
|
|
66
77
|
};
|
|
67
78
|
/**
|
|
68
79
|
* Get all shared hook scripts. Content is platform-independent and can be
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/shared-hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,SAAS,YAAY,CAAC,YAAoB;IACxC,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/shared-hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,SAAS,YAAY,CAAC,YAAoB;IACxC,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AA2BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAGjC;IACF,MAAM,EAAE;QACN,kBAAkB;QAClB,0BAA0B;QAC1B,4BAA4B;KAC7B;IACD,MAAM,EAAE;QACN,kBAAkB;QAClB,iCAAiC;QACjC,4BAA4B;KAC7B;IACD,KAAK,EAAE,CAAC,0BAA0B,CAAC;IACnC,MAAM,EAAE,CAAC,kBAAkB,EAAE,0BAA0B,CAAC;IACxD,KAAK,EAAE,CAAC,kBAAkB,EAAE,0BAA0B,CAAC;IACvD,OAAO,EAAE,CAAC,0BAA0B,CAAC;IACrC,SAAS,EAAE;QACT,kBAAkB;QAClB,0BAA0B;QAC1B,4BAA4B;KAC7B;IACD,KAAK,EAAE;QACL,kBAAkB;QAClB,0BAA0B;QAC1B,4BAA4B;KAC7B;IACD,IAAI,EAAE;QACJ,kBAAkB;QAClB,0BAA0B;QAC1B,4BAA4B;KAC7B;IACD,IAAI,EAAE,CAAC,kBAAkB,EAAE,0BAA0B,CAAC;CACvD,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC;SACjC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SAChC,IAAI,EAAE,CAAC;IAEV,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,+BAA+B,CAC7C,QAA4B;IAE5B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,wBAAwB,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpE,OAAO,oBAAoB,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -18,9 +18,11 @@ missing or a tag is absent, the breadcrumb degrades to a generic
|
|
|
18
18
|
the broken state instead of the hook silently masking it.
|
|
19
19
|
|
|
20
20
|
Shared across all hook-capable platforms (Claude, Cursor, Codex, Qoder,
|
|
21
|
-
CodeBuddy, Droid, Gemini, Copilot). Kiro
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
CodeBuddy, Droid, Gemini, Copilot, Kiro). Kiro wires this via the CLI
|
|
22
|
+
custom agent's ``hooks.userPromptSubmit`` and the IDE ``.kiro.hook``
|
|
23
|
+
``promptSubmit`` event; its output branch emits a plain-text breadcrumb
|
|
24
|
+
(Kiro adds hook stdout directly to the conversation context). Written to
|
|
25
|
+
each platform's hooks directory via writeSharedHooks() at init time.
|
|
24
26
|
|
|
25
27
|
Silent exit 0 cases (no output):
|
|
26
28
|
- No .trellis/ directory found (not a Trellis project)
|
|
@@ -32,6 +34,8 @@ import json
|
|
|
32
34
|
import os
|
|
33
35
|
import re
|
|
34
36
|
import sys
|
|
37
|
+
import queue
|
|
38
|
+
import threading
|
|
35
39
|
from pathlib import Path
|
|
36
40
|
|
|
37
41
|
# Force UTF-8 on stdin/stdout/stderr on Windows. Default codepage there is
|
|
@@ -100,6 +104,7 @@ def _detect_platform(input_data: dict) -> str | None:
|
|
|
100
104
|
"QODER_PROJECT_DIR": "qoder",
|
|
101
105
|
"KIRO_PROJECT_DIR": "kiro",
|
|
102
106
|
"COPILOT_PROJECT_DIR": "copilot",
|
|
107
|
+
"TRAE_PROJECT_DIR": "trae",
|
|
103
108
|
}
|
|
104
109
|
for env_name, platform in env_map.items():
|
|
105
110
|
if os.environ.get(env_name):
|
|
@@ -121,6 +126,8 @@ def _detect_platform(input_data: dict) -> str | None:
|
|
|
121
126
|
return "droid"
|
|
122
127
|
if ".kiro" in script_parts:
|
|
123
128
|
return "kiro"
|
|
129
|
+
if ".trae" in script_parts:
|
|
130
|
+
return "trae"
|
|
124
131
|
return None
|
|
125
132
|
|
|
126
133
|
|
|
@@ -300,14 +307,44 @@ def build_breadcrumb(
|
|
|
300
307
|
# Entry
|
|
301
308
|
# ---------------------------------------------------------------------------
|
|
302
309
|
|
|
310
|
+
def _load_hook_input() -> dict:
|
|
311
|
+
"""Read hook JSON without trusting host runners to close stdin.
|
|
312
|
+
|
|
313
|
+
Kiro IDE `runCommand` and similar hook runners can leave stdin open while
|
|
314
|
+
sending no payload. A plain `json.load(sys.stdin)` then blocks forever.
|
|
315
|
+
Normal hook runners write the complete JSON payload and close stdin, so the
|
|
316
|
+
short daemon read preserves that path while failing closed to `{}` for
|
|
317
|
+
non-piping hosts.
|
|
318
|
+
"""
|
|
319
|
+
result_queue: "queue.Queue[str | BaseException]" = queue.Queue(maxsize=1)
|
|
320
|
+
|
|
321
|
+
def _read() -> None:
|
|
322
|
+
try:
|
|
323
|
+
result_queue.put(sys.stdin.read())
|
|
324
|
+
except BaseException as exc:
|
|
325
|
+
result_queue.put(exc)
|
|
326
|
+
|
|
327
|
+
reader = threading.Thread(target=_read, daemon=True)
|
|
328
|
+
reader.start()
|
|
329
|
+
try:
|
|
330
|
+
raw = result_queue.get(timeout=0.2)
|
|
331
|
+
except queue.Empty:
|
|
332
|
+
return {}
|
|
333
|
+
|
|
334
|
+
if isinstance(raw, BaseException):
|
|
335
|
+
return {}
|
|
336
|
+
try:
|
|
337
|
+
data = json.loads(raw) if raw.strip() else {}
|
|
338
|
+
except (json.JSONDecodeError, ValueError):
|
|
339
|
+
return {}
|
|
340
|
+
return data if isinstance(data, dict) else {}
|
|
341
|
+
|
|
342
|
+
|
|
303
343
|
def main() -> int:
|
|
304
344
|
if os.environ.get("TRELLIS_HOOKS") == "0" or os.environ.get("TRELLIS_DISABLE_HOOKS") == "1":
|
|
305
345
|
return 0
|
|
306
346
|
|
|
307
|
-
|
|
308
|
-
data = json.load(sys.stdin)
|
|
309
|
-
except (json.JSONDecodeError, ValueError):
|
|
310
|
-
data = {}
|
|
347
|
+
data = _load_hook_input()
|
|
311
348
|
|
|
312
349
|
cwd_str = data.get("cwd") or os.getcwd()
|
|
313
350
|
cwd = Path(cwd_str)
|
|
@@ -342,6 +379,14 @@ def main() -> int:
|
|
|
342
379
|
parts.append(breadcrumb)
|
|
343
380
|
breadcrumb = "\n\n".join(parts)
|
|
344
381
|
|
|
382
|
+
# Kiro (CLI userPromptSubmit / IDE promptSubmit) adds a hook's stdout
|
|
383
|
+
# directly to the conversation context — no JSON envelope. Emit the bare
|
|
384
|
+
# breadcrumb text. Conditionally isolated: all other platforms keep the
|
|
385
|
+
# hookSpecificOutput JSON path below unchanged.
|
|
386
|
+
if platform == "kiro":
|
|
387
|
+
print(breadcrumb)
|
|
388
|
+
return 0
|
|
389
|
+
|
|
345
390
|
# Gemini CLI 0.40.x rejects "UserPromptSubmit" — its per-turn event is
|
|
346
391
|
# named "BeforeAgent". Other platforms (Claude/Cursor/Qoder/CodeBuddy/
|
|
347
392
|
# Droid/Codex/Copilot) accept the original Claude-style name.
|
|
@@ -137,6 +137,7 @@ def should_skip_injection() -> bool:
|
|
|
137
137
|
"GEMINI_NON_INTERACTIVE",
|
|
138
138
|
"KIRO_NON_INTERACTIVE",
|
|
139
139
|
"COPILOT_NON_INTERACTIVE",
|
|
140
|
+
"TRAE_NON_INTERACTIVE",
|
|
140
141
|
]
|
|
141
142
|
return any(os.environ.get(var) == "1" for var in non_interactive_vars)
|
|
142
143
|
|
|
@@ -195,6 +196,7 @@ def _detect_platform(input_data: dict) -> str | None:
|
|
|
195
196
|
"QODER_PROJECT_DIR": "qoder",
|
|
196
197
|
"KIRO_PROJECT_DIR": "kiro",
|
|
197
198
|
"COPILOT_PROJECT_DIR": "copilot",
|
|
199
|
+
"TRAE_PROJECT_DIR": "trae",
|
|
198
200
|
}
|
|
199
201
|
for env_name, platform in env_map.items():
|
|
200
202
|
if os.environ.get(env_name):
|
|
@@ -216,6 +218,8 @@ def _detect_platform(input_data: dict) -> str | None:
|
|
|
216
218
|
return "droid"
|
|
217
219
|
if ".kiro" in script_parts:
|
|
218
220
|
return "kiro"
|
|
221
|
+
if ".trae" in script_parts:
|
|
222
|
+
return "trae"
|
|
219
223
|
return None
|
|
220
224
|
|
|
221
225
|
|
|
@@ -739,6 +743,7 @@ def main():
|
|
|
739
743
|
"GEMINI_PROJECT_DIR",
|
|
740
744
|
"KIRO_PROJECT_DIR",
|
|
741
745
|
"COPILOT_PROJECT_DIR",
|
|
746
|
+
"TRAE_PROJECT_DIR",
|
|
742
747
|
]
|
|
743
748
|
project_dir = None
|
|
744
749
|
for var in project_dir_env_vars:
|
|
@@ -813,6 +818,14 @@ Context loaded. Follow <task-status>. Load workflow/spec/task details only when
|
|
|
813
818
|
</ready>""")
|
|
814
819
|
|
|
815
820
|
context_text = output.getvalue()
|
|
821
|
+
|
|
822
|
+
# Kiro (CLI trellis agent agentSpawn) adds a hook's stdout directly to the
|
|
823
|
+
# conversation context — no JSON envelope. Emit the bare overview text.
|
|
824
|
+
# Conditionally isolated: all other platforms keep the JSON path below.
|
|
825
|
+
if _detect_platform(hook_input) == "kiro":
|
|
826
|
+
print(context_text, flush=True)
|
|
827
|
+
return
|
|
828
|
+
|
|
816
829
|
result = {
|
|
817
830
|
# Claude Code / Qoder / CodeBuddy / Droid / Gemini / Copilot format
|
|
818
831
|
"hookSpecificOutput": {
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: trellis-check
|
|
3
|
+
description: |
|
|
4
|
+
Code quality check expert. Reviews code changes against specs and self-fixes issues.
|
|
5
|
+
tools: Read, Write, Edit, Bash, Glob, Grep
|
|
6
|
+
---
|
|
7
|
+
# Check Agent
|
|
8
|
+
|
|
9
|
+
You are the Check Agent in the Trellis workflow.
|
|
10
|
+
|
|
11
|
+
## Recursion Guard
|
|
12
|
+
|
|
13
|
+
You are already the `trellis-check` sub-agent that the main session dispatched. Do the review and fixes directly.
|
|
14
|
+
|
|
15
|
+
- Do NOT spawn another `trellis-check` or `trellis-implement` sub-agent.
|
|
16
|
+
- If SessionStart context, workflow-state breadcrumbs, or workflow.md say to dispatch `trellis-implement` / `trellis-check`, treat that as a main-session instruction that is already satisfied by your current role.
|
|
17
|
+
- Only the main session may dispatch Trellis implement/check agents. If more implementation work is needed, report that recommendation instead of spawning.
|
|
18
|
+
|
|
19
|
+
## Context
|
|
20
|
+
|
|
21
|
+
Before checking, read:
|
|
22
|
+
- `.trellis/spec/` - Development guidelines
|
|
23
|
+
- Task `prd.md` - Requirements document
|
|
24
|
+
- Task `design.md` - Technical design (if exists)
|
|
25
|
+
- Task `implement.md` - Execution plan (if exists)
|
|
26
|
+
- Pre-commit checklist for quality standards
|
|
27
|
+
|
|
28
|
+
## Core Responsibilities
|
|
29
|
+
|
|
30
|
+
1. **Get code changes** - Use git diff to get uncommitted code
|
|
31
|
+
2. **Review task artifacts** - Check changes against prd.md, design.md if present, and implement.md if present
|
|
32
|
+
3. **Check against specs** - Verify code follows guidelines
|
|
33
|
+
4. **Self-fix** - Fix issues yourself, not just report them
|
|
34
|
+
5. **Run verification** - typecheck and lint
|
|
35
|
+
|
|
36
|
+
## Important
|
|
37
|
+
|
|
38
|
+
**Fix issues yourself**, don't just report them.
|
|
39
|
+
|
|
40
|
+
You have write and edit tools, you can modify code directly.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Workflow
|
|
45
|
+
|
|
46
|
+
### Step 1: Get Changes
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
git diff --name-only # List changed files
|
|
50
|
+
git diff # View specific changes
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Step 2: Check Against Specs and Task Artifacts
|
|
54
|
+
|
|
55
|
+
Read the task's prd.md, design.md if present, and implement.md if present, then read relevant specs in `.trellis/spec/` to check code:
|
|
56
|
+
|
|
57
|
+
- Does it satisfy the task requirements
|
|
58
|
+
- Does it follow the technical design and implementation plan when present
|
|
59
|
+
- Does it follow directory structure conventions
|
|
60
|
+
- Does it follow naming conventions
|
|
61
|
+
- Does it follow code patterns
|
|
62
|
+
- Are there missing types
|
|
63
|
+
- Are there potential bugs
|
|
64
|
+
|
|
65
|
+
### Step 3: Self-Fix
|
|
66
|
+
|
|
67
|
+
After finding issues:
|
|
68
|
+
|
|
69
|
+
1. Fix the issue directly (use edit tool)
|
|
70
|
+
2. Record what was fixed
|
|
71
|
+
3. Continue checking other issues
|
|
72
|
+
|
|
73
|
+
### Step 4: Run Verification
|
|
74
|
+
|
|
75
|
+
Run project's lint and typecheck commands to verify changes.
|
|
76
|
+
|
|
77
|
+
If failed, fix issues and re-run.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Report Format
|
|
82
|
+
|
|
83
|
+
```markdown
|
|
84
|
+
## Self-Check Complete
|
|
85
|
+
|
|
86
|
+
### Files Checked
|
|
87
|
+
|
|
88
|
+
- src/components/Feature.tsx
|
|
89
|
+
- src/hooks/useFeature.ts
|
|
90
|
+
|
|
91
|
+
### Issues Found and Fixed
|
|
92
|
+
|
|
93
|
+
1. `<file>:<line>` - <what was fixed>
|
|
94
|
+
2. `<file>:<line>` - <what was fixed>
|
|
95
|
+
|
|
96
|
+
### Issues Not Fixed
|
|
97
|
+
|
|
98
|
+
(If there are issues that cannot be self-fixed, list them here with reasons)
|
|
99
|
+
|
|
100
|
+
### Verification Results
|
|
101
|
+
|
|
102
|
+
- TypeCheck: Passed
|
|
103
|
+
- Lint: Passed
|
|
104
|
+
|
|
105
|
+
### Summary
|
|
106
|
+
|
|
107
|
+
Checked X files, found Y issues, all fixed.
|
|
108
|
+
```
|