@nowcrew/daemon 0.6.15 → 0.6.17

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.
Files changed (46) hide show
  1. package/dist/agent-ability/controller.js +6 -2
  2. package/dist/agent-ability/resolver.js +6 -0
  3. package/dist/agent-ability/runtime-context.js +7 -1
  4. package/dist/agent-ability/runtime.js +2 -3
  5. package/dist/atomic-private-write.js +54 -1
  6. package/dist/automatic-install-target.js +40 -11
  7. package/dist/console.js +9 -0
  8. package/dist/control-plane-url.js +2 -2
  9. package/dist/daemon-migration-controller.js +198 -0
  10. package/dist/daemon-migration-wiring.js +22 -0
  11. package/dist/daemon-update-eligibility.js +1 -1
  12. package/dist/directory-projection-identity.js +32 -0
  13. package/dist/directory-projection.js +922 -0
  14. package/dist/execution-protocol.js +78 -11
  15. package/dist/execution-runner.js +50 -2
  16. package/dist/i18n.js +1 -0
  17. package/dist/local-execution-prompt.js +57 -0
  18. package/dist/local-executor.js +99 -40
  19. package/dist/machine-info.js +45 -9
  20. package/dist/normalize.js +5 -0
  21. package/dist/profile-layout.js +41 -0
  22. package/dist/project-skills/controller.js +74 -14
  23. package/dist/project-skills/execution-adapter.js +11 -0
  24. package/dist/project-skills/initialized-reconciler.js +20 -0
  25. package/dist/project-skills/projection-set-switch.js +419 -0
  26. package/dist/project-skills/projection-state-domain.js +153 -0
  27. package/dist/project-skills/projection-state-store.js +841 -0
  28. package/dist/project-skills/projection-state-transaction.js +318 -0
  29. package/dist/project-skills/projection-state.js +3 -0
  30. package/dist/project-skills/reconciler.js +299 -68
  31. package/dist/project-skills/runtime-warning.js +6 -0
  32. package/dist/project-skills/scanner.js +30 -1
  33. package/dist/project-skills/types.js +9 -0
  34. package/dist/project-workspaces/resolver.js +179 -0
  35. package/dist/project-workspaces/types.js +1 -0
  36. package/dist/prompt.js +64 -5
  37. package/dist/runner.js +1 -0
  38. package/dist/runtimes/claude.js +235 -4
  39. package/dist/runtimes/codex-app-server-runner.js +92 -23
  40. package/dist/runtimes/codex-contract.js +123 -0
  41. package/dist/runtimes/codex.js +2 -0
  42. package/dist/serve.js +31 -17
  43. package/dist/session.js +3 -0
  44. package/dist/supervised-runtime.js +12 -4
  45. package/dist/workspace.js +14 -5
  46. package/package.json +1 -1
