@nowcrew/daemon 0.6.19 → 0.6.21
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/dist/atomic-no-replace-rename.js +91 -0
- package/dist/completion-retransmitter-logging.js +16 -0
- package/dist/completion-retransmitter.js +39 -4
- package/dist/control-plane-url.js +4 -2
- package/dist/directory-projection-publication.js +105 -0
- package/dist/directory-projection.js +20 -4
- package/dist/execution-journal.js +40 -4
- package/dist/execution-posix-stop-proof.js +82 -0
- package/dist/execution-runner.js +68 -8
- package/dist/local-executor.js +67 -52
- package/dist/machine-info.js +8 -5
- package/dist/project-skills/capability.js +109 -0
- package/dist/project-skills/controller-convergence.js +57 -0
- package/dist/project-skills/controller.js +80 -24
- package/dist/project-skills/initialized-reconciler.js +4 -4
- package/dist/project-skills/projection-state-domain.js +19 -2
- package/dist/project-skills/projection-state-store.js +3 -2
- package/dist/project-skills/projection-state-transaction.js +5 -1
- package/dist/project-skills/projection-state.js +1 -1
- package/dist/project-skills/reconciler.js +275 -102
- package/dist/project-skills/runtime-launch.js +102 -0
- package/dist/project-skills/runtime-root-bootstrap.js +47 -0
- package/dist/project-skills/runtime-root-domain.js +268 -0
- package/dist/project-skills/runtime-root-gc.js +293 -0
- package/dist/project-skills/runtime-root-lease-artifact.js +46 -0
- package/dist/project-skills/runtime-root-leases.js +487 -0
- package/dist/project-skills/runtime-root-source-identity.js +60 -0
- package/dist/project-skills/runtime-root-startup.js +49 -0
- package/dist/project-skills/runtime-root-state-artifact-domain.js +143 -0
- package/dist/project-skills/runtime-root-state-index.js +356 -0
- package/dist/project-skills/runtime-root-store.js +722 -0
- package/dist/project-skills/serve-capability.js +28 -0
- package/dist/project-skills/serve-startup.js +22 -0
- package/dist/project-skills/types.js +1 -0
- package/dist/runtimes/codex-home-migration-cli.js +26 -0
- package/dist/runtimes/codex-home-migration.js +112 -0
- package/dist/runtimes/codex-home.js +200 -17
- package/dist/serve.js +60 -79
- package/dist/supervised-runtime.js +1 -5
- package/package.json +2 -1
package/dist/execution-runner.js
CHANGED
|
@@ -14,10 +14,13 @@ import { readBoundImDecisionFile, resetBoundImDecisionFile } from "./bound-im-de
|
|
|
14
14
|
import { RuntimeCancelledError } from "./runtime-cancellation.js";
|
|
15
15
|
import { supervisorLaunch } from "./supervised-runtime.js";
|
|
16
16
|
import { appendAgentMemoryContext } from "./agent-memory/policy.js";
|
|
17
|
+
import { ProjectSkillRuntimeOwnershipUnverifiedError, } from "./project-skills/reconciler.js";
|
|
17
18
|
import { projectSkillExecutionProjection, projectSkillProjectionErrorCode } from "./project-skills/execution-adapter.js";
|
|
19
|
+
import { redactProjectSkillRuntimeRootError, } from "./project-skills/runtime-launch.js";
|
|
18
20
|
import { createProjectRegistry } from "./project-skills/registry.js";
|
|
19
21
|
import { ProjectContextUnavailableError, resolveProjectContext } from "./project-workspaces/resolver.js";
|
|
20
22
|
import { PROJECT_WORKSPACES_CAPABILITY } from "./machine-info.js";
|
|
23
|
+
import { PROJECT_SKILL_PROJECTION_V2_CAPABILITY } from "./project-skills/types.js";
|
|
21
24
|
export { supervisorLaunch } from "./supervised-runtime.js";
|
|
22
25
|
const ACTIVITY_KIND = {
|
|
23
26
|
init: "working",
|
|
@@ -217,6 +220,10 @@ function rejection(executionId, reason, message, at) {
|
|
|
217
220
|
export function projectWorkspaceCapabilityRejection(spec, capabilities, at) {
|
|
218
221
|
const projectContext = spec.workspace.projectContext;
|
|
219
222
|
const nativeRuntime = spec.runtime.name === "codex" || spec.runtime.name === "claude";
|
|
223
|
+
if (spec.agent.projectSkillBindingGeneration !== undefined
|
|
224
|
+
&& (!nativeRuntime || !capabilities?.includes(PROJECT_SKILL_PROJECTION_V2_CAPABILITY))) {
|
|
225
|
+
return rejection(spec.executionId, "capability_missing", `${PROJECT_SKILL_PROJECTION_V2_CAPABILITY} is unavailable`, at);
|
|
226
|
+
}
|
|
220
227
|
return projectContext !== undefined
|
|
221
228
|
&& projectContext.projectIds.length > 0
|
|
222
229
|
&& (!nativeRuntime || !capabilities?.includes(PROJECT_WORKSPACES_CAPABILITY))
|
|
@@ -423,6 +430,21 @@ export async function runExecution(config, input, dependencies) {
|
|
|
423
430
|
const resetBoundImDecision = dependencies.resetBoundImDecision ?? resetBoundImDecisionFile;
|
|
424
431
|
const telemetry = new TelemetryQueue(dependencies.report, bestEffortTimeoutMs, positiveTelemetryLimit(dependencies.telemetryMaxPendingFrames, DEFAULT_TELEMETRY_MAX_PENDING_FRAMES), Math.max(config.executionLimits.maxEventBytes, positiveTelemetryLimit(dependencies.telemetryMaxPendingBytes, DEFAULT_TELEMETRY_MAX_PENDING_BYTES)));
|
|
425
432
|
const supervisorState = { active: null, abortOnce: null };
|
|
433
|
+
const proveActiveSupervisorStopped = async (error, retainProjectSkillLease = false) => {
|
|
434
|
+
if (error instanceof ProjectSkillRuntimeOwnershipUnverifiedError)
|
|
435
|
+
throw error;
|
|
436
|
+
if (supervisorState.active === null || supervisorState.abortOnce === null)
|
|
437
|
+
return;
|
|
438
|
+
try {
|
|
439
|
+
await supervisorState.abortOnce();
|
|
440
|
+
}
|
|
441
|
+
catch (abortError) {
|
|
442
|
+
if (retainProjectSkillLease)
|
|
443
|
+
throw new ProjectSkillRuntimeOwnershipUnverifiedError();
|
|
444
|
+
const detail = abortError instanceof Error ? abortError.message : String(abortError);
|
|
445
|
+
throw new AggregateError([error, abortError], `Failed to stop the execution supervisor: ${detail}`);
|
|
446
|
+
}
|
|
447
|
+
};
|
|
426
448
|
let launchClosed = false;
|
|
427
449
|
const launchAttempts = new Set();
|
|
428
450
|
const closeLaunchGate = async () => {
|
|
@@ -557,6 +579,22 @@ export async function runExecution(config, input, dependencies) {
|
|
|
557
579
|
},
|
|
558
580
|
} : {}),
|
|
559
581
|
};
|
|
582
|
+
// This is the sole production brand owner. Pre-spawn rejection has no process; startGuarded
|
|
583
|
+
// aborts its own failures, and this wrapper awaits full-tree stop for every later rejection.
|
|
584
|
+
const projectSkillLeaseSafeLaunchOwner = Object.freeze({
|
|
585
|
+
claim(launch) {
|
|
586
|
+
const safeLaunch = async (root) => {
|
|
587
|
+
try {
|
|
588
|
+
return await launch(root);
|
|
589
|
+
}
|
|
590
|
+
catch (error) {
|
|
591
|
+
await proveActiveSupervisorStopped(error, true);
|
|
592
|
+
throw redactProjectSkillRuntimeRootError(error, root);
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
return safeLaunch;
|
|
596
|
+
},
|
|
597
|
+
});
|
|
560
598
|
const localDependencies = {
|
|
561
599
|
...(dependencies.cancellation === undefined ? {} : { cancellation: dependencies.cancellation }),
|
|
562
600
|
...(dependencies.startupGate === undefined ? {} : { startupGate: dependencies.startupGate }),
|
|
@@ -564,6 +602,7 @@ export async function runExecution(config, input, dependencies) {
|
|
|
564
602
|
? {}
|
|
565
603
|
: { startupTimeoutMs: dependencies.startupTimeoutMs }),
|
|
566
604
|
...(dependencies.projectSkills === undefined ? {} : { projectSkills: dependencies.projectSkills }),
|
|
605
|
+
projectSkillLeaseSafeLaunchOwner,
|
|
567
606
|
...(dependencies.abilityRelease === undefined ? {} : { abilityRelease: dependencies.abilityRelease }),
|
|
568
607
|
launchRuntime: async (request) => {
|
|
569
608
|
if (launchClosed || dependencies.cancellation?.isRequested())
|
|
@@ -574,7 +613,26 @@ export async function runExecution(config, input, dependencies) {
|
|
|
574
613
|
try {
|
|
575
614
|
const processStartedAt = now().toISOString();
|
|
576
615
|
const launchControl = { cancel: null };
|
|
577
|
-
const
|
|
616
|
+
const startOwnedSupervisor = async () => {
|
|
617
|
+
const handle = await startSupervisor(supervisorLaunch(request));
|
|
618
|
+
let abortPromise = null;
|
|
619
|
+
const abortOnce = () => {
|
|
620
|
+
if (abortPromise === null) {
|
|
621
|
+
try {
|
|
622
|
+
abortPromise = Promise.resolve(handle.abort());
|
|
623
|
+
}
|
|
624
|
+
catch (error) {
|
|
625
|
+
abortPromise = Promise.reject(error);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
return abortPromise;
|
|
629
|
+
};
|
|
630
|
+
const ownedHandle = { ...handle, abort: abortOnce };
|
|
631
|
+
supervisorState.active = ownedHandle;
|
|
632
|
+
supervisorState.abortOnce = abortOnce;
|
|
633
|
+
return ownedHandle;
|
|
634
|
+
};
|
|
635
|
+
const guarded = await dependencies.journal.startGuarded(spec.executionId, processStartedAt, startOwnedSupervisor, {
|
|
578
636
|
beforeRelease: ({ handle, abort }) => {
|
|
579
637
|
supervisorState.active = handle;
|
|
580
638
|
let stopPromise = null;
|
|
@@ -736,17 +794,19 @@ export async function runExecution(config, input, dependencies) {
|
|
|
736
794
|
const cancelled = error instanceof ExecutionCancelledError || error instanceof RuntimeCancelledError;
|
|
737
795
|
if (cancelled) {
|
|
738
796
|
await closeLaunchGate();
|
|
739
|
-
await dependencies.cancellation?.waitForStop();
|
|
740
|
-
}
|
|
741
|
-
else if (supervisorState.active !== null && supervisorState.abortOnce !== null) {
|
|
742
797
|
try {
|
|
743
|
-
await
|
|
798
|
+
await dependencies.cancellation?.waitForStop();
|
|
744
799
|
}
|
|
745
|
-
catch (
|
|
746
|
-
|
|
747
|
-
|
|
800
|
+
catch (stopError) {
|
|
801
|
+
if (spec.agent.projectSkillBindingGeneration !== undefined) {
|
|
802
|
+
throw new ProjectSkillRuntimeOwnershipUnverifiedError();
|
|
803
|
+
}
|
|
804
|
+
throw stopError;
|
|
748
805
|
}
|
|
749
806
|
}
|
|
807
|
+
else {
|
|
808
|
+
await proveActiveSupervisorStopped(error, spec.agent.projectSkillBindingGeneration !== undefined);
|
|
809
|
+
}
|
|
750
810
|
completion = cancelled
|
|
751
811
|
? ExecutionCompletedSchema.parse({
|
|
752
812
|
type: "execution:completed",
|
package/dist/local-executor.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createInterface } from "node:readline";
|
|
|
2
2
|
import { readFile, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { delimiter, join } from "node:path";
|
|
4
4
|
import { prepareWorkspace, rotateAgentSession, safeKey, } from "./workspace.js";
|
|
5
|
-
import { CLAUDE_ADDITIONAL_DIRECTORY_INSTRUCTIONS_ENV, isClaudeAdditionalDirectoryInstructionsSupported, probeClaudeVersion,
|
|
5
|
+
import { CLAUDE_ADDITIONAL_DIRECTORY_INSTRUCTIONS_ENV, isClaudeAdditionalDirectoryInstructionsSupported, probeClaudeVersion, spawnClaude, } from "./runtimes/claude.js";
|
|
6
6
|
import { spawnCodex } from "./runtimes/codex.js";
|
|
7
7
|
import { DEEPSEEK_CODEX_MODEL, DEEPSEEK_CODEX_REASONING_LEVELS, materializeDeepSeekCodexHome, } from "./runtimes/codex-deepseek-config.js";
|
|
8
8
|
import { materializeDefaultCodexHome } from "./runtimes/codex-home.js";
|
|
@@ -21,7 +21,9 @@ import { awaitWithCancellation, RuntimeCancelledError, } from "./runtime-cancell
|
|
|
21
21
|
import { isRuntimeReadyEvent, } from "./runtime-startup-gate.js";
|
|
22
22
|
import { dslog } from "./slog.js";
|
|
23
23
|
import { boundedDiagnosticJsonArray } from "./diagnostic-json.js";
|
|
24
|
+
import { ProjectProjectionError, } from "./project-skills/reconciler.js";
|
|
24
25
|
import { formatProjectSkillRuntimeWarning } from "./project-skills/runtime-warning.js";
|
|
26
|
+
import { projectSkillRuntimeDirectories, redactProjectSkillRuntimeRootText, redactProjectSkillRuntimeRootValue, } from "./project-skills/runtime-launch.js";
|
|
25
27
|
import { diffMemoryPruneNotes, evaluateMemoryPrunePostcondition, inspectMemoryPruneFilesWithinDeadline, parseMemoryPruneTraceId, } from "./memory-prune-diagnostics.js";
|
|
26
28
|
import { createLocalMemoryTelemetry, logLocalMemoryContextPrepareFailure, logLocalMemoryDiagnosticsFailure, } from "./local-memory-telemetry.js";
|
|
27
29
|
import { CodexStartupStageParser } from "./codex-startup-stage.js";
|
|
@@ -195,6 +197,19 @@ async function withKeyedLease(key, operation, cancellation) {
|
|
|
195
197
|
}
|
|
196
198
|
}
|
|
197
199
|
export async function executeLocal(input, callbacks = {}, dependencies = {}) {
|
|
200
|
+
const versionedProjectSkills = input.projectSkills !== undefined
|
|
201
|
+
&& !Array.isArray(input.projectSkills);
|
|
202
|
+
if (versionedProjectSkills && (input.runtime.name !== "codex" && input.runtime.name !== "claude")) {
|
|
203
|
+
throw new ProjectProjectionError("skill_projection_failed");
|
|
204
|
+
}
|
|
205
|
+
if (versionedProjectSkills && dependencies.projectSkills === undefined) {
|
|
206
|
+
throw new ProjectProjectionError("skill_projection_failed");
|
|
207
|
+
}
|
|
208
|
+
if (input.projectSkills !== undefined
|
|
209
|
+
&& dependencies.projectSkills !== undefined
|
|
210
|
+
&& dependencies.projectSkillLeaseSafeLaunchOwner === undefined) {
|
|
211
|
+
throw new ProjectProjectionError("skill_projection_failed");
|
|
212
|
+
}
|
|
198
213
|
const stableProtocolRuntime = dependencies.launchRuntime !== undefined;
|
|
199
214
|
const supportsNativeResume = input.runtime.name === "claude"
|
|
200
215
|
|| (stableProtocolRuntime && runtimeCapability(input.runtime.name).nativeResume);
|
|
@@ -263,6 +278,8 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
263
278
|
if (key.startsWith("CREW_AGENT_MEMORY_"))
|
|
264
279
|
delete inheritedEnv[key];
|
|
265
280
|
}
|
|
281
|
+
const sourceCodexHome = inheritedEnv.CODEX_HOME
|
|
282
|
+
?? (inheritedEnv.HOME === undefined ? undefined : join(inheritedEnv.HOME, ".codex"));
|
|
266
283
|
try {
|
|
267
284
|
if (isDeepSeekCodex && !providerConfig.providerApiKey) {
|
|
268
285
|
throw new Error("DeepSeek API key is not configured for this Agent");
|
|
@@ -270,11 +287,6 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
270
287
|
if (isDeepSeekCodex) {
|
|
271
288
|
await awaitWithCancellation((dependencies.materializeDeepSeekCodexHome ?? materializeDeepSeekCodexHome)(workspace.homeDir), dependencies.cancellation);
|
|
272
289
|
}
|
|
273
|
-
else if (runtime.name === "codex") {
|
|
274
|
-
const sourceCodexHome = inheritedEnv.CODEX_HOME
|
|
275
|
-
?? (inheritedEnv.HOME === undefined ? undefined : join(inheritedEnv.HOME, ".codex"));
|
|
276
|
-
await awaitWithCancellation((dependencies.materializeDefaultCodexHome ?? materializeDefaultCodexHome)(workspace.homeDir, sourceCodexHome), dependencies.cancellation);
|
|
277
|
-
}
|
|
278
290
|
const supportsNativeResume = runtime.name === "claude"
|
|
279
291
|
|| (dependencies.launchRuntime !== undefined && runtimeCapability(runtime.name).nativeResume);
|
|
280
292
|
const storedCurrentPrior = input.session.enabled && supportsNativeResume
|
|
@@ -336,6 +348,9 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
336
348
|
const launchSessionId = resumeSessionId ?? (rotated
|
|
337
349
|
? await rotateAgentSession(workspace.sessionDir)
|
|
338
350
|
: workspace.agentSessionId);
|
|
351
|
+
if (runtime.name === "codex") {
|
|
352
|
+
await awaitWithCancellation((dependencies.materializeDefaultCodexHome ?? materializeDefaultCodexHome)(workspace.homeDir, sourceCodexHome, launchSessionId), dependencies.cancellation);
|
|
353
|
+
}
|
|
339
354
|
const promptContext = {
|
|
340
355
|
workspace: executionWorkspace,
|
|
341
356
|
resuming,
|
|
@@ -485,7 +500,9 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
485
500
|
}
|
|
486
501
|
const runtimeLaunchAt = Date.now();
|
|
487
502
|
memoryPruneFailurePhase = "runtime_launch";
|
|
488
|
-
|
|
503
|
+
let activeProjectSkillRuntimeRoot;
|
|
504
|
+
const launchPreparedRuntime = async (runtimeRoot, abilityContext) => {
|
|
505
|
+
activeProjectSkillRuntimeRoot = runtimeRoot;
|
|
489
506
|
const effectiveSystemPrompt = abilityContext === undefined
|
|
490
507
|
? systemPrompt
|
|
491
508
|
: `${systemPrompt}\n\n${abilityContext.prompt}`;
|
|
@@ -521,31 +538,16 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
521
538
|
skill_count: abilityContext.skillCount,
|
|
522
539
|
});
|
|
523
540
|
}
|
|
524
|
-
const codexSkillRoots
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
? abilityContext?.skillRoot === undefined
|
|
535
|
-
? []
|
|
536
|
-
: await resolveOrderedUniqueClaudeDirectories([
|
|
537
|
-
join(workspace.dir, ".crew", "claude-skills"),
|
|
538
|
-
workspace.dir,
|
|
539
|
-
abilityContext.skillRoot,
|
|
540
|
-
])
|
|
541
|
-
: await resolveOrderedUniqueClaudeDirectories([
|
|
542
|
-
...input.projectContext.secondary.map((project) => project.root),
|
|
543
|
-
...(input.projectSkills === undefined
|
|
544
|
-
? []
|
|
545
|
-
: [join(workspace.dir, ".crew", "claude-skills")]),
|
|
546
|
-
...(abilityContext?.skillRoot === undefined ? [] : [abilityContext.skillRoot]),
|
|
547
|
-
], input.projectContext.primary === undefined ? [] : [input.projectContext.primary.root])
|
|
548
|
-
: [];
|
|
541
|
+
const { codexSkillRoots, claudeAdditionalDirectories } = await projectSkillRuntimeDirectories({
|
|
542
|
+
runtime: runtime.name,
|
|
543
|
+
...(runtimeRoot === undefined ? {} : { runtimeRoot }),
|
|
544
|
+
agentRoot: workspace.dir,
|
|
545
|
+
projectSkillsPresent: input.projectSkills !== undefined,
|
|
546
|
+
...(input.projectContext === undefined ? {} : { projectContext: input.projectContext }),
|
|
547
|
+
...(abilityContext?.skillRoot === undefined
|
|
548
|
+
? {}
|
|
549
|
+
: { abilitySkillRoot: abilityContext.skillRoot }),
|
|
550
|
+
});
|
|
549
551
|
let runtimeEnv = childEnv;
|
|
550
552
|
if (runtime.name === "claude"
|
|
551
553
|
&& input.projectContext !== undefined
|
|
@@ -571,7 +573,10 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
571
573
|
runtime: runtime.name,
|
|
572
574
|
bin: runtime.name === "deepseek-harness" ? "dsh-acp-demo" : runtime.name,
|
|
573
575
|
cwd: input.projectContext?.primary?.root ?? executionWorkspace.runDir,
|
|
574
|
-
...(
|
|
576
|
+
...(runtimeRoot !== undefined
|
|
577
|
+
|| (input.projectSkills === undefined && input.abilityRelease === undefined)
|
|
578
|
+
? {}
|
|
579
|
+
: { agentRoot: workspace.dir }),
|
|
575
580
|
systemPromptPath: workspace.systemPromptPath,
|
|
576
581
|
systemPrompt: effectiveSystemPrompt,
|
|
577
582
|
wakePrompt,
|
|
@@ -598,17 +603,22 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
598
603
|
memoryPruneFailurePhase = "runtime_launch";
|
|
599
604
|
return launchRuntime(launchRequest);
|
|
600
605
|
};
|
|
601
|
-
const launchWithAbility = () => input.abilityRelease !== undefined && dependencies.abilityRelease !== undefined
|
|
602
|
-
? dependencies.abilityRelease.prepareAndLaunch(input.launch.agentsRoot, input.handle, input.abilityRelease, launchPreparedRuntime)
|
|
603
|
-
: launchPreparedRuntime();
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
606
|
+
const launchWithAbility = (runtimeRoot) => input.abilityRelease !== undefined && dependencies.abilityRelease !== undefined
|
|
607
|
+
? dependencies.abilityRelease.prepareAndLaunch(input.launch.agentsRoot, input.handle, input.abilityRelease, (abilityContext) => launchPreparedRuntime(runtimeRoot, abilityContext))
|
|
608
|
+
: launchPreparedRuntime(runtimeRoot);
|
|
609
|
+
let child;
|
|
610
|
+
if (input.projectSkills !== undefined && dependencies.projectSkills !== undefined) {
|
|
611
|
+
const launchOwner = dependencies.projectSkillLeaseSafeLaunchOwner;
|
|
612
|
+
if (launchOwner === undefined)
|
|
613
|
+
throw new ProjectProjectionError("skill_projection_failed");
|
|
614
|
+
child = await dependencies.projectSkills.prepareAndLaunch(input.launch.agentsRoot, input.executionId, input.handle, input.projectSkills, launchOwner.claim(launchWithAbility), (warning) => callbacks.onConsole?.({
|
|
615
|
+
stream: "system",
|
|
616
|
+
text: formatProjectSkillRuntimeWarning(warning),
|
|
617
|
+
}));
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
child = await launchWithAbility();
|
|
621
|
+
}
|
|
612
622
|
localMemoryTelemetry?.markRuntimeStarted();
|
|
613
623
|
memoryPruneFailurePhase = "runtime_execution";
|
|
614
624
|
if (child.cancel !== undefined) {
|
|
@@ -660,7 +670,8 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
660
670
|
usage = meta.usage;
|
|
661
671
|
if (meta.model)
|
|
662
672
|
observedModel = meta.model;
|
|
663
|
-
for (const
|
|
673
|
+
for (const rawActivity of normalizeEvent(event)) {
|
|
674
|
+
const activity = redactProjectSkillRuntimeRootValue(rawActivity, activeProjectSkillRuntimeRoot);
|
|
664
675
|
if (activity.kind === "sending")
|
|
665
676
|
sentViaCrew = true;
|
|
666
677
|
activities.push(activity);
|
|
@@ -668,18 +679,20 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
668
679
|
}
|
|
669
680
|
const extracted = extractFinalText(event);
|
|
670
681
|
if (extracted) {
|
|
682
|
+
const safeExtracted = redactProjectSkillRuntimeRootText(extracted, activeProjectSkillRuntimeRoot);
|
|
671
683
|
const incremental = typeof event === "object" && event !== null
|
|
672
684
|
&& "type" in event && (event.type === "kimi.acp.text_delta"
|
|
673
685
|
|| event.type === "hermes.acp.text_delta"
|
|
674
686
|
|| event.type === "deepseek-harness.acp.text_delta"
|
|
675
687
|
|| event.type === "opencode.text_delta");
|
|
676
|
-
finalText = incremental ? `${finalText ?? ""}${
|
|
688
|
+
finalText = incremental ? `${finalText ?? ""}${safeExtracted}` : safeExtracted;
|
|
677
689
|
}
|
|
678
690
|
for (const text of decodeExternalOutputEvent(runtime.name, event, externalOutput)) {
|
|
679
|
-
callbacks.onExternalOutput?.(text);
|
|
691
|
+
callbacks.onExternalOutput?.(redactProjectSkillRuntimeRootText(text, activeProjectSkillRuntimeRoot));
|
|
692
|
+
}
|
|
693
|
+
for (const chunk of consoleFormatter.format(event)) {
|
|
694
|
+
callbacks.onConsole?.(redactProjectSkillRuntimeRootValue(chunk, activeProjectSkillRuntimeRoot));
|
|
680
695
|
}
|
|
681
|
-
for (const chunk of consoleFormatter.format(event))
|
|
682
|
-
callbacks.onConsole?.(chunk);
|
|
683
696
|
});
|
|
684
697
|
let stderrTail = "";
|
|
685
698
|
const codexStartupStageState = { last: null };
|
|
@@ -700,8 +713,8 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
700
713
|
})
|
|
701
714
|
: null;
|
|
702
715
|
child.stderr.on("data", (data) => {
|
|
703
|
-
|
|
704
|
-
|
|
716
|
+
const text = redactProjectSkillRuntimeRootText(String(data), activeProjectSkillRuntimeRoot);
|
|
717
|
+
process.stderr.write(text);
|
|
705
718
|
stderrTail = (stderrTail + text).slice(-STDERR_TAIL_CAP);
|
|
706
719
|
codexStartupStageParser?.push(text);
|
|
707
720
|
});
|
|
@@ -761,7 +774,9 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
761
774
|
memoryPruneRuntimeExitCode = exitCode;
|
|
762
775
|
const errorTail = [
|
|
763
776
|
stderrTail.trim(),
|
|
764
|
-
spawnError
|
|
777
|
+
spawnError === undefined
|
|
778
|
+
? undefined
|
|
779
|
+
: redactProjectSkillRuntimeRootText(spawnError, activeProjectSkillRuntimeRoot),
|
|
765
780
|
terminationSignal ? `terminated by ${terminationSignal}` : undefined,
|
|
766
781
|
].filter(Boolean).join(" ").trim();
|
|
767
782
|
const finish = exitActivity(runtime.name, exitCode, errorTail);
|
package/dist/machine-info.js
CHANGED
|
@@ -61,7 +61,9 @@ export const daemonCapabilities = (runtimePlatform = process.platform, readiness
|
|
|
61
61
|
export const daemonCapabilityBindings = (runtimePlatform = process.platform, injectedCapabilities) => {
|
|
62
62
|
const snapshot = injectedCapabilities === undefined
|
|
63
63
|
? daemonCapabilities(runtimePlatform)
|
|
64
|
-
: Object.
|
|
64
|
+
: (Object.isFrozen(injectedCapabilities)
|
|
65
|
+
? injectedCapabilities
|
|
66
|
+
: Object.freeze([...injectedCapabilities]));
|
|
65
67
|
return Object.freeze({
|
|
66
68
|
controlPlaneUrl: snapshot,
|
|
67
69
|
machineHello: snapshot,
|
|
@@ -169,6 +171,10 @@ export async function collectMachineHello(agentsRoot, executionLimits, runtimePl
|
|
|
169
171
|
const executionRuntimes = backend.supported
|
|
170
172
|
? await (dependencies.detectExecutable ?? detectExecutionRuntimes)(runtimes)
|
|
171
173
|
: [];
|
|
174
|
+
const baseCapabilities = dependencies.capabilities ?? daemonCapabilities(runtimePlatform);
|
|
175
|
+
const capabilities = additionalCapabilities.length === 0 && Object.isFrozen(baseCapabilities)
|
|
176
|
+
? baseCapabilities
|
|
177
|
+
: Object.freeze([...baseCapabilities, ...additionalCapabilities]);
|
|
172
178
|
return {
|
|
173
179
|
type: "machine:hello",
|
|
174
180
|
hostname: hostname(),
|
|
@@ -176,10 +182,7 @@ export async function collectMachineHello(agentsRoot, executionLimits, runtimePl
|
|
|
176
182
|
daemonVersion: daemonVersion(),
|
|
177
183
|
runtimes,
|
|
178
184
|
executionRuntimes,
|
|
179
|
-
capabilities
|
|
180
|
-
...(dependencies.capabilities ?? daemonCapabilities(runtimePlatform)),
|
|
181
|
-
...additionalCapabilities,
|
|
182
|
-
]),
|
|
185
|
+
capabilities,
|
|
183
186
|
...(dependencies.profileName === undefined ? {} : {
|
|
184
187
|
layoutVersion: 1,
|
|
185
188
|
profileName: dependencies.profileName,
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { PROJECT_SKILLS_CAPABILITY, PROJECT_SKILL_PROJECTION_V2_CAPABILITY, } from "./types.js";
|
|
2
|
+
export function projectSkillV2RolloutReady(platform, readiness) {
|
|
3
|
+
const platformReady = platform === "darwin"
|
|
4
|
+
|| platform === "linux"
|
|
5
|
+
|| (platform === "win32" && readiness.nativeWindowsSmokePassed);
|
|
6
|
+
return platformReady
|
|
7
|
+
&& readiness.runtimeRootStorePrimitiveReady
|
|
8
|
+
&& readiness.runtimeRootStoreRecoveryReady
|
|
9
|
+
&& readiness.leaseRecoveryReady
|
|
10
|
+
&& readiness.controllerReady
|
|
11
|
+
&& readiness.executionHandlerReady
|
|
12
|
+
&& readiness.codexAdapterReady
|
|
13
|
+
&& readiness.claudeAdapterReady;
|
|
14
|
+
}
|
|
15
|
+
export function effectiveProjectSkillCapabilities(capabilities, projectSkillsReady, projectSkillV2Ready) {
|
|
16
|
+
const projectSkillCapabilitiesReady = projectSkillsReady && projectSkillV2Ready;
|
|
17
|
+
if (!projectSkillCapabilitiesReady
|
|
18
|
+
&& !capabilities.includes(PROJECT_SKILLS_CAPABILITY)
|
|
19
|
+
&& !capabilities.includes(PROJECT_SKILL_PROJECTION_V2_CAPABILITY)
|
|
20
|
+
&& Object.isFrozen(capabilities))
|
|
21
|
+
return capabilities;
|
|
22
|
+
const filtered = capabilities.filter((capability) => capability !== PROJECT_SKILL_PROJECTION_V2_CAPABILITY
|
|
23
|
+
&& (projectSkillCapabilitiesReady || capability !== PROJECT_SKILLS_CAPABILITY));
|
|
24
|
+
if (!projectSkillCapabilitiesReady || !filtered.includes(PROJECT_SKILLS_CAPABILITY)) {
|
|
25
|
+
return Object.freeze(filtered);
|
|
26
|
+
}
|
|
27
|
+
const v1Index = filtered.indexOf(PROJECT_SKILLS_CAPABILITY);
|
|
28
|
+
return Object.freeze([
|
|
29
|
+
...filtered.slice(0, v1Index + 1),
|
|
30
|
+
PROJECT_SKILL_PROJECTION_V2_CAPABILITY,
|
|
31
|
+
...filtered.slice(v1Index + 1),
|
|
32
|
+
]);
|
|
33
|
+
}
|
|
34
|
+
export function withProjectSkillCapabilityStatus(value, status) {
|
|
35
|
+
return {
|
|
36
|
+
...value,
|
|
37
|
+
projectSkillsStatus: status,
|
|
38
|
+
capabilities: status === "ready"
|
|
39
|
+
? value.capabilities
|
|
40
|
+
: effectiveProjectSkillCapabilities(value.capabilities, false, false),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const settleReadinessGate = async (operation) => {
|
|
44
|
+
try {
|
|
45
|
+
return await operation() === true;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
export async function createProjectSkillConnectionCapabilitySnapshot(input) {
|
|
52
|
+
const runtimeRootStorePrimitiveReady = await settleReadinessGate(input.probeRuntimeRootStorePrimitive);
|
|
53
|
+
const controllerReady = await settleReadinessGate(input.initializeController);
|
|
54
|
+
const recoveryReady = await settleReadinessGate(input.recoverRuntimeRootsAndLeases);
|
|
55
|
+
const readiness = Object.freeze({
|
|
56
|
+
runtimeRootStorePrimitiveReady,
|
|
57
|
+
runtimeRootStoreRecoveryReady: recoveryReady,
|
|
58
|
+
leaseRecoveryReady: recoveryReady,
|
|
59
|
+
controllerReady,
|
|
60
|
+
executionHandlerReady: true,
|
|
61
|
+
codexAdapterReady: true,
|
|
62
|
+
claudeAdapterReady: true,
|
|
63
|
+
nativeWindowsSmokePassed: false,
|
|
64
|
+
});
|
|
65
|
+
const projectSkillsReady = projectSkillV2RolloutReady(input.platform, readiness);
|
|
66
|
+
return Object.freeze({
|
|
67
|
+
capabilities: effectiveProjectSkillCapabilities(input.baseCapabilities, projectSkillsReady, projectSkillsReady),
|
|
68
|
+
projectSkillsReady,
|
|
69
|
+
readiness,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
export async function prepareProjectSkillConnectionCapabilities(input) {
|
|
73
|
+
const snapshot = await createProjectSkillConnectionCapabilitySnapshot({
|
|
74
|
+
...input,
|
|
75
|
+
baseCapabilities: [...input.baseCapabilities, ...await input.additionalCapabilities()],
|
|
76
|
+
});
|
|
77
|
+
input.applyReadiness(snapshot.projectSkillsReady);
|
|
78
|
+
return snapshot.capabilities;
|
|
79
|
+
}
|
|
80
|
+
export function createProjectSkillControllerReadiness(input) {
|
|
81
|
+
let status = "initializing";
|
|
82
|
+
let initialization = null;
|
|
83
|
+
const ensure = () => {
|
|
84
|
+
if (status === "ready")
|
|
85
|
+
return Promise.resolve(true);
|
|
86
|
+
if (initialization !== null)
|
|
87
|
+
return initialization;
|
|
88
|
+
status = "initializing";
|
|
89
|
+
const attempt = input.initialize().then(() => {
|
|
90
|
+
status = "ready";
|
|
91
|
+
return true;
|
|
92
|
+
}, (error) => {
|
|
93
|
+
status = "unavailable";
|
|
94
|
+
input.onUnavailable(error);
|
|
95
|
+
return false;
|
|
96
|
+
}).finally(() => {
|
|
97
|
+
if (initialization === attempt)
|
|
98
|
+
initialization = null;
|
|
99
|
+
input.onSettled();
|
|
100
|
+
});
|
|
101
|
+
initialization = attempt;
|
|
102
|
+
return attempt;
|
|
103
|
+
};
|
|
104
|
+
return Object.freeze({
|
|
105
|
+
status: () => status,
|
|
106
|
+
ensure,
|
|
107
|
+
applyPreflight: (ready) => { status = ready ? "ready" : "unavailable"; },
|
|
108
|
+
});
|
|
109
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ProjectProjectionError, } from "./reconciler.js";
|
|
2
|
+
export const MAX_REMEMBERED_PROJECT_SKILL_AGENTS = 64;
|
|
3
|
+
const compareBinary = (left, right) => {
|
|
4
|
+
if (left < right)
|
|
5
|
+
return -1;
|
|
6
|
+
if (left > right)
|
|
7
|
+
return 1;
|
|
8
|
+
return 0;
|
|
9
|
+
};
|
|
10
|
+
const copySnapshot = (snapshot) => Object.freeze({
|
|
11
|
+
bindings: Object.freeze(snapshot.bindings.map((binding) => Object.freeze({ ...binding }))),
|
|
12
|
+
generation: snapshot.generation,
|
|
13
|
+
});
|
|
14
|
+
export function createProjectSkillSnapshotEpoch(maxEntries = MAX_REMEMBERED_PROJECT_SKILL_AGENTS) {
|
|
15
|
+
if (!Number.isSafeInteger(maxEntries) || maxEntries < 1) {
|
|
16
|
+
throw new ProjectProjectionError("skill_projection_failed");
|
|
17
|
+
}
|
|
18
|
+
const snapshots = new Map();
|
|
19
|
+
return Object.freeze({
|
|
20
|
+
begin() {
|
|
21
|
+
snapshots.clear();
|
|
22
|
+
},
|
|
23
|
+
remember(handle, snapshot) {
|
|
24
|
+
const previous = snapshots.get(handle);
|
|
25
|
+
if (previous !== undefined && snapshot.generation < previous.generation)
|
|
26
|
+
return;
|
|
27
|
+
if (previous === undefined && snapshots.size >= maxEntries) {
|
|
28
|
+
throw new ProjectProjectionError("skill_projection_failed");
|
|
29
|
+
}
|
|
30
|
+
snapshots.set(handle, copySnapshot(snapshot));
|
|
31
|
+
},
|
|
32
|
+
forget(handle) {
|
|
33
|
+
snapshots.delete(handle);
|
|
34
|
+
},
|
|
35
|
+
entries() {
|
|
36
|
+
return Object.freeze([...snapshots.entries()]
|
|
37
|
+
.sort(([left], [right]) => compareBinary(left, right))
|
|
38
|
+
.map(([handle, snapshot]) => Object.freeze([handle, copySnapshot(snapshot)])));
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const stableErrorCode = (reason) => reason?.code === "skill_projection_snapshot_corrupt"
|
|
43
|
+
? "skill_projection_snapshot_corrupt"
|
|
44
|
+
: "skill_projection_failed";
|
|
45
|
+
export function toPathPrivateConvergenceResults(entries, results) {
|
|
46
|
+
return Object.freeze(entries.map(([handle], index) => {
|
|
47
|
+
const result = results[index];
|
|
48
|
+
if (result?.status === "fulfilled") {
|
|
49
|
+
return Object.freeze({ handle, status: "fulfilled" });
|
|
50
|
+
}
|
|
51
|
+
return Object.freeze({
|
|
52
|
+
handle,
|
|
53
|
+
status: "rejected",
|
|
54
|
+
errorCode: stableErrorCode(result?.reason),
|
|
55
|
+
});
|
|
56
|
+
}));
|
|
57
|
+
}
|