@fitlab-ai/agent-infra 0.9.3 → 0.9.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/README.md +3 -1
- package/README.zh-CN.md +3 -1
- package/bin/cli.ts +12 -0
- package/dist/bin/cli.js +14 -0
- package/dist/bin/internal-cli.js +144 -123
- package/dist/lib/agent-clients/adapter.js +94 -4
- package/dist/lib/{sandbox/credentials.js → agent-clients/adapters/claude-code-credentials.js} +4 -14
- package/dist/lib/agent-clients/adapters/claude-code-refresh.js +85 -0
- package/dist/lib/agent-clients/adapters/claude-code-sandbox.js +247 -0
- package/dist/lib/agent-clients/adapters/claude-code.js +17 -3
- package/dist/lib/agent-clients/adapters/codex-lifecycle/app-server.js +382 -0
- package/dist/lib/agent-clients/adapters/codex-lifecycle/evidence.js +163 -0
- package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +211 -0
- package/dist/lib/agent-clients/adapters/codex.js +2 -2
- package/dist/lib/agent-clients/adapters/opencode-sandbox.js +108 -0
- package/dist/lib/agent-clients/adapters/opencode.js +15 -3
- package/dist/lib/agent-clients/adapters/runtimes/claude-code.dockerfile +65 -0
- package/dist/lib/agent-clients/registry.js +9 -1
- package/dist/lib/git/worktree-identity.js +64 -0
- package/dist/lib/internal/codex-lifecycle.js +202 -0
- package/dist/lib/internal/sandbox-control.js +24 -0
- package/dist/lib/internal/task-activity.js +45 -13
- package/dist/lib/internal/task-create.js +48 -0
- package/dist/lib/internal/task-ledger.js +12 -3
- package/dist/lib/internal/task-lifecycle.js +19 -1
- package/dist/lib/internal/task-orchestration.js +170 -27
- package/dist/lib/platform/github-client.js +19 -2
- package/dist/lib/platform/pr-checks.js +1 -1
- package/dist/lib/platform/pull-requests.js +47 -1
- package/dist/lib/platform/releases.js +13 -5
- package/dist/lib/process-data/index.js +239 -0
- package/dist/lib/process-data/normalize.js +198 -0
- package/dist/lib/process-data/privacy.js +33 -0
- package/dist/lib/process-data/reconcile.js +95 -0
- package/dist/lib/process-data/repair.js +58 -0
- package/dist/lib/process-data/sources.js +345 -0
- package/dist/lib/process-data/store.js +282 -0
- package/dist/lib/process-data/types.js +2 -0
- package/dist/lib/run/index.js +4 -3
- package/dist/lib/run/tui.js +7 -8
- package/dist/lib/sandbox/agent-client-reconciler.js +26 -2
- package/dist/lib/sandbox/capture.js +7 -2
- package/dist/lib/sandbox/commands/create.js +110 -228
- package/dist/lib/sandbox/commands/enter.js +15 -47
- package/dist/lib/sandbox/commands/list-running.js +16 -6
- package/dist/lib/sandbox/commands/ls.js +10 -6
- package/dist/lib/sandbox/commands/rebuild.js +4 -3
- package/dist/lib/sandbox/commands/refresh.js +4 -84
- package/dist/lib/sandbox/commands/rm.js +24 -3
- package/dist/lib/sandbox/commands/show.js +12 -3
- package/dist/lib/sandbox/commands/start.js +7 -4
- package/dist/lib/sandbox/config.js +2 -0
- package/dist/lib/sandbox/constants.js +6 -0
- package/dist/lib/sandbox/control/client.js +58 -0
- package/dist/lib/sandbox/control/protocol.js +54 -0
- package/dist/lib/sandbox/control/server.js +144 -0
- package/dist/lib/sandbox/dockerfile.js +36 -13
- package/dist/lib/sandbox/mounts.js +17 -4
- package/dist/lib/sandbox/recovery.js +128 -5
- package/dist/lib/sandbox/redaction.js +12 -0
- package/dist/lib/sandbox/runtimes/base.dockerfile +24 -74
- package/dist/lib/sandbox/workspace-identity.js +95 -0
- package/dist/lib/sandbox/workspace-view.js +109 -0
- package/dist/lib/task/activity-intent.js +257 -51
- package/dist/lib/task/activity-log.js +32 -5
- package/dist/lib/task/commit-finalization.js +278 -0
- package/dist/lib/task/commit-intent.js +165 -0
- package/dist/lib/task/create-service.js +137 -0
- package/dist/lib/task/create.js +333 -0
- package/dist/lib/task/decision-intents.js +31 -17
- package/dist/lib/task/delegation-receipts.js +2 -2
- package/dist/lib/task/implementation-inputs.js +54 -7
- package/dist/lib/task/ledger-intents.js +35 -1
- package/dist/lib/task/orchestration.js +505 -34
- package/dist/lib/task/resolve-ref.js +41 -1
- package/dist/lib/task/review-fingerprint.js +4 -0
- package/dist/lib/task/workspace-snapshot.js +78 -3
- package/lib/agent-clients/adapter.ts +130 -6
- package/lib/{sandbox/credentials.ts → agent-clients/adapters/claude-code-credentials.ts} +3 -18
- package/lib/agent-clients/adapters/claude-code-refresh.ts +128 -0
- package/lib/agent-clients/adapters/claude-code-sandbox.ts +295 -0
- package/lib/agent-clients/adapters/claude-code.ts +21 -3
- package/lib/agent-clients/adapters/codex-lifecycle/app-server.ts +442 -0
- package/lib/agent-clients/adapters/codex-lifecycle/evidence.ts +307 -0
- package/lib/agent-clients/adapters/codex-lifecycle/store.ts +250 -0
- package/lib/agent-clients/adapters/codex.ts +2 -2
- package/lib/agent-clients/adapters/opencode-sandbox.ts +136 -0
- package/lib/agent-clients/adapters/opencode.ts +18 -3
- package/lib/agent-clients/adapters/runtimes/claude-code.dockerfile +65 -0
- package/lib/agent-clients/registry.ts +9 -1
- package/lib/git/worktree-identity.ts +86 -0
- package/lib/internal/codex-lifecycle.ts +204 -0
- package/lib/internal/sandbox-control.ts +24 -0
- package/lib/internal/task-activity.ts +50 -14
- package/lib/internal/task-create.ts +49 -0
- package/lib/internal/task-ledger.ts +12 -3
- package/lib/internal/task-lifecycle.ts +22 -1
- package/lib/internal/task-orchestration.ts +117 -21
- package/lib/platform/github-client.ts +20 -2
- package/lib/platform/pr-checks.ts +1 -1
- package/lib/platform/pull-requests.ts +49 -1
- package/lib/platform/releases.ts +16 -4
- package/lib/process-data/index.ts +224 -0
- package/lib/process-data/normalize.ts +202 -0
- package/lib/process-data/privacy.ts +41 -0
- package/lib/process-data/reconcile.ts +110 -0
- package/lib/process-data/repair.ts +64 -0
- package/lib/process-data/sources.ts +354 -0
- package/lib/process-data/store.ts +315 -0
- package/lib/process-data/types.ts +135 -0
- package/lib/run/index.ts +5 -3
- package/lib/run/tui.ts +11 -8
- package/lib/sandbox/agent-client-reconciler.ts +44 -2
- package/lib/sandbox/capture.ts +9 -2
- package/lib/sandbox/commands/create.ts +127 -260
- package/lib/sandbox/commands/enter.ts +13 -59
- package/lib/sandbox/commands/list-running.ts +23 -6
- package/lib/sandbox/commands/ls.ts +22 -6
- package/lib/sandbox/commands/rebuild.ts +4 -3
- package/lib/sandbox/commands/refresh.ts +4 -126
- package/lib/sandbox/commands/rm.ts +24 -3
- package/lib/sandbox/commands/show.ts +29 -3
- package/lib/sandbox/commands/start.ts +6 -4
- package/lib/sandbox/config.ts +4 -0
- package/lib/sandbox/constants.ts +8 -0
- package/lib/sandbox/control/client.ts +79 -0
- package/lib/sandbox/control/protocol.ts +110 -0
- package/lib/sandbox/control/server.ts +155 -0
- package/lib/sandbox/dockerfile.ts +66 -13
- package/lib/sandbox/mounts.ts +24 -4
- package/lib/sandbox/recovery.ts +163 -6
- package/lib/sandbox/redaction.ts +14 -0
- package/lib/sandbox/runtimes/base.dockerfile +24 -74
- package/lib/sandbox/tool-types.ts +16 -0
- package/lib/sandbox/workspace-identity.ts +123 -0
- package/lib/sandbox/workspace-view.ts +150 -0
- package/lib/task/activity-intent.ts +350 -61
- package/lib/task/activity-log.ts +46 -7
- package/lib/task/commit-finalization.ts +376 -0
- package/lib/task/commit-intent.ts +230 -0
- package/lib/task/create-service.ts +171 -0
- package/lib/task/create.ts +372 -0
- package/lib/task/decision-intents.ts +32 -12
- package/lib/task/delegation-receipts.ts +2 -2
- package/lib/task/implementation-inputs.ts +62 -8
- package/lib/task/ledger-intents.ts +43 -3
- package/lib/task/orchestration.ts +673 -41
- package/lib/task/resolve-ref.ts +46 -1
- package/lib/task/review-fingerprint.ts +9 -0
- package/lib/task/workspace-snapshot.ts +98 -4
- package/package.json +7 -7
- package/templates/.agents/hooks/lifecycle-delegation.js +47 -3
- package/templates/.agents/rules/README.en.md +1 -1
- package/templates/.agents/rules/README.zh-CN.md +1 -1
- package/templates/.agents/rules/human-decision-context.en.md +11 -2
- package/templates/.agents/rules/human-decision-context.zh-CN.md +11 -2
- package/templates/.agents/rules/pr-checks-commands.en.md +1 -1
- package/templates/.agents/rules/pr-checks-commands.github.en.md +1 -1
- package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +2 -2
- package/templates/.agents/rules/pr-checks-commands.zh-CN.md +1 -1
- package/templates/.agents/rules/review-handshake.zh-CN.md +1 -1
- package/templates/.agents/rules/task-management.en.md +3 -0
- package/templates/.agents/rules/task-management.zh-CN.md +3 -0
- package/templates/.agents/skills/code-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/commit/SKILL.en.md +21 -17
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +28 -16
- package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +50 -0
- package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +56 -0
- package/templates/.agents/skills/commit/reference/task-status-update.en.md +4 -4
- package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +4 -4
- package/templates/.agents/skills/complete-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/create-pr/SKILL.en.md +4 -4
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/create-task/SKILL.en.md +26 -43
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +26 -43
- package/templates/.agents/skills/create-task/reference/context-capture.en.md +34 -0
- package/templates/.agents/skills/create-task/reference/context-capture.zh-CN.md +34 -0
- package/templates/.agents/skills/review-code/SKILL.en.md +2 -2
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/review-code/reference/output-templates.en.md +1 -1
- package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +1 -1
- package/templates/.agents/skills/review-pr/SKILL.en.md +36 -8
- package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +36 -8
- package/templates/.agents/skills/review-pr/reference/report-template.en.md +1 -1
- package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +1 -1
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +67 -50
- package/templates/.agents/skills/watch-pr/SKILL.en.md +4 -4
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +2 -2
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +2 -2
- package/templates/.agents/templates/task.en.md +1 -1
- package/templates/.agents/templates/task.zh-CN.md +1 -1
- package/templates/.claude/commands/watch-pr.en.md +1 -1
- package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
- package/templates/.claude/rules/tool-preferences.en.md +20 -0
- package/templates/.claude/rules/tool-preferences.zh-CN.md +20 -0
- package/templates/.codex/hooks.json +50 -0
- package/templates/.opencode/commands/watch-pr.en.md +1 -1
- package/templates/.opencode/commands/watch-pr.zh-CN.md +1 -1
- package/templates/.gemini/commands/_project_/review-pr.en.toml +0 -10
- package/templates/.gemini/commands/_project_/review-pr.zh-CN.toml +0 -10
package/README.md
CHANGED
|
@@ -91,6 +91,7 @@ Every command above works the same way in Claude Code, Codex, Antigravity CLI, a
|
|
|
91
91
|
- **Bilingual project docs**: English-first docs with synchronized Chinese translations
|
|
92
92
|
- **Template-source architecture**: `templates/` mirrors the rendered project structure
|
|
93
93
|
- **AI-assisted updates**: template changes can be merged while preserving project-specific customization
|
|
94
|
+
- **Auditable process-data archive**: preserve local tasks and GitHub evidence in append-only, verifiable snapshots
|
|
94
95
|
|
|
95
96
|
## Quick Start
|
|
96
97
|
|
|
@@ -175,7 +176,7 @@ The most-used lifecycle commands, in delivery order. The command prefix varies b
|
|
|
175
176
|
| Command | Purpose |
|
|
176
177
|
|---------|---------|
|
|
177
178
|
| `create-task` / `import-issue` | Start a task from a description or a GitHub Issue |
|
|
178
|
-
| `run-task` | Resume the lifecycle with fresh isolated executors/reviewers when the selected client exposes verified actual model/effort evidence;
|
|
179
|
+
| `run-task` | Resume the lifecycle with fresh isolated executors/reviewers when the selected client exposes verified actual model/effort evidence; Codex now has an experimental Hooks + App Server evidence channel, but orchestration remains disabled until that channel is connected to delegation receipts |
|
|
179
180
|
| `analyze-task` → `review-analysis` | Capture scope and risks, then review the analysis |
|
|
180
181
|
| `plan-task` → `review-plan` | Design the approach, then review the plan |
|
|
181
182
|
| `code-task` → `review-code` | Implement and test, then run a structured code review |
|
|
@@ -206,6 +207,7 @@ my-project/
|
|
|
206
207
|
|
|
207
208
|
In-depth guides live under [`docs/en/`](./docs/en/README.md):
|
|
208
209
|
|
|
210
|
+
- [Process Data Archive](./docs/en/process-data.md) — capture, verify, audit, repair, export, privacy, and backup guidance
|
|
209
211
|
- [Architecture Overview](./docs/en/architecture.md) — bootstrap CLI, end-to-end flow, layered architecture
|
|
210
212
|
- [Platform Support](./docs/en/platform-support.md) — macOS, Linux, Windows; sandbox engines and resources
|
|
211
213
|
- [Sandbox](./docs/en/sandbox.md) — sandbox aliases, host-sandbox file exchange, user-level dotfiles channel
|
package/README.zh-CN.md
CHANGED
|
@@ -90,6 +90,7 @@ agent-infra 的目标就是把这层共享基础设施标准化。它为所有
|
|
|
90
90
|
- **双语文档**:英文为主文档,配套同步的中文版本
|
|
91
91
|
- **模板源架构**:`templates/` 目录镜像最终渲染出的项目结构
|
|
92
92
|
- **AI 辅助升级**:模板升级时可合并变更,同时尽量保留项目侧定制
|
|
93
|
+
- **可审计的过程数据归档**:把本地任务与 GitHub 证据保存为只追加、可校验的快照
|
|
93
94
|
|
|
94
95
|
## 快速开始
|
|
95
96
|
|
|
@@ -174,7 +175,7 @@ ai agent-client configure
|
|
|
174
175
|
| 命令 | 用途 |
|
|
175
176
|
|------|------|
|
|
176
177
|
| `create-task` / `import-issue` | 从描述或 GitHub Issue 创建任务 |
|
|
177
|
-
| `run-task` | 当所选客户端能提供已验证的 actual model/effort 证据时,用 fresh 隔离 executor/reviewer
|
|
178
|
+
| `run-task` | 当所选客户端能提供已验证的 actual model/effort 证据时,用 fresh 隔离 executor/reviewer 续跑生命周期;Codex 现已具备实验性的 Hooks + App Server 证据通道,但在该通道接入 delegation receipt 前仍不会启用 orchestration |
|
|
178
179
|
| `analyze-task` → `review-analysis` | 明确范围与风险,再审查分析 |
|
|
179
180
|
| `plan-task` → `review-plan` | 设计实现路径,再审查方案 |
|
|
180
181
|
| `code-task` → `review-code` | 实现并测试,再执行结构化代码审查 |
|
|
@@ -205,6 +206,7 @@ my-project/
|
|
|
205
206
|
|
|
206
207
|
深度指南位于 [`docs/zh-CN/`](./docs/zh-CN/README.md):
|
|
207
208
|
|
|
209
|
+
- [过程数据归档](./docs/zh-CN/process-data.md) — 采集、校验、审计、修复、导出、隐私与备份指南
|
|
208
210
|
- [架构概览](./docs/zh-CN/architecture.md) — 引导 CLI、端到端流程、分层架构
|
|
209
211
|
- [平台支持](./docs/zh-CN/platform-support.md) — macOS、Linux、Windows;沙箱引擎与资源配置
|
|
210
212
|
- [沙箱](./docs/zh-CN/sandbox.md) — 沙箱 aliases、宿主-沙箱文件交换、用户级 dotfiles 通道
|
package/bin/cli.ts
CHANGED
|
@@ -17,6 +17,7 @@ Usage: ai <command> [options]
|
|
|
17
17
|
Commands:
|
|
18
18
|
agent-client List, inspect, enable, disable, or configure Agent Clients
|
|
19
19
|
cp <ssh-alias> Copy local clipboard image to a remote macOS clipboard or Linux sandbox over SSH
|
|
20
|
+
data Capture, verify, audit, repair, and export process data
|
|
20
21
|
decide Record a ruling; code-stage decisions require explicit implementation intent
|
|
21
22
|
help Show this help message
|
|
22
23
|
init Initialize a new project with update-agent-infra seed command
|
|
@@ -94,6 +95,17 @@ switch (command) {
|
|
|
94
95
|
if (code) process.exitCode = code;
|
|
95
96
|
break;
|
|
96
97
|
}
|
|
98
|
+
case 'data': {
|
|
99
|
+
const imported = await importCommand('../lib/process-data/index.ts');
|
|
100
|
+
if (!imported) break;
|
|
101
|
+
const { cmdData } = imported;
|
|
102
|
+
const code = await cmdData(process.argv.slice(3)).catch((e: unknown) => {
|
|
103
|
+
process.stderr.write(`Error: ${errorMessage(e)}\n`);
|
|
104
|
+
return 1;
|
|
105
|
+
});
|
|
106
|
+
if (code) process.exitCode = code;
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
97
109
|
case 'decide': {
|
|
98
110
|
const imported = await importCommand('../lib/decide.ts');
|
|
99
111
|
if (!imported) break;
|
package/dist/bin/cli.js
CHANGED
|
@@ -21,6 +21,7 @@ Usage: ai <command> [options]
|
|
|
21
21
|
Commands:
|
|
22
22
|
agent-client List, inspect, enable, disable, or configure Agent Clients
|
|
23
23
|
cp <ssh-alias> Copy local clipboard image to a remote macOS clipboard or Linux sandbox over SSH
|
|
24
|
+
data Capture, verify, audit, repair, and export process data
|
|
24
25
|
decide Record a ruling; code-stage decisions require explicit implementation intent
|
|
25
26
|
help Show this help message
|
|
26
27
|
init Initialize a new project with update-agent-infra seed command
|
|
@@ -96,6 +97,19 @@ switch (command) {
|
|
|
96
97
|
process.exitCode = code;
|
|
97
98
|
break;
|
|
98
99
|
}
|
|
100
|
+
case 'data': {
|
|
101
|
+
const imported = await importCommand('../lib/process-data/index.ts');
|
|
102
|
+
if (!imported)
|
|
103
|
+
break;
|
|
104
|
+
const { cmdData } = imported;
|
|
105
|
+
const code = await cmdData(process.argv.slice(3)).catch((e) => {
|
|
106
|
+
process.stderr.write(`Error: ${errorMessage(e)}\n`);
|
|
107
|
+
return 1;
|
|
108
|
+
});
|
|
109
|
+
if (code)
|
|
110
|
+
process.exitCode = code;
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
99
113
|
case 'decide': {
|
|
100
114
|
const imported = await importCommand('../lib/decide.ts');
|
|
101
115
|
if (!imported)
|
package/dist/bin/internal-cli.js
CHANGED
|
@@ -5,129 +5,150 @@ if (major < 22 || (major === 22 && minor < 9)) {
|
|
|
5
5
|
process.exit(1);
|
|
6
6
|
}
|
|
7
7
|
const command = process.argv[2] || '';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
break;
|
|
13
|
-
}
|
|
14
|
-
case 'git-workflow': {
|
|
15
|
-
const { gitWorkflow } = await import('../lib/internal/git-workflow.js');
|
|
16
|
-
gitWorkflow(process.argv.slice(3));
|
|
17
|
-
break;
|
|
18
|
-
}
|
|
19
|
-
case 'release-workflow': {
|
|
20
|
-
const { releaseWorkflow } = await import('../lib/internal/release-workflow.js');
|
|
21
|
-
await releaseWorkflow(process.argv.slice(3));
|
|
22
|
-
break;
|
|
23
|
-
}
|
|
24
|
-
case 'platform-release-notes': {
|
|
25
|
-
const { platformReleaseNotes } = await import('../lib/internal/platform-release-notes.js');
|
|
26
|
-
platformReleaseNotes(process.argv.slice(3));
|
|
27
|
-
break;
|
|
28
|
-
}
|
|
29
|
-
case 'platform-context': {
|
|
30
|
-
const { platformContext } = await import('../lib/internal/platform-context.js');
|
|
31
|
-
platformContext(process.argv.slice(3));
|
|
32
|
-
break;
|
|
33
|
-
}
|
|
34
|
-
case 'platform-comment': {
|
|
35
|
-
const { platformComment } = await import('../lib/internal/platform-comment.js');
|
|
36
|
-
platformComment(process.argv.slice(3));
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
39
|
-
case 'platform-issue': {
|
|
40
|
-
const { platformIssue } = await import('../lib/internal/platform-issue.js');
|
|
41
|
-
platformIssue(process.argv.slice(3));
|
|
42
|
-
break;
|
|
43
|
-
}
|
|
44
|
-
case 'platform-pr': {
|
|
45
|
-
const { platformPr } = await import('../lib/internal/platform-pr.js');
|
|
46
|
-
platformPr(process.argv.slice(3));
|
|
47
|
-
break;
|
|
48
|
-
}
|
|
49
|
-
case 'platform-pr-review': {
|
|
50
|
-
const { platformPrReview } = await import('../lib/internal/platform-pr-review.js');
|
|
51
|
-
platformPrReview(process.argv.slice(3));
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
case 'pr-review-grade': {
|
|
55
|
-
const { prReviewGrade } = await import('../lib/internal/pr-review-grade.js');
|
|
56
|
-
prReviewGrade(process.argv.slice(3));
|
|
57
|
-
break;
|
|
58
|
-
}
|
|
59
|
-
case 'platform-checks': {
|
|
60
|
-
const { platformChecks } = await import('../lib/internal/platform-checks.js');
|
|
61
|
-
await platformChecks(process.argv.slice(3));
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
case 'task-context': {
|
|
65
|
-
const { taskContext } = await import('../lib/internal/task-context.js');
|
|
66
|
-
taskContext(process.argv.slice(3));
|
|
67
|
-
break;
|
|
68
|
-
}
|
|
69
|
-
case 'task-ledger': {
|
|
70
|
-
const { taskLedger } = await import('../lib/internal/task-ledger.js');
|
|
71
|
-
taskLedger(process.argv.slice(3));
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
case 'task-warning': {
|
|
75
|
-
const { taskWarning } = await import('../lib/internal/task-warning.js');
|
|
76
|
-
taskWarning(process.argv.slice(3));
|
|
77
|
-
break;
|
|
78
|
-
}
|
|
79
|
-
case 'task-activity': {
|
|
80
|
-
const { taskActivity } = await import('../lib/internal/task-activity.js');
|
|
81
|
-
taskActivity(process.argv.slice(3));
|
|
82
|
-
break;
|
|
83
|
-
}
|
|
84
|
-
case 'task-artifact': {
|
|
85
|
-
const { taskArtifact } = await import('../lib/internal/task-artifact.js');
|
|
86
|
-
taskArtifact(process.argv.slice(3));
|
|
87
|
-
break;
|
|
88
|
-
}
|
|
89
|
-
case 'task-orchestration': {
|
|
90
|
-
const { taskOrchestration } = await import('../lib/internal/task-orchestration.js');
|
|
91
|
-
taskOrchestration(process.argv.slice(3));
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
case 'task-review': {
|
|
95
|
-
const { taskReview } = await import('../lib/internal/task-review.js');
|
|
96
|
-
taskReview(process.argv.slice(3));
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
case 'task-event': {
|
|
100
|
-
const { taskEvent } = await import('../lib/internal/task-event.js');
|
|
101
|
-
taskEvent(process.argv.slice(3));
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
case 'task-lifecycle': {
|
|
105
|
-
const { taskLifecycle } = await import('../lib/internal/task-lifecycle.js');
|
|
106
|
-
taskLifecycle(process.argv.slice(3));
|
|
107
|
-
break;
|
|
108
|
-
}
|
|
109
|
-
case 'task-short-id': {
|
|
110
|
-
const { taskShortId } = await import('../lib/internal/task-short-id.js');
|
|
111
|
-
taskShortId(process.argv.slice(3));
|
|
112
|
-
break;
|
|
113
|
-
}
|
|
114
|
-
case 'task-snapshot': {
|
|
115
|
-
const { taskSnapshot } = await import('../lib/internal/task-snapshot.js');
|
|
116
|
-
taskSnapshot(process.argv.slice(3));
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
case 'task-verify': {
|
|
120
|
-
const { taskVerify } = await import('../lib/internal/task-verify.js');
|
|
121
|
-
taskVerify(process.argv.slice(3));
|
|
122
|
-
break;
|
|
123
|
-
}
|
|
124
|
-
default:
|
|
125
|
-
process.stdout.write(`${JSON.stringify({
|
|
126
|
-
status: 'failed',
|
|
127
|
-
changed: false,
|
|
128
|
-
error: { code: 'INTERNAL_COMMAND_INVALID', message: `unknown internal command '${command}'` }
|
|
129
|
-
})}\n`);
|
|
130
|
-
process.exitCode = 1;
|
|
8
|
+
if (process.env.AGENT_INFRA_CONTROL_TOKEN
|
|
9
|
+
&& (command === 'task-lifecycle' || command === 'task-orchestration')) {
|
|
10
|
+
const { sandboxControl } = await import('../lib/internal/sandbox-control.js');
|
|
11
|
+
sandboxControl(['client', command, ...process.argv.slice(3)]);
|
|
131
12
|
}
|
|
13
|
+
else
|
|
14
|
+
switch (command) {
|
|
15
|
+
case 'task-create': {
|
|
16
|
+
const { taskCreate } = await import('../lib/internal/task-create.js');
|
|
17
|
+
taskCreate(process.argv.slice(3));
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
case 'sandbox-control': {
|
|
21
|
+
const { sandboxControl } = await import('../lib/internal/sandbox-control.js');
|
|
22
|
+
sandboxControl(process.argv.slice(3));
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
case 'agent-client': {
|
|
26
|
+
const { agentClient } = await import('../lib/internal/agent-client.js');
|
|
27
|
+
agentClient(process.argv.slice(3));
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
case 'codex-lifecycle': {
|
|
31
|
+
const { codexLifecycle } = await import('../lib/internal/codex-lifecycle.js');
|
|
32
|
+
await codexLifecycle(process.argv.slice(3));
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
case 'git-workflow': {
|
|
36
|
+
const { gitWorkflow } = await import('../lib/internal/git-workflow.js');
|
|
37
|
+
gitWorkflow(process.argv.slice(3));
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
case 'release-workflow': {
|
|
41
|
+
const { releaseWorkflow } = await import('../lib/internal/release-workflow.js');
|
|
42
|
+
await releaseWorkflow(process.argv.slice(3));
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
case 'platform-release-notes': {
|
|
46
|
+
const { platformReleaseNotes } = await import('../lib/internal/platform-release-notes.js');
|
|
47
|
+
platformReleaseNotes(process.argv.slice(3));
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
case 'platform-context': {
|
|
51
|
+
const { platformContext } = await import('../lib/internal/platform-context.js');
|
|
52
|
+
platformContext(process.argv.slice(3));
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
case 'platform-comment': {
|
|
56
|
+
const { platformComment } = await import('../lib/internal/platform-comment.js');
|
|
57
|
+
platformComment(process.argv.slice(3));
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
case 'platform-issue': {
|
|
61
|
+
const { platformIssue } = await import('../lib/internal/platform-issue.js');
|
|
62
|
+
platformIssue(process.argv.slice(3));
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
case 'platform-pr': {
|
|
66
|
+
const { platformPr } = await import('../lib/internal/platform-pr.js');
|
|
67
|
+
platformPr(process.argv.slice(3));
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
case 'platform-pr-review': {
|
|
71
|
+
const { platformPrReview } = await import('../lib/internal/platform-pr-review.js');
|
|
72
|
+
platformPrReview(process.argv.slice(3));
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case 'pr-review-grade': {
|
|
76
|
+
const { prReviewGrade } = await import('../lib/internal/pr-review-grade.js');
|
|
77
|
+
prReviewGrade(process.argv.slice(3));
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
case 'platform-checks': {
|
|
81
|
+
const { platformChecks } = await import('../lib/internal/platform-checks.js');
|
|
82
|
+
await platformChecks(process.argv.slice(3));
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
case 'task-context': {
|
|
86
|
+
const { taskContext } = await import('../lib/internal/task-context.js');
|
|
87
|
+
taskContext(process.argv.slice(3));
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
case 'task-ledger': {
|
|
91
|
+
const { taskLedger } = await import('../lib/internal/task-ledger.js');
|
|
92
|
+
taskLedger(process.argv.slice(3));
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
case 'task-warning': {
|
|
96
|
+
const { taskWarning } = await import('../lib/internal/task-warning.js');
|
|
97
|
+
taskWarning(process.argv.slice(3));
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
case 'task-activity': {
|
|
101
|
+
const { taskActivity } = await import('../lib/internal/task-activity.js');
|
|
102
|
+
taskActivity(process.argv.slice(3));
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case 'task-artifact': {
|
|
106
|
+
const { taskArtifact } = await import('../lib/internal/task-artifact.js');
|
|
107
|
+
taskArtifact(process.argv.slice(3));
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case 'task-orchestration': {
|
|
111
|
+
const { taskOrchestration } = await import('../lib/internal/task-orchestration.js');
|
|
112
|
+
taskOrchestration(process.argv.slice(3));
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
case 'task-review': {
|
|
116
|
+
const { taskReview } = await import('../lib/internal/task-review.js');
|
|
117
|
+
taskReview(process.argv.slice(3));
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
case 'task-event': {
|
|
121
|
+
const { taskEvent } = await import('../lib/internal/task-event.js');
|
|
122
|
+
taskEvent(process.argv.slice(3));
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
case 'task-lifecycle': {
|
|
126
|
+
const { taskLifecycle } = await import('../lib/internal/task-lifecycle.js');
|
|
127
|
+
taskLifecycle(process.argv.slice(3));
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
case 'task-short-id': {
|
|
131
|
+
const { taskShortId } = await import('../lib/internal/task-short-id.js');
|
|
132
|
+
taskShortId(process.argv.slice(3));
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
case 'task-snapshot': {
|
|
136
|
+
const { taskSnapshot } = await import('../lib/internal/task-snapshot.js');
|
|
137
|
+
taskSnapshot(process.argv.slice(3));
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
case 'task-verify': {
|
|
141
|
+
const { taskVerify } = await import('../lib/internal/task-verify.js');
|
|
142
|
+
taskVerify(process.argv.slice(3));
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
default:
|
|
146
|
+
process.stdout.write(`${JSON.stringify({
|
|
147
|
+
status: 'failed',
|
|
148
|
+
changed: false,
|
|
149
|
+
error: { code: 'INTERNAL_COMMAND_INVALID', message: `unknown internal command '${command}'` }
|
|
150
|
+
})}\n`);
|
|
151
|
+
process.exitCode = 1;
|
|
152
|
+
}
|
|
132
153
|
export {};
|
|
133
154
|
//# sourceMappingURL=internal-cli.js.map
|
|
@@ -3,6 +3,43 @@ import { SANDBOX_HOOK_PHASES } from '../sandbox/tool-types.js';
|
|
|
3
3
|
const PROJECT_ASSET_CATEGORIES = ['managed', 'merged', 'ejected'];
|
|
4
4
|
const MAX_SANDBOX_HOOK_TIMEOUT_MS = 300_000;
|
|
5
5
|
const TOOL_ID_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
|
|
6
|
+
function freezeSandboxImageDescriptor(id, value) {
|
|
7
|
+
if (value === undefined)
|
|
8
|
+
return undefined;
|
|
9
|
+
const keys = value && typeof value === 'object' && !Array.isArray(value)
|
|
10
|
+
? Object.keys(value)
|
|
11
|
+
: [];
|
|
12
|
+
const fragment = value?.dockerfileFragment;
|
|
13
|
+
const exclusions = value?.dotfilesExclusions;
|
|
14
|
+
const validExclusion = (entry) => {
|
|
15
|
+
if (typeof entry !== 'string'
|
|
16
|
+
|| entry === ''
|
|
17
|
+
|| entry.startsWith('/')
|
|
18
|
+
|| entry.endsWith('/')
|
|
19
|
+
|| entry.includes('\\')
|
|
20
|
+
|| /[*?[\]]/.test(entry)) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return entry.split('/').every((segment) => segment !== '' && segment !== '.' && segment !== '..');
|
|
24
|
+
};
|
|
25
|
+
if (!value
|
|
26
|
+
|| typeof value !== 'object'
|
|
27
|
+
|| Array.isArray(value)
|
|
28
|
+
|| keys.length === 0
|
|
29
|
+
|| keys.some((key) => !['dockerfileFragment', 'dotfilesExclusions'].includes(key))
|
|
30
|
+
|| (fragment !== undefined && (typeof fragment !== 'string' || !TOOL_ID_PATTERN.test(fragment)))
|
|
31
|
+
|| (exclusions !== undefined && (!Array.isArray(exclusions)
|
|
32
|
+
|| exclusions.some((entry) => !validExclusion(entry))
|
|
33
|
+
|| new Set(exclusions).size !== exclusions.length))) {
|
|
34
|
+
throw new Error(`Agent Client '${id}' has an invalid sandbox image descriptor`);
|
|
35
|
+
}
|
|
36
|
+
return Object.freeze({
|
|
37
|
+
...(fragment === undefined ? {} : { dockerfileFragment: fragment }),
|
|
38
|
+
...(exclusions === undefined
|
|
39
|
+
? {}
|
|
40
|
+
: { dotfilesExclusions: Object.freeze([...exclusions]) })
|
|
41
|
+
});
|
|
42
|
+
}
|
|
6
43
|
function freezeRecoveryProbe(id, checkId, value) {
|
|
7
44
|
if (!value
|
|
8
45
|
|| typeof value.script !== 'string'
|
|
@@ -153,8 +190,8 @@ function defineAgentClientAdapter(candidate) {
|
|
|
153
190
|
}
|
|
154
191
|
const evidence = candidate.delegationEvidence;
|
|
155
192
|
if (!evidence
|
|
156
|
-
|| !['host-event', 'unavailable'].includes(evidence.actualModel)
|
|
157
|
-
|| !['host-event', 'spawn-ack', 'unavailable'].includes(evidence.actualReasoningEffort)) {
|
|
193
|
+
|| !['host-event', 'app-server', 'unavailable'].includes(evidence.actualModel)
|
|
194
|
+
|| !['host-event', 'app-server', 'spawn-ack', 'unavailable'].includes(evidence.actualReasoningEffort)) {
|
|
158
195
|
throw new Error(`Agent Client '${candidate.id}' has invalid delegation evidence`);
|
|
159
196
|
}
|
|
160
197
|
if (typeof candidate.project !== 'object'
|
|
@@ -236,9 +273,55 @@ function defineAgentClientAdapter(candidate) {
|
|
|
236
273
|
target: seed.target
|
|
237
274
|
});
|
|
238
275
|
});
|
|
276
|
+
let customCommand;
|
|
277
|
+
if (candidate.project.customCommand !== undefined) {
|
|
278
|
+
const descriptor = candidate.project.customCommand;
|
|
279
|
+
const placeholders = typeof descriptor?.target === 'string'
|
|
280
|
+
? [...descriptor.target.matchAll(/\$\{([^}]+)\}/g)].map((match) => match[1])
|
|
281
|
+
: [];
|
|
282
|
+
const targetProbe = typeof descriptor?.target === 'string'
|
|
283
|
+
? descriptor.target.replaceAll('${skillName}', 'skill')
|
|
284
|
+
: '';
|
|
285
|
+
const frontmatter = descriptor?.frontmatter;
|
|
286
|
+
if (!descriptor
|
|
287
|
+
|| typeof descriptor !== 'object'
|
|
288
|
+
|| placeholders.length !== 1
|
|
289
|
+
|| placeholders[0] !== 'skillName'
|
|
290
|
+
|| targetProbe.includes('${')
|
|
291
|
+
|| !isProjectRelativeLiteral(targetProbe)
|
|
292
|
+
|| !paths.some((prefix) => targetProbe.startsWith(prefix))
|
|
293
|
+
|| !frontmatter
|
|
294
|
+
|| typeof frontmatter !== 'object'
|
|
295
|
+
|| Array.isArray(frontmatter)
|
|
296
|
+
|| Object.values(frontmatter).some((value) => typeof value !== 'string' && typeof value !== 'boolean')
|
|
297
|
+
|| (descriptor.argumentsToken !== undefined
|
|
298
|
+
&& (typeof descriptor.argumentsToken !== 'string'
|
|
299
|
+
|| descriptor.argumentsToken === ''
|
|
300
|
+
|| /[\r\n]/.test(descriptor.argumentsToken)))
|
|
301
|
+
|| (descriptor.includeUsage !== undefined
|
|
302
|
+
&& typeof descriptor.includeUsage !== 'boolean')
|
|
303
|
+
|| (descriptor.inheritDisableModelInvocation !== undefined
|
|
304
|
+
&& typeof descriptor.inheritDisableModelInvocation !== 'boolean')) {
|
|
305
|
+
throw new Error(`Agent Client '${candidate.id}' has an invalid custom command`);
|
|
306
|
+
}
|
|
307
|
+
customCommand = Object.freeze({
|
|
308
|
+
target: descriptor.target,
|
|
309
|
+
frontmatter: Object.freeze({ ...frontmatter }),
|
|
310
|
+
...(descriptor.argumentsToken === undefined
|
|
311
|
+
? {}
|
|
312
|
+
: { argumentsToken: descriptor.argumentsToken }),
|
|
313
|
+
...(descriptor.includeUsage === undefined
|
|
314
|
+
? {}
|
|
315
|
+
: { includeUsage: descriptor.includeUsage }),
|
|
316
|
+
...(descriptor.inheritDisableModelInvocation === undefined
|
|
317
|
+
? {}
|
|
318
|
+
: { inheritDisableModelInvocation: descriptor.inheritDisableModelInvocation })
|
|
319
|
+
});
|
|
320
|
+
}
|
|
239
321
|
if (!candidate.sandbox || typeof candidate.sandbox.createTool !== 'function') {
|
|
240
322
|
throw new Error(`Agent Client '${candidate.id}' requires a sandbox descriptor`);
|
|
241
323
|
}
|
|
324
|
+
const image = freezeSandboxImageDescriptor(candidate.id, candidate.sandbox.image);
|
|
242
325
|
const hookIds = new Set();
|
|
243
326
|
const hooks = Object.freeze(candidate.sandbox.hooks.map((hook) => {
|
|
244
327
|
if (!hook.id
|
|
@@ -328,9 +411,16 @@ function defineAgentClientAdapter(candidate) {
|
|
|
328
411
|
project: Object.freeze({
|
|
329
412
|
ownedPathPrefixes: Object.freeze(paths),
|
|
330
413
|
...projectAssets,
|
|
331
|
-
seedCommands: Object.freeze(seedCommands)
|
|
414
|
+
seedCommands: Object.freeze(seedCommands),
|
|
415
|
+
...(customCommand === undefined ? {} : { customCommand })
|
|
332
416
|
}),
|
|
333
|
-
sandbox: Object.freeze({
|
|
417
|
+
sandbox: Object.freeze({
|
|
418
|
+
createTool,
|
|
419
|
+
aliases,
|
|
420
|
+
hooks,
|
|
421
|
+
recoveryChecks,
|
|
422
|
+
...(image === undefined ? {} : { image })
|
|
423
|
+
})
|
|
334
424
|
});
|
|
335
425
|
}
|
|
336
426
|
export { defineAgentClientAdapter };
|
package/dist/lib/{sandbox/credentials.js → agent-clients/adapters/claude-code-credentials.js}
RENAMED
|
@@ -2,15 +2,10 @@ import { execFileSync } from 'node:child_process';
|
|
|
2
2
|
import { randomBytes } from 'node:crypto';
|
|
3
3
|
import fs from 'node:fs';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
-
import { hostJoin } from '
|
|
5
|
+
import { hostJoin } from '../../sandbox/engines/wsl2-paths.js';
|
|
6
|
+
import { redactCommandError } from '../../sandbox/redaction.js';
|
|
6
7
|
const LOCKED_PATTERN = /errSecInteractionNotAllowed|User interaction is not allowed/i;
|
|
7
8
|
const NOT_FOUND_PATTERN = /errSecItemNotFound|specified item could not be found/i;
|
|
8
|
-
const REDACTION_PATTERNS = [
|
|
9
|
-
{ pattern: /\{[^{}]*"claudeAiOauth"[\s\S]*?\}\s*\}/g, replacement: '[REDACTED credentials blob]' },
|
|
10
|
-
{ pattern: /sk-ant-[A-Za-z0-9_-]{20,}/g, replacement: '[REDACTED claude token]' },
|
|
11
|
-
{ pattern: /gh[psoru]_[A-Za-z0-9]{30,}/g, replacement: '[REDACTED github token]' },
|
|
12
|
-
{ pattern: /Bearer\s+[A-Za-z0-9._~+/=-]{20,}/gi, replacement: 'Bearer [REDACTED]' }
|
|
13
|
-
];
|
|
14
9
|
function isRecord(value) {
|
|
15
10
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
16
11
|
}
|
|
@@ -20,13 +15,8 @@ function hasNonEmptyString(value) {
|
|
|
20
15
|
function errorMessage(error) {
|
|
21
16
|
return error instanceof Error ? error.message : 'unknown error';
|
|
22
17
|
}
|
|
23
|
-
export function redactCommandError(text) {
|
|
24
|
-
if (!text || typeof text !== 'string') {
|
|
25
|
-
return '';
|
|
26
|
-
}
|
|
27
|
-
return REDACTION_PATTERNS.reduce((result, { pattern, replacement }) => result.replace(pattern, replacement), text);
|
|
28
|
-
}
|
|
29
18
|
export const redactSecurityOutput = redactCommandError;
|
|
19
|
+
export { redactCommandError };
|
|
30
20
|
function extractStderrSafely(error) {
|
|
31
21
|
const stderr = typeof error === 'object' && error !== null && 'stderr' in error
|
|
32
22
|
? error.stderr
|
|
@@ -492,4 +482,4 @@ export function prepareClaudeCredentials(home, project, resolvedTools, extractFn
|
|
|
492
482
|
writeFn(home, project, blob);
|
|
493
483
|
return { status: 'OK' };
|
|
494
484
|
}
|
|
495
|
-
//# sourceMappingURL=credentials.js.map
|
|
485
|
+
//# sourceMappingURL=claude-code-credentials.js.map
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { parseArgs } from 'node:util';
|
|
3
|
+
import { buildLockedGuidance, discoverProjects, formatCredentialWarnings, formatRemaining, reconcileClaudeCredentials, redactCommandError, validateClaudeCredentialsEnvOverride } from './claude-code-credentials.js';
|
|
4
|
+
import { runProbe } from '../../sandbox/shell.js';
|
|
5
|
+
const USAGE = 'Usage: ai sandbox refresh';
|
|
6
|
+
export function probeClaudeStatus(spawnFn = runProbe) {
|
|
7
|
+
const result = spawnFn('claude', ['/status'], {
|
|
8
|
+
encoding: 'utf8',
|
|
9
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
10
|
+
timeout: 30_000
|
|
11
|
+
});
|
|
12
|
+
return {
|
|
13
|
+
ok: result.status === 0,
|
|
14
|
+
stderr: result.stderr?.toString() ?? '',
|
|
15
|
+
error: result.error?.message ?? null
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export async function runClaudeCodeRefresh(args, deps = {}) {
|
|
19
|
+
const { spawnFn = runProbe, execFn, readFn, existsFn, writeFn, writeHostFn, discoverFn = discoverProjects, writeStdout = (chunk) => process.stdout.write(chunk), writeStderr = (chunk) => process.stderr.write(chunk) } = deps;
|
|
20
|
+
if (args[0] === '--help' || args[0] === '-h' || args[0] === 'help') {
|
|
21
|
+
writeStdout(`${USAGE}\n`);
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
const { positionals } = parseArgs({ args, allowPositionals: true, strict: true });
|
|
25
|
+
if (positionals.length > 0) {
|
|
26
|
+
throw new Error(USAGE);
|
|
27
|
+
}
|
|
28
|
+
validateClaudeCredentialsEnvOverride();
|
|
29
|
+
const home = homedir();
|
|
30
|
+
if (!home) {
|
|
31
|
+
throw new Error('sandbox: home directory is required');
|
|
32
|
+
}
|
|
33
|
+
const projects = discoverFn(home);
|
|
34
|
+
if (projects.length === 0) {
|
|
35
|
+
writeStdout('No project credentials to refresh.\n');
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
const reconcileOptions = { execFn, readFn, existsFn, writeFn, writeHostFn, projects };
|
|
39
|
+
let result = reconcileClaudeCredentials(home, reconcileOptions);
|
|
40
|
+
if (result.status === 'STALE_ACCESS' && result.authoritative === null) {
|
|
41
|
+
writeStdout('Host credentials appear stale; probing claude /status to trigger refresh...\n');
|
|
42
|
+
const probe = probeClaudeStatus(spawnFn);
|
|
43
|
+
if (!probe.ok) {
|
|
44
|
+
writeStderr(`Probe failed: ${redactCommandError(probe.stderr || probe.error || 'unknown error')}\n`);
|
|
45
|
+
writeStderr('Run "claude /login" on the host to renew credentials.\n');
|
|
46
|
+
return 1;
|
|
47
|
+
}
|
|
48
|
+
writeStdout('Probe succeeded; re-inspecting host credentials.\n');
|
|
49
|
+
result = reconcileClaudeCredentials(home, reconcileOptions);
|
|
50
|
+
}
|
|
51
|
+
if (result.status === 'MISSING') {
|
|
52
|
+
writeStderr('No Claude Code credentials found on host.\n');
|
|
53
|
+
writeStderr('Run "claude /login" on the host to authenticate.\n');
|
|
54
|
+
return 1;
|
|
55
|
+
}
|
|
56
|
+
if (result.status === 'KEYCHAIN_LOCKED') {
|
|
57
|
+
writeStderr(`${buildLockedGuidance()}\n`);
|
|
58
|
+
return 1;
|
|
59
|
+
}
|
|
60
|
+
if (result.status === 'KEYCHAIN_ERROR') {
|
|
61
|
+
writeStderr(`Host keychain error: ${redactCommandError(result.detail || 'unknown error')}\n`);
|
|
62
|
+
writeStderr(`${buildLockedGuidance()}\n`);
|
|
63
|
+
return 1;
|
|
64
|
+
}
|
|
65
|
+
if (result.status === 'KEYCHAIN_WRITE_FAILED') {
|
|
66
|
+
writeStderr(`[host] keychain write failed: ${formatCredentialWarnings(result.warnings) || 'unknown error'}\n`);
|
|
67
|
+
return 1;
|
|
68
|
+
}
|
|
69
|
+
if (result.status !== 'OK') {
|
|
70
|
+
writeStderr('Host credentials still invalid after probe; run "claude /login".\n');
|
|
71
|
+
return 1;
|
|
72
|
+
}
|
|
73
|
+
if (result.authoritative && result.authoritative !== 'host' && result.hostWritten) {
|
|
74
|
+
writeStdout(`[host] reconciled from ${result.authoritative}\n`);
|
|
75
|
+
}
|
|
76
|
+
for (const project of projects) {
|
|
77
|
+
const action = result.filesWritten.includes(project) ? 'updated' : 'unchanged';
|
|
78
|
+
writeStdout(`[${project}] ${action}; expires in ${formatRemaining(result.expiresAt)}\n`);
|
|
79
|
+
}
|
|
80
|
+
for (const failure of result.fileErrors) {
|
|
81
|
+
writeStderr(`[${failure.project}] sync failed: ${failure.error}\n`);
|
|
82
|
+
}
|
|
83
|
+
return result.fileErrors.length > 0 ? 1 : 0;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=claude-code-refresh.js.map
|