@sift-wiki/conductor 0.2.0-beta.1 → 0.2.0-beta.2

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 (94) hide show
  1. package/dist/adapters/claudeAgent.js +1 -0
  2. package/dist/adapters/claudeAgent.js.map +1 -1
  3. package/dist/adapters/codexAgent.js +1 -0
  4. package/dist/adapters/codexAgent.js.map +1 -1
  5. package/dist/adapters/fakeAgent.js +1 -0
  6. package/dist/adapters/fakeAgent.js.map +1 -1
  7. package/dist/adapters/httpAgent.js +1 -0
  8. package/dist/adapters/httpAgent.js.map +1 -1
  9. package/dist/adapters/processAgent.js +4 -0
  10. package/dist/adapters/processAgent.js.map +1 -1
  11. package/dist/adapters/provider/runProvider.js +4 -0
  12. package/dist/adapters/provider/runProvider.js.map +1 -1
  13. package/dist/adapters/provider/store.js +3 -4
  14. package/dist/adapters/provider/store.js.map +1 -1
  15. package/dist/adapters/types.d.ts +9 -0
  16. package/dist/cli.d.ts +6 -0
  17. package/dist/cli.js +16 -4
  18. package/dist/cli.js.map +1 -1
  19. package/dist/conductorClient.d.ts +56 -19
  20. package/dist/conductorClient.js +91 -40
  21. package/dist/conductorClient.js.map +1 -1
  22. package/dist/config.js +4 -5
  23. package/dist/config.js.map +1 -1
  24. package/dist/daemon.d.ts +19 -6
  25. package/dist/daemon.js +160 -122
  26. package/dist/daemon.js.map +1 -1
  27. package/dist/desktop/app/controller.d.ts +1 -1
  28. package/dist/desktop/app/runtimeController.d.ts +7 -0
  29. package/dist/desktop/app/runtimeController.js +12 -1
  30. package/dist/desktop/app/runtimeController.js.map +1 -1
  31. package/dist/localApi/contracts.d.ts +15 -4
  32. package/dist/localApi/contracts.js +19 -1
  33. package/dist/localApi/contracts.js.map +1 -1
  34. package/dist/localApi/recovery.d.ts +66 -0
  35. package/dist/localApi/recovery.js +115 -0
  36. package/dist/localApi/recovery.js.map +1 -0
  37. package/dist/localApi/server.js +3 -1
  38. package/dist/localApi/server.js.map +1 -1
  39. package/dist/localApp/service.js +16 -4
  40. package/dist/localApp/service.js.map +1 -1
  41. package/dist/protocol/fenced.d.ts +135 -0
  42. package/dist/protocol/fenced.js +142 -0
  43. package/dist/protocol/fenced.js.map +1 -0
  44. package/dist/redaction.js +2 -0
  45. package/dist/redaction.js.map +1 -1
  46. package/dist/runtime/atomicFile.d.ts +6 -0
  47. package/dist/runtime/atomicFile.js +78 -0
  48. package/dist/runtime/atomicFile.js.map +1 -0
  49. package/dist/runtime/daemonCapabilities.d.ts +7 -0
  50. package/dist/runtime/daemonCapabilities.js +24 -0
  51. package/dist/runtime/daemonCapabilities.js.map +1 -0
  52. package/dist/runtime/eventOutbox.d.ts +100 -0
  53. package/dist/runtime/eventOutbox.js +206 -0
  54. package/dist/runtime/eventOutbox.js.map +1 -0
  55. package/dist/runtime/executionJournal.d.ts +102 -0
  56. package/dist/runtime/executionJournal.js +209 -0
  57. package/dist/runtime/executionJournal.js.map +1 -0
  58. package/dist/runtime/executionSafety.d.ts +76 -0
  59. package/dist/runtime/executionSafety.js +207 -0
  60. package/dist/runtime/executionSafety.js.map +1 -0
  61. package/dist/runtime/fencedExecutionState.d.ts +43 -0
  62. package/dist/runtime/fencedExecutionState.js +158 -0
  63. package/dist/runtime/fencedExecutionState.js.map +1 -0
  64. package/dist/runtime/leaseManager.d.ts +38 -0
  65. package/dist/runtime/leaseManager.js +102 -0
  66. package/dist/runtime/leaseManager.js.map +1 -0
  67. package/dist/runtime/localRunQueue.d.ts +1 -1
  68. package/dist/runtime/localRunQueue.js +8 -0
  69. package/dist/runtime/localRunQueue.js.map +1 -1
  70. package/dist/runtime/localSessionCache.d.ts +1 -1
  71. package/dist/runtime/localSessionCache.js.map +1 -1
  72. package/dist/runtime/process.d.ts +13 -1
  73. package/dist/runtime/process.js +39 -9
  74. package/dist/runtime/process.js.map +1 -1
  75. package/dist/runtime/recoveryCoordinator.d.ts +19 -0
  76. package/dist/runtime/recoveryCoordinator.js +183 -0
  77. package/dist/runtime/recoveryCoordinator.js.map +1 -0
  78. package/dist/runtime/runtimeLock.d.ts +33 -0
  79. package/dist/runtime/runtimeLock.js +140 -0
  80. package/dist/runtime/runtimeLock.js.map +1 -0
  81. package/dist/runtime/runtimeService.d.ts +6 -1
  82. package/dist/runtime/runtimeService.js +54 -20
  83. package/dist/runtime/runtimeService.js.map +1 -1
  84. package/dist/runtime/taskExecution.d.ts +2 -0
  85. package/dist/runtime/taskExecution.js +18 -12
  86. package/dist/runtime/taskExecution.js.map +1 -1
  87. package/dist/types.d.ts +28 -13
  88. package/dist/version.d.ts +1 -1
  89. package/dist/version.js +1 -1
  90. package/dist/workTypes.d.ts +5 -5
  91. package/dist-web/assets/index-CWAdDb9V.js +72 -0
  92. package/dist-web/index.html +2 -2
  93. package/package.json +1 -1
  94. package/dist-web/assets/index-D5X9InfE.js +0 -72
