@fitlab-ai/agent-infra 0.6.5 → 0.7.1
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 +51 -25
- package/README.zh-CN.md +49 -23
- package/bin/cli.ts +1 -1
- package/dist/bin/cli.js +1 -1
- package/dist/lib/builtin-tuis.js +45 -0
- package/dist/lib/defaults.json +4 -0
- package/dist/lib/init.js +65 -23
- package/dist/lib/prompt.js +49 -1
- package/dist/lib/sandbox/commands/create.js +4 -2
- package/dist/lib/sandbox/commands/enter.js +15 -4
- package/dist/lib/sandbox/commands/list-running.js +153 -0
- package/dist/lib/sandbox/commands/ls.js +24 -45
- package/dist/lib/sandbox/commands/rebuild.js +7 -13
- package/dist/lib/sandbox/commands/rm.js +2 -0
- package/dist/lib/sandbox/config.js +3 -0
- package/dist/lib/sandbox/image-prune.js +18 -0
- package/dist/lib/sandbox/index.js +2 -1
- package/dist/lib/sandbox/runtimes/ai-tools.dockerfile +10 -6
- package/dist/lib/sandbox/task-resolver.js +18 -0
- package/dist/lib/sandbox/tools.js +213 -8
- package/dist/lib/update.js +70 -18
- package/lib/builtin-tuis.ts +55 -0
- package/lib/defaults.json +4 -0
- package/lib/init.ts +97 -35
- package/lib/prompt.ts +54 -1
- package/lib/sandbox/commands/create.ts +10 -2
- package/lib/sandbox/commands/enter.ts +14 -4
- package/lib/sandbox/commands/list-running.ts +188 -0
- package/lib/sandbox/commands/ls.ts +28 -49
- package/lib/sandbox/commands/rebuild.ts +12 -14
- package/lib/sandbox/commands/rm.ts +3 -0
- package/lib/sandbox/config.ts +7 -0
- package/lib/sandbox/image-prune.ts +23 -0
- package/lib/sandbox/index.ts +2 -1
- package/lib/sandbox/runtimes/ai-tools.dockerfile +10 -6
- package/lib/sandbox/task-resolver.ts +23 -1
- package/lib/sandbox/tools.ts +248 -9
- package/lib/update.ts +85 -30
- package/package.json +1 -1
- package/templates/.agents/QUICKSTART.en.md +1 -1
- package/templates/.agents/QUICKSTART.zh-CN.md +1 -1
- package/templates/.agents/README.en.md +111 -2
- package/templates/.agents/README.zh-CN.md +111 -2
- package/templates/.agents/rules/create-issue.en.md +1 -1
- package/templates/.agents/rules/create-issue.github.en.md +1 -1
- package/templates/.agents/rules/create-issue.github.zh-CN.md +1 -1
- package/templates/.agents/rules/create-issue.zh-CN.md +1 -1
- package/templates/.agents/rules/issue-sync.github.en.md +6 -5
- package/templates/.agents/rules/issue-sync.github.zh-CN.md +6 -5
- package/templates/.agents/rules/milestone-inference.github.en.md +2 -2
- package/templates/.agents/rules/milestone-inference.github.zh-CN.md +2 -2
- package/templates/.agents/rules/no-mid-flow-questions.en.md +57 -0
- package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +57 -0
- package/templates/.agents/rules/pr-sync.github.en.md +4 -5
- package/templates/.agents/rules/pr-sync.github.zh-CN.md +4 -5
- package/templates/.agents/rules/task-management.en.md +9 -6
- package/templates/.agents/rules/task-management.zh-CN.md +9 -6
- package/templates/.agents/rules/task-short-id.en.md +141 -0
- package/templates/.agents/rules/task-short-id.zh-CN.md +124 -0
- package/templates/.agents/rules/testing-discipline.en.md +2 -2
- package/templates/.agents/rules/testing-discipline.zh-CN.md +2 -2
- package/templates/.agents/scripts/task-short-id.js +713 -0
- package/templates/.agents/scripts/validate-artifact.js +1 -1
- package/templates/.agents/skills/analyze-task/SKILL.en.md +20 -4
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +20 -5
- package/templates/.agents/skills/block-task/SKILL.en.md +12 -0
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +12 -1
- package/templates/.agents/skills/cancel-task/SKILL.en.md +12 -0
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +12 -1
- package/templates/.agents/skills/check-task/SKILL.en.md +47 -32
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +46 -32
- package/templates/.agents/skills/close-codescan/SKILL.en.md +11 -0
- package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +11 -0
- package/templates/.agents/skills/close-dependabot/SKILL.en.md +11 -0
- package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +11 -0
- package/templates/.agents/skills/code-task/SKILL.en.md +121 -0
- package/templates/.agents/skills/{implement-task → code-task}/SKILL.zh-CN.md +55 -25
- package/templates/.agents/skills/{implement-task → code-task}/config/verify.en.json +4 -4
- package/templates/.agents/skills/{implement-task → code-task}/config/verify.zh-CN.json +4 -4
- package/templates/.agents/skills/{implement-task → code-task}/reference/branch-management.zh-CN.md +2 -2
- package/templates/.agents/skills/{implement-task/reference/implementation-rules.en.md → code-task/reference/code-rules.en.md} +6 -6
- package/templates/.agents/skills/{implement-task/reference/implementation-rules.zh-CN.md → code-task/reference/code-rules.zh-CN.md} +3 -3
- package/templates/.agents/skills/code-task/reference/dual-mode.en.md +69 -0
- package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +69 -0
- package/templates/.agents/skills/{refine-task/reference/fix-workflow.en.md → code-task/reference/fix-mode.en.md} +12 -12
- package/templates/.agents/skills/{refine-task/reference/fix-workflow.zh-CN.md → code-task/reference/fix-mode.zh-CN.md} +8 -8
- package/templates/.agents/skills/code-task/reference/output-template.en.md +20 -0
- package/templates/.agents/skills/code-task/reference/output-template.zh-CN.md +20 -0
- package/templates/.agents/skills/{implement-task → code-task}/reference/report-template.en.md +4 -4
- package/templates/.agents/skills/{implement-task → code-task}/reference/report-template.zh-CN.md +3 -3
- package/templates/.agents/skills/code-task/scripts/detect-mode.js +370 -0
- package/templates/.agents/skills/commit/SKILL.en.md +6 -2
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +6 -2
- package/templates/.agents/skills/commit/reference/task-status-update.en.md +10 -6
- package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +10 -6
- package/templates/.agents/skills/complete-task/SKILL.en.md +17 -3
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +17 -4
- package/templates/.agents/skills/create-pr/SKILL.en.md +21 -1
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +21 -1
- package/templates/.agents/skills/create-task/SKILL.en.md +14 -0
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +14 -1
- package/templates/.agents/skills/import-codescan/SKILL.en.md +15 -1
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +15 -1
- package/templates/.agents/skills/import-dependabot/SKILL.en.md +16 -2
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +16 -2
- package/templates/.agents/skills/import-issue/SKILL.en.md +17 -3
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +17 -3
- package/templates/.agents/skills/plan-task/SKILL.en.md +8 -4
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +8 -5
- package/templates/.agents/skills/restore-task/SKILL.en.md +16 -3
- package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +16 -4
- package/templates/.agents/skills/review-analysis/SKILL.en.md +80 -0
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +105 -0
- package/templates/.agents/skills/review-analysis/config/verify.en.json +51 -0
- package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +51 -0
- package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +87 -0
- package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +87 -0
- package/templates/.agents/skills/review-analysis/reference/report-template.en.md +90 -0
- package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +91 -0
- package/templates/.agents/skills/review-analysis/reference/review-criteria.en.md +47 -0
- package/templates/.agents/skills/review-analysis/reference/review-criteria.zh-CN.md +47 -0
- package/templates/.agents/skills/{review-task → review-code}/SKILL.en.md +15 -9
- package/templates/.agents/skills/{review-task → review-code}/SKILL.zh-CN.md +19 -10
- package/templates/.agents/skills/{review-task → review-code}/config/verify.en.json +7 -5
- package/templates/.agents/skills/{review-task → review-code}/config/verify.zh-CN.json +6 -4
- package/templates/.agents/skills/{review-task → review-code}/reference/output-templates.en.md +21 -17
- package/templates/.agents/skills/{review-task → review-code}/reference/output-templates.zh-CN.md +19 -15
- package/templates/.agents/skills/{review-task → review-code}/reference/report-template.en.md +5 -6
- package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +91 -0
- package/templates/.agents/skills/review-code/reference/review-criteria.en.md +48 -0
- package/templates/.agents/skills/{review-task → review-code}/reference/review-criteria.zh-CN.md +10 -4
- package/templates/.agents/skills/review-plan/SKILL.en.md +80 -0
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +105 -0
- package/templates/.agents/skills/{refine-task → review-plan}/config/verify.en.json +14 -10
- package/templates/.agents/skills/{refine-task → review-plan}/config/verify.zh-CN.json +14 -10
- package/templates/.agents/skills/review-plan/reference/output-templates.en.md +87 -0
- package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +87 -0
- package/templates/.agents/skills/review-plan/reference/report-template.en.md +90 -0
- package/templates/.agents/skills/{review-task → review-plan}/reference/report-template.zh-CN.md +3 -3
- package/templates/.agents/skills/review-plan/reference/review-criteria.en.md +47 -0
- package/templates/.agents/skills/review-plan/reference/review-criteria.zh-CN.md +47 -0
- package/templates/.agents/skills/test/SKILL.en.md +2 -2
- package/templates/.agents/skills/test/SKILL.zh-CN.md +13 -31
- package/templates/.agents/skills/update-agent-infra/SKILL.en.md +1 -0
- package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +1 -0
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +113 -21
- package/templates/.agents/templates/task.en.md +4 -3
- package/templates/.agents/templates/task.zh-CN.md +3 -2
- package/templates/.agents/workflows/bug-fix.en.yaml +126 -80
- package/templates/.agents/workflows/bug-fix.zh-CN.yaml +90 -44
- package/templates/.agents/workflows/feature-development.en.yaml +115 -70
- package/templates/.agents/workflows/feature-development.zh-CN.yaml +92 -47
- package/templates/.agents/workflows/refactoring.en.yaml +123 -78
- package/templates/.agents/workflows/refactoring.zh-CN.yaml +89 -44
- package/templates/.claude/commands/code-task.en.md +8 -0
- package/templates/.claude/commands/code-task.zh-CN.md +8 -0
- package/templates/.claude/commands/review-analysis.en.md +8 -0
- package/templates/.claude/commands/review-analysis.zh-CN.md +8 -0
- package/templates/.claude/commands/review-code.en.md +8 -0
- package/templates/.claude/commands/review-code.zh-CN.md +8 -0
- package/templates/.claude/commands/review-plan.en.md +8 -0
- package/templates/.claude/commands/review-plan.zh-CN.md +8 -0
- package/templates/.gemini/commands/_project_/archive-tasks.zh-CN.toml +1 -1
- package/templates/.gemini/commands/_project_/code-task.en.toml +8 -0
- package/templates/.gemini/commands/_project_/code-task.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/init-labels.zh-CN.toml +1 -1
- package/templates/.gemini/commands/_project_/init-milestones.zh-CN.toml +1 -1
- package/templates/.gemini/commands/_project_/review-analysis.en.toml +8 -0
- package/templates/.gemini/commands/_project_/review-analysis.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/review-code.en.toml +8 -0
- package/templates/.gemini/commands/_project_/review-code.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/review-plan.en.toml +8 -0
- package/templates/.gemini/commands/_project_/review-plan.zh-CN.toml +8 -0
- package/templates/.opencode/commands/code-task.en.md +11 -0
- package/templates/.opencode/commands/code-task.zh-CN.md +11 -0
- package/templates/.opencode/commands/review-analysis.en.md +11 -0
- package/templates/.opencode/commands/review-analysis.zh-CN.md +11 -0
- package/templates/.opencode/commands/review-code.en.md +11 -0
- package/templates/.opencode/commands/review-code.zh-CN.md +11 -0
- package/templates/.opencode/commands/review-plan.en.md +11 -0
- package/templates/.opencode/commands/review-plan.zh-CN.md +11 -0
- package/templates/.agents/skills/implement-task/SKILL.en.md +0 -173
- package/templates/.agents/skills/implement-task/reference/output-template.en.md +0 -20
- package/templates/.agents/skills/implement-task/reference/output-template.zh-CN.md +0 -20
- package/templates/.agents/skills/refine-task/SKILL.en.md +0 -153
- package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +0 -153
- package/templates/.agents/skills/refine-task/reference/report-template.en.md +0 -64
- package/templates/.agents/skills/refine-task/reference/report-template.zh-CN.md +0 -64
- package/templates/.agents/skills/review-task/reference/review-criteria.en.md +0 -42
- package/templates/.claude/commands/implement-task.en.md +0 -8
- package/templates/.claude/commands/implement-task.zh-CN.md +0 -8
- package/templates/.claude/commands/refine-task.en.md +0 -8
- package/templates/.claude/commands/refine-task.zh-CN.md +0 -8
- package/templates/.claude/commands/review-task.en.md +0 -8
- package/templates/.claude/commands/review-task.zh-CN.md +0 -8
- package/templates/.gemini/commands/_project_/implement-task.en.toml +0 -8
- package/templates/.gemini/commands/_project_/implement-task.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/refine-task.en.toml +0 -8
- package/templates/.gemini/commands/_project_/refine-task.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/review-task.en.toml +0 -8
- package/templates/.gemini/commands/_project_/review-task.zh-CN.toml +0 -8
- package/templates/.opencode/commands/implement-task.en.md +0 -11
- package/templates/.opencode/commands/implement-task.zh-CN.md +0 -11
- package/templates/.opencode/commands/refine-task.en.md +0 -11
- package/templates/.opencode/commands/refine-task.zh-CN.md +0 -11
- package/templates/.opencode/commands/review-task.en.md +0 -11
- package/templates/.opencode/commands/review-task.zh-CN.md +0 -11
- /package/templates/.agents/skills/{implement-task → code-task}/reference/branch-management.en.md +0 -0
package/lib/update.ts
CHANGED
|
@@ -3,6 +3,8 @@ import path from 'node:path';
|
|
|
3
3
|
import { info, ok, err } from './log.ts';
|
|
4
4
|
import { resolveTemplateDir } from './paths.ts';
|
|
5
5
|
import { renderFile, copySkillDir, KNOWN_PLATFORMS } from './render.ts';
|
|
6
|
+
import { isPathOwnedByDisabledTUI, resolveEnabledTUIs } from './builtin-tuis.ts';
|
|
7
|
+
import type { BuiltinTUIId } from './builtin-tuis.ts';
|
|
6
8
|
|
|
7
9
|
type FileRegistry = {
|
|
8
10
|
managed: string[];
|
|
@@ -15,14 +17,19 @@ type UpdateConfig = {
|
|
|
15
17
|
org: string;
|
|
16
18
|
language: string;
|
|
17
19
|
platform?: { type?: string };
|
|
20
|
+
requiresPullRequest?: boolean;
|
|
18
21
|
sandbox?: Record<string, unknown>;
|
|
22
|
+
task?: { shortIdLength: number };
|
|
19
23
|
labels?: Record<string, unknown>;
|
|
20
24
|
files?: Partial<FileRegistry>;
|
|
25
|
+
tuis?: unknown;
|
|
21
26
|
};
|
|
22
27
|
|
|
23
28
|
type Defaults = {
|
|
24
29
|
platform: { type: string };
|
|
30
|
+
requiresPullRequest: boolean;
|
|
25
31
|
sandbox: Record<string, unknown>;
|
|
32
|
+
task: { shortIdLength: number };
|
|
26
33
|
labels: Record<string, unknown>;
|
|
27
34
|
files: FileRegistry;
|
|
28
35
|
};
|
|
@@ -43,7 +50,7 @@ function isPathOwnedByOtherPlatform(relativePath: string, platformType: string):
|
|
|
43
50
|
return candidate !== platformType;
|
|
44
51
|
}
|
|
45
52
|
|
|
46
|
-
function syncFileRegistry(config: UpdateConfig, platformType: string) {
|
|
53
|
+
function syncFileRegistry(config: UpdateConfig, platformType: string, enabledTUIs: Set<BuiltinTUIId>) {
|
|
47
54
|
config.files ||= {};
|
|
48
55
|
const before = JSON.stringify({
|
|
49
56
|
files: {
|
|
@@ -65,6 +72,7 @@ function syncFileRegistry(config: UpdateConfig, platformType: string) {
|
|
|
65
72
|
|
|
66
73
|
for (const entry of defaults.files.managed) {
|
|
67
74
|
if (isPathOwnedByOtherPlatform(entry, platformType)) continue;
|
|
75
|
+
if (isPathOwnedByDisabledTUI(entry, enabledTUIs)) continue;
|
|
68
76
|
if (!allExisting.includes(entry)) {
|
|
69
77
|
config.files.managed.push(entry);
|
|
70
78
|
added.managed.push(entry);
|
|
@@ -72,6 +80,7 @@ function syncFileRegistry(config: UpdateConfig, platformType: string) {
|
|
|
72
80
|
}
|
|
73
81
|
for (const entry of defaults.files.merged) {
|
|
74
82
|
if (isPathOwnedByOtherPlatform(entry, platformType)) continue;
|
|
83
|
+
if (isPathOwnedByDisabledTUI(entry, enabledTUIs)) continue;
|
|
75
84
|
if (!allExisting.includes(entry)) {
|
|
76
85
|
config.files.merged.push(entry);
|
|
77
86
|
added.merged.push(entry);
|
|
@@ -116,6 +125,7 @@ async function cmdUpdate(): Promise<void> {
|
|
|
116
125
|
const config = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8')) as UpdateConfig;
|
|
117
126
|
const { project, org, language } = config;
|
|
118
127
|
const platformType = config.platform?.type || defaults.platform.type;
|
|
128
|
+
const enabledTUIs = resolveEnabledTUIs(config.tuis);
|
|
119
129
|
const replacements = { project, org };
|
|
120
130
|
|
|
121
131
|
info(`Updating seed files for: ${project}`);
|
|
@@ -148,36 +158,44 @@ async function cmdUpdate(): Promise<void> {
|
|
|
148
158
|
// Ignore missing legacy script from pre-ESM installs.
|
|
149
159
|
}
|
|
150
160
|
|
|
151
|
-
// update Claude command
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
161
|
+
// update Claude command (only if enabled)
|
|
162
|
+
if (enabledTUIs.has('claude-code')) {
|
|
163
|
+
renderFile(
|
|
164
|
+
path.join(templateDir, '.claude', 'commands', claudeSrc),
|
|
165
|
+
path.join('.claude', 'commands', 'update-agent-infra.md'),
|
|
166
|
+
replacements
|
|
167
|
+
);
|
|
168
|
+
ok('Updated .claude/commands/update-agent-infra.md');
|
|
169
|
+
}
|
|
158
170
|
|
|
159
|
-
// update Gemini command
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
171
|
+
// update Gemini command (only if enabled)
|
|
172
|
+
if (enabledTUIs.has('gemini-cli')) {
|
|
173
|
+
renderFile(
|
|
174
|
+
path.join(templateDir, '.gemini', 'commands', '_project_', geminiSrc),
|
|
175
|
+
path.join('.gemini', 'commands', project, 'update-agent-infra.toml'),
|
|
176
|
+
replacements
|
|
177
|
+
);
|
|
178
|
+
ok(`Updated .gemini/commands/${project}/update-agent-infra.toml`);
|
|
179
|
+
}
|
|
166
180
|
|
|
167
|
-
// update OpenCode command
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
181
|
+
// update OpenCode command (only if enabled)
|
|
182
|
+
if (enabledTUIs.has('opencode')) {
|
|
183
|
+
renderFile(
|
|
184
|
+
path.join(templateDir, '.opencode', 'commands', opencodeSrc),
|
|
185
|
+
path.join('.opencode', 'commands', 'update-agent-infra.md'),
|
|
186
|
+
replacements
|
|
187
|
+
);
|
|
188
|
+
ok('Updated .opencode/commands/update-agent-infra.md');
|
|
189
|
+
}
|
|
174
190
|
|
|
175
191
|
// sync file registry
|
|
176
|
-
const { added, changed } = syncFileRegistry(config, platformType);
|
|
192
|
+
const { added, changed } = syncFileRegistry(config, platformType, enabledTUIs);
|
|
177
193
|
const hasNewEntries = added.managed.length > 0 || added.merged.length > 0;
|
|
178
194
|
const platformAdded = !config.platform;
|
|
179
195
|
const sandboxAdded = !config.sandbox;
|
|
196
|
+
const taskAdded = !config.task;
|
|
180
197
|
const labelsAdded = !config.labels;
|
|
198
|
+
const requiresPullRequestAdded = config.requiresPullRequest === undefined;
|
|
181
199
|
let configChanged = changed;
|
|
182
200
|
|
|
183
201
|
if (platformAdded) {
|
|
@@ -190,11 +208,21 @@ async function cmdUpdate(): Promise<void> {
|
|
|
190
208
|
configChanged = true;
|
|
191
209
|
}
|
|
192
210
|
|
|
211
|
+
if (taskAdded) {
|
|
212
|
+
config.task = structuredClone(defaults.task);
|
|
213
|
+
configChanged = true;
|
|
214
|
+
}
|
|
215
|
+
|
|
193
216
|
if (labelsAdded) {
|
|
194
217
|
config.labels = structuredClone(defaults.labels);
|
|
195
218
|
configChanged = true;
|
|
196
219
|
}
|
|
197
220
|
|
|
221
|
+
if (requiresPullRequestAdded) {
|
|
222
|
+
config.requiresPullRequest = defaults.requiresPullRequest;
|
|
223
|
+
configChanged = true;
|
|
224
|
+
}
|
|
225
|
+
|
|
198
226
|
if (configChanged) {
|
|
199
227
|
console.log('');
|
|
200
228
|
if (hasNewEntries) {
|
|
@@ -205,28 +233,40 @@ async function cmdUpdate(): Promise<void> {
|
|
|
205
233
|
for (const entry of added.merged) {
|
|
206
234
|
ok(` merged: ${entry}`);
|
|
207
235
|
}
|
|
208
|
-
} else if (platformAdded || sandboxAdded || labelsAdded) {
|
|
236
|
+
} else if (platformAdded || sandboxAdded || taskAdded || labelsAdded || requiresPullRequestAdded) {
|
|
209
237
|
if (platformAdded) {
|
|
210
238
|
info(`Default platform config added to ${CONFIG_PATH}.`);
|
|
211
239
|
}
|
|
212
240
|
if (sandboxAdded) {
|
|
213
241
|
info(`Default sandbox config added to ${CONFIG_PATH}.`);
|
|
214
242
|
}
|
|
243
|
+
if (taskAdded) {
|
|
244
|
+
info(`Default task.shortIdLength=${defaults.task.shortIdLength} added to ${CONFIG_PATH}.`);
|
|
245
|
+
}
|
|
215
246
|
if (labelsAdded) {
|
|
216
247
|
info(`Default labels.in config added to ${CONFIG_PATH}.`);
|
|
217
248
|
}
|
|
249
|
+
if (requiresPullRequestAdded) {
|
|
250
|
+
info(`Default requiresPullRequest=${defaults.requiresPullRequest} added to ${CONFIG_PATH}.`);
|
|
251
|
+
}
|
|
218
252
|
} else {
|
|
219
253
|
info(`File registry changed in ${CONFIG_PATH}.`);
|
|
220
254
|
}
|
|
221
255
|
if (hasNewEntries && sandboxAdded) {
|
|
222
256
|
info(`Default sandbox config added to ${CONFIG_PATH}.`);
|
|
223
257
|
}
|
|
258
|
+
if (hasNewEntries && taskAdded) {
|
|
259
|
+
info(`Default task.shortIdLength=${defaults.task.shortIdLength} added to ${CONFIG_PATH}.`);
|
|
260
|
+
}
|
|
224
261
|
if (hasNewEntries && labelsAdded) {
|
|
225
262
|
info(`Default labels.in config added to ${CONFIG_PATH}.`);
|
|
226
263
|
}
|
|
227
264
|
if (hasNewEntries && platformAdded) {
|
|
228
265
|
info(`Default platform config added to ${CONFIG_PATH}.`);
|
|
229
266
|
}
|
|
267
|
+
if (hasNewEntries && requiresPullRequestAdded) {
|
|
268
|
+
info(`Default requiresPullRequest=${defaults.requiresPullRequest} added to ${CONFIG_PATH}.`);
|
|
269
|
+
}
|
|
230
270
|
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
231
271
|
ok(`Updated ${CONFIG_PATH}`);
|
|
232
272
|
}
|
|
@@ -235,12 +275,27 @@ async function cmdUpdate(): Promise<void> {
|
|
|
235
275
|
console.log('');
|
|
236
276
|
ok('Seed files updated successfully!');
|
|
237
277
|
console.log('');
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
278
|
+
if (enabledTUIs.size === 0) {
|
|
279
|
+
console.log(' No built-in TUI enabled (tuis: []).');
|
|
280
|
+
console.log(` Configure "customTUIs" in ${CONFIG_PATH} if needed.`);
|
|
281
|
+
console.log('');
|
|
282
|
+
} else {
|
|
283
|
+
console.log(' Next step: run the full update in your AI TUI:');
|
|
284
|
+
console.log('');
|
|
285
|
+
const claudeOrOpencode: string[] = [];
|
|
286
|
+
if (enabledTUIs.has('claude-code')) claudeOrOpencode.push('Claude Code');
|
|
287
|
+
if (enabledTUIs.has('opencode')) claudeOrOpencode.push('OpenCode');
|
|
288
|
+
if (claudeOrOpencode.length > 0) {
|
|
289
|
+
console.log(` ${claudeOrOpencode.join(' / ')}: /update-agent-infra`);
|
|
290
|
+
}
|
|
291
|
+
if (enabledTUIs.has('gemini-cli')) {
|
|
292
|
+
console.log(` Gemini CLI: /${project}:update-agent-infra`);
|
|
293
|
+
}
|
|
294
|
+
if (enabledTUIs.has('codex')) {
|
|
295
|
+
console.log(' Codex CLI: $update-agent-infra');
|
|
296
|
+
}
|
|
297
|
+
console.log('');
|
|
298
|
+
}
|
|
244
299
|
}
|
|
245
300
|
|
|
246
301
|
export { cmdUpdate };
|
package/package.json
CHANGED
|
@@ -164,7 +164,7 @@ The receiving AI should read this document first to get up to speed.
|
|
|
164
164
|
|
|
165
165
|
### 1. One AI Per Phase
|
|
166
166
|
|
|
167
|
-
Don't have multiple AIs working on the same files simultaneously. Follow the sequential workflow:
|
|
167
|
+
Don't have multiple AIs working on the same files simultaneously. Follow the sequential workflow: analysis → analysis-review → design → design-review → code → code-review → commit (when any review finds issues, re-run the matching upstream stage).
|
|
168
168
|
|
|
169
169
|
### 2. Always Create Handoff Documents
|
|
170
170
|
|
|
@@ -164,7 +164,7 @@ cp .agents/templates/handoff.md .agents/workspace/active/handoff-task-001-phase2
|
|
|
164
164
|
|
|
165
165
|
### 1. 每个阶段一个 AI
|
|
166
166
|
|
|
167
|
-
不要让多个 AI
|
|
167
|
+
不要让多个 AI 同时处理相同的文件。遵循顺序工作流:分析 → 分析审查 → 设计 → 设计审查 → 编码 → 代码审查 → 提交(任一审查发现问题时,回到同名上游阶段重跑)。
|
|
168
168
|
|
|
169
169
|
### 2. 始终创建交接文档
|
|
170
170
|
|
|
@@ -210,6 +210,38 @@ The `files` field in `.agents/.airc.json` groups project files into three catego
|
|
|
210
210
|
|
|
211
211
|
`ejected` entries support literal paths or globs, using the same matching rules as `merged`.
|
|
212
212
|
|
|
213
|
+
## Built-in TUI Selection
|
|
214
|
+
|
|
215
|
+
Use the top-level `.agents/.airc.json` `tuis` array to pick which built-in TUIs (`claude-code`, `codex`, `gemini-cli`, `opencode`) agent-infra should install command files for and keep in sync.
|
|
216
|
+
|
|
217
|
+
| Value | Meaning |
|
|
218
|
+
|-------|---------|
|
|
219
|
+
| `tuis` missing or `null` | All four built-in TUIs are enabled (backward-compatible default for legacy `.airc.json` predating this field). |
|
|
220
|
+
| `tuis: []` | No built-in TUI is managed. Use this when the project only relies on `customTUIs` and does not need any built-in command files installed. |
|
|
221
|
+
| `tuis: [<subset>]` | Only the listed TUIs are managed. Unknown ids are ignored. |
|
|
222
|
+
|
|
223
|
+
`ai init` includes an interactive multi-select for this field:
|
|
224
|
+
|
|
225
|
+
- Press Enter to accept the default (all built-in TUIs enabled).
|
|
226
|
+
- Type comma-separated numbers or ids (e.g. `1,3` or `claude-code,opencode`) to keep a subset.
|
|
227
|
+
- Type `none` to explicitly disable every built-in TUI (typically combined with a `customTUIs` entry added later).
|
|
228
|
+
- Invalid input (duplicate, out-of-range, unknown id, whitespace-only) aborts init with a non-zero exit code.
|
|
229
|
+
|
|
230
|
+
### Side effects of disabling a TUI
|
|
231
|
+
|
|
232
|
+
When you disable a built-in TUI (either via `ai init` or by hand-editing `.airc.json`), the next `ai update` / `update-agent-infra` will:
|
|
233
|
+
|
|
234
|
+
- skip seed command writes for that TUI (e.g. `.gemini/commands/<project>/update-agent-infra.toml`);
|
|
235
|
+
- skip the TUI's owned default entries when backfilling `files.managed` / `files.merged`;
|
|
236
|
+
- **clean up existing files** under the TUI's owned path prefix (`.claude/`, `.codex/`, `.gemini/`, `.opencode/`) — these are listed in `report.managed.removed`, mirroring the cleanup behavior when switching `platform`.
|
|
237
|
+
|
|
238
|
+
To opt a specific file out of this cleanup, list it in `files.ejected`; ejected entries owned by disabled TUIs are preserved as-is and are not re-created by sync.
|
|
239
|
+
|
|
240
|
+
### Relation to other config fields
|
|
241
|
+
|
|
242
|
+
- `tuis` controls **which TUI command files agent-infra writes and maintains**. It is independent from `sandbox.tools`, which controls **which CLIs the sandbox image installs**. Toggling one does not affect the other; the README for `sandbox.tools` lives in the Sandbox section.
|
|
243
|
+
- `tuis` is independent from `customTUIs` (see below). CustomTUI command files are not removed when you disable a built-in TUI, even if the customTUI's `dir` falls under that TUI's owned prefix (e.g. a customTUI configured with `dir: ".codex/commands"` is preserved when `codex` is disabled).
|
|
244
|
+
|
|
213
245
|
## Custom TUI Configuration
|
|
214
246
|
|
|
215
247
|
Use the top-level `.agents/.airc.json` `customTUIs` array when your team uses an AI TUI that is not one of the built-in command targets. This config lets agent-infra show the correct next-step commands and generate command files for project custom skills by learning from an existing command in the custom TUI directory.
|
|
@@ -224,8 +256,8 @@ Supported `invoke` placeholders:
|
|
|
224
256
|
|
|
225
257
|
| Placeholder | Replaced with | Example |
|
|
226
258
|
|-------------|---------------|---------|
|
|
227
|
-
| `${skillName}` | The skill command name, such as `review-
|
|
228
|
-
| `${projectName}` | The `.airc.json` `project` value. Use this for namespaced commands. | `/${projectName}:${skillName}` -> `/agent-infra:review-
|
|
259
|
+
| `${skillName}` | The skill command name, such as `review-code` or `commit`. | `<your-cli> ${skillName}` -> `<your-cli> review-code` |
|
|
260
|
+
| `${projectName}` | The `.airc.json` `project` value. Use this for namespaced commands. | `/${projectName}:${skillName}` -> `/agent-infra:review-code` |
|
|
229
261
|
|
|
230
262
|
Non-namespaced custom TUI:
|
|
231
263
|
|
|
@@ -258,6 +290,83 @@ Namespaced custom TUI:
|
|
|
258
290
|
|
|
259
291
|
`customTUIs` should contain one entry per custom TUI. To let `update-agent-infra` generate command files for custom skills, keep at least one existing command file in `dir` that references a built-in skill path such as `.agents/skills/analyze-task/SKILL.md`; agent-infra uses that file as the format reference.
|
|
260
292
|
|
|
293
|
+
## Sandbox Custom Tools
|
|
294
|
+
|
|
295
|
+
`customTUIs` (above) generates slash-command files but does not change the sandbox image. To install a non-npm TUI (pip / cargo / curl-based / pre-built binary) into the sandbox image and live-mount its credentials, declare it under `sandbox.customTools` in `.agents/.airc.json`. Built-in tools (`claude-code`, `codex`, `opencode`, `gemini-cli`) keep working unchanged.
|
|
296
|
+
|
|
297
|
+
### Required fields
|
|
298
|
+
|
|
299
|
+
| Field | Meaning |
|
|
300
|
+
|-------|---------|
|
|
301
|
+
| `id` | Lowercase id matching `^[a-z0-9][a-z0-9-]*$`. Referenced from `sandbox.tools`. Must not collide with a built-in id. |
|
|
302
|
+
| `install` | Install descriptor. `{ "type": "npm", "cmd": "<npm package spec>" }` runs `npm install -g <cmd>`. `{ "type": "shell", "cmd": "<shell>" }` runs the shell command(s) as `devuser` during image build. `cmd` must be non-empty. |
|
|
303
|
+
|
|
304
|
+
Minimal entry — the contract for getting a tool into the image is just these two fields:
|
|
305
|
+
|
|
306
|
+
```json
|
|
307
|
+
{
|
|
308
|
+
"sandbox": {
|
|
309
|
+
"tools": ["my-shell-tool"],
|
|
310
|
+
"customTools": [
|
|
311
|
+
{
|
|
312
|
+
"id": "my-shell-tool",
|
|
313
|
+
"install": { "type": "shell", "cmd": "curl -fsSL https://example.com/install.sh | bash" }
|
|
314
|
+
}
|
|
315
|
+
]
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Optional integration fields
|
|
321
|
+
|
|
322
|
+
Add only the fields your tool actually needs. Omit them and the loader fills sensible defaults; provide them and the loader uses your value. Provide an explicit empty string and the loader rejects it (preventing silent install-verification bypass).
|
|
323
|
+
|
|
324
|
+
| Field | Default when omitted | When to provide |
|
|
325
|
+
|-------|---------------------|-----------------|
|
|
326
|
+
| `name` | `id` | A friendlier display name in sandbox reports / hints. |
|
|
327
|
+
| `containerMount` | `/home/devuser/.<id>` | Your tool stores its config / state somewhere other than `~/.<id>`. Must be an absolute path. |
|
|
328
|
+
| `versionCmd` | `which <id>` | The installed binary name differs from `id` (e.g. id `anthropic-claude`, binary `claude`); set `"claude --version"` so sandbox-create can verify the install. |
|
|
329
|
+
| `setupHint` | `Run \`<id>\` inside the container to set up.` | The setup story is non-obvious and worth a one-liner. |
|
|
330
|
+
| `envVars` | (none) | Your tool reads config from a path the env points to (e.g. `XDG_CONFIG_HOME`-style or a custom `*_CONFIG` env). Shape: `Record<string, string>`. |
|
|
331
|
+
| `hostPreSeedFiles` / `hostPreSeedDirs` | (none) | Seed the tool's sandbox dir from host files / directories on first launch. |
|
|
332
|
+
| `pathRewriteFiles` | (none) | Seeded files contain absolute host paths that need rewriting to container paths. |
|
|
333
|
+
| `hostLiveMounts` | (none) | Share host credentials live (e.g. OAuth tokens) with the container. Read-write. |
|
|
334
|
+
| `postSetupCmds` | (none) | Run commands inside the container after first setup (e.g. symlinks). |
|
|
335
|
+
|
|
336
|
+
> **`sandboxBase` is not user-configurable.** The loader always assigns `~/.agent-infra/sandboxes/<id>` so `ai sandbox rm` / `prune` can find tool state. Any `sandboxBase` value in `customTools` entries is silently ignored.
|
|
337
|
+
|
|
338
|
+
Real-world example — `anthropic-claude` as a user-defined id with binary name `claude` and host credential live-mount:
|
|
339
|
+
|
|
340
|
+
```json
|
|
341
|
+
{
|
|
342
|
+
"sandbox": {
|
|
343
|
+
"tools": ["claude-code", "anthropic-claude"],
|
|
344
|
+
"customTools": [
|
|
345
|
+
{
|
|
346
|
+
"id": "anthropic-claude",
|
|
347
|
+
"install": { "type": "npm", "cmd": "@anthropic-ai/claude-code@stable" },
|
|
348
|
+
"versionCmd": "claude --version",
|
|
349
|
+
"hostLiveMounts": [
|
|
350
|
+
{ "hostPath": "~/.claude/.credentials.json", "containerSubpath": ".credentials.json" }
|
|
351
|
+
]
|
|
352
|
+
}
|
|
353
|
+
]
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Trust boundary and execution context
|
|
359
|
+
|
|
360
|
+
- `install.cmd` runs as user `devuser` (non-root) during `docker build`. It can write to the container's filesystem but cannot escape to the host. The trust model is the same as for the `sandbox.dockerfile` escape hatch — you own the `.airc.json` in your repo, so you own what runs at build time.
|
|
361
|
+
- Because the build runs as `devuser`, shell installs cannot `sudo` / `apt-get`. Available options for non-npm distributions:
|
|
362
|
+
- User-scope installers landing in `~/.local/bin`, `~/.cargo/bin`, `~/.npm-global/bin` (e.g. `pipx`, `cargo install`, `curl … | bash` with `INSTALL_DIR=$HOME/.local/bin`).
|
|
363
|
+
- When you genuinely need root or system packages, fall back to the existing `sandbox.dockerfile` field and own the full Dockerfile.
|
|
364
|
+
- Changing `install.cmd` (or any field that participates in the image signature) triggers exactly one image rebuild on the next `ai sandbox` invocation.
|
|
365
|
+
|
|
366
|
+
### Interaction with `sandbox.dockerfile`
|
|
367
|
+
|
|
368
|
+
When you set `sandbox.dockerfile` to point at your own Dockerfile, agent-infra still passes both `AI_TOOL_PACKAGES` (space-separated npm package specs) and `AI_TOOLS_SHELL_INSTALL_B64` (base64-encoded shell install script) as `--build-arg`. Your custom Dockerfile decides whether to consume them; if it does not declare the matching `ARG`, the shell installs for `customTools` are silently skipped — taking over the Dockerfile means taking over the install path.
|
|
369
|
+
|
|
261
370
|
## Skill Authoring Conventions
|
|
262
371
|
|
|
263
372
|
When writing or updating `.agents/skills/*/SKILL.md` files and their templates, keep step numbering consistent:
|
|
@@ -210,6 +210,38 @@ args: "<task-id>" # 可选
|
|
|
210
210
|
|
|
211
211
|
`ejected` 条目支持字面路径或 glob,匹配规则与 `merged` 相同。
|
|
212
212
|
|
|
213
|
+
## 内建 TUI 选择
|
|
214
|
+
|
|
215
|
+
`.agents/.airc.json` 顶层 `tuis` 数组用于决定 agent-infra 应当为哪些内建 TUI(`claude-code`、`codex`、`gemini-cli`、`opencode`)安装并维护命令文件。
|
|
216
|
+
|
|
217
|
+
| 取值 | 含义 |
|
|
218
|
+
|------|------|
|
|
219
|
+
| `tuis` 缺失或为 `null` | 启用全部四个内建 TUI(向后兼容默认,适用于本字段引入之前的 `.airc.json`) |
|
|
220
|
+
| `tuis: []` | 不维护任何内建 TUI。适用于只依赖 `customTUIs`、不需要安装任何内建命令文件的项目 |
|
|
221
|
+
| `tuis: [<子集>]` | 仅维护列出的 TUI;未知 id 会被忽略 |
|
|
222
|
+
|
|
223
|
+
`ai init` 会通过交互式多选询问该字段:
|
|
224
|
+
|
|
225
|
+
- 直接回车 = 接受默认值(全部内建 TUI 启用)。
|
|
226
|
+
- 输入逗号分隔的编号或 id(如 `1,3` 或 `claude-code,opencode`)= 只保留子集。
|
|
227
|
+
- 输入 `none` = 明确不启用任何内建 TUI(通常配合后续在 `customTUIs` 添加条目使用)。
|
|
228
|
+
- 非法输入(重复、超界、未知 id、纯空白)会让 init 以非零退出码终止。
|
|
229
|
+
|
|
230
|
+
### 取消某个 TUI 的副作用
|
|
231
|
+
|
|
232
|
+
通过 `ai init` 或手工编辑 `.airc.json` 取消某个内建 TUI 后,下一次 `ai update` / `update-agent-infra` 会:
|
|
233
|
+
|
|
234
|
+
- 跳过该 TUI 的 seed 命令文件写入(例如 `.gemini/commands/<project>/update-agent-infra.toml`);
|
|
235
|
+
- 在回填 `files.managed` / `files.merged` 时跳过该 TUI owned 的默认条目;
|
|
236
|
+
- **物理清理**该 TUI owned 路径前缀(`.claude/`、`.codex/`、`.gemini/`、`.opencode/`)下的已有文件——清理列表会出现在 `report.managed.removed`,与切换 `platform` 时的清理行为一致。
|
|
237
|
+
|
|
238
|
+
若希望保留某个具体文件,把它加入 `files.ejected`:被 ejected 的、属于已取消 TUI 的条目会保持原状,sync 不会重新创建也不会删除。
|
|
239
|
+
|
|
240
|
+
### 与其他配置字段的关系
|
|
241
|
+
|
|
242
|
+
- `tuis` 控制 **agent-infra 写入与维护哪些 TUI 的命令文件**,与 `sandbox.tools`(控制**沙箱镜像里安装哪些 CLI**)相互独立。两者互不影响;`sandbox.tools` 的说明见 Sandbox 一节。
|
|
243
|
+
- `tuis` 与 `customTUIs`(见下)相互独立。取消某个内建 TUI 时 customTUI 命令文件不会被清理,即便 customTUI 的 `dir` 落在该 TUI 的 owned 前缀下(例如 `dir: ".codex/commands"` 的 customTUI 在 `codex` 被取消时仍会保留)。
|
|
244
|
+
|
|
213
245
|
## 自定义 TUI 配置
|
|
214
246
|
|
|
215
247
|
当团队使用的 AI TUI 不属于内置命令目标时,可以在 `.agents/.airc.json` 顶层配置 `customTUIs` 数组。该配置用于让 agent-infra 输出正确的下一步命令,并通过学习自定义 TUI 目录中的既有命令文件,为项目自定义 skill 生成同格式命令。
|
|
@@ -224,8 +256,8 @@ args: "<task-id>" # 可选
|
|
|
224
256
|
|
|
225
257
|
| 占位符 | 替换为 | 示例 |
|
|
226
258
|
|--------|--------|------|
|
|
227
|
-
| `${skillName}` | skill 命令名,例如 `review-
|
|
228
|
-
| `${projectName}` | `.airc.json` 中的 `project` 值,适用于带命名空间的命令。 | `/${projectName}:${skillName}` -> `/agent-infra:review-
|
|
259
|
+
| `${skillName}` | skill 命令名,例如 `review-code` 或 `commit`。 | `<your-cli> ${skillName}` -> `<your-cli> review-code` |
|
|
260
|
+
| `${projectName}` | `.airc.json` 中的 `project` 值,适用于带命名空间的命令。 | `/${projectName}:${skillName}` -> `/agent-infra:review-code` |
|
|
229
261
|
|
|
230
262
|
不带命名空间的自定义 TUI:
|
|
231
263
|
|
|
@@ -258,6 +290,83 @@ args: "<task-id>" # 可选
|
|
|
258
290
|
|
|
259
291
|
`customTUIs` 每个条目对应一个自定义 TUI。若希望 `update-agent-infra` 为自定义 skill 生成命令文件,请在 `dir` 中保留至少一个引用内置 skill 路径的既有命令文件,例如 `.agents/skills/analyze-task/SKILL.md`;agent-infra 会以该文件作为格式参考。
|
|
260
292
|
|
|
293
|
+
## 沙箱自定义工具(Sandbox Custom Tools)
|
|
294
|
+
|
|
295
|
+
上文 `customTUIs` 只负责生成 slash-command 文件,**不影响沙箱镜像**。如果要把一个非 npm 分发的 TUI(pip / cargo / curl 脚本 / 裸二进制)装进沙箱镜像、并 live-mount 它的凭证目录,需要在 `.agents/.airc.json` 的 `sandbox.customTools` 中声明。内建的四个工具(`claude-code` / `codex` / `opencode` / `gemini-cli`)行为保持不变。
|
|
296
|
+
|
|
297
|
+
### 必填字段
|
|
298
|
+
|
|
299
|
+
| 字段 | 含义 |
|
|
300
|
+
|------|------|
|
|
301
|
+
| `id` | 小写 id,匹配 `^[a-z0-9][a-z0-9-]*$`;由 `sandbox.tools` 引用;不可与内建 id 冲突。 |
|
|
302
|
+
| `install` | 安装描述符。`{ "type": "npm", "cmd": "<npm 包规范>" }` 执行 `npm install -g <cmd>`;`{ "type": "shell", "cmd": "<shell>" }` 在镜像构建阶段以 `devuser` 执行 shell。`cmd` 必须非空。 |
|
|
303
|
+
|
|
304
|
+
最小入口——把一个工具装进镜像所需的契约只有这两个字段:
|
|
305
|
+
|
|
306
|
+
```json
|
|
307
|
+
{
|
|
308
|
+
"sandbox": {
|
|
309
|
+
"tools": ["my-shell-tool"],
|
|
310
|
+
"customTools": [
|
|
311
|
+
{
|
|
312
|
+
"id": "my-shell-tool",
|
|
313
|
+
"install": { "type": "shell", "cmd": "curl -fsSL https://example.com/install.sh | bash" }
|
|
314
|
+
}
|
|
315
|
+
]
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### 可选集成字段
|
|
321
|
+
|
|
322
|
+
只在你的工具真正需要时才加。**省略**则 loader 用合理默认值;**显式提供**则用你给的值;**显式给空串**会被拒绝(防止安装验证被绕过)。
|
|
323
|
+
|
|
324
|
+
| 字段 | 省略时的默认值 | 什么时候应该提供 |
|
|
325
|
+
|------|---------------|----------------|
|
|
326
|
+
| `name` | `id` | 想在沙箱报告 / 提示里显示更友好的名称。 |
|
|
327
|
+
| `containerMount` | `/home/devuser/.<id>` | 工具的配置 / 状态目录不在 `~/.<id>` 而在别处。必须是绝对路径。 |
|
|
328
|
+
| `versionCmd` | `which <id>` | 安装后的可执行文件名与 `id` 不同(例如 id 是 `anthropic-claude`,二进制名是 `claude`);填 `"claude --version"` 让 sandbox-create 能验证安装。 |
|
|
329
|
+
| `setupHint` | `Run \`<id>\` inside the container to set up.` | setup 流程不一目了然,值得用一行说明。 |
|
|
330
|
+
| `envVars` | (无) | 工具通过环境变量找配置(如 `XDG_CONFIG_HOME` 风格或自定义 `*_CONFIG` 变量)。形状:`Record<string, string>`。 |
|
|
331
|
+
| `hostPreSeedFiles` / `hostPreSeedDirs` | (无) | 首次启动时从宿主复制文件 / 目录到工具沙箱配置目录。 |
|
|
332
|
+
| `pathRewriteFiles` | (无) | seed 进来的文件里有宿主绝对路径,需要改写为容器路径。 |
|
|
333
|
+
| `hostLiveMounts` | (无) | 把宿主凭证(如 OAuth token)实时挂进容器,读写共享。 |
|
|
334
|
+
| `postSetupCmds` | (无) | 首次安装完成后在容器内执行命令(如建符号链接)。 |
|
|
335
|
+
|
|
336
|
+
> **`sandboxBase` 不由用户配置。** loader 永远使用 `~/.agent-infra/sandboxes/<id>`,这样 `ai sandbox rm` / `prune` 才能找到工具状态目录。`customTools` 条目里写的任何 `sandboxBase` 都会被静默忽略。
|
|
337
|
+
|
|
338
|
+
实际场景示例——`anthropic-claude` 作为用户自定义 id,二进制名是 `claude`,并把宿主凭证 live-mount 进来:
|
|
339
|
+
|
|
340
|
+
```json
|
|
341
|
+
{
|
|
342
|
+
"sandbox": {
|
|
343
|
+
"tools": ["claude-code", "anthropic-claude"],
|
|
344
|
+
"customTools": [
|
|
345
|
+
{
|
|
346
|
+
"id": "anthropic-claude",
|
|
347
|
+
"install": { "type": "npm", "cmd": "@anthropic-ai/claude-code@stable" },
|
|
348
|
+
"versionCmd": "claude --version",
|
|
349
|
+
"hostLiveMounts": [
|
|
350
|
+
{ "hostPath": "~/.claude/.credentials.json", "containerSubpath": ".credentials.json" }
|
|
351
|
+
]
|
|
352
|
+
}
|
|
353
|
+
]
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### 信任边界与执行身份
|
|
359
|
+
|
|
360
|
+
- `install.cmd` 在 `docker build` 阶段以 `devuser`(非 root)身份执行,只能写容器内文件系统,不能逃逸到宿主。信任模型与现有 `sandbox.dockerfile` 一致:你是 `.airc.json` 的作者,本次构建做什么由你负责。
|
|
361
|
+
- 因为不是 root,shell 安装无法 `sudo` / `apt-get`。非 npm 分发的几条可用路径:
|
|
362
|
+
- 用户态安装器,落到 `~/.local/bin`、`~/.cargo/bin`、`~/.npm-global/bin`(如 `pipx`、`cargo install`、`curl … | bash` 配合 `INSTALL_DIR=$HOME/.local/bin`)。
|
|
363
|
+
- 确实需要 root / 系统包时,仍走原有 `sandbox.dockerfile` 字段,接管整个 Dockerfile。
|
|
364
|
+
- 修改 `install.cmd` 或任何参与镜像签名的字段,下次 `ai sandbox` 命令会触发一次镜像重建。
|
|
365
|
+
|
|
366
|
+
### 与 `sandbox.dockerfile` 的交互
|
|
367
|
+
|
|
368
|
+
当 `sandbox.dockerfile` 指向自定义 Dockerfile 时,agent-infra 仍会把 `AI_TOOL_PACKAGES`(空格分隔的 npm 包规范)和 `AI_TOOLS_SHELL_INSTALL_B64`(base64 编码的 shell 安装脚本)作为 `--build-arg` 传入。你的自定义 Dockerfile 若未声明对应 `ARG`,shell 安装路径会被 docker build 静默忽略——这是接管 Dockerfile 后的应有代价。
|
|
369
|
+
|
|
261
370
|
## Skill 编写规范
|
|
262
371
|
|
|
263
372
|
编写或维护 `.agents/skills/*/SKILL.md` 及其模板时,步骤编号遵循以下规则:
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
|
|
3
3
|
This code platform does not provide an Issue creation rule.
|
|
4
4
|
|
|
5
|
-
`create-task` skips the cascade Issue creation step on this platform; the local `task.md` remains a valid artifact. If you later want to bind the task to an Issue, manually write `issue_number` into `task.md` and the subsequent skills (`commit` / `
|
|
5
|
+
`create-task` skips the cascade Issue creation step on this platform; the local `task.md` remains a valid artifact. If you later want to bind the task to an Issue, manually write `issue_number` into `task.md` and the subsequent skills (`commit` / `code-task` / `complete-task`, etc.) will pick up Issue metadata syncing through the existing cascade rules.
|
|
@@ -5,7 +5,7 @@ After `create-task` writes the local `task.md`, follow this rule to cascade Issu
|
|
|
5
5
|
## Boundary
|
|
6
6
|
|
|
7
7
|
- Issue title and body must come from `task.md` only
|
|
8
|
-
- Do not read `analysis.md`, `plan.md`, `
|
|
8
|
+
- Do not read `analysis.md`, `review-analysis.md`, `plan.md`, `review-plan.md`, `code.md`, or any review-code artifact
|
|
9
9
|
- Persistent outputs are limited to the remote Issue and the `issue_number` written back to `task.md`
|
|
10
10
|
- If Issue creation fails, do not roll back `task.md`; the current task remains valid for the workflow, and the user can later manually fill `issue_number` so other skills' cascade sync takes over
|
|
11
11
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
## 行为边界
|
|
6
6
|
|
|
7
7
|
- Issue 标题和正文只能来自 `task.md`
|
|
8
|
-
- 不读取 `analysis.md`、`plan.md`、`
|
|
8
|
+
- 不读取 `analysis.md`、`review-analysis.md`、`plan.md`、`review-plan.md`、`code.md` 或代码审查产物
|
|
9
9
|
- 持久产物只有:远端 Issue + `task.md` 中回写的 `issue_number`
|
|
10
10
|
- Issue 创建失败时不回滚 `task.md`;当前 task 仍可继续后续工作流,未来可由用户手动写入 `issue_number`,让其它技能的级联同步接管
|
|
11
11
|
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
|
|
3
3
|
当前代码平台未提供 Issue 创建规则。
|
|
4
4
|
|
|
5
|
-
`create-task` 在本平台上会跳过级联创建 Issue 步骤;本地 `task.md` 仍然是有效产物。如果将来需要把任务绑定到一个 Issue,可手动在 `task.md` 中写入 `issue_number`,后续技能(`commit` / `
|
|
5
|
+
`create-task` 在本平台上会跳过级联创建 Issue 步骤;本地 `task.md` 仍然是有效产物。如果将来需要把任务绑定到一个 Issue,可手动在 `task.md` 中写入 `issue_number`,后续技能(`commit` / `code-task` / `complete-task` 等)会按既有的级联同步规则自动接管 Issue 元数据更新。
|
|
@@ -123,7 +123,7 @@ When a skill creates or imports an Issue, automatically add the current executor
|
|
|
123
123
|
|
|
124
124
|
## `in:` Label Sync
|
|
125
125
|
|
|
126
|
-
> **Trigger timing**: run `in:` label sync only after code is committed (the `commit` skill). Do not run it during `
|
|
126
|
+
> **Trigger timing**: run `in:` label sync only after code is committed (the `commit` skill). Do not run it during `code-task`. During `create-pr`, only copy the labels from the Issue to the PR without recomputing them.
|
|
127
127
|
|
|
128
128
|
Read the `labels.in` mapping from `.agents/.airc.json`.
|
|
129
129
|
|
|
@@ -262,7 +262,7 @@ task comment sync always runs and is never downgraded.
|
|
|
262
262
|
|
|
263
263
|
## Backfill Rules (run before `/complete-task` archives)
|
|
264
264
|
|
|
265
|
-
- Scan `task.md`, `analysis*.md`, `
|
|
265
|
+
- Scan `task.md`, `analysis*.md`, `review-analysis*.md`, `plan*.md`, `review-plan*.md`, `code*.md`, and `review-code*.md` in the task directory
|
|
266
266
|
- Check whether each `{file-stem}` was already published by its hidden marker; publish only missing artifacts
|
|
267
267
|
- Backfill only appends missing comments and never deletes or reorders existing comments
|
|
268
268
|
- Resolve `{agent}` for backfilled comments in this order:
|
|
@@ -281,10 +281,11 @@ Title mapping:
|
|
|
281
281
|
|
|
282
282
|
- `task` -> `Task File`
|
|
283
283
|
- `analysis` / `analysis-r{N}` -> `Requirements Analysis` / `Requirements Analysis (Round {N})`
|
|
284
|
+
- `review-analysis` / `review-analysis-r{N}` -> `Requirements Analysis Review (Round 1)` / `Requirements Analysis Review (Round {N})`
|
|
284
285
|
- `plan` / `plan-r{N}` -> `Technical Plan` / `Technical Plan (Round {N})`
|
|
285
|
-
- `
|
|
286
|
-
- `
|
|
287
|
-
- `
|
|
286
|
+
- `review-plan` / `review-plan-r{N}` -> `Technical Plan Review (Round 1)` / `Technical Plan Review (Round {N})`
|
|
287
|
+
- `code` / `code-r{N}` -> `Code Report (Round 1)` / `Code Report (Round {N})`
|
|
288
|
+
- `review-code` / `review-code-r{N}` -> `Code Review (Round 1)` / `Code Review (Round {N})`
|
|
288
289
|
- `summary` -> `Delivery Summary`
|
|
289
290
|
|
|
290
291
|
Backfilled comments are also not gated by `has_triage` or `has_push`.
|
|
@@ -123,7 +123,7 @@ fi
|
|
|
123
123
|
|
|
124
124
|
## `in:` label 同步
|
|
125
125
|
|
|
126
|
-
> **触发时机**:`in:` label 同步应在代码提交后(commit 技能)执行,不在
|
|
126
|
+
> **触发时机**:`in:` label 同步应在代码提交后(commit 技能)执行,不在 code-task 阶段执行。create-pr 阶段仅从 Issue 复制到 PR,不重新计算。
|
|
127
127
|
|
|
128
128
|
读取 `.agents/.airc.json` 的 `labels.in` 映射。
|
|
129
129
|
|
|
@@ -262,7 +262,7 @@ task 留言同步始终执行,不受权限降级影响。
|
|
|
262
262
|
|
|
263
263
|
## 补发规则(`/complete-task` 归档前执行)
|
|
264
264
|
|
|
265
|
-
- 扫描任务目录中的 `task.md`、`analysis*.md`、`
|
|
265
|
+
- 扫描任务目录中的 `task.md`、`analysis*.md`、`review-analysis*.md`、`plan*.md`、`review-plan*.md`、`code*.md`、`review-code*.md`
|
|
266
266
|
- 对每个 `{file-stem}` 用隐藏标记检查是否已发布;未发布则补发,已发布则跳过
|
|
267
267
|
- 补发只追加缺失评论,不删除或重排已有评论
|
|
268
268
|
- 补发评论的 `{agent}` 按以下顺序确定:
|
|
@@ -281,10 +281,11 @@ task 留言同步始终执行,不受权限降级影响。
|
|
|
281
281
|
|
|
282
282
|
- `task` -> `任务文件`
|
|
283
283
|
- `analysis` / `analysis-r{N}` -> `需求分析` / `需求分析(Round {N})`
|
|
284
|
+
- `review-analysis` / `review-analysis-r{N}` -> `需求分析审查(Round 1)` / `需求分析审查(Round {N})`
|
|
284
285
|
- `plan` / `plan-r{N}` -> `技术方案` / `技术方案(Round {N})`
|
|
285
|
-
- `
|
|
286
|
-
- `
|
|
287
|
-
- `
|
|
286
|
+
- `review-plan` / `review-plan-r{N}` -> `技术方案审查(Round 1)` / `技术方案审查(Round {N})`
|
|
287
|
+
- `code` / `code-r{N}` -> `实现报告(Round 1)` / `实现报告(Round {N})`
|
|
288
|
+
- `review-code` / `review-code-r{N}` -> `代码审查(Round 1)` / `代码审查(Round {N})`
|
|
288
289
|
- `summary` -> `交付摘要`
|
|
289
290
|
|
|
290
291
|
补发评论同样不受 `has_triage` / `has_push` 限制。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Milestone Inference Rules
|
|
2
2
|
|
|
3
|
-
Read this file before the `create-task` platform rule, `
|
|
3
|
+
Read this file before the `create-task` platform rule, `code-task`, or `create-pr` handles a milestone.
|
|
4
4
|
|
|
5
5
|
## General Principles
|
|
6
6
|
|
|
@@ -56,7 +56,7 @@ fi
|
|
|
56
56
|
|
|
57
57
|
If `has_triage=false`, inference returns empty, or `gh issue edit` fails, skip and continue without blocking the `import-issue` workflow.
|
|
58
58
|
|
|
59
|
-
## Phase 2: `
|
|
59
|
+
## Phase 2: `code-task`
|
|
60
60
|
|
|
61
61
|
Goal: narrow the Issue milestone from a release line to a concrete version when implementation starts.
|
|
62
62
|
|