@nowcrew/daemon 0.6.87-beta.3 → 0.6.87
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/external-output.js +154 -68
- package/dist/main.js +6 -2
- package/dist/serve.js +17 -11
- package/dist/storage-identity.js +4 -1
- package/dist/storage-ownership.js +93 -5
- package/dist/storage-runtime-controller.js +40 -20
- package/dist/storage-runtime.js +38 -2
- package/dist/storage-serve-adapter.js +22 -5
- package/package.json +9 -10
- package/dist/project-skills/capability.js +0 -109
- package/dist/project-skills/controller-convergence.js +0 -57
- package/dist/project-skills/projection-set-switch.js +0 -419
- package/dist/project-skills/projection-state-domain.js +0 -170
- package/dist/project-skills/projection-state-store.js +0 -842
- package/dist/project-skills/projection-state-transaction.js +0 -322
- package/dist/project-skills/projection-state.js +0 -3
- package/dist/project-skills/runtime-root-bootstrap.js +0 -47
- package/dist/project-skills/runtime-root-domain.js +0 -268
- package/dist/project-skills/runtime-root-gc.js +0 -293
- package/dist/project-skills/runtime-root-lease-artifact.js +0 -46
- package/dist/project-skills/runtime-root-leases.js +0 -487
- package/dist/project-skills/runtime-root-source-identity.js +0 -60
- package/dist/project-skills/runtime-root-startup.js +0 -49
- package/dist/project-skills/runtime-root-state-artifact-domain.js +0 -143
- package/dist/project-skills/runtime-root-state-index.js +0 -356
- package/dist/project-skills/runtime-root-store.js +0 -722
- package/dist/project-skills/serve-capability.js +0 -28
- package/dist/project-skills/serve-startup.js +0 -37
package/dist/storage-runtime.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { findInstallationForProfile, readInstallations, resolveLocalStorageRoots, } from "./storage-config.js";
|
|
2
2
|
import { storageHelloIdentity } from "./storage-identity.js";
|
|
3
3
|
import { storageLayout } from "./storage-layout.js";
|
|
4
|
-
import { readStorageOwnershipClaim } from "./storage-ownership.js";
|
|
4
|
+
import { readStorageOwnershipClaim, resolveWorkspaceStorageOwnershipClaim, } from "./storage-ownership.js";
|
|
5
5
|
const canonicalServerUrl = (value) => value.replace(/\/+$/u, "");
|
|
6
6
|
export function resolveStorageRuntime(input) {
|
|
7
7
|
const installation = findInstallationForProfile(input.records, input.profile);
|
|
@@ -45,7 +45,7 @@ export async function loadStorageRuntime(input) {
|
|
|
45
45
|
return null;
|
|
46
46
|
let ownership;
|
|
47
47
|
try {
|
|
48
|
-
ownership = await readStorageOwnershipClaim(baseline.layout.persistentRoot);
|
|
48
|
+
ownership = await readStorageOwnershipClaim(baseline.layout.persistentRoot, baseline.layout.workspaceId);
|
|
49
49
|
}
|
|
50
50
|
catch (error) {
|
|
51
51
|
if (error.code !== "ENOENT")
|
|
@@ -53,3 +53,39 @@ export async function loadStorageRuntime(input) {
|
|
|
53
53
|
}
|
|
54
54
|
return ownership === undefined ? baseline : resolveStorageRuntime({ ...input, records, ownership });
|
|
55
55
|
}
|
|
56
|
+
export async function bindStorageRuntimeOwnership(runtime, server) {
|
|
57
|
+
const workspaceId = server.workspaceId.toLowerCase();
|
|
58
|
+
const machineId = server.machineId.toLowerCase();
|
|
59
|
+
if (runtime.installation.workspaceId !== workspaceId) {
|
|
60
|
+
throw new Error("Storage runtime server workspace identity changed");
|
|
61
|
+
}
|
|
62
|
+
const existing = runtime.identity.storageOwnership;
|
|
63
|
+
if (existing !== undefined) {
|
|
64
|
+
if (existing.machineId !== machineId)
|
|
65
|
+
throw new Error("Storage runtime server machine identity changed");
|
|
66
|
+
return runtime;
|
|
67
|
+
}
|
|
68
|
+
const ownership = await resolveWorkspaceStorageOwnershipClaim({
|
|
69
|
+
nowworkHome: runtime.layout.persistentRoot,
|
|
70
|
+
machineId,
|
|
71
|
+
workspaceId,
|
|
72
|
+
environment: runtime.installation.environment,
|
|
73
|
+
workspaceRootFingerprint: runtime.identity.workspaceRootFingerprint,
|
|
74
|
+
});
|
|
75
|
+
return Object.freeze({
|
|
76
|
+
...runtime,
|
|
77
|
+
identity: storageHelloIdentity({ installation: runtime.installation, layout: runtime.layout, ownership }),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
export function createStorageRuntimeOwnershipBinding(initial) {
|
|
81
|
+
let runtime = initial;
|
|
82
|
+
let bindTail = Promise.resolve();
|
|
83
|
+
const bind = (server) => {
|
|
84
|
+
const current = bindTail.then(async () => {
|
|
85
|
+
runtime = await bindStorageRuntimeOwnership(runtime, server);
|
|
86
|
+
});
|
|
87
|
+
bindTail = current.catch(() => undefined);
|
|
88
|
+
return current;
|
|
89
|
+
};
|
|
90
|
+
return Object.freeze({ identity: () => runtime.identity, bind });
|
|
91
|
+
}
|
|
@@ -9,6 +9,15 @@ export function storageMigrationCapabilities(configured, options) {
|
|
|
9
9
|
...(options.ready ? [STORAGE_MIGRATION_CAPABILITY] : []),
|
|
10
10
|
])]);
|
|
11
11
|
}
|
|
12
|
+
export function bindStorageMigrationServerIdentity(options, identity, callbacks) {
|
|
13
|
+
const bind = options?.bindServerIdentity;
|
|
14
|
+
if (bind === undefined) {
|
|
15
|
+
if (options?.ready === true)
|
|
16
|
+
callbacks.onBound();
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
void Promise.resolve().then(() => bind(identity)).then(callbacks.onBound).catch(callbacks.onError);
|
|
20
|
+
}
|
|
12
21
|
export function createServeStorageStatusDelivery(options, dependencies) {
|
|
13
22
|
return createStorageStatusDelivery({
|
|
14
23
|
...(options?.statusOutboxPath === undefined ? {} : { outboxPath: options.statusOutboxPath }),
|
|
@@ -17,28 +26,36 @@ export function createServeStorageStatusDelivery(options, dependencies) {
|
|
|
17
26
|
});
|
|
18
27
|
}
|
|
19
28
|
export function attachStorageMigrationRuntime(options, dependencies) {
|
|
20
|
-
let
|
|
29
|
+
let migrationAdmissionClosed = false;
|
|
30
|
+
let identityAdmissionClosed = options?.bindServerIdentity !== undefined;
|
|
21
31
|
if (options?.ready === true) {
|
|
22
32
|
options.attach?.({
|
|
23
33
|
gate: {
|
|
24
34
|
isBusy: dependencies.isBusy,
|
|
25
35
|
closeAndFlush: async () => {
|
|
26
|
-
|
|
36
|
+
migrationAdmissionClosed = true;
|
|
27
37
|
await dependencies.waitForExecutionFrames();
|
|
28
38
|
if (dependencies.isBusy()) {
|
|
29
|
-
|
|
39
|
+
migrationAdmissionClosed = false;
|
|
30
40
|
throw Object.assign(new Error("active execution entered before storage migration quiesce"), {
|
|
31
41
|
code: "runtime_busy",
|
|
32
42
|
});
|
|
33
43
|
}
|
|
34
44
|
await dependencies.flushLocalState();
|
|
35
45
|
},
|
|
36
|
-
reopen: () => {
|
|
46
|
+
reopen: () => { migrationAdmissionClosed = false; },
|
|
37
47
|
},
|
|
38
48
|
sendStatus: dependencies.sendStatus,
|
|
39
49
|
});
|
|
40
50
|
}
|
|
41
|
-
return Object.freeze({
|
|
51
|
+
return Object.freeze({
|
|
52
|
+
isAdmissionClosed: () => migrationAdmissionClosed || identityAdmissionClosed,
|
|
53
|
+
beginIdentityBinding: () => {
|
|
54
|
+
if (options?.bindServerIdentity !== undefined)
|
|
55
|
+
identityAdmissionClosed = true;
|
|
56
|
+
},
|
|
57
|
+
completeIdentityBinding: () => { identityAdmissionClosed = false; },
|
|
58
|
+
});
|
|
42
59
|
}
|
|
43
60
|
export function replayStorageMigrationStatus(options, socket, isCurrent, onError, deliver) {
|
|
44
61
|
return options?.replayStatus?.((frame) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nowcrew/daemon",
|
|
3
|
-
"version": "0.6.87
|
|
3
|
+
"version": "0.6.87",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "crew daemon — 运行在用户机器:拉起/管理 agent 进程,注入 crew CLI,归一化 runtime 事件",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -16,14 +16,6 @@
|
|
|
16
16
|
"publishConfig": {
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
|
-
"scripts": {
|
|
20
|
-
"daemon": "pnpm --filter @nowcrew/cli build && tsx src/main.ts",
|
|
21
|
-
"build": "tsc -p tsconfig.json",
|
|
22
|
-
"codex-home:migrate": "tsx src/runtimes/codex-home-migration-cli.ts",
|
|
23
|
-
"prepublishOnly": "pnpm build && node ../scripts/daemon-release-artifact.mjs --strict-registry",
|
|
24
|
-
"test": "vitest run",
|
|
25
|
-
"typecheck": "tsc --noEmit"
|
|
26
|
-
},
|
|
27
19
|
"dependencies": {
|
|
28
20
|
"@agentclientprotocol/sdk": "1.2.1",
|
|
29
21
|
"@nowcrew/cli": "0.4.13",
|
|
@@ -44,5 +36,12 @@
|
|
|
44
36
|
"tsx": "^4.19.0",
|
|
45
37
|
"typescript": "^5.6.0",
|
|
46
38
|
"vitest": "^2.1.0"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"daemon": "pnpm --filter @nowcrew/cli build && tsx src/main.ts",
|
|
42
|
+
"build": "tsc -p tsconfig.json",
|
|
43
|
+
"codex-home:migrate": "tsx src/runtimes/codex-home-migration-cli.ts",
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"typecheck": "tsc --noEmit"
|
|
47
46
|
}
|
|
48
|
-
}
|
|
47
|
+
}
|
|
@@ -1,109 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
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
|
-
}
|