@@ -0,0 +1,153 @@
1
+ import { createHash } from "node:crypto";
2
+ import { posix, win32 } from "node:path";
3
+ import { z } from "zod";
4
+ import { compareProjectSkillRefs, isProjectId, isProjectSkillName, MAX_AGENT_PROJECT_SKILL_BINDINGS, MAX_PROJECT_ID_LENGTH, MAX_PROJECT_SKILL_NAME_LENGTH, } from "./types.js";
5
+ const MANAGED_BY = "nowcrew-project-skills-v2";
6
+ const MAX_SOURCE_PATH_BYTES = 16 * 1024;
7
+ const MAX_GENERATION = 2_147_483_647;
8
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
9
+ export class ProjectSkillProjectionStateError extends Error {
10
+ code;
11
+ constructor(code) {
12
+ super(code);
13
+ this.code = code;
14
+ this.name = "ProjectSkillProjectionStateError";
15
+ }
16
+ }
17
+ const corrupt = () => {
18
+ throw new ProjectSkillProjectionStateError("skill_projection_state_corrupt");
19
+ };
20
+ const unmanaged = () => {
21
+ throw new ProjectSkillProjectionStateError("skill_projection_state_unmanaged");
22
+ };
23
+ const immutableBinding = (binding) => Object.freeze({
24
+ projectId: binding.projectId,
25
+ skillName: binding.skillName,
26
+ });
27
+ const canonicalBindings = (bindings) => {
28
+ if (bindings.length > MAX_AGENT_PROJECT_SKILL_BINDINGS)
29
+ return corrupt();
30
+ const seen = new Set();
31
+ const canonical = bindings.map((binding) => {
32
+ if (!isProjectId(binding.projectId) || !isProjectSkillName(binding.skillName))
33
+ return corrupt();
34
+ const key = `${binding.projectId}\0${binding.skillName}`;
35
+ if (seen.has(key))
36
+ return corrupt();
37
+ seen.add(key);
38
+ return immutableBinding(binding);
39
+ }).sort(compareProjectSkillRefs);
40
+ return Object.freeze(canonical);
41
+ };
42
+ const digest = (value) => `sha256:${createHash("sha256").update(JSON.stringify(value), "utf8").digest("hex")}`;
43
+ export function computeProjectSkillBindingDigest(bindings) {
44
+ return digest(canonicalBindings(bindings));
45
+ }
46
+ const normalizeWindowsPath = (sourcePath) => {
47
+ let value = sourcePath.replaceAll("/", "\\");
48
+ if (/^\\\\\?\\UNC\\/iu.test(value))
49
+ value = `\\\\${value.slice(8)}`;
50
+ else if (/^\\\\\?\\[A-Za-z]:\\/u.test(value))
51
+ value = value.slice(4);
52
+ if (!win32.isAbsolute(value))
53
+ return corrupt();
54
+ return win32.normalize(value).toLowerCase();
55
+ };
56
+ const normalizeSourcePath = (sourcePath, platform) => {
57
+ if (sourcePath.includes("\0") || Buffer.byteLength(sourcePath, "utf8") > MAX_SOURCE_PATH_BYTES) {
58
+ return corrupt();
59
+ }
60
+ if (platform === "win32")
61
+ return normalizeWindowsPath(sourcePath);
62
+ if (!posix.isAbsolute(sourcePath))
63
+ return corrupt();
64
+ return posix.normalize(sourcePath);
65
+ };
66
+ export function normalizeProjectSkillResolutionRecords(records, platform = process.platform) {
67
+ if (records.length > MAX_AGENT_PROJECT_SKILL_BINDINGS)
68
+ return corrupt();
69
+ const seen = new Set();
70
+ const normalized = records.map((record) => {
71
+ if (!isProjectId(record.projectId) || !isProjectSkillName(record.skillName))
72
+ return corrupt();
73
+ const key = `${record.projectId}\0${record.skillName}`;
74
+ if (seen.has(key))
75
+ return corrupt();
76
+ seen.add(key);
77
+ if (record.mode === "missing") {
78
+ if (record.sourcePath !== null)
79
+ return corrupt();
80
+ return Object.freeze({
81
+ projectId: record.projectId,
82
+ skillName: record.skillName,
83
+ sourcePath: null,
84
+ mode: "missing",
85
+ });
86
+ }
87
+ if (record.mode !== "resolved" || record.sourcePath === null)
88
+ return corrupt();
89
+ return Object.freeze({
90
+ projectId: record.projectId,
91
+ skillName: record.skillName,
92
+ sourcePath: normalizeSourcePath(record.sourcePath, platform),
93
+ mode: "resolved",
94
+ });
95
+ }).sort(compareProjectSkillRefs);
96
+ return Object.freeze(normalized);
97
+ }
98
+ export function computeProjectSkillResolutionDigest(records, platform = process.platform) {
99
+ return digest(normalizeProjectSkillResolutionRecords(records, platform));
100
+ }
101
+ const sameBinding = (left, right) => left.projectId === right.projectId && left.skillName === right.skillName;
102
+ export function createAppliedProjectSkillManifest(input) {
103
+ if (!Number.isInteger(input.generation) || input.generation < 0 || input.generation > MAX_GENERATION) {
104
+ return corrupt();
105
+ }
106
+ const bindings = canonicalBindings(input.bindings);
107
+ const resolutions = normalizeProjectSkillResolutionRecords(input.resolutions, input.platform);
108
+ if (bindings.length !== resolutions.length
109
+ || bindings.some((binding, index) => !sameBinding(binding, resolutions[index]))) {
110
+ return corrupt();
111
+ }
112
+ return Object.freeze({
113
+ managedBy: MANAGED_BY,
114
+ generation: input.generation,
115
+ bindings,
116
+ bindingDigest: digest(bindings),
117
+ resolutionDigest: digest(resolutions),
118
+ });
119
+ }
120
+ const ProjectSkillRefSchema = z.object({
121
+ projectId: z.string().min(1).max(MAX_PROJECT_ID_LENGTH),
122
+ skillName: z.string().min(1).max(MAX_PROJECT_SKILL_NAME_LENGTH),
123
+ }).strict();
124
+ const AppliedManifestSchema = z.object({
125
+ managedBy: z.literal(MANAGED_BY),
126
+ generation: z.number().int().min(0).max(MAX_GENERATION),
127
+ bindings: z.array(ProjectSkillRefSchema).max(MAX_AGENT_PROJECT_SKILL_BINDINGS),
128
+ bindingDigest: z.string().regex(DIGEST),
129
+ resolutionDigest: z.string().regex(DIGEST),
130
+ }).strict();
131
+ /** Strict local-store boundary parser; not re-exported from the public projection-state facade. */
132
+ export const parseAppliedProjectSkillManifest = (candidate) => {
133
+ if (candidate && typeof candidate === "object" && "managedBy" in candidate
134
+ && candidate.managedBy !== MANAGED_BY) {
135
+ return unmanaged();
136
+ }
137
+ const parsed = AppliedManifestSchema.safeParse(candidate);
138
+ if (!parsed.success)
139
+ return corrupt();
140
+ const bindings = canonicalBindings(parsed.data.bindings);
141
+ if (bindings.some((binding, index) => !sameBinding(binding, parsed.data.bindings[index]))) {
142
+ return corrupt();
143
+ }
144
+ if (parsed.data.bindingDigest !== digest(bindings))
145
+ return corrupt();
146
+ return Object.freeze({
147
+ managedBy: MANAGED_BY,
148
+ generation: parsed.data.generation,
149
+ bindings,
150
+ bindingDigest: parsed.data.bindingDigest,
151
+ resolutionDigest: parsed.data.resolutionDigest,
152
+ });
153
+ };