@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
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
type JsonPrimitive = null | boolean | number | string;
|
|
2
|
+
type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue };
|
|
3
|
+
|
|
4
|
+
type Availability<T> =
|
|
5
|
+
| { state: 'known'; value: T }
|
|
6
|
+
| { state: 'unknown' | 'unavailable'; reason: string };
|
|
7
|
+
|
|
8
|
+
type SourceKind = 'local-file' | 'github-rest' | 'operational-report' | 'structured-telemetry';
|
|
9
|
+
|
|
10
|
+
type PrivacyDisposition =
|
|
11
|
+
| { state: 'included' }
|
|
12
|
+
| { state: 'excluded-sensitive'; ruleId: string }
|
|
13
|
+
| { state: 'unavailable'; reason: string };
|
|
14
|
+
|
|
15
|
+
type CapturedObject = {
|
|
16
|
+
sourceKind: SourceKind;
|
|
17
|
+
sourceIdentity: string;
|
|
18
|
+
sha256: string;
|
|
19
|
+
bytes: number;
|
|
20
|
+
content?: string;
|
|
21
|
+
disposition?: PrivacyDisposition;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type StoredObjectEvidence = Omit<CapturedObject, 'content'>;
|
|
25
|
+
|
|
26
|
+
type RestPageEvidence = {
|
|
27
|
+
index: number;
|
|
28
|
+
itemCount: number;
|
|
29
|
+
canonicalSha256: string;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
type RestCollectionEvidence = {
|
|
33
|
+
endpoint: string;
|
|
34
|
+
requestCount: number;
|
|
35
|
+
dataPageCount: number;
|
|
36
|
+
itemCount: number;
|
|
37
|
+
termination: 'short-page';
|
|
38
|
+
pages: RestPageEvidence[];
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
type NormalizedKind =
|
|
42
|
+
| 'task'
|
|
43
|
+
| 'artifact'
|
|
44
|
+
| 'platform-resource'
|
|
45
|
+
| 'lifecycle-event'
|
|
46
|
+
| 'review-finding'
|
|
47
|
+
| 'human-ruling'
|
|
48
|
+
| 'telemetry'
|
|
49
|
+
| 'operational-report'
|
|
50
|
+
| 'missing'
|
|
51
|
+
| 'conflict';
|
|
52
|
+
|
|
53
|
+
type NormalizedRecord = {
|
|
54
|
+
recordId: string;
|
|
55
|
+
kind: NormalizedKind;
|
|
56
|
+
sourceIdentity: string;
|
|
57
|
+
sourceSha256: string;
|
|
58
|
+
binding?: string;
|
|
59
|
+
observedAt?: Availability<string>;
|
|
60
|
+
data?: JsonValue;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
type QualityCategory =
|
|
64
|
+
| 'missing-local'
|
|
65
|
+
| 'missing-remote'
|
|
66
|
+
| 'duplicate-identity'
|
|
67
|
+
| 'binding-conflict'
|
|
68
|
+
| 'content-mismatch'
|
|
69
|
+
| 'schema-difference'
|
|
70
|
+
| 'mutable-remote'
|
|
71
|
+
| 'unrecoverable'
|
|
72
|
+
| 'privacy-excluded';
|
|
73
|
+
|
|
74
|
+
type QualityFinding = {
|
|
75
|
+
findingId: string;
|
|
76
|
+
category: QualityCategory;
|
|
77
|
+
severity: 'info' | 'warning' | 'error';
|
|
78
|
+
identities: string[];
|
|
79
|
+
repairable: boolean;
|
|
80
|
+
reason: string;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
type RepairAction = {
|
|
84
|
+
repairId: string;
|
|
85
|
+
operation: 'add' | 'supersede' | 'link';
|
|
86
|
+
sourceRecordId: string;
|
|
87
|
+
targetRecordId: string;
|
|
88
|
+
preconditionSha256: string;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
type SnapshotManifest = {
|
|
92
|
+
schema: 'raw-manifest/v1';
|
|
93
|
+
snapshotId: string;
|
|
94
|
+
scope: 'all' | 'local' | 'github';
|
|
95
|
+
repository: string;
|
|
96
|
+
observedFrom: string;
|
|
97
|
+
observedTo: string;
|
|
98
|
+
objects: StoredObjectEvidence[];
|
|
99
|
+
endpoints: RestCollectionEvidence[];
|
|
100
|
+
recordCount: number;
|
|
101
|
+
findingCount: number;
|
|
102
|
+
repairCount: number;
|
|
103
|
+
privacyPolicyVersion: 'process-data-privacy/v1';
|
|
104
|
+
excerptsEnabled: boolean;
|
|
105
|
+
dispositionCounts: Record<'included' | 'excluded-sensitive' | 'unavailable', number>;
|
|
106
|
+
manifestSha256: string;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
type ProcessDataError = {
|
|
110
|
+
code: string;
|
|
111
|
+
message: string;
|
|
112
|
+
retryable?: boolean;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
type ProcessResult<T> = { ok: true; value: T } | { ok: false; error: ProcessDataError };
|
|
116
|
+
|
|
117
|
+
export type {
|
|
118
|
+
Availability,
|
|
119
|
+
CapturedObject,
|
|
120
|
+
JsonPrimitive,
|
|
121
|
+
JsonValue,
|
|
122
|
+
NormalizedKind,
|
|
123
|
+
NormalizedRecord,
|
|
124
|
+
PrivacyDisposition,
|
|
125
|
+
ProcessDataError,
|
|
126
|
+
ProcessResult,
|
|
127
|
+
QualityCategory,
|
|
128
|
+
QualityFinding,
|
|
129
|
+
RepairAction,
|
|
130
|
+
RestCollectionEvidence,
|
|
131
|
+
RestPageEvidence,
|
|
132
|
+
SnapshotManifest,
|
|
133
|
+
SourceKind,
|
|
134
|
+
StoredObjectEvidence
|
|
135
|
+
};
|
package/lib/run/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { loadServerConfig } from '../server/config.ts';
|
|
4
|
-
import {
|
|
4
|
+
import { resolveSandboxTarget, type SandboxWorkspaceIdentity } from '../sandbox/workspace-identity.ts';
|
|
5
5
|
import { createRunId, runInSandbox, type SandboxRunMetadata } from '../sandbox/capture.ts';
|
|
6
6
|
import { loadShortIdByTaskId, normalizeShortIdInput } from '../task/short-id.ts';
|
|
7
7
|
import { buildTuiCommand, renderPrompt, selectTui } from './tui.ts';
|
|
@@ -19,6 +19,7 @@ export type ParsedRunArgs = {
|
|
|
19
19
|
export type SandboxRunRequest = {
|
|
20
20
|
taskRef: string;
|
|
21
21
|
branch: string;
|
|
22
|
+
workspace?: SandboxWorkspaceIdentity;
|
|
22
23
|
command: string[];
|
|
23
24
|
runId?: string;
|
|
24
25
|
recreate?: boolean;
|
|
@@ -136,7 +137,6 @@ function resolveActiveTaskIdentity(taskRef: string, repoRoot: string): ActiveTas
|
|
|
136
137
|
|
|
137
138
|
if (TASK_ID_RE.test(taskRef)) {
|
|
138
139
|
taskId = taskRef;
|
|
139
|
-
resolvedTaskRef = loadShortIdByTaskId(repoRoot).get(taskId) ?? taskRef;
|
|
140
140
|
} else {
|
|
141
141
|
const normalized = normalizeShortIdInput(taskRef, { shortIdLength: readShortIdLength(repoRoot) });
|
|
142
142
|
if (normalized.kind !== 'shortId') return null;
|
|
@@ -211,7 +211,8 @@ export async function runSkill(args: string[], options: RunSkillOptions = {}): P
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
const repoRoot = options.repoRoot ?? config?.repoRoot ?? process.cwd();
|
|
214
|
-
const
|
|
214
|
+
const target = resolveSandboxTarget(parsed.taskRef, repoRoot);
|
|
215
|
+
const branch = target.branch;
|
|
215
216
|
const identity = resolveActiveTaskIdentity(parsed.taskRef, repoRoot);
|
|
216
217
|
const runId = identity ? createRunId() : undefined;
|
|
217
218
|
const writeStdout = options.writeStdout ?? ((chunk: string) => process.stdout.write(chunk));
|
|
@@ -222,6 +223,7 @@ export async function runSkill(args: string[], options: RunSkillOptions = {}): P
|
|
|
222
223
|
const result = await runSandbox({
|
|
223
224
|
taskRef: parsed.taskRef,
|
|
224
225
|
branch,
|
|
226
|
+
workspace: target.workspace,
|
|
225
227
|
command,
|
|
226
228
|
runId,
|
|
227
229
|
recreate: parsed.recreate
|
package/lib/run/tui.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { renderAgentClientInvocation } from '../agent-clients/invocation.ts';
|
|
2
2
|
import { getAgentClientAdapter } from '../agent-clients/registry.ts';
|
|
3
|
+
import type { AgentClientId } from '../agent-clients/types.ts';
|
|
3
4
|
|
|
4
5
|
export type TuiName = 'claude' | 'codex' | 'antigravity' | 'opencode';
|
|
5
6
|
|
|
6
7
|
const TUI_NAMES = new Set(['claude', 'codex', 'antigravity', 'opencode']);
|
|
8
|
+
const TUI_AGENT_CLIENT_IDS: Readonly<Record<TuiName, AgentClientId>> = Object.freeze({
|
|
9
|
+
claude: 'claude-code',
|
|
10
|
+
codex: 'codex',
|
|
11
|
+
antigravity: 'antigravity-cli',
|
|
12
|
+
opencode: 'opencode'
|
|
13
|
+
});
|
|
7
14
|
|
|
8
15
|
export type CommandConfig = {
|
|
9
16
|
defaultTui?: unknown;
|
|
@@ -29,14 +36,10 @@ export function selectTui(
|
|
|
29
36
|
}
|
|
30
37
|
|
|
31
38
|
export function renderPrompt(params: { tui: TuiName; skill: string; args: string[] }): string {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
args: params.args
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
return `/${suffix}`;
|
|
39
|
+
return renderAgentClientInvocation(
|
|
40
|
+
getAgentClientAdapter(TUI_AGENT_CLIENT_IDS[params.tui]).invocation,
|
|
41
|
+
{ skillName: params.skill, args: params.args }
|
|
42
|
+
);
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
export function buildTuiCommand(tui: TuiName, prompt: string): [string, string[]] {
|
|
@@ -51,6 +51,12 @@ type SandboxRuntimeCapabilityProjection = Readonly<{
|
|
|
51
51
|
}>;
|
|
52
52
|
repair?: AgentClientSandboxRecoveryCheck['repair'];
|
|
53
53
|
}>[];
|
|
54
|
+
image: SandboxImageContribution;
|
|
55
|
+
}>;
|
|
56
|
+
|
|
57
|
+
type SandboxImageContribution = Readonly<{
|
|
58
|
+
dockerfileFragments: readonly string[];
|
|
59
|
+
dotfilesExclusions: readonly string[];
|
|
54
60
|
}>;
|
|
55
61
|
|
|
56
62
|
type PlannedAgentClientRecoveryCheck = Readonly<{
|
|
@@ -64,6 +70,7 @@ type SandboxCapabilityPlan = Readonly<{
|
|
|
64
70
|
hooksByPhase: Readonly<Record<SandboxHookPhase, readonly AgentClientSandboxHook[]>>;
|
|
65
71
|
recoveryChecks: readonly PlannedAgentClientRecoveryCheck[];
|
|
66
72
|
aliases: readonly SandboxAlias[];
|
|
73
|
+
image: SandboxImageContribution;
|
|
67
74
|
imageSignature: string;
|
|
68
75
|
runtimeSignature: string;
|
|
69
76
|
runtimeProjection: SandboxRuntimeCapabilityProjection;
|
|
@@ -147,6 +154,36 @@ function assertUniqueTools(tools: readonly SandboxTool[]): void {
|
|
|
147
154
|
}
|
|
148
155
|
}
|
|
149
156
|
|
|
157
|
+
function unique(values: readonly string[]): readonly string[] {
|
|
158
|
+
return Object.freeze([...new Set(values)]);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function sandboxImageContribution(
|
|
162
|
+
adapters: readonly AgentClientAdapter[],
|
|
163
|
+
tools: readonly SandboxTool[]
|
|
164
|
+
): SandboxImageContribution {
|
|
165
|
+
const homePrefix = '/home/devuser/';
|
|
166
|
+
const derivedExclusions = tools.map((tool) => {
|
|
167
|
+
if (!tool.containerMount.startsWith(homePrefix)) {
|
|
168
|
+
throw new Error(
|
|
169
|
+
`Agent Client '${tool.id}' container mount must be below ${homePrefix.slice(0, -1)}`
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
return tool.containerMount.slice(homePrefix.length);
|
|
173
|
+
});
|
|
174
|
+
return Object.freeze({
|
|
175
|
+
dockerfileFragments: unique(adapters.flatMap((adapter) =>
|
|
176
|
+
adapter.sandbox.image?.dockerfileFragment
|
|
177
|
+
? [adapter.sandbox.image.dockerfileFragment]
|
|
178
|
+
: []
|
|
179
|
+
)),
|
|
180
|
+
dotfilesExclusions: unique([
|
|
181
|
+
...derivedExclusions,
|
|
182
|
+
...adapters.flatMap((adapter) => adapter.sandbox.image?.dotfilesExclusions ?? [])
|
|
183
|
+
])
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
150
187
|
function hooksByPhase(
|
|
151
188
|
adapters: readonly AgentClientAdapter[]
|
|
152
189
|
): SandboxCapabilityPlan['hooksByPhase'] {
|
|
@@ -207,6 +244,7 @@ function createSandboxCapabilityPlan(
|
|
|
207
244
|
|
|
208
245
|
const tools = Object.freeze([...nonClientTools, ...selectedTools, ...selectedCustomTools]);
|
|
209
246
|
assertUniqueTools(tools);
|
|
247
|
+
const image = sandboxImageContribution(selectedAgentClients, selectedTools);
|
|
210
248
|
const phaseHooks = hooksByPhase(selectedAgentClients);
|
|
211
249
|
const hookProjection = selectedAgentClients.flatMap((adapter) =>
|
|
212
250
|
adapter.sandbox.hooks.map((hook) => ({
|
|
@@ -239,7 +277,8 @@ function createSandboxCapabilityPlan(
|
|
|
239
277
|
tools: Object.freeze(tools.map(runtimeToolProjection)),
|
|
240
278
|
selectedAgentClients: Object.freeze(selectedAgentClients.map((adapter) => adapter.id)),
|
|
241
279
|
hooks: Object.freeze(hookProjection),
|
|
242
|
-
recoveryChecks: recoveryCheckProjection
|
|
280
|
+
recoveryChecks: recoveryCheckProjection,
|
|
281
|
+
image
|
|
243
282
|
});
|
|
244
283
|
const cleanupInventory = Object.freeze([
|
|
245
284
|
agentInfraTool(config.home),
|
|
@@ -256,6 +295,7 @@ function createSandboxCapabilityPlan(
|
|
|
256
295
|
aliases: Object.freeze(
|
|
257
296
|
listAgentClientAdapters().flatMap((adapter) => adapter.sandbox.aliases)
|
|
258
297
|
),
|
|
298
|
+
image,
|
|
259
299
|
imageSignature: hash(tools.map(({ id, install }) => ({ id, install }))),
|
|
260
300
|
runtimeSignature: hash(runtimeProjection),
|
|
261
301
|
runtimeProjection,
|
|
@@ -367,12 +407,14 @@ export {
|
|
|
367
407
|
DEFAULT_SANDBOX_HOOK_TIMEOUT_MS,
|
|
368
408
|
createSandboxCapabilityPlan,
|
|
369
409
|
runBoundedSandboxHookCommand,
|
|
370
|
-
runSandboxHooks
|
|
410
|
+
runSandboxHooks,
|
|
411
|
+
sandboxImageContribution
|
|
371
412
|
};
|
|
372
413
|
export type {
|
|
373
414
|
HookExecutionResult,
|
|
374
415
|
SandboxCapabilityConfig,
|
|
375
416
|
SandboxCapabilityPlan,
|
|
417
|
+
SandboxImageContribution,
|
|
376
418
|
PlannedAgentClientRecoveryCheck,
|
|
377
419
|
SandboxRuntimeCapabilityProjection
|
|
378
420
|
};
|
package/lib/sandbox/capture.ts
CHANGED
|
@@ -11,10 +11,12 @@ import {
|
|
|
11
11
|
startSandboxContainer,
|
|
12
12
|
type SandboxRow
|
|
13
13
|
} from './commands/list-running.ts';
|
|
14
|
+
import { resolveSandboxTarget, type SandboxWorkspaceIdentity } from './workspace-identity.ts';
|
|
14
15
|
|
|
15
16
|
export type SandboxCaptureRequest = {
|
|
16
17
|
taskRef: string;
|
|
17
18
|
branch: string;
|
|
19
|
+
workspace?: SandboxWorkspaceIdentity;
|
|
18
20
|
command: string[];
|
|
19
21
|
timeoutMs?: number;
|
|
20
22
|
recreate?: boolean;
|
|
@@ -44,6 +46,7 @@ export type SandboxCaptureOptions = {
|
|
|
44
46
|
startContainer?: (name: string) => void;
|
|
45
47
|
ensureReady?: (params: {
|
|
46
48
|
branch: string;
|
|
49
|
+
workspace?: SandboxWorkspaceIdentity;
|
|
47
50
|
row: SandboxRow;
|
|
48
51
|
allowRecreate: boolean;
|
|
49
52
|
}) => Promise<SandboxReadyResult>;
|
|
@@ -183,6 +186,8 @@ export async function runInSandbox(
|
|
|
183
186
|
): Promise<SandboxCaptureResult> {
|
|
184
187
|
const config = options.engine ? null : loadConfig();
|
|
185
188
|
const engine = options.engine ?? detectEngine(config!);
|
|
189
|
+
const workspace = request.workspace
|
|
190
|
+
?? (config ? resolveSandboxTarget(request.taskRef, config.repoRoot).workspace : undefined);
|
|
186
191
|
const rows =
|
|
187
192
|
options.rows ??
|
|
188
193
|
(() => {
|
|
@@ -200,6 +205,7 @@ export async function runInSandbox(
|
|
|
200
205
|
if (options.ensureReady) {
|
|
201
206
|
container = (await options.ensureReady({
|
|
202
207
|
branch: request.branch,
|
|
208
|
+
workspace,
|
|
203
209
|
row: found,
|
|
204
210
|
allowRecreate: request.recreate ?? false
|
|
205
211
|
})).container;
|
|
@@ -208,11 +214,12 @@ export async function runInSandbox(
|
|
|
208
214
|
config,
|
|
209
215
|
engine,
|
|
210
216
|
branch: request.branch,
|
|
217
|
+
workspace,
|
|
211
218
|
row: found,
|
|
212
219
|
allowRecreate: request.recreate,
|
|
213
|
-
recreate: async (
|
|
220
|
+
recreate: async () => {
|
|
214
221
|
const { create } = await import('./commands/create.ts');
|
|
215
|
-
await create([
|
|
222
|
+
await create([request.taskRef, '--no-refresh']);
|
|
216
223
|
}
|
|
217
224
|
})).container;
|
|
218
225
|
} else if (!found.running) {
|