@nowcrew/daemon 0.6.79-beta.2 → 0.6.80-beta.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/dist/local-executor.js +6 -17
- package/dist/main.js +0 -0
- package/dist/package-manager-env.js +75 -0
- package/dist/runner.js +2 -1
- package/dist/runtime-env.js +21 -0
- package/package.json +10 -9
- 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/local-executor.js
CHANGED
|
@@ -32,6 +32,8 @@ import { diffMemoryPruneNotes, evaluateMemoryPrunePostcondition, inspectMemoryPr
|
|
|
32
32
|
import { createLocalMemoryTelemetry, logLocalMemoryContextPrepareFailure, logLocalMemoryDiagnosticsFailure, } from "./local-memory-telemetry.js";
|
|
33
33
|
import { CodexStartupStageParser } from "./codex-startup-stage.js";
|
|
34
34
|
import { formatRuntimeStartupError } from "./runtime-startup-error.js";
|
|
35
|
+
import { machinePackageManagerEnv, packageManagerEnvFacts } from "./package-manager-env.js";
|
|
36
|
+
import { sanitizeEnvVars } from "./runtime-env.js";
|
|
35
37
|
import { commitLocalMemoryResultAfterExit, initializeLocalMemoryV2ForWorkspace, isLocalMemoryV2Eligible, localMemoryResultPath as makeLocalMemoryResultPath, renderLocalMemoryResultInstructions, } from "./local-memory/runtime.js";
|
|
36
38
|
export class RuntimeRunningCallbackTimeoutError extends Error {
|
|
37
39
|
constructor(runtime, timeoutMs) {
|
|
@@ -49,15 +51,6 @@ const MEMORY_PRUNE_DIAGNOSTICS_TIMEOUT_MS = 2_000;
|
|
|
49
51
|
const LOCAL_MEMORY_DIAGNOSTICS_TIMEOUT_MS = 250;
|
|
50
52
|
const CLAUDE_INSTRUCTION_WARNING = "claude_additional_directory_instructions_unverified";
|
|
51
53
|
const CODEX_COLLABORATION_EXEC_WARNING = "codex_collaboration_disabled_on_exec";
|
|
52
|
-
const ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
53
|
-
const RESERVED_ENV = new Set([
|
|
54
|
-
"PATH",
|
|
55
|
-
"XDG_CONFIG_HOME",
|
|
56
|
-
"XDG_DATA_HOME",
|
|
57
|
-
"XDG_CACHE_HOME",
|
|
58
|
-
"GH_CONFIG_DIR",
|
|
59
|
-
"CLOUDSDK_CONFIG",
|
|
60
|
-
]);
|
|
61
54
|
function withoutClaudeInstructionFlag(env) {
|
|
62
55
|
if (!(CLAUDE_ADDITIONAL_DIRECTORY_INSTRUCTIONS_ENV in env))
|
|
63
56
|
return env;
|
|
@@ -68,14 +61,6 @@ function withoutClaudeInstructionFlag(env) {
|
|
|
68
61
|
const warnRuntimeLocally = (code) => {
|
|
69
62
|
process.stderr.write(`[runtime-warning] ${code}\n`);
|
|
70
63
|
};
|
|
71
|
-
export function sanitizeEnvVars(raw) {
|
|
72
|
-
if (!raw)
|
|
73
|
-
return {};
|
|
74
|
-
return Object.fromEntries(Object.entries(raw).filter(([key, value]) => typeof value === "string"
|
|
75
|
-
&& ENV_KEY_RE.test(key)
|
|
76
|
-
&& !key.toUpperCase().startsWith("CREW_")
|
|
77
|
-
&& !RESERVED_ENV.has(key.toUpperCase())));
|
|
78
|
-
}
|
|
79
64
|
export function awaitExit(child) {
|
|
80
65
|
return new Promise((resolve) => {
|
|
81
66
|
let settled = false;
|
|
@@ -461,6 +446,9 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
461
446
|
const baseEnv = {
|
|
462
447
|
...inheritedEnv,
|
|
463
448
|
...sanitizeEnvVars(providerConfig.envVars),
|
|
449
|
+
...(input.trainingProjectContext === undefined
|
|
450
|
+
? {}
|
|
451
|
+
: machinePackageManagerEnv(inheritedEnv)),
|
|
464
452
|
...input.launch.systemEnv,
|
|
465
453
|
PATH: `${workspace.crewDir}${delimiter}${augmentedPath()}`,
|
|
466
454
|
CREW_SERVER_URL: input.launch.serverUrl,
|
|
@@ -503,6 +491,7 @@ async function executeLocalUnlocked(input, callbacks, dependencies) {
|
|
|
503
491
|
qa_runtime_root: childEnv.QA_RUNTIME_ROOT ?? null,
|
|
504
492
|
qa_runtime_root_present: childEnv.QA_RUNTIME_ROOT !== undefined,
|
|
505
493
|
inherited_qa_runtime_root_present: inheritedEnv.QA_RUNTIME_ROOT !== undefined,
|
|
494
|
+
...packageManagerEnvFacts(childEnv),
|
|
506
495
|
training_root: join(workspace.dir, "training"),
|
|
507
496
|
project_context_present: input.projectContext !== undefined,
|
|
508
497
|
project_ids: JSON.stringify(input.projectContext === undefined
|
package/dist/main.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
function nonEmpty(value) {
|
|
3
|
+
const normalized = value?.trim();
|
|
4
|
+
return normalized === undefined || normalized === "" ? undefined : normalized;
|
|
5
|
+
}
|
|
6
|
+
function registryUrl(value) {
|
|
7
|
+
const normalized = nonEmpty(value);
|
|
8
|
+
if (normalized === undefined)
|
|
9
|
+
return undefined;
|
|
10
|
+
try {
|
|
11
|
+
const protocol = new URL(normalized).protocol;
|
|
12
|
+
return protocol === "http:" || protocol === "https:" ? normalized : undefined;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function configuredPath(env) {
|
|
19
|
+
const explicit = env.CREW_PACKAGE_MANAGER_USERCONFIG?.trim();
|
|
20
|
+
if (explicit !== undefined && explicit !== "")
|
|
21
|
+
return explicit;
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
function registryFromNpmrc(path) {
|
|
25
|
+
if (path === undefined)
|
|
26
|
+
return undefined;
|
|
27
|
+
try {
|
|
28
|
+
const line = readFileSync(path, "utf8")
|
|
29
|
+
.split(/\r?\n/u)
|
|
30
|
+
.find((entry) => /^\s*registry\s*=/u.test(entry));
|
|
31
|
+
return registryUrl(line?.replace(/^\s*registry\s*=\s*/u, ""));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function npmrcHasAuth(path) {
|
|
38
|
+
if (path === undefined)
|
|
39
|
+
return false;
|
|
40
|
+
try {
|
|
41
|
+
return /^\s*(?:(?:\/\/[^=\s]+:)?_(?:auth|authToken|password))\s*=/imu.test(readFileSync(path, "utf8"));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Keep machine-owned npm credentials available for explicitly authorized
|
|
49
|
+
* training dependency installs. The daemon must opt in with
|
|
50
|
+
* CREW_PACKAGE_MANAGER_USERCONFIG; Agent env cannot reach this path.
|
|
51
|
+
*/
|
|
52
|
+
export function machinePackageManagerEnv(env = process.env) {
|
|
53
|
+
const npmUserConfig = configuredPath(env);
|
|
54
|
+
const yarnRegistry = npmUserConfig === undefined
|
|
55
|
+
? undefined
|
|
56
|
+
: registryUrl(env.YARN_REGISTRY) ?? registryFromNpmrc(npmUserConfig);
|
|
57
|
+
const entries = npmUserConfig === undefined
|
|
58
|
+
? []
|
|
59
|
+
: [["NPM_CONFIG_USERCONFIG", npmUserConfig]];
|
|
60
|
+
const alwaysAuth = npmrcHasAuth(npmUserConfig) ? "true" : undefined;
|
|
61
|
+
return Object.fromEntries(yarnRegistry === undefined && alwaysAuth === undefined
|
|
62
|
+
? entries
|
|
63
|
+
: [
|
|
64
|
+
...entries,
|
|
65
|
+
...(yarnRegistry === undefined ? [] : [["YARN_REGISTRY", yarnRegistry]]),
|
|
66
|
+
...(alwaysAuth === undefined ? [] : [["NPM_CONFIG_ALWAYS_AUTH", alwaysAuth]]),
|
|
67
|
+
]);
|
|
68
|
+
}
|
|
69
|
+
export function packageManagerEnvFacts(env) {
|
|
70
|
+
return {
|
|
71
|
+
npm_userconfig_present: Boolean(env.NPM_CONFIG_USERCONFIG?.trim()),
|
|
72
|
+
yarn_registry_present: Boolean(env.YARN_REGISTRY?.trim()),
|
|
73
|
+
npm_always_auth_present: Boolean(env.NPM_CONFIG_ALWAYS_AUTH?.trim()),
|
|
74
|
+
};
|
|
75
|
+
}
|
package/dist/runner.js
CHANGED
|
@@ -11,7 +11,8 @@ import { readOriginDecisionFile, resetOriginDecisionFile } from "./origin-decisi
|
|
|
11
11
|
import { readBoundImDecisionFile, resetBoundImDecisionFile } from "./bound-im-decision.js";
|
|
12
12
|
import { launchSupervisedRuntime } from "./supervised-runtime.js";
|
|
13
13
|
import { awaitWithCancellation, } from "./runtime-cancellation.js";
|
|
14
|
-
export { awaitExit, exitActivity
|
|
14
|
+
export { awaitExit, exitActivity } from "./local-executor.js";
|
|
15
|
+
export { sanitizeEnvVars } from "./runtime-env.js";
|
|
15
16
|
const ICON = {
|
|
16
17
|
init: "🟢", text: "💬", reading: "📖", sending: "📨", checking: "🔎",
|
|
17
18
|
claiming: "📌", crew: "⚙️", tool: "🛠️", tool_result: "↩️", done: "✅", error: "❌",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
2
|
+
export const RESERVED_ENV = new Set([
|
|
3
|
+
"PATH",
|
|
4
|
+
"XDG_CONFIG_HOME",
|
|
5
|
+
"XDG_DATA_HOME",
|
|
6
|
+
"XDG_CACHE_HOME",
|
|
7
|
+
"GH_CONFIG_DIR",
|
|
8
|
+
"CLOUDSDK_CONFIG",
|
|
9
|
+
"NPM_CONFIG_USERCONFIG",
|
|
10
|
+
"YARN_REGISTRY",
|
|
11
|
+
"NPM_CONFIG_ALWAYS_AUTH",
|
|
12
|
+
]);
|
|
13
|
+
/** 用户自定义环境只能补充普通变量,不能覆盖 daemon 维护的运行时契约。 */
|
|
14
|
+
export function sanitizeEnvVars(raw) {
|
|
15
|
+
if (!raw)
|
|
16
|
+
return {};
|
|
17
|
+
return Object.fromEntries(Object.entries(raw).filter(([key, value]) => typeof value === "string"
|
|
18
|
+
&& ENV_KEY_RE.test(key)
|
|
19
|
+
&& !key.toUpperCase().startsWith("CREW_")
|
|
20
|
+
&& !RESERVED_ENV.has(key.toUpperCase())));
|
|
21
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nowcrew/daemon",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.80-beta.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "crew daemon — 运行在用户机器:拉起/管理 agent 进程,注入 crew CLI,归一化 runtime 事件",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -16,6 +16,14 @@
|
|
|
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
|
+
},
|
|
19
27
|
"dependencies": {
|
|
20
28
|
"@agentclientprotocol/sdk": "1.2.1",
|
|
21
29
|
"@nowcrew/cli": "0.4.13",
|
|
@@ -36,12 +44,5 @@
|
|
|
36
44
|
"tsx": "^4.19.0",
|
|
37
45
|
"typescript": "^5.6.0",
|
|
38
46
|
"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"
|
|
46
47
|
}
|
|
47
|
-
}
|
|
48
|
+
}
|
|
@@ -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
|
-
}
|