@@ -0,0 +1,142 @@
1
+ import { z } from "zod";
2
+ export const FENCED_ATTEMPTS_CAPABILITY = "fenced-attempts-v1";
3
+ export const attemptAuthoritySchema = z.object({
4
+ attemptId: z.string().min(1),
5
+ leaseGeneration: z.number().int().positive(),
6
+ leaseExpiresAt: z.iso.datetime(),
7
+ mustStopAt: z.iso.datetime(),
8
+ }).strict();
9
+ export const attemptAuthorityFenceSchema = attemptAuthoritySchema.pick({
10
+ attemptId: true,
11
+ leaseGeneration: true,
12
+ }).strict();
13
+ export const clientEventIdentitySchema = z.object({
14
+ clientEventId: z.string().min(1).max(200),
15
+ clientSequence: z.number().int().positive(),
16
+ }).strict();
17
+ export const reconciliationDecisionSchema = z.enum([
18
+ "resume",
19
+ "stop",
20
+ "superseded",
21
+ "already_terminal",
22
+ "retry_as_new_attempt",
23
+ ]);
24
+ export const reconcileAttemptRequestSchema = z.object({
25
+ attemptId: z.string().min(1),
26
+ leaseGeneration: z.number().int().positive(),
27
+ lastAcknowledgedClientSequence: z.number().int().nonnegative(),
28
+ providerResumeSupported: z.boolean(),
29
+ supervisedProcessRunning: z.boolean(),
30
+ terminalResult: z.object({
31
+ disposition: z.enum(["completed", "failed", "cancelled"]),
32
+ summary: z.record(z.string(), z.unknown()).optional(),
33
+ }).strict().optional(),
34
+ }).strict();
35
+ export const reconcileAttemptResponseSchema = z.object({
36
+ decision: reconciliationDecisionSchema,
37
+ authority: attemptAuthoritySchema.optional(),
38
+ lastAcknowledgedClientSequence: z.number().int().nonnegative(),
39
+ canonicalStatus: z.string().min(1),
40
+ cancellationRequested: z.boolean(),
41
+ reason: z.string().min(1).max(1_000).optional(),
42
+ }).superRefine((value, context) => {
43
+ if ((value.decision === "resume" || value.decision === "retry_as_new_attempt") &&
44
+ value.authority === undefined) {
45
+ context.addIssue({
46
+ code: "custom",
47
+ message: value.decision === "resume"
48
+ ? "A resume reconciliation decision requires refreshed authority."
49
+ : "A retry-as-new-attempt decision requires replacement authority.",
50
+ path: ["authority"],
51
+ });
52
+ }
53
+ if (value.decision !== "resume" &&
54
+ value.decision !== "retry_as_new_attempt" &&
55
+ value.authority !== undefined) {
56
+ context.addIssue({
57
+ code: "custom",
58
+ message: "Only a resume or retry-as-new-attempt decision may grant authority.",
59
+ path: ["authority"],
60
+ });
61
+ }
62
+ });
63
+ export const settlementResultSchema = z.object({
64
+ attemptId: z.string().min(1),
65
+ idempotencyKey: z.string().min(1).max(200),
66
+ disposition: z.enum(["completed", "failed", "cancelled"]),
67
+ payloadDigest: z.string().min(1),
68
+ terminalAt: z.iso.datetime(),
69
+ repeated: z.boolean(),
70
+ }).strict();
71
+ export const fencedSettlementResponseSchema = z.object({
72
+ job: z.looseObject({
73
+ id: z.string().min(1),
74
+ status: z.enum(["completed", "failed", "cancelled"]),
75
+ }),
76
+ settlement: settlementResultSchema,
77
+ }).strict();
78
+ export const eventAcknowledgementSchema = z.object({
79
+ eventId: z.string().min(1),
80
+ attemptId: z.string().min(1),
81
+ clientEventId: z.string().min(1).max(200),
82
+ clientSequence: z.number().int().positive(),
83
+ acknowledgedClientSequence: z.number().int().nonnegative(),
84
+ serverSequence: z.number().int().positive(),
85
+ repeated: z.boolean(),
86
+ }).strict();
87
+ export const lateResultRequestSchema = z.object({
88
+ idempotencyKey: z.string().min(1).max(200),
89
+ summary: z.record(z.string(), z.unknown()),
90
+ artifactId: z.string().min(1).optional(),
91
+ brainRecordId: z.string().min(1).optional(),
92
+ }).strict();
93
+ export const lateResultResponseSchema = z.object({
94
+ lateResult: z.object({
95
+ id: z.string().min(1),
96
+ attemptId: z.string().min(1),
97
+ reviewStatus: z.literal("pending"),
98
+ }).loose(),
99
+ repeated: z.boolean(),
100
+ }).strict();
101
+ const AUTHORITY_ERROR_CODES = new Set([
102
+ "stale_attempt",
103
+ "stale_generation",
104
+ "authority_expired",
105
+ "deadline_exceeded",
106
+ "run_cancelled",
107
+ "attempt_superseded",
108
+ "already_terminal",
109
+ ]);
110
+ export function classifyApiFailure(status, code) {
111
+ if (status === 0 || status === 408 || status === 425 || status === 429 || status >= 500) {
112
+ return "retryable";
113
+ }
114
+ if (status === 401 || status === 403) {
115
+ return "authentication";
116
+ }
117
+ if (AUTHORITY_ERROR_CODES.has(code)) {
118
+ return "authority_lost";
119
+ }
120
+ if (status === 409) {
121
+ return "conflict";
122
+ }
123
+ return "invalid_request";
124
+ }
125
+ export function fencedMutationBody(body, options) {
126
+ return {
127
+ ...body,
128
+ ...(options?.authority === undefined
129
+ ? {}
130
+ : authorityFence(options.authority)),
131
+ ...(options?.idempotencyKey === undefined
132
+ ? {}
133
+ : { idempotencyKey: z.string().min(1).max(200).parse(options.idempotencyKey) }),
134
+ };
135
+ }
136
+ export function authorityFence(authority) {
137
+ return attemptAuthorityFenceSchema.parse({
138
+ attemptId: authority.attemptId,
139
+ leaseGeneration: authority.leaseGeneration,
140
+ });
141
+ }
142
+ //# sourceMappingURL=fenced.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fenced.js","sourceRoot":"","sources":["../../src/protocol/fenced.ts"],"names":[],"mappings":"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"}
package/dist/redaction.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const CONDUCTOR_CREDENTIAL_PATTERN = /sift_conductor_([^:\s]+):([^\s]+)/gu;
2
2
  const PAIRING_CODE_PATTERN = /\bSC-[A-Za-z0-9_-]+\b/gu;
