@fitlab-ai/agent-infra 0.9.0 → 0.9.2
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 +22 -5
- package/README.zh-CN.md +21 -5
- package/bin/cli.ts +12 -0
- package/dist/bin/cli.js +14 -0
- package/dist/bin/internal-cli.js +20 -0
- package/dist/lib/agent-client.js +163 -0
- package/dist/lib/agent-clients/adapter.js +294 -0
- package/dist/lib/agent-clients/adapters/claude-code.js +62 -0
- package/dist/lib/agent-clients/adapters/codex-sandbox.js +210 -0
- package/dist/lib/agent-clients/adapters/codex.js +54 -0
- package/dist/lib/agent-clients/adapters/gemini-cli.js +64 -0
- package/dist/lib/agent-clients/adapters/index.js +20 -0
- package/dist/lib/agent-clients/adapters/opencode.js +64 -0
- package/dist/lib/agent-clients/config.js +177 -0
- package/dist/lib/agent-clients/custom-tuis.js +99 -0
- package/dist/lib/agent-clients/invocation.js +9 -0
- package/dist/lib/agent-clients/next-steps.js +38 -0
- package/dist/lib/agent-clients/project-assets.js +45 -0
- package/dist/lib/agent-clients/reconcile.js +235 -0
- package/dist/lib/agent-clients/registry.js +72 -0
- package/dist/lib/agent-clients/schema.js +57 -0
- package/dist/lib/agent-clients/types.js +29 -0
- package/dist/lib/builtin-tuis.js +9 -14
- package/dist/lib/defaults.json +85 -73
- package/dist/lib/git/review-snapshot.js +25 -10
- package/dist/lib/git/reviewed-commit-equivalence.js +110 -0
- package/dist/lib/init.js +47 -91
- package/dist/lib/internal/agent-client.js +117 -0
- package/dist/lib/internal/git-workflow.js +1 -1
- package/dist/lib/internal/platform-release-notes.js +53 -0
- package/dist/lib/internal/release-workflow.js +175 -17
- package/dist/lib/internal/task-orchestration.js +151 -0
- package/dist/lib/internal/task-review.js +65 -0
- package/dist/lib/merge.js +2 -1
- package/dist/lib/platform/adapters.js +38 -1
- package/dist/lib/platform/change-request-git-evidence.js +113 -0
- package/dist/lib/platform/github-release-notes.js +96 -0
- package/dist/lib/platform/issues.js +4 -2
- package/dist/lib/platform/merged-pr-equivalence.js +84 -0
- package/dist/lib/platform/pr-checks.js +43 -15
- package/dist/lib/platform/pull-requests.js +113 -7
- package/dist/lib/platform/release-notes.js +143 -0
- package/dist/lib/platform/releases.js +1 -1
- package/dist/lib/platform/verification-required.js +31 -9
- package/dist/lib/prompt.js +15 -3
- package/dist/lib/release/channels.js +4 -1
- package/dist/lib/release/workflow.js +4 -2
- package/dist/lib/remove-dir.js +25 -0
- package/dist/lib/run/tui.js +8 -2
- package/dist/lib/sandbox/agent-client-reconciler.js +234 -0
- package/dist/lib/sandbox/build-proxy.js +63 -0
- package/dist/lib/sandbox/clipboard/linux.js +2 -1
- package/dist/lib/sandbox/commands/create.js +133 -189
- package/dist/lib/sandbox/commands/enter.js +17 -1
- package/dist/lib/sandbox/commands/prune.js +2 -2
- package/dist/lib/sandbox/commands/rebuild.js +24 -7
- package/dist/lib/sandbox/commands/rm.js +3 -2
- package/dist/lib/sandbox/config.js +21 -4
- package/dist/lib/sandbox/constants.js +3 -0
- package/dist/lib/sandbox/dockerfile.js +2 -1
- package/dist/lib/sandbox/image-build.js +2 -1
- package/dist/lib/sandbox/managed-fs.js +10 -5
- package/dist/lib/sandbox/recovery.js +52 -36
- package/dist/lib/sandbox/runtimes/ai-tools.dockerfile +24 -3
- package/dist/lib/sandbox/runtimes/base.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/java17.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/java21.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/node20.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/node22.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/python3.dockerfile +8 -1
- package/dist/lib/sandbox/shell.js +3 -2
- package/dist/lib/sandbox/tool-types.js +8 -0
- package/dist/lib/sandbox/tools.js +2 -126
- package/dist/lib/task/artifact-lifecycle.js +1 -49
- package/dist/lib/task/commands/decisions.js +50 -20
- package/dist/lib/task/commands/issue-body.js +10 -5
- package/dist/lib/task/delegation-receipts.js +107 -0
- package/dist/lib/task/events.js +101 -2
- package/dist/lib/task/issue-form.js +2 -0
- package/dist/lib/task/orchestration.js +420 -0
- package/dist/lib/task/review-artifacts.js +143 -59
- package/dist/lib/task/review-finalization.js +166 -0
- package/dist/lib/task/review-fingerprint.js +13 -0
- package/dist/lib/task/verification-checks.js +2 -1
- package/dist/lib/task/verification-engine.js +168 -23
- package/dist/lib/task/verification-review.js +1 -1
- package/dist/lib/task/verification.js +4 -2
- package/dist/lib/task/workspace-snapshot.js +34 -0
- package/dist/lib/update.js +42 -161
- package/lib/agent-client.ts +214 -0
- package/lib/agent-clients/adapter.ts +461 -0
- package/lib/agent-clients/adapters/claude-code.ts +70 -0
- package/lib/agent-clients/adapters/codex-sandbox.ts +245 -0
- package/lib/agent-clients/adapters/codex.ts +58 -0
- package/lib/agent-clients/adapters/gemini-cli.ts +65 -0
- package/lib/agent-clients/adapters/index.ts +27 -0
- package/lib/agent-clients/adapters/opencode.ts +66 -0
- package/lib/agent-clients/config.ts +278 -0
- package/lib/agent-clients/custom-tuis.ts +149 -0
- package/lib/agent-clients/invocation.ts +19 -0
- package/lib/agent-clients/next-steps.ts +72 -0
- package/lib/agent-clients/project-assets.ts +96 -0
- package/lib/agent-clients/reconcile.ts +324 -0
- package/lib/agent-clients/registry.ts +144 -0
- package/lib/agent-clients/schema.ts +62 -0
- package/lib/agent-clients/types.ts +78 -0
- package/lib/benchmark/schemas/v1.0.0/case-manifest.schema.json +120 -0
- package/lib/benchmark/schemas/v1.0.0/common.schema.json +109 -0
- package/lib/benchmark/schemas/v1.0.0/grader-result.schema.json +160 -0
- package/lib/benchmark/schemas/v1.0.0/run-manifest.schema.json +122 -0
- package/lib/benchmark/schemas/v1.0.0/subject.schema.json +227 -0
- package/lib/builtin-tuis.ts +16 -15
- package/lib/defaults.json +24 -12
- package/lib/git/review-snapshot.ts +39 -9
- package/lib/git/reviewed-commit-equivalence.ts +135 -0
- package/lib/init.ts +53 -121
- package/lib/internal/agent-client.ts +131 -0
- package/lib/internal/git-workflow.ts +1 -1
- package/lib/internal/platform-release-notes.ts +55 -0
- package/lib/internal/release-workflow.ts +172 -18
- package/lib/internal/task-orchestration.ts +132 -0
- package/lib/internal/task-review.ts +65 -0
- package/lib/merge.ts +2 -1
- package/lib/platform/adapters.ts +142 -3
- package/lib/platform/change-request-git-evidence.ts +159 -0
- package/lib/platform/github-release-notes.ts +132 -0
- package/lib/platform/issues.ts +6 -4
- package/lib/platform/merged-pr-equivalence.ts +107 -0
- package/lib/platform/pr-checks.ts +57 -28
- package/lib/platform/pull-requests.ts +140 -25
- package/lib/platform/release-notes.ts +167 -0
- package/lib/platform/releases.ts +1 -1
- package/lib/platform/verification-required.ts +37 -9
- package/lib/prompt.ts +16 -3
- package/lib/release/channels.ts +4 -1
- package/lib/release/workflow.ts +4 -3
- package/lib/remove-dir.ts +28 -0
- package/lib/run/tui.ts +9 -1
- package/lib/sandbox/agent-client-reconciler.ts +378 -0
- package/lib/sandbox/build-proxy.ts +94 -0
- package/lib/sandbox/clipboard/linux.ts +2 -1
- package/lib/sandbox/commands/create.ts +188 -203
- package/lib/sandbox/commands/enter.ts +23 -1
- package/lib/sandbox/commands/prune.ts +2 -2
- package/lib/sandbox/commands/rebuild.ts +29 -7
- package/lib/sandbox/commands/rm.ts +3 -2
- package/lib/sandbox/config.ts +31 -4
- package/lib/sandbox/constants.ts +6 -0
- package/lib/sandbox/dockerfile.ts +2 -1
- package/lib/sandbox/image-build.ts +4 -1
- package/lib/sandbox/managed-fs.ts +18 -5
- package/lib/sandbox/recovery.ts +98 -67
- package/lib/sandbox/runtimes/ai-tools.dockerfile +24 -3
- package/lib/sandbox/runtimes/base.dockerfile +8 -1
- package/lib/sandbox/runtimes/java17.dockerfile +8 -1
- package/lib/sandbox/runtimes/java21.dockerfile +8 -1
- package/lib/sandbox/runtimes/node20.dockerfile +8 -1
- package/lib/sandbox/runtimes/node22.dockerfile +8 -1
- package/lib/sandbox/runtimes/python3.dockerfile +8 -1
- package/lib/sandbox/shell.ts +4 -2
- package/lib/sandbox/tool-types.ts +143 -0
- package/lib/sandbox/tools.ts +5 -157
- package/lib/task/artifact-lifecycle.ts +1 -38
- package/lib/task/commands/decisions.ts +53 -20
- package/lib/task/commands/issue-body.ts +10 -5
- package/lib/task/delegation-receipts.ts +170 -0
- package/lib/task/events.ts +111 -3
- package/lib/task/issue-form.ts +4 -0
- package/lib/task/orchestration.ts +543 -0
- package/lib/task/review-artifacts.ts +201 -69
- package/lib/task/review-finalization.ts +275 -0
- package/lib/task/review-fingerprint.ts +15 -1
- package/lib/task/verification-checks.ts +2 -1
- package/lib/task/verification-engine.ts +190 -25
- package/lib/task/verification-review.ts +2 -0
- package/lib/task/verification.ts +6 -3
- package/lib/task/workspace-snapshot.ts +36 -0
- package/lib/update.ts +48 -184
- package/package.json +2 -2
- package/templates/.agents/README.en.md +21 -20
- package/templates/.agents/README.zh-CN.md +21 -20
- package/templates/.agents/hooks/lifecycle-delegation.js +64 -0
- package/templates/.agents/rules/README.en.md +2 -0
- package/templates/.agents/rules/README.zh-CN.md +2 -0
- package/templates/.agents/rules/commit-and-pr.en.md +1 -0
- package/templates/.agents/rules/commit-and-pr.zh-CN.md +1 -0
- package/templates/.agents/rules/human-decision-context.en.md +14 -12
- package/templates/.agents/rules/human-decision-context.zh-CN.md +14 -12
- package/templates/.agents/rules/lifecycle-orchestration.en.md +21 -0
- package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +21 -0
- package/templates/.agents/rules/next-step-output.en.md +16 -0
- package/templates/.agents/rules/next-step-output.zh-CN.md +16 -0
- package/templates/.agents/rules/no-mid-flow-questions.en.md +2 -0
- package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +2 -0
- package/templates/.agents/rules/release-commands.en.md +2 -2
- package/templates/.agents/rules/release-commands.github.en.md +15 -39
- package/templates/.agents/rules/release-commands.github.zh-CN.md +14 -38
- package/templates/.agents/rules/release-commands.zh-CN.md +2 -2
- package/templates/.agents/rules/review-handshake.en.md +4 -3
- package/templates/.agents/rules/review-handshake.zh-CN.md +4 -3
- package/templates/.agents/rules/review-method.en.md +113 -0
- package/templates/.agents/rules/review-method.zh-CN.md +98 -0
- package/templates/.agents/rules/testing-discipline.en.md +20 -2
- package/templates/.agents/rules/testing-discipline.zh-CN.md +20 -2
- package/templates/.agents/skills/analyze-task/SKILL.en.md +9 -6
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +9 -6
- package/templates/.agents/skills/block-task/SKILL.en.md +4 -4
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/cancel-task/SKILL.en.md +4 -4
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/check-task/SKILL.en.md +16 -16
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +16 -16
- package/templates/.agents/skills/close-codescan/SKILL.en.md +4 -4
- package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/close-dependabot/SKILL.en.md +4 -4
- package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/code-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/code-task/reference/fix-mode.en.md +14 -16
- package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +14 -16
- package/templates/.agents/skills/code-task/reference/output-template.en.md +3 -3
- package/templates/.agents/skills/code-task/reference/output-template.zh-CN.md +3 -3
- package/templates/.agents/skills/commit/SKILL.en.md +11 -1
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +11 -1
- package/templates/.agents/skills/commit/reference/task-status-update.en.md +24 -28
- package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +24 -28
- package/templates/.agents/skills/complete-task/SKILL.en.md +3 -3
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/complete-task/config/verify.en.json +0 -1
- package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +0 -1
- package/templates/.agents/skills/create-pr/SKILL.en.md +10 -10
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +10 -10
- package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +3 -3
- package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +3 -3
- package/templates/.agents/skills/create-release-note/SKILL.en.md +17 -38
- package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +16 -37
- package/templates/.agents/skills/create-task/SKILL.en.md +15 -11
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +15 -11
- package/templates/.agents/skills/create-task/reference/context-capture.en.md +29 -0
- package/templates/.agents/skills/create-task/reference/context-capture.zh-CN.md +29 -0
- package/templates/.agents/skills/import-codescan/SKILL.en.md +5 -5
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/import-dependabot/SKILL.en.md +5 -5
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/import-issue/SKILL.en.md +5 -5
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/init-labels/SKILL.en.md +4 -4
- package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/init-milestones/SKILL.en.md +4 -4
- package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/plan-task/SKILL.en.md +5 -5
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/refine-title/SKILL.en.md +1 -1
- package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/release/SKILL.en.md +1 -1
- package/templates/.agents/skills/review-analysis/SKILL.en.md +13 -2
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +14 -3
- package/templates/.agents/skills/review-analysis/config/verify.en.json +6 -0
- package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +6 -0
- package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +13 -15
- package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +13 -15
- package/templates/.agents/skills/review-analysis/reference/report-template.en.md +51 -5
- package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +52 -6
- package/templates/.agents/skills/review-analysis/reference/review-criteria.en.md +25 -22
- package/templates/.agents/skills/review-analysis/reference/review-criteria.zh-CN.md +25 -22
- package/templates/.agents/skills/review-code/SKILL.en.md +28 -8
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +28 -8
- package/templates/.agents/skills/review-code/config/verify.en.json +7 -0
- package/templates/.agents/skills/review-code/config/verify.zh-CN.json +7 -0
- package/templates/.agents/skills/review-code/reference/concurrency-risks.en.md +25 -0
- package/templates/.agents/skills/review-code/reference/concurrency-risks.zh-CN.md +25 -0
- package/templates/.agents/skills/review-code/reference/cross-platform-risks.en.md +27 -0
- package/templates/.agents/skills/review-code/reference/cross-platform-risks.zh-CN.md +27 -0
- package/templates/.agents/skills/review-code/reference/documentation-antipatterns.en.md +13 -0
- package/templates/.agents/skills/review-code/reference/documentation-antipatterns.zh-CN.md +13 -0
- package/templates/.agents/skills/review-code/reference/migration-risks.en.md +25 -0
- package/templates/.agents/skills/review-code/reference/migration-risks.zh-CN.md +25 -0
- package/templates/.agents/skills/review-code/reference/output-templates.en.md +22 -24
- package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +22 -24
- package/templates/.agents/skills/review-code/reference/report-template.en.md +54 -7
- package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +54 -7
- package/templates/.agents/skills/review-code/reference/review-criteria.en.md +29 -24
- package/templates/.agents/skills/review-code/reference/review-criteria.zh-CN.md +29 -24
- package/templates/.agents/skills/review-code/reference/security-risks.en.md +25 -0
- package/templates/.agents/skills/review-code/reference/security-risks.zh-CN.md +25 -0
- package/templates/.agents/skills/review-plan/SKILL.en.md +13 -2
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +14 -3
- package/templates/.agents/skills/review-plan/config/verify.en.json +6 -0
- package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +6 -0
- package/templates/.agents/skills/review-plan/reference/output-templates.en.md +13 -15
- package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +13 -15
- package/templates/.agents/skills/review-plan/reference/report-template.en.md +61 -5
- package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +61 -5
- package/templates/.agents/skills/review-plan/reference/review-criteria.en.md +21 -24
- package/templates/.agents/skills/review-plan/reference/review-criteria.zh-CN.md +21 -24
- package/templates/.agents/skills/run-task/SKILL.en.md +22 -0
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +22 -0
- package/templates/.agents/skills/run-task/config/verify.en.json +9 -0
- package/templates/.agents/skills/run-task/config/verify.zh-CN.json +9 -0
- package/templates/.agents/skills/test/SKILL.en.md +4 -4
- package/templates/.agents/skills/test/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/test-integration/SKILL.en.md +4 -4
- package/templates/.agents/skills/test-integration/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/update-agent-infra/SKILL.en.md +5 -5
- package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +647 -203
- package/templates/.agents/skills/upgrade-dependency/SKILL.en.md +4 -4
- package/templates/.agents/skills/upgrade-dependency/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/watch-pr/SKILL.en.md +8 -8
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +8 -8
- package/templates/.agents/templates/task.en.md +18 -0
- package/templates/.agents/templates/task.zh-CN.md +18 -0
- package/templates/.claude/agents/agent-infra-lifecycle-executor.en.md +6 -0
- package/templates/.claude/agents/agent-infra-lifecycle-executor.zh-CN.md +6 -0
- package/templates/.claude/agents/agent-infra-lifecycle-reviewer.en.md +6 -0
- package/templates/.claude/agents/agent-infra-lifecycle-reviewer.zh-CN.md +6 -0
- package/templates/.claude/commands/run-task.en.md +8 -0
- package/templates/.claude/commands/run-task.zh-CN.md +8 -0
- package/templates/.claude/settings.json +24 -0
- package/templates/.codex/agents/agent-infra-lifecycle-executor.en.toml +3 -0
- package/templates/.codex/agents/agent-infra-lifecycle-executor.zh-CN.toml +3 -0
- package/templates/.codex/agents/agent-infra-lifecycle-reviewer.en.toml +3 -0
- package/templates/.codex/agents/agent-infra-lifecycle-reviewer.zh-CN.toml +3 -0
- package/templates/.gemini/commands/_project_/run-task.en.toml +8 -0
- package/templates/.gemini/commands/_project_/run-task.zh-CN.toml +8 -0
- package/templates/.opencode/commands/run-task.en.md +11 -0
- package/templates/.opencode/commands/run-task.zh-CN.md +11 -0
package/dist/lib/update.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { normalizeAgentClients } from './agent-clients/config.js';
|
|
4
|
+
import { applyAgentClientReconciliation, planAgentClientReconciliation } from './agent-clients/reconcile.js';
|
|
3
5
|
import { info, ok, err } from './log.js';
|
|
4
6
|
import { resolveTemplateDir } from './paths.js';
|
|
5
|
-
import { renderFile, copySkillDir
|
|
6
|
-
import { isPathOwnedByDisabledTUI, resolveEnabledTUIs } from './builtin-tuis.js';
|
|
7
|
+
import { renderFile, copySkillDir } from './render.js';
|
|
7
8
|
const defaults = JSON.parse(fs.readFileSync(new URL('./defaults.json', import.meta.url), 'utf8'));
|
|
8
9
|
const CONFIG_DIR = '.agents';
|
|
9
10
|
const CONFIG_PATH = path.join(CONFIG_DIR, '.airc.json');
|
|
10
|
-
const AGENT_INFRA_SANDBOX_TOOL = 'agent-infra';
|
|
11
|
-
const LEGACY_DEFAULT_SANDBOX_TOOLS = ['claude-code', 'codex', 'gemini-cli', 'opencode'];
|
|
12
|
-
const DEFAULT_SANDBOX_TOOLS = [AGENT_INFRA_SANDBOX_TOOL, ...LEGACY_DEFAULT_SANDBOX_TOOLS];
|
|
13
11
|
// One-time migration of the legacy project-level PR switch to the three-state
|
|
14
12
|
// `prFlow` preference. `true` (the old default / "PR flow on") maps to the
|
|
15
13
|
// strong constraint `required`; `false` maps to `disabled`. A missing or
|
|
@@ -28,80 +26,6 @@ function migratePrFlow(config) {
|
|
|
28
26
|
}
|
|
29
27
|
return null;
|
|
30
28
|
}
|
|
31
|
-
function isLegacyDefaultSandboxTools(value) {
|
|
32
|
-
if (!Array.isArray(value) || value.length !== LEGACY_DEFAULT_SANDBOX_TOOLS.length) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
const tools = new Set(value);
|
|
36
|
-
return LEGACY_DEFAULT_SANDBOX_TOOLS.every((tool) => tools.has(tool));
|
|
37
|
-
}
|
|
38
|
-
function migrateSandboxTools(config) {
|
|
39
|
-
const tools = config.sandbox?.tools;
|
|
40
|
-
if (!isLegacyDefaultSandboxTools(tools)) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
config.sandbox = {
|
|
44
|
-
...config.sandbox,
|
|
45
|
-
tools: [...DEFAULT_SANDBOX_TOOLS]
|
|
46
|
-
};
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
function isPathOwnedByOtherPlatform(relativePath, platformType) {
|
|
50
|
-
const top = String(relativePath || '').replace(/\\/g, '/').replace(/^\.\//, '').split('/')[0] ?? '';
|
|
51
|
-
if (!top.startsWith('.'))
|
|
52
|
-
return false;
|
|
53
|
-
const candidate = top.slice(1);
|
|
54
|
-
if (!KNOWN_PLATFORMS.has(candidate))
|
|
55
|
-
return false;
|
|
56
|
-
return candidate !== platformType;
|
|
57
|
-
}
|
|
58
|
-
function syncFileRegistry(config, platformType, enabledTUIs) {
|
|
59
|
-
config.files ||= {};
|
|
60
|
-
const before = JSON.stringify({
|
|
61
|
-
files: {
|
|
62
|
-
managed: config.files.managed || [],
|
|
63
|
-
merged: config.files.merged || [],
|
|
64
|
-
ejected: config.files.ejected || []
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
config.files.managed = config.files.managed || [];
|
|
68
|
-
config.files.merged = config.files.merged || [];
|
|
69
|
-
config.files.ejected = config.files.ejected || [];
|
|
70
|
-
const allExisting = [
|
|
71
|
-
...config.files.managed,
|
|
72
|
-
...config.files.merged,
|
|
73
|
-
...config.files.ejected
|
|
74
|
-
];
|
|
75
|
-
const added = { managed: [], merged: [] };
|
|
76
|
-
for (const entry of defaults.files.managed) {
|
|
77
|
-
if (isPathOwnedByOtherPlatform(entry, platformType))
|
|
78
|
-
continue;
|
|
79
|
-
if (isPathOwnedByDisabledTUI(entry, enabledTUIs))
|
|
80
|
-
continue;
|
|
81
|
-
if (!allExisting.includes(entry)) {
|
|
82
|
-
config.files.managed.push(entry);
|
|
83
|
-
added.managed.push(entry);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
for (const entry of defaults.files.merged) {
|
|
87
|
-
if (isPathOwnedByOtherPlatform(entry, platformType))
|
|
88
|
-
continue;
|
|
89
|
-
if (isPathOwnedByDisabledTUI(entry, enabledTUIs))
|
|
90
|
-
continue;
|
|
91
|
-
if (!allExisting.includes(entry)) {
|
|
92
|
-
config.files.merged.push(entry);
|
|
93
|
-
added.merged.push(entry);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
const after = JSON.stringify({
|
|
97
|
-
files: {
|
|
98
|
-
managed: config.files.managed,
|
|
99
|
-
merged: config.files.merged,
|
|
100
|
-
ejected: config.files.ejected
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
return { added, changed: before !== after };
|
|
104
|
-
}
|
|
105
29
|
async function cmdUpdate() {
|
|
106
30
|
console.log('');
|
|
107
31
|
console.log(' ai update');
|
|
@@ -126,22 +50,36 @@ async function cmdUpdate() {
|
|
|
126
50
|
const config = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'));
|
|
127
51
|
const { project, org, language } = config;
|
|
128
52
|
const platformType = config.platform?.type || defaults.platform.type;
|
|
129
|
-
const enabledTUIs = resolveEnabledTUIs(config.tuis);
|
|
130
53
|
const replacements = { project, org };
|
|
54
|
+
const normalizedOriginal = normalizeAgentClients(config);
|
|
55
|
+
const currentRegistry = {
|
|
56
|
+
managed: config.files?.managed || [],
|
|
57
|
+
merged: config.files?.merged || [],
|
|
58
|
+
ejected: config.files?.ejected || []
|
|
59
|
+
};
|
|
60
|
+
const platformAdded = !config.platform;
|
|
61
|
+
const sandboxAdded = !config.sandbox;
|
|
62
|
+
const taskAdded = !config.task;
|
|
63
|
+
const labelsAdded = !config.labels;
|
|
64
|
+
const prFlowMigrated = migratePrFlow(config);
|
|
65
|
+
if (platformAdded)
|
|
66
|
+
config.platform = structuredClone(defaults.platform);
|
|
67
|
+
if (sandboxAdded)
|
|
68
|
+
config.sandbox = structuredClone(defaults.sandbox);
|
|
69
|
+
if (taskAdded)
|
|
70
|
+
config.task = structuredClone(defaults.task);
|
|
71
|
+
if (labelsAdded)
|
|
72
|
+
config.labels = structuredClone(defaults.labels);
|
|
73
|
+
const workflowPlan = planAgentClientReconciliation({
|
|
74
|
+
config: config,
|
|
75
|
+
mutation: { type: 'replace-state', state: normalizedOriginal.state },
|
|
76
|
+
projectRoot: process.cwd(),
|
|
77
|
+
templateRoot: templateDir,
|
|
78
|
+
platformType,
|
|
79
|
+
language
|
|
80
|
+
});
|
|
131
81
|
info(`Updating seed files for: ${project}`);
|
|
132
82
|
console.log('');
|
|
133
|
-
// select language-specific template filenames
|
|
134
|
-
let claudeSrc, geminiSrc, opencodeSrc;
|
|
135
|
-
if (language === 'zh-CN') {
|
|
136
|
-
claudeSrc = 'update-agent-infra.zh-CN.md';
|
|
137
|
-
geminiSrc = 'update-agent-infra.zh-CN.toml';
|
|
138
|
-
opencodeSrc = 'update-agent-infra.zh-CN.md';
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
claudeSrc = 'update-agent-infra.en.md';
|
|
142
|
-
geminiSrc = 'update-agent-infra.en.toml';
|
|
143
|
-
opencodeSrc = 'update-agent-infra.en.md';
|
|
144
|
-
}
|
|
145
83
|
// update skill
|
|
146
84
|
copySkillDir(path.join(templateDir, '.agents', 'skills', 'update-agent-infra'), path.join('.agents', 'skills', 'update-agent-infra'), replacements, language, platformType);
|
|
147
85
|
ok('Updated .agents/skills/update-agent-infra/');
|
|
@@ -153,54 +91,15 @@ async function cmdUpdate() {
|
|
|
153
91
|
catch {
|
|
154
92
|
// Ignore missing legacy script from pre-ESM installs.
|
|
155
93
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
// update Gemini command (only if enabled)
|
|
162
|
-
if (enabledTUIs.has('gemini-cli')) {
|
|
163
|
-
renderFile(path.join(templateDir, '.gemini', 'commands', '_project_', geminiSrc), path.join('.gemini', 'commands', project, 'update-agent-infra.toml'), replacements);
|
|
164
|
-
ok(`Updated .gemini/commands/${project}/update-agent-infra.toml`);
|
|
165
|
-
}
|
|
166
|
-
// update OpenCode command (only if enabled)
|
|
167
|
-
if (enabledTUIs.has('opencode')) {
|
|
168
|
-
renderFile(path.join(templateDir, '.opencode', 'commands', opencodeSrc), path.join('.opencode', 'commands', 'update-agent-infra.md'), replacements);
|
|
169
|
-
ok('Updated .opencode/commands/update-agent-infra.md');
|
|
170
|
-
}
|
|
171
|
-
// sync file registry
|
|
172
|
-
const { added, changed } = syncFileRegistry(config, platformType, enabledTUIs);
|
|
94
|
+
const added = {
|
|
95
|
+
managed: workflowPlan.projectAssets.registry.managed.filter((entry) => !currentRegistry.managed.includes(entry)),
|
|
96
|
+
merged: workflowPlan.projectAssets.registry.merged.filter((entry) => !currentRegistry.merged.includes(entry))
|
|
97
|
+
};
|
|
173
98
|
const hasNewEntries = added.managed.length > 0 || added.merged.length > 0;
|
|
174
|
-
const
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const prFlowMigrated = migratePrFlow(config);
|
|
179
|
-
const sandboxToolsMigrated = !sandboxAdded && migrateSandboxTools(config);
|
|
180
|
-
let configChanged = changed;
|
|
181
|
-
if (platformAdded) {
|
|
182
|
-
config.platform = structuredClone(defaults.platform);
|
|
183
|
-
configChanged = true;
|
|
184
|
-
}
|
|
185
|
-
if (sandboxAdded) {
|
|
186
|
-
config.sandbox = structuredClone(defaults.sandbox);
|
|
187
|
-
configChanged = true;
|
|
188
|
-
}
|
|
189
|
-
if (taskAdded) {
|
|
190
|
-
config.task = structuredClone(defaults.task);
|
|
191
|
-
configChanged = true;
|
|
192
|
-
}
|
|
193
|
-
if (labelsAdded) {
|
|
194
|
-
config.labels = structuredClone(defaults.labels);
|
|
195
|
-
configChanged = true;
|
|
196
|
-
}
|
|
197
|
-
if (prFlowMigrated) {
|
|
198
|
-
configChanged = true;
|
|
199
|
-
}
|
|
200
|
-
if (sandboxToolsMigrated) {
|
|
201
|
-
configChanged = true;
|
|
202
|
-
}
|
|
203
|
-
if (configChanged) {
|
|
99
|
+
const reconcileResult = applyAgentClientReconciliation(workflowPlan);
|
|
100
|
+
for (const target of reconcileResult.applied)
|
|
101
|
+
ok(`Updated ${target}`);
|
|
102
|
+
if (reconcileResult.configUpdated) {
|
|
204
103
|
console.log('');
|
|
205
104
|
if (hasNewEntries) {
|
|
206
105
|
info(`New file entries synced to ${CONFIG_PATH}:`);
|
|
@@ -227,9 +126,6 @@ async function cmdUpdate() {
|
|
|
227
126
|
if (prFlowMigrated) {
|
|
228
127
|
info(`Migrated legacy requiresPullRequest to prFlow="${prFlowMigrated}" in ${CONFIG_PATH}.`);
|
|
229
128
|
}
|
|
230
|
-
if (sandboxToolsMigrated) {
|
|
231
|
-
info(`Migrated default sandbox.tools to include ${AGENT_INFRA_SANDBOX_TOOL} in ${CONFIG_PATH}.`);
|
|
232
|
-
}
|
|
233
129
|
}
|
|
234
130
|
else {
|
|
235
131
|
info(`File registry changed in ${CONFIG_PATH}.`);
|
|
@@ -249,37 +145,22 @@ async function cmdUpdate() {
|
|
|
249
145
|
if (hasNewEntries && prFlowMigrated) {
|
|
250
146
|
info(`Migrated legacy requiresPullRequest to prFlow="${prFlowMigrated}" in ${CONFIG_PATH}.`);
|
|
251
147
|
}
|
|
252
|
-
if (hasNewEntries && sandboxToolsMigrated) {
|
|
253
|
-
info(`Migrated default sandbox.tools to include ${AGENT_INFRA_SANDBOX_TOOL} in ${CONFIG_PATH}.`);
|
|
254
|
-
}
|
|
255
|
-
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
256
148
|
ok(`Updated ${CONFIG_PATH}`);
|
|
257
149
|
}
|
|
258
150
|
// done
|
|
259
151
|
console.log('');
|
|
260
152
|
ok('Seed files updated successfully!');
|
|
261
153
|
console.log('');
|
|
262
|
-
if (
|
|
263
|
-
console.log(' No
|
|
154
|
+
if (workflowPlan.nextSteps.length === 0) {
|
|
155
|
+
console.log(' No Agent Client project integration enabled.');
|
|
264
156
|
console.log(` Configure "customTUIs" in ${CONFIG_PATH} if needed.`);
|
|
265
157
|
console.log('');
|
|
266
158
|
}
|
|
267
159
|
else {
|
|
268
160
|
console.log(' Next step: run the full update in your AI TUI:');
|
|
269
161
|
console.log('');
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
claudeOrOpencode.push('Claude Code');
|
|
273
|
-
if (enabledTUIs.has('opencode'))
|
|
274
|
-
claudeOrOpencode.push('OpenCode');
|
|
275
|
-
if (claudeOrOpencode.length > 0) {
|
|
276
|
-
console.log(` ${claudeOrOpencode.join(' / ')}: /update-agent-infra`);
|
|
277
|
-
}
|
|
278
|
-
if (enabledTUIs.has('gemini-cli')) {
|
|
279
|
-
console.log(` Gemini CLI: /${project}:update-agent-infra`);
|
|
280
|
-
}
|
|
281
|
-
if (enabledTUIs.has('codex')) {
|
|
282
|
-
console.log(' Codex CLI: $update-agent-infra');
|
|
162
|
+
for (const nextStep of workflowPlan.nextSteps) {
|
|
163
|
+
console.log(` ${nextStep.displayName}: ${nextStep.command}`);
|
|
283
164
|
}
|
|
284
165
|
console.log('');
|
|
285
166
|
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
import { AgentClientConfigError, normalizeAgentClients } from './agent-clients/config.ts';
|
|
5
|
+
import {
|
|
6
|
+
applyAgentClientReconciliation,
|
|
7
|
+
planAgentClientReconciliation
|
|
8
|
+
} from './agent-clients/reconcile.ts';
|
|
9
|
+
import { listAgentClientAdapters } from './agent-clients/registry.ts';
|
|
10
|
+
import { AGENT_CLIENT_IDS, isAgentClientId } from './agent-clients/types.ts';
|
|
11
|
+
import type { AgentClientState } from './agent-clients/types.ts';
|
|
12
|
+
import { closePrompt, multiSelect } from './prompt.ts';
|
|
13
|
+
import { resolveTemplateDir } from './paths.ts';
|
|
14
|
+
|
|
15
|
+
const USAGE = `Usage: ai agent-client <operation>
|
|
16
|
+
|
|
17
|
+
Operations:
|
|
18
|
+
list List built-in Agent Clients
|
|
19
|
+
status Show project integration and sandbox state
|
|
20
|
+
enable <client-id> Enable project integration only
|
|
21
|
+
disable <client-id> Disable project integration only
|
|
22
|
+
configure Configure integration and sandbox state interactively
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
class AgentClientCommandError extends Error {
|
|
26
|
+
readonly code: string;
|
|
27
|
+
|
|
28
|
+
constructor(code: string, message: string) {
|
|
29
|
+
super(`${code}: ${message}`);
|
|
30
|
+
this.name = 'AgentClientCommandError';
|
|
31
|
+
this.code = code;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function readConfig(projectRoot: string): Record<string, unknown> {
|
|
36
|
+
const configPath = path.join(projectRoot, '.agents', '.airc.json');
|
|
37
|
+
if (!fs.existsSync(configPath)) {
|
|
38
|
+
throw new AgentClientCommandError(
|
|
39
|
+
'AGENT_CLIENT_CONFIG_NOT_FOUND',
|
|
40
|
+
'No .agents/.airc.json found. Run "ai init" first.'
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
let parsed: unknown;
|
|
44
|
+
try {
|
|
45
|
+
parsed = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
46
|
+
} catch (error) {
|
|
47
|
+
throw new AgentClientCommandError(
|
|
48
|
+
'AGENT_CLIENT_CONFIG_INVALID',
|
|
49
|
+
error instanceof Error ? error.message : String(error)
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
53
|
+
throw new AgentClientCommandError(
|
|
54
|
+
'AGENT_CLIENT_CONFIG_INVALID',
|
|
55
|
+
'configuration root must be an object'
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return parsed as Record<string, unknown>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function choices() {
|
|
62
|
+
return listAgentClientAdapters().map((adapter) => ({
|
|
63
|
+
id: adapter.id,
|
|
64
|
+
label: adapter.displayName
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function selected(state: AgentClientState, field: 'enabled' | 'installInSandbox'): string[] {
|
|
69
|
+
return AGENT_CLIENT_IDS.filter((id) => state[id][field]);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function workflowPlan(
|
|
73
|
+
projectRoot: string,
|
|
74
|
+
config: Record<string, unknown>,
|
|
75
|
+
mutation: Parameters<typeof planAgentClientReconciliation>[0]['mutation']
|
|
76
|
+
) {
|
|
77
|
+
const templateRoot = resolveTemplateDir();
|
|
78
|
+
if (!templateRoot) {
|
|
79
|
+
throw new AgentClientCommandError('AGENT_CLIENT_TEMPLATE_NOT_FOUND', 'Template directory not found');
|
|
80
|
+
}
|
|
81
|
+
const platform = config.platform;
|
|
82
|
+
const platformType = typeof platform === 'object' && platform !== null && 'type' in platform
|
|
83
|
+
? String(platform.type ?? 'github')
|
|
84
|
+
: 'github';
|
|
85
|
+
return planAgentClientReconciliation({
|
|
86
|
+
config,
|
|
87
|
+
mutation,
|
|
88
|
+
projectRoot,
|
|
89
|
+
templateRoot,
|
|
90
|
+
platformType,
|
|
91
|
+
language: String(config.language ?? 'en')
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function printState(state: AgentClientState): void {
|
|
96
|
+
for (const adapter of listAgentClientAdapters()) {
|
|
97
|
+
const value = state[adapter.id];
|
|
98
|
+
process.stdout.write(
|
|
99
|
+
` ${adapter.id}: enabled=${String(value.enabled)} installInSandbox=${String(value.installInSandbox)}\n`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function cmdAgentClient(args: string[]): Promise<number> {
|
|
105
|
+
const operation = args[0];
|
|
106
|
+
if (!operation || operation === '--help' || operation === '-h' || operation === 'help') {
|
|
107
|
+
process.stdout.write(USAGE);
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (operation === 'list') {
|
|
112
|
+
if (args.length !== 1) {
|
|
113
|
+
throw new AgentClientCommandError('AGENT_CLIENT_ARGUMENT_INVALID', 'list accepts no arguments');
|
|
114
|
+
}
|
|
115
|
+
for (const adapter of listAgentClientAdapters()) {
|
|
116
|
+
process.stdout.write(
|
|
117
|
+
`${adapter.id}\t${adapter.displayName}\t${adapter.invocation}\tcommands=${adapter.capabilities.commands.level}\tsandbox=${adapter.capabilities.sandbox.level}\n`
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
return 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const projectRoot = process.cwd();
|
|
124
|
+
const config = readConfig(projectRoot);
|
|
125
|
+
try {
|
|
126
|
+
if (operation === 'status') {
|
|
127
|
+
if (args.length !== 1) {
|
|
128
|
+
throw new AgentClientCommandError('AGENT_CLIENT_ARGUMENT_INVALID', 'status accepts no arguments');
|
|
129
|
+
}
|
|
130
|
+
const plan = workflowPlan(projectRoot, config, { type: 'none' });
|
|
131
|
+
process.stdout.write(`source: ${plan.source}\n`);
|
|
132
|
+
printState(plan.desired);
|
|
133
|
+
for (const seed of plan.seedOperations) {
|
|
134
|
+
process.stdout.write(` seed ${seed.target}: ${seed.kind}\n`);
|
|
135
|
+
}
|
|
136
|
+
for (const diagnostic of plan.diagnostics) {
|
|
137
|
+
process.stdout.write(` diagnostic ${diagnostic.code} at ${diagnostic.path}\n`);
|
|
138
|
+
}
|
|
139
|
+
return 0;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (operation === 'enable' || operation === 'disable') {
|
|
143
|
+
if (args.length !== 2) {
|
|
144
|
+
throw new AgentClientCommandError(
|
|
145
|
+
'AGENT_CLIENT_ARGUMENT_INVALID',
|
|
146
|
+
`${operation} requires exactly one client id`
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
const id = args[1];
|
|
150
|
+
if (!isAgentClientId(id)) {
|
|
151
|
+
throw new AgentClientCommandError('UNKNOWN_AGENT_CLIENT', `Unknown Agent Client '${String(id)}'`);
|
|
152
|
+
}
|
|
153
|
+
const plan = workflowPlan(projectRoot, config, {
|
|
154
|
+
type: 'set-enabled',
|
|
155
|
+
id,
|
|
156
|
+
value: operation === 'enable'
|
|
157
|
+
});
|
|
158
|
+
process.stdout.write('Before:\n');
|
|
159
|
+
printState(plan.before);
|
|
160
|
+
const result = applyAgentClientReconciliation(plan);
|
|
161
|
+
process.stdout.write('After:\n');
|
|
162
|
+
printState(plan.desired);
|
|
163
|
+
process.stdout.write(
|
|
164
|
+
`Result: ${result.status}; applied=${result.applied.length}; protected=${result.protected.length}\n`
|
|
165
|
+
);
|
|
166
|
+
return 0;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (operation === 'configure') {
|
|
170
|
+
if (args.length !== 1) {
|
|
171
|
+
throw new AgentClientCommandError('AGENT_CLIENT_ARGUMENT_INVALID', 'configure accepts no arguments');
|
|
172
|
+
}
|
|
173
|
+
const normalized = normalizeAgentClients(config);
|
|
174
|
+
let enabled: string[];
|
|
175
|
+
let installed: string[];
|
|
176
|
+
try {
|
|
177
|
+
enabled = await multiSelect(
|
|
178
|
+
'Agent Client project integrations',
|
|
179
|
+
choices(),
|
|
180
|
+
selected(normalized.state, 'enabled')
|
|
181
|
+
);
|
|
182
|
+
installed = await multiSelect(
|
|
183
|
+
'Agent Clients installed in sandbox',
|
|
184
|
+
choices(),
|
|
185
|
+
selected(normalized.state, 'installInSandbox')
|
|
186
|
+
);
|
|
187
|
+
} finally {
|
|
188
|
+
closePrompt();
|
|
189
|
+
}
|
|
190
|
+
const state = Object.fromEntries(AGENT_CLIENT_IDS.map((id) => [id, {
|
|
191
|
+
enabled: enabled.includes(id),
|
|
192
|
+
installInSandbox: installed.includes(id)
|
|
193
|
+
}])) as AgentClientState;
|
|
194
|
+
const plan = workflowPlan(projectRoot, config, { type: 'replace-state', state });
|
|
195
|
+
const result = applyAgentClientReconciliation(plan);
|
|
196
|
+
process.stdout.write(
|
|
197
|
+
`Result: ${result.status}; applied=${result.applied.length}; protected=${result.protected.length}\n`
|
|
198
|
+
);
|
|
199
|
+
return 0;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
throw new AgentClientCommandError(
|
|
203
|
+
'AGENT_CLIENT_OPERATION_INVALID',
|
|
204
|
+
`Unknown operation '${operation}'`
|
|
205
|
+
);
|
|
206
|
+
} catch (error) {
|
|
207
|
+
if (error instanceof AgentClientConfigError) {
|
|
208
|
+
throw new AgentClientCommandError(error.code, error.message);
|
|
209
|
+
}
|
|
210
|
+
throw error;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export { AgentClientCommandError, cmdAgentClient };
|