ultra-builder-pro-cli 3.0.2 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ultra-template/contexts/TEMPLATE.md +6 -0
- package/CHANGELOG.md +83 -1
- package/README.md +126 -36
- package/README.zh-CN.md +440 -0
- package/adapters/_shared/host-profile.cjs +3 -151
- package/adapters/_shared/plugin-core.cjs +57 -0
- package/adapters/_shared/runtime-assets.cjs +64 -12
- package/adapters/codex.js +3 -6
- package/bin/delegate-worker.cjs +2 -345
- package/bin/delegate.cjs +3 -530
- package/docs/ARCHITECTURE.md +59 -18
- package/docs/ARTIFACT-AUTHORITY.md +21 -5
- package/docs/DECISIONS.md +31 -10
- package/docs/PLUGIN-ISOLATION-CONTRACT.md +28 -12
- package/docs/RUNTIME-COMPAT-MATRIX.md +106 -26
- package/docs/SKILL-AUTHORING.md +15 -3
- package/docs/WORKFLOW-LIFECYCLE.md +83 -29
- package/docs/evals/ultra-5-0-journey-results.md +62 -0
- package/docs/evals/ultra-5-0-live-acp-conformance.md +93 -0
- package/docs/evals/ultra-5-0-route-journeys.md +145 -0
- package/package.json +2 -1
- package/skills/ultra-change/SKILL.md +30 -4
- package/skills/ultra-delegate/SKILL.md +80 -7
- package/skills/ultra-delegate/patches/zcode-acp-0.1.0-zcode-0.16.5.patch +184 -0
- package/skills/ultra-delegate/references/delegation-contract.md +60 -1
- package/skills/ultra-delegate/scripts/acp-conformance.cjs +287 -0
- package/skills/ultra-delegate/scripts/acp-driver.cjs +762 -0
- package/skills/ultra-delegate/scripts/agent-execution-driver.cjs +320 -0
- package/skills/ultra-delegate/scripts/cli-driver.cjs +61 -0
- package/skills/ultra-delegate/scripts/delegate-worker.cjs +328 -0
- package/skills/ultra-delegate/scripts/delegate.cjs +690 -0
- package/skills/ultra-delegate/scripts/host-profile.cjs +267 -0
- package/skills/ultra-deliver/SKILL.md +13 -0
- package/skills/ultra-dev/SKILL.md +18 -2
- package/skills/ultra-init/SKILL.md +12 -0
- package/skills/ultra-plan/SKILL.md +21 -3
- package/skills/ultra-research/SKILL.md +33 -5
- package/skills/ultra-status/SKILL.md +37 -7
- package/skills/ultra-status/references/route-contract.md +100 -0
- package/skills/ultra-test/SKILL.md +16 -1
- /package/{adapters/_shared → skills/ultra-delegate/scripts}/delegate-profiles/kimi-read-only.md +0 -0
- /package/{adapters/_shared → skills/ultra-delegate/scripts}/delegate-profiles/kimi-write.md +0 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { spawnSync } = require('node:child_process');
|
|
6
|
+
|
|
7
|
+
const ACP_PROTOCOL_VERSION = 1;
|
|
8
|
+
const DEFAULT_CAPTURE_LIMIT_BYTES = 4 * 1024 * 1024;
|
|
9
|
+
|
|
10
|
+
class AgentExecutionDriver {
|
|
11
|
+
constructor(spec) {
|
|
12
|
+
this.spec = spec;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async run() {
|
|
16
|
+
throw new Error('AgentExecutionDriver.run() must be implemented by a concrete driver');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
class BoundedCapture {
|
|
21
|
+
constructor(limitBytes = DEFAULT_CAPTURE_LIMIT_BYTES) {
|
|
22
|
+
if (!Number.isInteger(limitBytes) || limitBytes < 256) {
|
|
23
|
+
throw new Error('capture limit must be an integer of at least 256 bytes');
|
|
24
|
+
}
|
|
25
|
+
this.limitBytes = limitBytes;
|
|
26
|
+
this.buffer = Buffer.alloc(0);
|
|
27
|
+
this.truncated = false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
append(chunk) {
|
|
31
|
+
const incoming = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
|
|
32
|
+
if (incoming.length >= this.limitBytes) {
|
|
33
|
+
this.buffer = incoming.subarray(incoming.length - this.limitBytes);
|
|
34
|
+
this.truncated = true;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (this.buffer.length + incoming.length <= this.limitBytes) {
|
|
38
|
+
this.buffer = Buffer.concat([this.buffer, incoming]);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const keep = this.limitBytes - incoming.length;
|
|
42
|
+
this.buffer = Buffer.concat([this.buffer.subarray(this.buffer.length - keep), incoming]);
|
|
43
|
+
this.truncated = true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
text() {
|
|
47
|
+
const payload = this.buffer.toString('utf8');
|
|
48
|
+
return this.truncated
|
|
49
|
+
? `[ultra-delegate: output truncated to ${this.limitBytes} bytes]\n${payload}`
|
|
50
|
+
: payload;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
write(file) {
|
|
54
|
+
fs.writeFileSync(file, this.text(), { mode: 0o600 });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function terminateProcessGroup(child, signal = 'SIGTERM', options = {}) {
|
|
59
|
+
if (!child || !child.pid) return;
|
|
60
|
+
const platform = options.platform || process.platform;
|
|
61
|
+
const runSync = options.spawnSync || spawnSync;
|
|
62
|
+
if (platform === 'win32') {
|
|
63
|
+
try {
|
|
64
|
+
const args = ['/PID', String(child.pid), '/T', '/F'];
|
|
65
|
+
const result = runSync('taskkill.exe', args, { stdio: 'ignore', windowsHide: true });
|
|
66
|
+
if (result?.status === 0) return;
|
|
67
|
+
} catch {}
|
|
68
|
+
try { child.kill(signal); } catch {}
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
process.kill(-child.pid, signal);
|
|
73
|
+
} catch {}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function executablePath(command, env = process.env) {
|
|
77
|
+
if (typeof command !== 'string' || !command.trim()) return null;
|
|
78
|
+
const candidates = [];
|
|
79
|
+
if (path.isAbsolute(command) || command.includes(path.sep)) {
|
|
80
|
+
candidates.push(path.resolve(command));
|
|
81
|
+
} else {
|
|
82
|
+
for (const entry of String(env.PATH || '').split(path.delimiter).filter(Boolean)) {
|
|
83
|
+
candidates.push(path.join(entry, command));
|
|
84
|
+
if (process.platform === 'win32') {
|
|
85
|
+
for (const extension of String(env.PATHEXT || '.EXE;.CMD;.BAT')
|
|
86
|
+
.split(';').filter(Boolean)) {
|
|
87
|
+
candidates.push(path.join(entry, `${command}${extension.toLowerCase()}`));
|
|
88
|
+
candidates.push(path.join(entry, `${command}${extension.toUpperCase()}`));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
for (const candidate of candidates) {
|
|
94
|
+
try {
|
|
95
|
+
const stat = fs.statSync(candidate);
|
|
96
|
+
if (!stat.isFile()) continue;
|
|
97
|
+
fs.accessSync(candidate, process.platform === 'win32' ? fs.constants.F_OK : fs.constants.X_OK);
|
|
98
|
+
return candidate;
|
|
99
|
+
} catch {}
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function capability(acp, probe = {}) {
|
|
105
|
+
return {
|
|
106
|
+
candidate: !!acp,
|
|
107
|
+
surface: acp?.surface || null,
|
|
108
|
+
transport: acp?.transport || null,
|
|
109
|
+
protocol_versions: Array.isArray(acp?.protocolVersions) ? [...acp.protocolVersions] : [],
|
|
110
|
+
conformance_status: acp?.conformance?.status || 'not_available',
|
|
111
|
+
conformance_evidence: acp?.conformance?.evidence || null,
|
|
112
|
+
conformance_reason: acp?.conformance?.reason || null,
|
|
113
|
+
executable_available: probe.executableAvailable ?? null,
|
|
114
|
+
candidate_valid: probe.candidateValid ?? null,
|
|
115
|
+
candidate_identity_valid: probe.candidateIdentityValid ?? null,
|
|
116
|
+
candidate_identity_reason: probe.candidateIdentityReason ?? null,
|
|
117
|
+
candidate_identity_fallback_reason: probe.candidateIdentityFallbackReason ?? null,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function cliSelection(cliCommand, acp, fallbackReason, probe) {
|
|
122
|
+
return {
|
|
123
|
+
driver: 'cli',
|
|
124
|
+
command: cliCommand,
|
|
125
|
+
args: null,
|
|
126
|
+
protocolVersion: null,
|
|
127
|
+
fallbackReason,
|
|
128
|
+
acpCapability: capability(acp, probe),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function inspectCandidateIdentity(acp, context, runCandidateProbe) {
|
|
133
|
+
if (typeof acp.identityProbes !== 'function') {
|
|
134
|
+
return { valid: null, reason: null, fallbackReason: null };
|
|
135
|
+
}
|
|
136
|
+
let probes;
|
|
137
|
+
try {
|
|
138
|
+
probes = acp.identityProbes(context);
|
|
139
|
+
} catch {
|
|
140
|
+
return {
|
|
141
|
+
valid: false,
|
|
142
|
+
reason: 'identity_probe_definition',
|
|
143
|
+
fallbackReason: 'acp_candidate_identity_unavailable',
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
if (!Array.isArray(probes) || probes.length === 0) {
|
|
147
|
+
return {
|
|
148
|
+
valid: false,
|
|
149
|
+
reason: 'identity_probe_definition',
|
|
150
|
+
fallbackReason: 'acp_candidate_identity_unavailable',
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
for (const probe of probes) {
|
|
154
|
+
if (!probe || typeof probe.label !== 'string' || !probe.label
|
|
155
|
+
|| typeof probe.command !== 'string' || !probe.command
|
|
156
|
+
|| !Array.isArray(probe.args) || !probe.args.every((item) => typeof item === 'string')
|
|
157
|
+
|| typeof probe.expectedStdout !== 'string' || !probe.expectedStdout) {
|
|
158
|
+
return {
|
|
159
|
+
valid: false,
|
|
160
|
+
reason: 'identity_probe_definition',
|
|
161
|
+
fallbackReason: 'acp_candidate_identity_unavailable',
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
let result;
|
|
165
|
+
try {
|
|
166
|
+
result = runCandidateProbe(probe.command, probe.args, {
|
|
167
|
+
encoding: 'utf8',
|
|
168
|
+
env: context.env,
|
|
169
|
+
maxBuffer: 64 * 1024,
|
|
170
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
171
|
+
timeout: 5000,
|
|
172
|
+
windowsHide: true,
|
|
173
|
+
});
|
|
174
|
+
} catch {
|
|
175
|
+
return {
|
|
176
|
+
valid: false,
|
|
177
|
+
reason: probe.label,
|
|
178
|
+
fallbackReason: 'acp_candidate_identity_unavailable',
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
if (result?.error || result?.status !== 0) {
|
|
182
|
+
return {
|
|
183
|
+
valid: false,
|
|
184
|
+
reason: probe.label,
|
|
185
|
+
fallbackReason: 'acp_candidate_identity_unavailable',
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
if (String(result.stdout || '').trim() !== probe.expectedStdout) {
|
|
189
|
+
return {
|
|
190
|
+
valid: false,
|
|
191
|
+
reason: probe.label,
|
|
192
|
+
fallbackReason: 'acp_candidate_identity_mismatch',
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return { valid: true, reason: null, fallbackReason: null };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function selectExecutionDriver({
|
|
200
|
+
host,
|
|
201
|
+
profile,
|
|
202
|
+
cliCommand,
|
|
203
|
+
env = process.env,
|
|
204
|
+
runCandidateProbe = spawnSync,
|
|
205
|
+
}) {
|
|
206
|
+
const acp = profile?.acp;
|
|
207
|
+
if (!acp) return cliSelection(cliCommand, null, 'acp_not_available');
|
|
208
|
+
if (env.ULTRA_DELEGATE_FORCE_CLI === '1') {
|
|
209
|
+
return cliSelection(cliCommand, acp, 'acp_forced_cli');
|
|
210
|
+
}
|
|
211
|
+
let command;
|
|
212
|
+
let args;
|
|
213
|
+
let candidateValid = true;
|
|
214
|
+
try {
|
|
215
|
+
command = typeof acp.command === 'function'
|
|
216
|
+
? acp.command({ host, cliCommand, env })
|
|
217
|
+
: acp.command;
|
|
218
|
+
args = typeof acp.argv === 'function'
|
|
219
|
+
? acp.argv({ host, cliCommand, env })
|
|
220
|
+
: acp.argv;
|
|
221
|
+
candidateValid = typeof command === 'string' && command.trim()
|
|
222
|
+
&& Array.isArray(args) && args.every((item) => typeof item === 'string');
|
|
223
|
+
} catch {
|
|
224
|
+
candidateValid = false;
|
|
225
|
+
}
|
|
226
|
+
const probe = {
|
|
227
|
+
candidateValid: !!candidateValid,
|
|
228
|
+
executableAvailable: candidateValid ? !!executablePath(command, env) : false,
|
|
229
|
+
};
|
|
230
|
+
if (acp.transport !== 'stdio') {
|
|
231
|
+
return cliSelection(cliCommand, acp, 'acp_stdio_unavailable', probe);
|
|
232
|
+
}
|
|
233
|
+
if (!Array.isArray(acp.protocolVersions) || !acp.protocolVersions.includes(ACP_PROTOCOL_VERSION)) {
|
|
234
|
+
return cliSelection(cliCommand, acp, 'acp_v1_unavailable', probe);
|
|
235
|
+
}
|
|
236
|
+
if (acp.conformance?.status !== 'passed') {
|
|
237
|
+
return cliSelection(cliCommand, acp, 'acp_conformance_not_passed', probe);
|
|
238
|
+
}
|
|
239
|
+
if (typeof acp.conformance.evidence !== 'string' || !acp.conformance.evidence.trim()) {
|
|
240
|
+
return cliSelection(cliCommand, acp, 'acp_conformance_evidence_missing', probe);
|
|
241
|
+
}
|
|
242
|
+
if (!candidateValid) {
|
|
243
|
+
return cliSelection(cliCommand, acp, 'acp_candidate_invalid', probe);
|
|
244
|
+
}
|
|
245
|
+
if (!probe.executableAvailable) {
|
|
246
|
+
return cliSelection(cliCommand, acp, 'acp_command_unavailable', probe);
|
|
247
|
+
}
|
|
248
|
+
const identity = inspectCandidateIdentity(acp, {
|
|
249
|
+
host, command, args, cliCommand, env,
|
|
250
|
+
}, runCandidateProbe);
|
|
251
|
+
probe.candidateIdentityValid = identity.valid;
|
|
252
|
+
probe.candidateIdentityReason = identity.reason;
|
|
253
|
+
probe.candidateIdentityFallbackReason = identity.fallbackReason;
|
|
254
|
+
if (identity.fallbackReason) {
|
|
255
|
+
return cliSelection(cliCommand, acp, identity.fallbackReason, probe);
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
driver: 'acp',
|
|
259
|
+
command,
|
|
260
|
+
args,
|
|
261
|
+
protocolVersion: ACP_PROTOCOL_VERSION,
|
|
262
|
+
fallbackReason: null,
|
|
263
|
+
acpCapability: capability(acp, probe),
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
async function runExecutionDriver(spec) {
|
|
268
|
+
if (spec.execution_driver === 'acp') {
|
|
269
|
+
const { AcpDriver } = require('./acp-driver.cjs');
|
|
270
|
+
const acpResult = await new AcpDriver(spec).run();
|
|
271
|
+
const fallback = spec.cli_fallback;
|
|
272
|
+
if (acpResult.failureType === 'acp_auth_required'
|
|
273
|
+
&& fallback && typeof fallback.command === 'string'
|
|
274
|
+
&& Array.isArray(fallback.args)) {
|
|
275
|
+
const { CliDriver } = require('./cli-driver.cjs');
|
|
276
|
+
const cliResult = await new CliDriver({
|
|
277
|
+
...spec,
|
|
278
|
+
execution_driver: 'cli',
|
|
279
|
+
command: fallback.command,
|
|
280
|
+
args: fallback.args,
|
|
281
|
+
}).run();
|
|
282
|
+
return {
|
|
283
|
+
...cliResult,
|
|
284
|
+
executionDriver: 'cli',
|
|
285
|
+
fallbackReason: 'acp_auth_required',
|
|
286
|
+
protocolVersion: acpResult.protocolVersion,
|
|
287
|
+
stopReason: acpResult.stopReason,
|
|
288
|
+
adapterExitCode: acpResult.adapterExitCode,
|
|
289
|
+
adapterExitSignal: acpResult.adapterExitSignal,
|
|
290
|
+
acpFallback: {
|
|
291
|
+
reason: 'acp_auth_required',
|
|
292
|
+
prompt_sent: false,
|
|
293
|
+
protocol_version: acpResult.protocolVersion,
|
|
294
|
+
adapter_exit_code: acpResult.adapterExitCode,
|
|
295
|
+
adapter_exit_signal: acpResult.adapterExitSignal,
|
|
296
|
+
transport_surface: spec.transport_surface,
|
|
297
|
+
},
|
|
298
|
+
transportSurface: fallback.transport_surface || spec.transport_surface,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
return acpResult;
|
|
302
|
+
}
|
|
303
|
+
if (spec.execution_driver === 'cli' || spec.execution_driver === undefined) {
|
|
304
|
+
const { CliDriver } = require('./cli-driver.cjs');
|
|
305
|
+
return new CliDriver(spec).run();
|
|
306
|
+
}
|
|
307
|
+
throw new Error(`unsupported execution driver: ${spec.execution_driver}`);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
module.exports = {
|
|
311
|
+
ACP_PROTOCOL_VERSION,
|
|
312
|
+
AgentExecutionDriver,
|
|
313
|
+
BoundedCapture,
|
|
314
|
+
DEFAULT_CAPTURE_LIMIT_BYTES,
|
|
315
|
+
executablePath,
|
|
316
|
+
inspectCandidateIdentity,
|
|
317
|
+
runExecutionDriver,
|
|
318
|
+
selectExecutionDriver,
|
|
319
|
+
terminateProcessGroup,
|
|
320
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const { spawn } = require('node:child_process');
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
AgentExecutionDriver,
|
|
8
|
+
BoundedCapture,
|
|
9
|
+
DEFAULT_CAPTURE_LIMIT_BYTES,
|
|
10
|
+
terminateProcessGroup,
|
|
11
|
+
} = require('./agent-execution-driver.cjs');
|
|
12
|
+
|
|
13
|
+
class CliDriver extends AgentExecutionDriver {
|
|
14
|
+
run() {
|
|
15
|
+
const spec = this.spec;
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
const limit = spec.capture_limit_bytes || DEFAULT_CAPTURE_LIMIT_BYTES;
|
|
18
|
+
const stdout = new BoundedCapture(limit);
|
|
19
|
+
const stderr = new BoundedCapture(limit);
|
|
20
|
+
let termination = null;
|
|
21
|
+
let spawnError = null;
|
|
22
|
+
let closed = false;
|
|
23
|
+
let hardKill = null;
|
|
24
|
+
const child = spawn(spec.command, spec.args, {
|
|
25
|
+
cwd: spec.cwd,
|
|
26
|
+
env: { ...process.env, ...spec.env },
|
|
27
|
+
detached: process.platform !== 'win32',
|
|
28
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
29
|
+
});
|
|
30
|
+
child.stdout.on('data', (chunk) => stdout.append(chunk));
|
|
31
|
+
child.stderr.on('data', (chunk) => stderr.append(chunk));
|
|
32
|
+
const finish = (code, signal) => {
|
|
33
|
+
if (closed) return;
|
|
34
|
+
closed = true;
|
|
35
|
+
clearInterval(cancelPoll);
|
|
36
|
+
clearTimeout(timeout);
|
|
37
|
+
if (hardKill) clearTimeout(hardKill);
|
|
38
|
+
stdout.write(spec.stdout);
|
|
39
|
+
stderr.write(spec.stderr);
|
|
40
|
+
resolve({ code, signal, termination, spawnError });
|
|
41
|
+
};
|
|
42
|
+
child.on('error', (error) => { spawnError = error; });
|
|
43
|
+
child.on('close', finish);
|
|
44
|
+
const requestTermination = (reason) => {
|
|
45
|
+
if (termination) return;
|
|
46
|
+
termination = reason;
|
|
47
|
+
terminateProcessGroup(child);
|
|
48
|
+
hardKill = setTimeout(() => terminateProcessGroup(child, 'SIGKILL'), 1500);
|
|
49
|
+
hardKill.unref();
|
|
50
|
+
};
|
|
51
|
+
const cancelPoll = setInterval(() => {
|
|
52
|
+
if (fs.existsSync(spec.cancel)) requestTermination('cancelled');
|
|
53
|
+
}, 100);
|
|
54
|
+
const timeout = setTimeout(() => requestTermination('timeout'), spec.timeout_ms);
|
|
55
|
+
cancelPoll.unref();
|
|
56
|
+
timeout.unref();
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = { CliDriver };
|