3
+ const PROVIDER_SECRET_PATTERN = /\b(?:sk-[A-Za-z0-9_-]{8,}|gh[pousr]_[A-Za-z0-9_-]{8,})\b/gu;
3
4
  const HOME_PATH_PATTERNS = [
4
5
  {
5
6
  regex: /\/Users\/([^/\\\s]+)/gu,
@@ -17,6 +18,7 @@ const HOME_PATH_PATTERNS = [
17
18
  export function redactSecrets(input) {
18
19
  let redacted = input.replace(CONDUCTOR_CREDENTIAL_PATTERN, "sift_conductor_$1:<redacted>");
19
20
  redacted = redacted.replace(PAIRING_CODE_PATTERN, "SC-<redacted>");
21
+ redacted = redacted.replace(PROVIDER_SECRET_PATTERN, "<provider-secret-redacted>");
20
22
  for (const pattern of HOME_PATH_PATTERNS) {
21
23
  redacted = redacted.replace(pattern.regex, pattern.replace);
22
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"redaction.js","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"AAAA,MAAM,4BAA4B,GAAG,qCAAqC,CAAC;AAC3E,MAAM,oBAAoB,GAAG,yBAAyB,CAAC;AACvD,MAAM,kBAAkB,GAAG;IACzB;QACE,KAAK,EAAE,wBAAwB;QAC/B,OAAO,EAAE,CAAC,MAAc,EAAE,IAAY,EAAE,EAAE,CAAC,UAAU,eAAe,CAAC,IAAI,CAAC,EAAE;KAC7E;IACD;QACE,KAAK,EAAE,uBAAuB;QAC9B,OAAO,EAAE,CAAC,MAAc,EAAE,IAAY,EAAE,EAAE,CAAC,SAAS,eAAe,CAAC,IAAI,CAAC,EAAE;KAC5E;IACD;QACE,KAAK,EAAE,mCAAmC;QAC1C,OAAO,EAAE,CAAC,MAAc,EAAE,MAAc,EAAE,IAAY,EAAE,EAAE,CAAC,GAAG,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,EAAE;KAC/F;CACO,CAAC;AAEX,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,4BAA4B,EAAE,8BAA8B,CAAC,CAAC;IAC3F,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,oBAAoB,EAAE,eAAe,CAAC,CAAC;IACnE,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;QACzC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,UAAkB;IACjD,OAAO,aAAa,CAAC,UAAU,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7E,CAAC"}
1
+ {"version":3,"file":"redaction.js","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"AAAA,MAAM,4BAA4B,GAAG,qCAAqC,CAAC;AAC3E,MAAM,oBAAoB,GAAG,yBAAyB,CAAC;AACvD,MAAM,uBAAuB,GAAG,4DAA4D,CAAC;AAC7F,MAAM,kBAAkB,GAAG;IACzB;QACE,KAAK,EAAE,wBAAwB;QAC/B,OAAO,EAAE,CAAC,MAAc,EAAE,IAAY,EAAE,EAAE,CAAC,UAAU,eAAe,CAAC,IAAI,CAAC,EAAE;KAC7E;IACD;QACE,KAAK,EAAE,uBAAuB;QAC9B,OAAO,EAAE,CAAC,MAAc,EAAE,IAAY,EAAE,EAAE,CAAC,SAAS,eAAe,CAAC,IAAI,CAAC,EAAE;KAC5E;IACD;QACE,KAAK,EAAE,mCAAmC;QAC1C,OAAO,EAAE,CAAC,MAAc,EAAE,MAAc,EAAE,IAAY,EAAE,EAAE,CAAC,GAAG,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,EAAE;KAC/F;CACO,CAAC;AAEX,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,4BAA4B,EAAE,8BAA8B,CAAC,CAAC;IAC3F,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,oBAAoB,EAAE,eAAe,CAAC,CAAC;IACnE,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,uBAAuB,EAAE,4BAA4B,CAAC,CAAC;IACnF,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;QACzC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,UAAkB;IACjD,OAAO,aAAa,CAAC,UAAU,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,6 @@
1
+ export type AtomicWriteOptions = {
2
+ backup?: boolean | undefined;
3
+ writeTemporary?: ((filePath: string, contents: string) => Promise<void>) | undefined;
4
+ };
5
+ export declare function atomicWriteOwnerOnly(filePath: string, contents: string, options?: AtomicWriteOptions): Promise<void>;
6
+ export declare function isNodeError(error: unknown): error is NodeJS.ErrnoException;
@@ -0,0 +1,78 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { chmod, mkdir, open, readFile, rename, rm, } from "node:fs/promises";
3
+ import path from "node:path";
4
+ export async function atomicWriteOwnerOnly(filePath, contents, options = {}) {
5
+ const directory = path.dirname(filePath);
6
+ await mkdir(directory, { recursive: true, mode: 0o700 });
7
+ await chmod(directory, 0o700);
8
+ if (options.backup === true) {
9
+ const previous = await readOptional(filePath);
10
+ if (previous !== undefined) {
11
+ await replaceFile(`${filePath}.last-good`, previous, options.writeTemporary);
12
+ }
13
+ }
14
+ await replaceFile(filePath, contents, options.writeTemporary);
15
+ }
16
+ async function replaceFile(filePath, contents, writeTemporary) {
17
+ const temporaryPath = `${filePath}.${String(process.pid)}.${randomUUID()}.tmp`;
18
+ try {
19
+ if (writeTemporary === undefined) {
20
+ await writeAndSync(temporaryPath, contents);
21
+ }
22
+ else {
23
+ await writeTemporary(temporaryPath, contents);
24
+ await chmod(temporaryPath, 0o600);
25
+ }
26
+ await rename(temporaryPath, filePath);
27
+ await chmod(filePath, 0o600);
28
+ await syncDirectory(path.dirname(filePath));
29
+ }
30
+ catch (error) {
31
+ await rm(temporaryPath, { force: true }).catch(() => undefined);
32
+ throw error;
33
+ }
34
+ }
35
+ async function writeAndSync(filePath, contents) {
36
+ let handle;
37
+ try {
38
+ handle = await open(filePath, "wx", 0o600);
39
+ await handle.writeFile(contents, "utf8");
40
+ await handle.sync();
41
+ }
42
+ finally {
43
+ await handle?.close();
44
+ }
45
+ }
46
+ async function syncDirectory(directory) {
47
+ let handle;
48
+ try {
49
+ handle = await open(directory, "r");
50
+ await handle.sync();
51
+ }
52
+ catch (error) {
53
+ if (!ignorableDirectorySyncError(error))
54
+ throw error;
55
+ }
56
+ finally {
57
+ await handle?.close();
58
+ }
59
+ }
60
+ async function readOptional(filePath) {
61
+ try {
62
+ return await readFile(filePath, "utf8");
63
+ }
64
+ catch (error) {
65
+ if (isNodeError(error) && error.code === "ENOENT")
66
+ return undefined;
67
+ throw error;
68
+ }
69
+ }
70
+ function ignorableDirectorySyncError(error) {
71
+ if (!isNodeError(error))
72
+ return false;
73
+ return error.code === "EINVAL" || error.code === "EISDIR" || error.code === "EPERM";
74
+ }
75
+ export function isNodeError(error) {
76
+ return error instanceof Error && "code" in error;
77
+ }
78
+ //# sourceMappingURL=atomicFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atomicFile.js","sourceRoot":"","sources":["../../src/runtime/atomicFile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { LocalAgentAdapter } from "../adapters/types.js";
2
+ import type { ConductorAgentAdvertisement, JsonObject } from "../types.js";
3
+ export type ReadyAdapter = LocalAgentAdapter & {
4
+ readinessMetadata: JsonObject;
5
+ };
6
+ export declare function daemonCapabilities(adapters: LocalAgentAdapter[]): JsonObject;
7
+ export declare function advertiseAdapters(adapters: ReadyAdapter[]): ConductorAgentAdvertisement[];
@@ -0,0 +1,24 @@
1
+ import { FENCED_ATTEMPTS_CAPABILITY } from "../protocol/fenced.js";
2
+ import { processTreeTerminationCapability } from "./process.js";
3
+ export function daemonCapabilities(adapters) {
4
+ return {
5
+ platform: process.platform,
6
+ adapters: adapters.map((adapter) => adapter.adapterType),
7
+ [FENCED_ATTEMPTS_CAPABILITY]: true,
8
+ processTreeTermination: processTreeTerminationCapability(),
9
+ };
10
+ }
11
+ export function advertiseAdapters(adapters) {
12
+ return adapters.map((adapter) => ({
13
+ localKey: adapter.localKey,
14
+ displayName: adapter.displayName,
15
+ adapterType: adapter.adapterType,
16
+ status: "active",
17
+ capabilities: {
18
+ ...adapter.capabilities,
19
+ ...adapter.readinessMetadata,
20
+ resumeSupport: adapter.resumeSupport ?? "none",
21
+ },
22
+ }));
23
+ }
24
+ //# sourceMappingURL=daemonCapabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemonCapabilities.js","sourceRoot":"","sources":["../../src/runtime/daemonCapabilities.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAE,gCAAgC,EAAE,MAAM,cAAc,CAAC;AAIhE,MAAM,UAAU,kBAAkB,CAAC,QAA6B;IAC9D,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC;QACxD,CAAC,0BAA0B,CAAC,EAAE,IAAI;QAClC,sBAAsB,EAAE,gCAAgC,EAAE;KAC3D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAwB;IACxD,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,MAAM,EAAE,QAAQ;QAChB,YAAY,EAAE;YACZ,GAAG,OAAO,CAAC,YAAY;YACvB,GAAG,OAAO,CAAC,iBAAiB;YAC5B,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,MAAM;SAC/C;KACF,CAAC,CAAC,CAAC;AACN,CAAC"}
@@ -0,0 +1,100 @@
1
+ import { z } from "zod";
2
+ import type { RunEventInput } from "../types.js";
3
+ import { type AtomicWriteOptions } from "./atomicFile.js";
4
+ export declare const OUTBOX_SCHEMA_VERSION = 1;
5
+ declare const outboxEntrySchema: z.ZodObject<{
6
+ clientEventId: z.ZodString;
7
+ clientSequence: z.ZodNumber;
8
+ attemptId: z.ZodString;
9
+ runId: z.ZodString;
10
+ authority: z.ZodObject<{
11
+ attemptId: z.ZodString;
12
+ leaseGeneration: z.ZodNumber;
13
+ }, z.core.$strict>;
14
+ event: z.ZodObject<{
15
+ eventType: z.ZodEnum<{
16
+ cancelled: "cancelled";
17
+ completed: "completed";
18
+ failed: "failed";
19
+ health: "health";
20
+ progress: "progress";
21
+ log: "log";
22
+ artifact: "artifact";
23
+ approval_requested: "approval_requested";
24
+ }>;
25
+ payload: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
26
+ occurredAt: z.ZodOptional<z.ZodISODateTime>;
27
+ }, z.core.$strict>;
28
+ attempts: z.ZodNumber;
29
+ enqueuedAt: z.ZodNumber;
30
+ nextAttemptAt: z.ZodNumber;
31
+ lastErrorMessage: z.ZodOptional<z.ZodString>;
32
+ }, z.core.$strict>;
33
+ declare const outboxFileSchema: z.ZodObject<{
34
+ schemaVersion: z.ZodLiteral<1>;
35
+ entries: z.ZodArray<z.ZodObject<{
36
+ clientEventId: z.ZodString;
37
+ clientSequence: z.ZodNumber;
38
+ attemptId: z.ZodString;
39
+ runId: z.ZodString;
40
+ authority: z.ZodObject<{
41
+ attemptId: z.ZodString;
42
+ leaseGeneration: z.ZodNumber;
43
+ }, z.core.$strict>;
44
+ event: z.ZodObject<{
45
+ eventType: z.ZodEnum<{
46
+ cancelled: "cancelled";
47
+ completed: "completed";
48
+ failed: "failed";
49
+ health: "health";
50
+ progress: "progress";
51
+ log: "log";
52
+ artifact: "artifact";
53
+ approval_requested: "approval_requested";
54
+ }>;
55
+ payload: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
56
+ occurredAt: z.ZodOptional<z.ZodISODateTime>;
57
+ }, z.core.$strict>;
58
+ attempts: z.ZodNumber;
59
+ enqueuedAt: z.ZodNumber;
60
+ nextAttemptAt: z.ZodNumber;
61
+ lastErrorMessage: z.ZodOptional<z.ZodString>;
62
+ }, z.core.$strict>>;
63
+ updatedAt: z.ZodISODateTime;
64
+ }, z.core.$strict>;
65
+ export type DurableRunEvent = z.infer<typeof outboxEntrySchema>;
66
+ export type EventOutboxSnapshot = z.infer<typeof outboxFileSchema>;
67
+ export declare class DurableEventOutbox {
68
+ readonly path: string;
69
+ private readonly options;
70
+ private loaded;
71
+ private snapshot;
72
+ constructor(path?: string, options?: AtomicWriteOptions & {
73
+ maxEntries?: number | undefined;
74
+ nowMs?: (() => number) | undefined;
75
+ createId?: (() => string) | undefined;
76
+ });
77
+ enqueue(input: {
78
+ attemptId: string;
79
+ runId: string;
80
+ authority: DurableRunEvent["authority"];
81
+ clientSequence: number;
82
+ event: RunEventInput;
83
+ error?: unknown;
84
+ }): Promise<DurableRunEvent>;
85
+ due(nowMs?: number): Promise<DurableRunEvent[]>;
86
+ acknowledge(attemptId: string, acknowledgedClientSequence: number): Promise<void>;
87
+ discardAttempt(attemptId: string): Promise<void>;
88
+ listAttempt(attemptId: string): Promise<DurableRunEvent[]>;
89
+ recordFailure(clientEventId: string, error: unknown, nextAttemptAt: number): Promise<void>;
90
+ stats(): Promise<{
91
+ retainedEntries: number;
92
+ lastClientSequence: number;
93
+ }>;
94
+ private load;
95
+ private persist;
96
+ private nowMs;
97
+ private createId;
98
+ }
99
+ export declare function defaultEventOutboxPath(env?: NodeJS.ProcessEnv): string;
100
+ export {};
@@ -0,0 +1,206 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { readFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { z } from "zod";
5
+ import { defaultConfigPath } from "../config.js";
6
+ import { attemptAuthorityFenceSchema, authorityFence } from "../protocol/fenced.js";
7
+ import { redactSecrets } from "../redaction.js";
8
+ import { atomicWriteOwnerOnly, isNodeError } from "./atomicFile.js";
9
+ export const OUTBOX_SCHEMA_VERSION = 1;
10
+ const MAX_OUTBOX_BYTES = 1024 * 1024;
11
+ const DEFAULT_MAX_ENTRIES = 1_000;
12
+ const eventTypeSchema = z.enum([
13
+ "health",
14
+ "progress",
15
+ "log",
16
+ "artifact",
17
+ "approval_requested",
18
+ "completed",
19
+ "failed",
20
+ "cancelled",
21
+ ]);
22
+ const outboxEntrySchema = z.object({
23
+ clientEventId: z.string().min(1).max(200),
24
+ clientSequence: z.number().int().positive(),
25
+ attemptId: z.string().min(1),
26
+ runId: z.string().min(1),
27
+ authority: attemptAuthorityFenceSchema,
28
+ event: z.object({
29
+ eventType: eventTypeSchema,
30
+ payload: z.record(z.string(), z.unknown()).optional(),
31
+ occurredAt: z.iso.datetime().optional(),
32
+ }).strict(),
33
+ attempts: z.number().int().nonnegative(),
34
+ enqueuedAt: z.number().int().nonnegative(),
35
+ nextAttemptAt: z.number().int().nonnegative(),
36
+ lastErrorMessage: z.string().max(1_000).optional(),
37
+ }).strict();
38
+ const outboxFileSchema = z.object({
39
+ schemaVersion: z.literal(OUTBOX_SCHEMA_VERSION),
40
+ entries: z.array(outboxEntrySchema),
41
+ updatedAt: z.iso.datetime(),
42
+ }).strict();
43
+ const legacyOutboxFileSchema = outboxFileSchema.omit({ schemaVersion: true }).extend({
44
+ schemaVersion: z.literal(0),
45
+ }).strict();
46
+ export class DurableEventOutbox {
47
+ path;
48
+ options;
49
+ loaded = false;
50
+ snapshot = emptySnapshot();
51
+ constructor(path = defaultEventOutboxPath(), options = {}) {
52
+ this.path = path;
53
+ this.options = options;
54
+ }
55
+ async enqueue(input) {
56
+ await this.load();
57
+ if (this.snapshot.entries.length >= (this.options.maxEntries ?? DEFAULT_MAX_ENTRIES)) {
58
+ throw new Error("Durable event outbox is full; refusing to lose an acknowledged event identity.");
59
+ }
60
+ const now = this.nowMs();
61
+ const entry = outboxEntrySchema.parse({
62
+ clientEventId: this.createId(),
63
+ clientSequence: input.clientSequence,
64
+ attemptId: input.attemptId,
65
+ runId: input.runId,
66
+ authority: authorityFence(input.authority),
67
+ event: sanitizeEvent(input.event),
68
+ attempts: 0,
69
+ enqueuedAt: now,
70
+ nextAttemptAt: now,
71
+ ...(input.error === undefined ? {} : { lastErrorMessage: safeError(input.error) }),
72
+ });
73
+ this.snapshot.entries.push(entry);
74
+ await this.persist();
75
+ return structuredClone(entry);
76
+ }
77
+ async due(nowMs = this.nowMs()) {
78
+ await this.load();
79
+ return structuredClone(this.snapshot.entries.filter((entry) => entry.nextAttemptAt <= nowMs));
80
+ }
81
+ async acknowledge(attemptId, acknowledgedClientSequence) {
82
+ await this.load();
83
+ this.snapshot.entries = this.snapshot.entries.filter((entry) => entry.attemptId !== attemptId || entry.clientSequence > acknowledgedClientSequence);
84
+ await this.persist();
85
+ }
86
+ async discardAttempt(attemptId) {
87
+ await this.load();
88
+ this.snapshot.entries = this.snapshot.entries.filter((entry) => entry.attemptId !== attemptId);
89
+ await this.persist();
90
+ }
91
+ async listAttempt(attemptId) {
92
+ await this.load();
93
+ return structuredClone(this.snapshot.entries
94
+ .filter((entry) => entry.attemptId === attemptId)
95
+ .sort((left, right) => left.clientSequence - right.clientSequence));
96
+ }
97
+ async recordFailure(clientEventId, error, nextAttemptAt) {
98
+ await this.load();
99
+ const entry = this.snapshot.entries.find((candidate) => candidate.clientEventId === clientEventId);
100
+ if (entry === undefined)
101
+ return;
102
+ entry.attempts += 1;
103
+ entry.nextAttemptAt = nextAttemptAt;
104
+ entry.lastErrorMessage = safeError(error);
105
+ await this.persist();
106
+ }
107
+ async stats() {
108
+ await this.load();
109
+ return {
110
+ retainedEntries: this.snapshot.entries.length,
111
+ lastClientSequence: Math.max(0, ...this.snapshot.entries.map((entry) => entry.clientSequence)),
112
+ };
113
+ }
114
+ async load() {
115
+ if (this.loaded)
116
+ return;
117
+ const contents = await readOptional(this.path);
118
+ if (contents === undefined) {
119
+ this.loaded = true;
120
+ return;
121
+ }
122
+ const parsed = parseSnapshot(contents);
123
+ if (parsed !== undefined) {
124
+ this.snapshot = parsed.snapshot;
125
+ this.loaded = true;
126
+ if (parsed.migrated)
127
+ await this.persist();
128
+ return;
129
+ }
130
+ const backup = await readOptional(`${this.path}.last-good`);
131
+ const recovered = backup === undefined ? undefined : parseSnapshot(backup);
132
+ if (recovered === undefined) {
133
+ throw new Error("Durable event outbox is corrupt and has no valid last-good snapshot.");
134
+ }
135
+ this.snapshot = recovered.snapshot;
136
+ this.loaded = true;
137
+ await this.persist();
138
+ }
139
+ async persist() {
140
+ this.snapshot.updatedAt = new Date(this.nowMs()).toISOString();
141
+ const parsed = outboxFileSchema.parse(this.snapshot);
142
+ const contents = `${JSON.stringify(parsed, null, 2)}\n`;
143
+ if (Buffer.byteLength(contents, "utf8") > MAX_OUTBOX_BYTES) {
144
+ throw new Error(`Durable event outbox exceeds its ${String(MAX_OUTBOX_BYTES)} byte limit.`);
145
+ }
146
+ await atomicWriteOwnerOnly(this.path, contents, { ...this.options, backup: true });
147
+ }
148
+ nowMs() {
149
+ return (this.options.nowMs ?? Date.now)();
150
+ }
151
+ createId() {
152
+ return (this.options.createId ?? randomUUID)();
153
+ }
154
+ }
155
+ export function defaultEventOutboxPath(env = process.env) {
156
+ return path.join(path.dirname(defaultConfigPath(env)), "runtime", "event-outbox.json");
157
+ }
158
+ function emptySnapshot() {
159
+ return { schemaVersion: OUTBOX_SCHEMA_VERSION, entries: [], updatedAt: new Date(0).toISOString() };
160
+ }
161
+ function parseSnapshot(contents) {
162
+ let raw;
163
+ try {
164
+ raw = JSON.parse(contents);
165
+ }
166
+ catch {
167
+ return undefined;
168
+ }
169
+ const current = outboxFileSchema.safeParse(raw);
170
+ if (current.success)
171
+ return { snapshot: current.data, migrated: false };
172
+ const legacy = legacyOutboxFileSchema.safeParse(raw);
173
+ if (!legacy.success)
174
+ return undefined;
175
+ return { snapshot: { ...legacy.data, schemaVersion: OUTBOX_SCHEMA_VERSION }, migrated: true };
176
+ }
177
+ function sanitizeEvent(event) {
178
+ return {
179
+ ...event,
180
+ ...(event.payload === undefined ? {} : { payload: sanitizeJson(event.payload) }),
181
+ };
182
+ }
183
+ function sanitizeJson(value) {
184
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => {
185
+ if (typeof entry === "string")
186
+ return [key, redactSecrets(entry)];
187
+ if (Array.isArray(entry)) {
188
+ return [key, entry.map((item) => typeof item === "string" ? redactSecrets(item) : item)];
189
+ }
190
+ return [key, entry];
191
+ }));
192
+ }
193
+ function safeError(error) {
194
+ return redactSecrets(error instanceof Error ? error.message : "Unknown event delivery failure.").slice(0, 1_000);
195
+ }
196
+ async function readOptional(filePath) {
197
+ try {
198
+ return await readFile(filePath, "utf8");
199
+ }
200
+ catch (error) {
201
+ if (isNodeError(error) && error.code === "ENOENT")
202
+ return undefined;
203
+ throw error;
204
+ }
205
+ }
206
+ //# sourceMappingURL=eventOutbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eventOutbox.js","sourceRoot":"","sources":["../../src/runtime/eventOutbox.ts"],"names":[],"mappings":"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"}