@jterrats/open-orchestra 1.0.17 → 1.0.18

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 (233) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/CLAUDE.md +1 -0
  3. package/dist/active-runtime-store.d.ts +18 -0
  4. package/dist/active-runtime-store.js +75 -0
  5. package/dist/active-runtime-store.js.map +1 -0
  6. package/dist/chat-api-errors.d.ts +7 -0
  7. package/dist/chat-api-errors.js +15 -0
  8. package/dist/chat-api-errors.js.map +1 -0
  9. package/dist/chat-api-message-persistence.d.ts +12 -0
  10. package/dist/chat-api-message-persistence.js +125 -0
  11. package/dist/chat-api-message-persistence.js.map +1 -0
  12. package/dist/chat-api-records.d.ts +35 -0
  13. package/dist/chat-api-records.js +94 -0
  14. package/dist/chat-api-records.js.map +1 -0
  15. package/dist/chat-api-service.d.ts +32 -0
  16. package/dist/chat-api-service.js +120 -0
  17. package/dist/chat-api-service.js.map +1 -0
  18. package/dist/chat-api-storage.d.ts +1 -0
  19. package/dist/chat-api-storage.js +14 -0
  20. package/dist/chat-api-storage.js.map +1 -0
  21. package/dist/chat-api-types.d.ts +81 -0
  22. package/dist/chat-api-types.js +2 -0
  23. package/dist/chat-api-types.js.map +1 -0
  24. package/dist/chat-compliance-service.d.ts +60 -0
  25. package/dist/chat-compliance-service.js +241 -0
  26. package/dist/chat-compliance-service.js.map +1 -0
  27. package/dist/chat-event-stream.d.ts +13 -0
  28. package/dist/chat-event-stream.js +124 -0
  29. package/dist/chat-event-stream.js.map +1 -0
  30. package/dist/chat-pagination.d.ts +6 -0
  31. package/dist/chat-pagination.js +64 -0
  32. package/dist/chat-pagination.js.map +1 -0
  33. package/dist/chat-storage-actor-validation.d.ts +4 -0
  34. package/dist/chat-storage-actor-validation.js +65 -0
  35. package/dist/chat-storage-actor-validation.js.map +1 -0
  36. package/dist/chat-storage-content-policy.d.ts +6 -0
  37. package/dist/chat-storage-content-policy.js +84 -0
  38. package/dist/chat-storage-content-policy.js.map +1 -0
  39. package/dist/chat-storage-errors.d.ts +20 -0
  40. package/dist/chat-storage-errors.js +17 -0
  41. package/dist/chat-storage-errors.js.map +1 -0
  42. package/dist/chat-storage-local-files.d.ts +17 -0
  43. package/dist/chat-storage-local-files.js +78 -0
  44. package/dist/chat-storage-local-files.js.map +1 -0
  45. package/dist/chat-storage-local-paths.d.ts +6 -0
  46. package/dist/chat-storage-local-paths.js +124 -0
  47. package/dist/chat-storage-local-paths.js.map +1 -0
  48. package/dist/chat-storage-local-projection.d.ts +10 -0
  49. package/dist/chat-storage-local-projection.js +55 -0
  50. package/dist/chat-storage-local-projection.js.map +1 -0
  51. package/dist/chat-storage-local-records.d.ts +13 -0
  52. package/dist/chat-storage-local-records.js +56 -0
  53. package/dist/chat-storage-local-records.js.map +1 -0
  54. package/dist/chat-storage-local.d.ts +6 -0
  55. package/dist/chat-storage-local.js +114 -0
  56. package/dist/chat-storage-local.js.map +1 -0
  57. package/dist/chat-storage-validation.d.ts +10 -0
  58. package/dist/chat-storage-validation.js +100 -0
  59. package/dist/chat-storage-validation.js.map +1 -0
  60. package/dist/chat-storage.d.ts +16 -0
  61. package/dist/chat-storage.js +4 -0
  62. package/dist/chat-storage.js.map +1 -0
  63. package/dist/chat-workflow-timeline.d.ts +17 -0
  64. package/dist/chat-workflow-timeline.js +210 -0
  65. package/dist/chat-workflow-timeline.js.map +1 -0
  66. package/dist/{workspace-claude-settings.d.ts → claude-settings.d.ts} +22 -3
  67. package/dist/{workspace-claude-settings.js → claude-settings.js} +28 -9
  68. package/dist/claude-settings.js.map +1 -0
  69. package/dist/command-init.d.ts +2 -0
  70. package/dist/command-init.js +150 -0
  71. package/dist/command-init.js.map +1 -0
  72. package/dist/command-manifest.js +1 -1
  73. package/dist/command-manifest.js.map +1 -1
  74. package/dist/commands.d.ts +1 -1
  75. package/dist/commands.js +1 -140
  76. package/dist/commands.js.map +1 -1
  77. package/dist/constants.d.ts +1 -0
  78. package/dist/constants.js +1 -0
  79. package/dist/constants.js.map +1 -1
  80. package/dist/context-runtime-preprocessor.d.ts +41 -0
  81. package/dist/context-runtime-preprocessor.js +199 -0
  82. package/dist/context-runtime-preprocessor.js.map +1 -0
  83. package/dist/cursor-settings.d.ts +25 -0
  84. package/dist/cursor-settings.js +72 -0
  85. package/dist/cursor-settings.js.map +1 -0
  86. package/dist/health-commands.js +43 -3
  87. package/dist/health-commands.js.map +1 -1
  88. package/dist/model-aliases.d.ts +5 -0
  89. package/dist/model-aliases.js +37 -0
  90. package/dist/model-aliases.js.map +1 -0
  91. package/dist/ollama-provider.js +25 -0
  92. package/dist/ollama-provider.js.map +1 -1
  93. package/dist/phase-playbooks.js +11 -0
  94. package/dist/phase-playbooks.js.map +1 -1
  95. package/dist/provider-agent-wrapper.js +14 -0
  96. package/dist/provider-agent-wrapper.js.map +1 -1
  97. package/dist/runtime-adapters.js +56 -0
  98. package/dist/runtime-adapters.js.map +1 -1
  99. package/dist/runtime-bootstrap.js +20 -22
  100. package/dist/runtime-bootstrap.js.map +1 -1
  101. package/dist/runtime-child-prompt.js +8 -0
  102. package/dist/runtime-child-prompt.js.map +1 -1
  103. package/dist/runtime-context-manifest.d.ts +4 -1
  104. package/dist/runtime-context-manifest.js +59 -3
  105. package/dist/runtime-context-manifest.js.map +1 -1
  106. package/dist/runtime-execution-adapters.js +19 -0
  107. package/dist/runtime-execution-adapters.js.map +1 -1
  108. package/dist/runtime-execution-renderer.js +4 -0
  109. package/dist/runtime-execution-renderer.js.map +1 -1
  110. package/dist/runtime-execution.js +13 -82
  111. package/dist/runtime-execution.js.map +1 -1
  112. package/dist/runtime-hooks.d.ts +46 -0
  113. package/dist/runtime-hooks.js +95 -0
  114. package/dist/runtime-hooks.js.map +1 -0
  115. package/dist/runtime-parent-actions.js +5 -0
  116. package/dist/runtime-parent-actions.js.map +1 -1
  117. package/dist/runtime-spawn-bridge.js +1 -0
  118. package/dist/runtime-spawn-bridge.js.map +1 -1
  119. package/dist/runtime-spawn-guidance.js +15 -61
  120. package/dist/runtime-spawn-guidance.js.map +1 -1
  121. package/dist/security/chat-guardrail-policy.d.ts +7 -0
  122. package/dist/security/chat-guardrail-policy.js +61 -0
  123. package/dist/security/chat-guardrail-policy.js.map +1 -0
  124. package/dist/security/chat-guardrail-types.d.ts +65 -0
  125. package/dist/security/chat-guardrail-types.js +2 -0
  126. package/dist/security/chat-guardrail-types.js.map +1 -0
  127. package/dist/security/chat-guardrail-validation.d.ts +9 -0
  128. package/dist/security/chat-guardrail-validation.js +64 -0
  129. package/dist/security/chat-guardrail-validation.js.map +1 -0
  130. package/dist/security/chat-guardrails.d.ts +3 -0
  131. package/dist/security/chat-guardrails.js +136 -0
  132. package/dist/security/chat-guardrails.js.map +1 -0
  133. package/dist/security/content-classifier.js +33 -1
  134. package/dist/security/content-classifier.js.map +1 -1
  135. package/dist/security/payment-card-detection.d.ts +3 -0
  136. package/dist/security/payment-card-detection.js +48 -0
  137. package/dist/security/payment-card-detection.js.map +1 -0
  138. package/dist/security/policy-types.d.ts +1 -1
  139. package/dist/security/provider-egress-policy.d.ts +27 -0
  140. package/dist/security/provider-egress-policy.js +72 -0
  141. package/dist/security/provider-egress-policy.js.map +1 -0
  142. package/dist/security/public-api-auth.d.ts +20 -0
  143. package/dist/security/public-api-auth.js +55 -0
  144. package/dist/security/public-api-auth.js.map +1 -0
  145. package/dist/security/public-api-policy.d.ts +8 -0
  146. package/dist/security/public-api-policy.js +40 -0
  147. package/dist/security/public-api-policy.js.map +1 -0
  148. package/dist/security/redaction.js +44 -13
  149. package/dist/security/redaction.js.map +1 -1
  150. package/dist/security/restricted-content-quarantine.d.ts +17 -0
  151. package/dist/security/restricted-content-quarantine.js +50 -0
  152. package/dist/security/restricted-content-quarantine.js.map +1 -0
  153. package/dist/security/restricted-data-classifier.d.ts +9 -0
  154. package/dist/security/restricted-data-classifier.js +254 -0
  155. package/dist/security/restricted-data-classifier.js.map +1 -0
  156. package/dist/skills-render.js +7 -14
  157. package/dist/skills-render.js.map +1 -1
  158. package/dist/telemetry-redaction.d.ts +2 -0
  159. package/dist/telemetry-redaction.js +25 -2
  160. package/dist/telemetry-redaction.js.map +1 -1
  161. package/dist/types/chat.d.ts +203 -0
  162. package/dist/types/chat.js +10 -0
  163. package/dist/types/chat.js.map +1 -0
  164. package/dist/types/model-config.d.ts +4 -0
  165. package/dist/types/public-api.d.ts +75 -0
  166. package/dist/types/public-api.js +2 -0
  167. package/dist/types/public-api.js.map +1 -0
  168. package/dist/types/restricted-data.d.ts +69 -0
  169. package/dist/types/restricted-data.js +8 -0
  170. package/dist/types/restricted-data.js.map +1 -0
  171. package/dist/types/restricted-fragment.d.ts +82 -0
  172. package/dist/types/restricted-fragment.js +14 -0
  173. package/dist/types/restricted-fragment.js.map +1 -0
  174. package/dist/types/runtime.d.ts +12 -0
  175. package/dist/types.d.ts +6 -0
  176. package/dist/types.js.map +1 -1
  177. package/dist/web-api.js +24 -0
  178. package/dist/web-api.js.map +1 -1
  179. package/dist/web-artifact-parsers.d.ts +6 -0
  180. package/dist/web-artifact-parsers.js +244 -0
  181. package/dist/web-artifact-parsers.js.map +1 -0
  182. package/dist/web-artifact-types.d.ts +76 -0
  183. package/dist/web-artifact-types.js +2 -0
  184. package/dist/web-artifact-types.js.map +1 -0
  185. package/dist/web-artifacts.d.ts +2 -43
  186. package/dist/web-artifacts.js +73 -58
  187. package/dist/web-artifacts.js.map +1 -1
  188. package/dist/web-chat-route-inputs.d.ts +11 -0
  189. package/dist/web-chat-route-inputs.js +156 -0
  190. package/dist/web-chat-route-inputs.js.map +1 -0
  191. package/dist/web-chat-routes.d.ts +7 -0
  192. package/dist/web-chat-routes.js +213 -0
  193. package/dist/web-chat-routes.js.map +1 -0
  194. package/dist/web-console/assets/index-CJup1cIA.css +1 -0
  195. package/dist/web-console/assets/index-CVDOfipu.js +11 -0
  196. package/dist/web-console/index.html +2 -2
  197. package/dist/web-evidence.d.ts +1 -1
  198. package/dist/web-evidence.js +9 -2
  199. package/dist/web-evidence.js.map +1 -1
  200. package/dist/web-public-route-inputs.d.ts +14 -0
  201. package/dist/web-public-route-inputs.js +136 -0
  202. package/dist/web-public-route-inputs.js.map +1 -0
  203. package/dist/web-public-routes.d.ts +6 -0
  204. package/dist/web-public-routes.js +194 -0
  205. package/dist/web-public-routes.js.map +1 -0
  206. package/dist/web-public-service.d.ts +16 -0
  207. package/dist/web-public-service.js +154 -0
  208. package/dist/web-public-service.js.map +1 -0
  209. package/dist/workflow-services.js +5 -0
  210. package/dist/workflow-services.js.map +1 -1
  211. package/dist/workspace-runtime-bootstrap.js +15 -4
  212. package/dist/workspace-runtime-bootstrap.js.map +1 -1
  213. package/docs/chat-audit-retention.md +76 -0
  214. package/docs/chat-provider-provenance-ledger.md +75 -0
  215. package/docs/context-runtime-preprocessing.md +37 -0
  216. package/docs/orchestra-mvp.md +8 -2
  217. package/docs/public-api-contract.md +43 -0
  218. package/docs/release-test-matrix.md +14 -14
  219. package/docs/restricted-fragment-storage-contract.md +147 -0
  220. package/docs/runtime-adapters.md +40 -7
  221. package/docs/site-manifest.json +128 -30
  222. package/package.json +5 -2
  223. package/site/dist/_headers +9 -0
  224. package/site/dist/_redirects +2 -0
  225. package/site/dist/architecture.mmd +61 -0
  226. package/site/dist/assets/index-Bi8l6tCE.js +10 -0
  227. package/site/dist/assets/index-BsCLqY__.css +1 -0
  228. package/site/dist/favicon.svg +19 -0
  229. package/site/dist/index.html +28 -0
  230. package/site/package.json +19 -0
  231. package/dist/web-console/assets/index-BHs7OIv8.css +0 -1
  232. package/dist/web-console/assets/index-BJuVTqfQ.js +0 -11
  233. package/dist/workspace-claude-settings.js.map +0 -1
@@ -0,0 +1,114 @@
1
+ import path from "node:path";
2
+ import { assertMatchingScope, assertThreadMessageScope, assertValidChatMessage, assertValidChatThread, CHAT_SCHEMA_VERSION, ChatStorageError, safeStorageIssue, } from "./chat-storage.js";
3
+ export { encodeStorageIdentifier } from "./chat-storage-local-paths.js";
4
+ import { LocalChatStorageFiles } from "./chat-storage-local-files.js";
5
+ import { applyLimit, isExactScope, notFound, } from "./chat-storage-local-records.js";
6
+ import { redactedMessage, threadExportRecord, tombstonedMessage, tombstonedThread, } from "./chat-storage-local-projection.js";
7
+ export function createLocalChatStorage(options) {
8
+ return new LocalChatStorage(options.workspaceRoot);
9
+ }
10
+ class LocalChatStorage {
11
+ workspaceRoot;
12
+ files;
13
+ constructor(workspaceRoot) {
14
+ this.workspaceRoot = path.resolve(workspaceRoot);
15
+ this.files = new LocalChatStorageFiles(this.workspaceRoot);
16
+ }
17
+ async initializeChatStorage(scope) {
18
+ await this.files.ensureScope(scope);
19
+ await this.files.readManifest(scope);
20
+ const threads = await this.files.projectThreads(scope);
21
+ const messages = await this.files.projectMessages(scope);
22
+ return {
23
+ schemaVersion: CHAT_SCHEMA_VERSION,
24
+ scope,
25
+ threads: threads.filter((thread) => isExactScope(scope, thread.scope))
26
+ .length,
27
+ messages: messages.filter((message) => isExactScope(scope, message.scope))
28
+ .length,
29
+ };
30
+ }
31
+ async createThread(scope, thread) {
32
+ assertMatchingScope(scope, thread.scope, "thread.scope");
33
+ assertValidChatThread(thread);
34
+ await this.files.ensureScope(scope);
35
+ const threads = await this.files.projectThreads(scope);
36
+ if (threads.some((entry) => entry.id === thread.id)) {
37
+ throw new ChatStorageError(safeStorageIssue("duplicate_record", "thread.id", "Chat thread already exists."));
38
+ }
39
+ await this.files.appendThread(scope, thread);
40
+ return thread;
41
+ }
42
+ async appendMessage(scope, message) {
43
+ assertMatchingScope(scope, message.scope, "message.scope");
44
+ assertValidChatMessage(message);
45
+ const thread = await this.getThread(scope, message.threadId);
46
+ if (!thread) {
47
+ throw new ChatStorageError(safeStorageIssue("not_found", "message.threadId", "Chat thread was not found."));
48
+ }
49
+ assertThreadMessageScope(thread, message);
50
+ const messages = await this.files.projectMessages(scope);
51
+ if (messages.some((entry) => entry.id === message.id)) {
52
+ throw new ChatStorageError(safeStorageIssue("duplicate_record", "message.id", "Chat message already exists."));
53
+ }
54
+ if (messages.some((entry) => entry.threadId === message.threadId &&
55
+ entry.sequence === message.sequence)) {
56
+ throw new ChatStorageError(safeStorageIssue("duplicate_record", "message.sequence", "Chat message sequence already exists in this thread."));
57
+ }
58
+ await this.files.appendMessage(scope, message);
59
+ return message;
60
+ }
61
+ async listThreads(scope, options = {}) {
62
+ await this.initializeChatStorage(scope);
63
+ const threads = applyLimit((await this.files.projectThreads(scope)).filter((thread) => isExactScope(scope, thread.scope)), options, scope);
64
+ return {
65
+ threads: threads.items,
66
+ ...(threads.nextCursor ? { nextCursor: threads.nextCursor } : {}),
67
+ };
68
+ }
69
+ async getThread(scope, threadId) {
70
+ await this.initializeChatStorage(scope);
71
+ return ((await this.files.projectThreads(scope)).find((thread) => thread.id === threadId && isExactScope(scope, thread.scope)) ?? null);
72
+ }
73
+ async listMessages(scope, threadId, options = {}) {
74
+ await this.initializeChatStorage(scope);
75
+ const messages = applyLimit((await this.files.projectMessages(scope)).filter((message) => message.threadId === threadId && isExactScope(scope, message.scope)), options, scope, threadId);
76
+ return {
77
+ messages: messages.items,
78
+ ...(messages.nextCursor ? { nextCursor: messages.nextCursor } : {}),
79
+ };
80
+ }
81
+ async redactMessage(scope, messageId, redaction) {
82
+ const message = await this.files.findMessage(scope, messageId);
83
+ const redacted = redactedMessage(message, redaction);
84
+ assertValidChatMessage(redacted);
85
+ await this.files.appendMessage(scope, redacted);
86
+ return redacted;
87
+ }
88
+ async tombstoneThread(scope, threadId, deletion) {
89
+ const thread = await this.getThread(scope, threadId);
90
+ if (!thread) {
91
+ throw notFound("thread.id", "Chat thread was not found.");
92
+ }
93
+ const tombstoned = tombstonedThread(thread, deletion);
94
+ assertValidChatThread(tombstoned);
95
+ await this.files.appendThread(scope, tombstoned);
96
+ return tombstoned;
97
+ }
98
+ async tombstoneMessage(scope, messageId, deletion) {
99
+ const message = await this.files.findMessage(scope, messageId);
100
+ const tombstoned = tombstonedMessage(message, deletion);
101
+ assertValidChatMessage(tombstoned);
102
+ await this.files.appendMessage(scope, tombstoned);
103
+ return tombstoned;
104
+ }
105
+ async exportThread(scope, threadId, options) {
106
+ const thread = await this.getThread(scope, threadId);
107
+ if (!thread) {
108
+ throw notFound("thread.id", "Chat thread was not found.");
109
+ }
110
+ const messages = (await this.listMessages(scope, threadId)).messages.filter((message) => options.includeTombstoned || message.contentState !== "tombstoned");
111
+ return threadExportRecord({ scope, thread, messages, options });
112
+ }
113
+ }
114
+ //# sourceMappingURL=chat-storage-local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-storage-local.js","sourceRoot":"","sources":["../src/chat-storage-local.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { type ChatValidationResult } from "./chat-storage-errors.js";
2
+ import type { ChatMessage, ChatScope, ChatThread } from "./types/chat.js";
3
+ export declare const CHAT_SCHEMA_VERSION = 1;
4
+ export declare function validateChatThread(thread: ChatThread): ChatValidationResult<ChatThread>;
5
+ export declare function validateChatMessage(message: ChatMessage): ChatValidationResult<ChatMessage>;
6
+ export declare function assertValidChatThread(thread: ChatThread): void;
7
+ export declare function assertValidChatMessage(message: ChatMessage): void;
8
+ export declare function assertMatchingScope(expected: ChatScope, actual: ChatScope, field?: string): void;
9
+ export declare function assertThreadMessageScope(thread: ChatThread, message: ChatMessage): void;
10
+ export declare function isSameScope(left: ChatScope, right: ChatScope): boolean;
@@ -0,0 +1,100 @@
1
+ import { genericInvalidIssue, safeStorageIssue, ChatStorageError, } from "./chat-storage-errors.js";
2
+ import { validateActor } from "./chat-storage-actor-validation.js";
3
+ import { validateContentPolicy, validateDeletion, validateExport, validateRetention, } from "./chat-storage-content-policy.js";
4
+ export const CHAT_SCHEMA_VERSION = 1;
5
+ export function validateChatThread(thread) {
6
+ const issues = baseRecordIssues("thread", thread);
7
+ issues.push(...validateContentPolicy("thread", thread));
8
+ return issues.length > 0
9
+ ? { ok: false, issues }
10
+ : { ok: true, value: thread };
11
+ }
12
+ export function validateChatMessage(message) {
13
+ const issues = baseRecordIssues("message", message);
14
+ if (!message.threadId) {
15
+ issues.push(safeStorageIssue("invalid_scope", "message.threadId", "Thread id is required."));
16
+ }
17
+ if (!Number.isSafeInteger(message.sequence) || message.sequence < 1) {
18
+ issues.push(safeStorageIssue("invalid_scope", "message.sequence", "Message sequence must be a positive safe integer."));
19
+ }
20
+ issues.push(...validateContentPolicy("message", message));
21
+ return issues.length > 0
22
+ ? { ok: false, issues }
23
+ : { ok: true, value: message };
24
+ }
25
+ export function assertValidChatThread(thread) {
26
+ const result = validateChatThread(thread);
27
+ if (!result.ok) {
28
+ throw new ChatStorageError(result.issues[0] ?? genericInvalidIssue());
29
+ }
30
+ }
31
+ export function assertValidChatMessage(message) {
32
+ const result = validateChatMessage(message);
33
+ if (!result.ok) {
34
+ throw new ChatStorageError(result.issues[0] ?? genericInvalidIssue());
35
+ }
36
+ }
37
+ export function assertMatchingScope(expected, actual, field = "scope") {
38
+ const missing = validateScope(expected, "request.scope");
39
+ if (missing.length > 0) {
40
+ throw new ChatStorageError(missing[0] ?? genericInvalidIssue());
41
+ }
42
+ if (!isSameScope(expected, actual)) {
43
+ throw new ChatStorageError(safeStorageIssue("scope_mismatch", field, "Chat record scope must match request scope."));
44
+ }
45
+ }
46
+ export function assertThreadMessageScope(thread, message) {
47
+ if (thread.id !== message.threadId ||
48
+ !isSameScope(thread.scope, message.scope)) {
49
+ throw new ChatStorageError(safeStorageIssue("scope_mismatch", "message.scope", "Chat message scope must match its thread scope."));
50
+ }
51
+ }
52
+ export function isSameScope(left, right) {
53
+ return (left.tenantId === right.tenantId &&
54
+ left.workspaceId === right.workspaceId &&
55
+ left.taskId === right.taskId &&
56
+ left.runId === right.runId &&
57
+ left.phase === right.phase &&
58
+ left.sessionId === right.sessionId);
59
+ }
60
+ function baseRecordIssues(recordName, record) {
61
+ const issues = [];
62
+ if (record.schemaVersion !== CHAT_SCHEMA_VERSION) {
63
+ issues.push(safeStorageIssue("unsupported_schema_version", `${recordName}.schemaVersion`, "Chat record schema version is not supported."));
64
+ }
65
+ if (!record.id) {
66
+ issues.push(safeStorageIssue("invalid_scope", `${recordName}.id`, "Chat record id is required."));
67
+ }
68
+ issues.push(...validateScope(record.scope, `${recordName}.scope`));
69
+ issues.push(...validateActor(record.actor, `${recordName}.actor`));
70
+ if (!record.provenance) {
71
+ issues.push(safeStorageIssue("invalid_provenance", `${recordName}.provenance`, "Chat provenance is required."));
72
+ }
73
+ else {
74
+ for (const field of [
75
+ "sourceKind",
76
+ "sourceId",
77
+ "createdAt",
78
+ "observedAt",
79
+ ]) {
80
+ if (!record.provenance[field]) {
81
+ issues.push(safeStorageIssue("invalid_provenance", `${recordName}.provenance.${field}`, "Chat provenance field is required."));
82
+ }
83
+ }
84
+ }
85
+ issues.push(...validateRetention(record.retention, `${recordName}.retention`));
86
+ issues.push(...validateExport(record.export, `${recordName}.export`));
87
+ issues.push(...validateDeletion(record.delete, `${recordName}.delete`));
88
+ return issues;
89
+ }
90
+ function validateScope(scope, field) {
91
+ if (!scope) {
92
+ return [
93
+ safeStorageIssue("invalid_scope", field, "Chat scope is required."),
94
+ ];
95
+ }
96
+ return ["tenantId", "workspaceId", "taskId", "runId", "phase", "sessionId"]
97
+ .filter((key) => !scope[key])
98
+ .map((key) => safeStorageIssue("invalid_scope", `${field}.${key}`, "Chat scope field is required."));
99
+ }
100
+ //# sourceMappingURL=chat-storage-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-storage-validation.js","sourceRoot":"","sources":["../src/chat-storage-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export { ChatStorageError, genericInvalidIssue, safeStorageIssue, type ChatStorageErrorCode, type ChatValidationIssue, type ChatValidationResult, } from "./chat-storage-errors.js";
2
+ export { isKnownChatActorKind, validateActor, } from "./chat-storage-actor-validation.js";
3
+ export { CHAT_SCHEMA_VERSION, assertMatchingScope, assertThreadMessageScope, assertValidChatMessage, assertValidChatThread, isSameScope, validateChatMessage, validateChatThread, } from "./chat-storage-validation.js";
4
+ import type { ChatDeleteMetadata, ChatExportOptions, ChatExportRecord, ChatListOptions, ChatMessage, ChatMessageListResult, ChatRedactionMetadata, ChatScope, ChatStorageState, ChatThread, ChatThreadListResult } from "./types/chat.js";
5
+ export interface ChatStorage {
6
+ initializeChatStorage(scope: ChatScope): Promise<ChatStorageState>;
7
+ createThread(scope: ChatScope, thread: ChatThread): Promise<ChatThread>;
8
+ appendMessage(scope: ChatScope, message: ChatMessage): Promise<ChatMessage>;
9
+ listThreads(scope: ChatScope, options?: ChatListOptions): Promise<ChatThreadListResult>;
10
+ getThread(scope: ChatScope, threadId: string): Promise<ChatThread | null>;
11
+ listMessages(scope: ChatScope, threadId: string, options?: ChatListOptions): Promise<ChatMessageListResult>;
12
+ redactMessage(scope: ChatScope, messageId: string, redaction: ChatRedactionMetadata): Promise<ChatMessage>;
13
+ tombstoneThread(scope: ChatScope, threadId: string, deletion: ChatDeleteMetadata): Promise<ChatThread>;
14
+ tombstoneMessage(scope: ChatScope, messageId: string, deletion: ChatDeleteMetadata): Promise<ChatMessage>;
15
+ exportThread(scope: ChatScope, threadId: string, options: ChatExportOptions): Promise<ChatExportRecord>;
16
+ }
@@ -0,0 +1,4 @@
1
+ export { ChatStorageError, genericInvalidIssue, safeStorageIssue, } from "./chat-storage-errors.js";
2
+ export { isKnownChatActorKind, validateActor, } from "./chat-storage-actor-validation.js";
3
+ export { CHAT_SCHEMA_VERSION, assertMatchingScope, assertThreadMessageScope, assertValidChatMessage, assertValidChatThread, isSameScope, validateChatMessage, validateChatThread, } from "./chat-storage-validation.js";
4
+ //# sourceMappingURL=chat-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-storage.js","sourceRoot":"","sources":["../src/chat-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,GAIjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oBAAoB,EACpB,aAAa,GACd,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,WAAW,EACX,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { ChatMessage, ChatScope } from "./types/chat.js";
2
+ export declare function listWorkflowTimelineMessages({ root, scope, threadId, }: {
3
+ root: string;
4
+ scope: ChatScope;
5
+ threadId: string;
6
+ }): Promise<ChatMessage[]>;
7
+ export declare function mergeTimelineMessages({ storedMessages, workflowMessages, scope, threadId, limit, cursor, }: {
8
+ storedMessages: ChatMessage[];
9
+ workflowMessages: ChatMessage[];
10
+ scope: ChatScope;
11
+ threadId: string;
12
+ limit?: number;
13
+ cursor?: string;
14
+ }): {
15
+ messages: ChatMessage[];
16
+ nextCursor?: string;
17
+ };
@@ -0,0 +1,210 @@
1
+ import { exportPolicy, retention } from "./chat-api-records.js";
2
+ import { paginateChatRecords } from "./chat-pagination.js";
3
+ import { readEvents } from "./workspace.js";
4
+ const TIMELINE_EVENT_TYPES = new Set([
5
+ "EVIDENCE_ADDED",
6
+ "REVIEW_RECORDED",
7
+ "GATE_APPROVED",
8
+ "GATE_BLOCKED",
9
+ "RUNTIME_DELEGATION_SESSION_PLANNED",
10
+ "RUNTIME_SPAWN_REQUEST_RENDERED",
11
+ "RUNTIME_DELEGATION_SESSION_QUEUED",
12
+ "RUNTIME_DELEGATION_SESSION_SPAWNED",
13
+ "RUNTIME_DELEGATION_SESSION_ACTIVE",
14
+ "RUNTIME_DELEGATION_SESSION_COMPLETED",
15
+ "RUNTIME_DELEGATION_SESSION_FAILED",
16
+ "RUNTIME_DELEGATION_SESSION_TIMED_OUT",
17
+ "RUNTIME_DELEGATION_SESSION_CANCELED",
18
+ "RUNTIME_DELEGATION_SESSION_CLOSED",
19
+ ]);
20
+ export async function listWorkflowTimelineMessages({ root, scope, threadId, }) {
21
+ const events = await readEvents(root);
22
+ return events
23
+ .filter((event) => isTimelineEvent(event))
24
+ .filter((event) => event.taskId === scope.taskId)
25
+ .filter((event) => matchesRun(event, scope.runId))
26
+ .sort(compareTimelineEvents)
27
+ .map((event, index) => projectTimelineMessage(event, scope, threadId, index));
28
+ }
29
+ export function mergeTimelineMessages({ storedMessages, workflowMessages, scope, threadId, limit, cursor, }) {
30
+ const merged = [...storedMessages, ...workflowMessages]
31
+ .sort(compareTimelineMessages)
32
+ .map((message, index) => ({
33
+ ...message,
34
+ sequence: index + 1,
35
+ }));
36
+ const page = paginateChatRecords(merged, {
37
+ ...(limit !== undefined ? { limit } : {}),
38
+ ...(cursor ? { cursor } : {}),
39
+ }, scope, threadId);
40
+ return {
41
+ messages: page.items,
42
+ ...(page.nextCursor ? { nextCursor: page.nextCursor } : {}),
43
+ };
44
+ }
45
+ function isTimelineEvent(event) {
46
+ return (event.type.startsWith("AUTONOMOUS_") || TIMELINE_EVENT_TYPES.has(event.type));
47
+ }
48
+ function matchesRun(event, expectedRunId) {
49
+ const runId = timelineRunId(event);
50
+ return !runId || runId === expectedRunId;
51
+ }
52
+ function compareTimelineEvents(left, right) {
53
+ return (left.timestamp.localeCompare(right.timestamp) ||
54
+ left.id.localeCompare(right.id));
55
+ }
56
+ function compareTimelineMessages(left, right) {
57
+ return (left.createdAt.localeCompare(right.createdAt) ||
58
+ left.id.localeCompare(right.id));
59
+ }
60
+ function projectTimelineMessage(event, scope, threadId, index) {
61
+ const runtime = runtimeSource(event);
62
+ const sessionId = stringMetadata(event, "sessionId");
63
+ const role = stringMetadata(event, "role");
64
+ const timelineEvent = {
65
+ sourceEventId: event.id,
66
+ eventType: event.type,
67
+ actor: event.actor,
68
+ summary: event.summary,
69
+ taskId: event.taskId ?? scope.taskId,
70
+ artifacts: event.artifacts ?? [],
71
+ };
72
+ const runId = timelineRunId(event);
73
+ const phase = stringMetadata(event, "phase");
74
+ const gateId = stringMetadata(event, "gateId");
75
+ const result = stringMetadata(event, "result");
76
+ const rationale = stringMetadata(event, "rationale");
77
+ const actionKind = stringMetadata(event, "actionKind");
78
+ if (runId)
79
+ timelineEvent.runId = runId;
80
+ if (phase)
81
+ timelineEvent.phase = phase;
82
+ if (gateId)
83
+ timelineEvent.gateId = gateId;
84
+ if (result)
85
+ timelineEvent.result = result;
86
+ if (rationale)
87
+ timelineEvent.rationale = rationale;
88
+ if (sessionId)
89
+ timelineEvent.sessionId = sessionId;
90
+ if (runtime)
91
+ timelineEvent.runtime = runtime;
92
+ if (actionKind)
93
+ timelineEvent.actionKind = actionKind;
94
+ return {
95
+ schemaVersion: 1,
96
+ id: `timeline-${event.id}`,
97
+ threadId,
98
+ scope,
99
+ actor: actorForTimelineEvent(event, scope, runtime, role, sessionId),
100
+ provenance: {
101
+ sourceKind: event.type === "REVIEW_RECORDED" ? "review" : "workflow_event",
102
+ sourceId: event.id,
103
+ createdAt: event.timestamp,
104
+ observedAt: event.timestamp,
105
+ ...(runtime ? { runtime } : {}),
106
+ },
107
+ createdAt: event.timestamp,
108
+ sequence: index + 1,
109
+ content: {
110
+ format: "workflow_event",
111
+ text: event.summary,
112
+ },
113
+ contentState: "redacted",
114
+ retention: retention(event.timestamp),
115
+ export: exportPolicy(event.timestamp),
116
+ delete: { status: "active", policyId: "chat-delete-logical" },
117
+ references: timelineReferences(event, scope),
118
+ timelineEvent,
119
+ };
120
+ }
121
+ function actorForTimelineEvent(event, scope, runtime, role, sessionId) {
122
+ if (event.type === "REVIEW_RECORDED") {
123
+ return {
124
+ kind: "reviewer",
125
+ actorId: event.actor,
126
+ role: event.actor,
127
+ reviewId: event.id,
128
+ };
129
+ }
130
+ if (event.type.startsWith("RUNTIME_DELEGATION_SESSION_") &&
131
+ runtime &&
132
+ role &&
133
+ sessionId) {
134
+ return {
135
+ kind: "subagent",
136
+ actorId: stringMetadata(event, "spawnedAgentId") ?? event.actor,
137
+ runtime,
138
+ role,
139
+ sessionId,
140
+ parentSessionId: scope.sessionId,
141
+ };
142
+ }
143
+ if ((event.type === "RUNTIME_SPAWN_REQUEST_RENDERED" ||
144
+ event.type === "RUNTIME_DELEGATION_SESSION_QUEUED" ||
145
+ event.type === "RUNTIME_DELEGATION_SESSION_PLANNED") &&
146
+ runtime &&
147
+ sessionId) {
148
+ return {
149
+ kind: "parent_agent",
150
+ actorId: event.actor,
151
+ runtime,
152
+ sessionId,
153
+ };
154
+ }
155
+ return {
156
+ kind: "workflow_event",
157
+ actorId: `workflow:${event.id}`,
158
+ sourceEventId: event.id,
159
+ eventType: event.type,
160
+ };
161
+ }
162
+ function timelineReferences(event, scope) {
163
+ const references = [
164
+ { kind: "task", id: scope.taskId },
165
+ { kind: "workflow_run", id: scope.runId },
166
+ ];
167
+ if (event.type === "REVIEW_RECORDED") {
168
+ references.push({ kind: "review", id: event.id, label: event.summary });
169
+ }
170
+ if (event.type === "EVIDENCE_ADDED") {
171
+ references.push({ kind: "evidence", id: event.id, label: event.summary });
172
+ }
173
+ if (event.type.startsWith("GATE_")) {
174
+ references.push({ kind: "decision", id: event.id, label: event.summary });
175
+ }
176
+ if (event.type === "RUNTIME_SPAWN_REQUEST_RENDERED" ||
177
+ event.type === "RUNTIME_DELEGATION_SESSION_QUEUED") {
178
+ references.push({
179
+ kind: "provider_request",
180
+ id: event.id,
181
+ label: event.summary,
182
+ });
183
+ }
184
+ return references;
185
+ }
186
+ function timelineRunId(event) {
187
+ const explicit = stringMetadata(event, "runId");
188
+ if (explicit)
189
+ return explicit;
190
+ const sessionId = stringMetadata(event, "sessionId");
191
+ if (!sessionId)
192
+ return undefined;
193
+ const parts = sessionId.split(":");
194
+ return parts.length >= 4 ? parts[1] : undefined;
195
+ }
196
+ function runtimeSource(event) {
197
+ const value = stringMetadata(event, "runtime");
198
+ if (value === "codex-cli" ||
199
+ value === "claude-cli" ||
200
+ value === "cursor-cli" ||
201
+ value === "generic-runtime") {
202
+ return value;
203
+ }
204
+ return undefined;
205
+ }
206
+ function stringMetadata(event, key) {
207
+ const value = event.metadata[key];
208
+ return typeof value === "string" && value.trim() ? value : undefined;
209
+ }
210
+ //# sourceMappingURL=chat-workflow-timeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-workflow-timeline.js","sourceRoot":"","sources":["../src/chat-workflow-timeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAW5C,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,gBAAgB;IAChB,iBAAiB;IACjB,eAAe;IACf,cAAc;IACd,oCAAoC;IACpC,gCAAgC;IAChC,mCAAmC;IACnC,oCAAoC;IACpC,mCAAmC;IACnC,sCAAsC;IACtC,mCAAmC;IACnC,sCAAsC;IACtC,qCAAqC;IACrC,mCAAmC;CACpC,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,EACjD,IAAI,EACJ,KAAK,EACL,QAAQ,GAKT;IACC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,MAAM;SACV,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;SACzC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC;SAChD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;SACjD,IAAI,CAAC,qBAAqB,CAAC;SAC3B,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CACpB,sBAAsB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CACtD,CAAC;AACN,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,EACpC,cAAc,EACd,gBAAgB,EAChB,KAAK,EACL,QAAQ,EACR,KAAK,EACL,MAAM,GAQP;IACC,MAAM,MAAM,GAAG,CAAC,GAAG,cAAc,EAAE,GAAG,gBAAgB,CAAC;SACpD,IAAI,CAAC,uBAAuB,CAAC;SAC7B,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACxB,GAAG,OAAO;QACV,QAAQ,EAAE,KAAK,GAAG,CAAC;KACpB,CAAC,CAAC,CAAC;IACN,MAAM,IAAI,GAAG,mBAAmB,CAC9B,MAAM,EACN;QACE,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9B,EACD,KAAK,EACL,QAAQ,CACT,CAAC;IACF,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,KAAK;QACpB,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5D,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAiB;IACxC,OAAO,CACL,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAC7E,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAiB,EAAE,aAAqB;IAC1D,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,CAAC,KAAK,IAAI,KAAK,KAAK,aAAa,CAAC;AAC3C,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAgB,EAAE,KAAiB;IAChE,OAAO,CACL,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC;QAC7C,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAChC,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAC9B,IAAiB,EACjB,KAAkB;IAElB,OAAO,CACL,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC;QAC7C,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAChC,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAC7B,KAAiB,EACjB,KAAgB,EAChB,QAAgB,EAChB,KAAa;IAEb,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC3C,MAAM,aAAa,GAA8B;QAC/C,aAAa,EAAE,KAAK,CAAC,EAAE;QACvB,SAAS,EAAE,KAAK,CAAC,IAAI;QACrB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM;QACpC,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,EAAE;KACjC,CAAC;IACF,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACvD,IAAI,KAAK;QAAE,aAAa,CAAC,KAAK,GAAG,KAAK,CAAC;IACvC,IAAI,KAAK;QAAE,aAAa,CAAC,KAAK,GAAG,KAAK,CAAC;IACvC,IAAI,MAAM;QAAE,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC;IAC1C,IAAI,MAAM;QAAE,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC;IAC1C,IAAI,SAAS;QAAE,aAAa,CAAC,SAAS,GAAG,SAAS,CAAC;IACnD,IAAI,SAAS;QAAE,aAAa,CAAC,SAAS,GAAG,SAAS,CAAC;IACnD,IAAI,OAAO;QAAE,aAAa,CAAC,OAAO,GAAG,OAAO,CAAC;IAC7C,IAAI,UAAU;QAAE,aAAa,CAAC,UAAU,GAAG,UAAU,CAAC;IACtD,OAAO;QACL,aAAa,EAAE,CAAC;QAChB,EAAE,EAAE,YAAY,KAAK,CAAC,EAAE,EAAE;QAC1B,QAAQ;QACR,KAAK;QACL,KAAK,EAAE,qBAAqB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC;QACpE,UAAU,EAAE;YACV,UAAU,EACR,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB;YAChE,QAAQ,EAAE,KAAK,CAAC,EAAE;YAClB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,UAAU,EAAE,KAAK,CAAC,SAAS;YAC3B,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChC;QACD,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,QAAQ,EAAE,KAAK,GAAG,CAAC;QACnB,OAAO,EAAE;YACP,MAAM,EAAE,gBAAgB;YACxB,IAAI,EAAE,KAAK,CAAC,OAAO;SACpB;QACD,YAAY,EAAE,UAAU;QACxB,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC;QACrC,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC;QACrC,MAAM,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,qBAAqB,EAAE;QAC7D,UAAU,EAAE,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC;QAC5C,aAAa;KACd,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAC5B,KAAiB,EACjB,KAAgB,EAChB,OAAsC,EACtC,IAAwB,EACxB,SAA6B;IAE7B,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACrC,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,KAAK,CAAC,KAAK;YACpB,IAAI,EAAE,KAAK,CAAC,KAAK;YACjB,QAAQ,EAAE,KAAK,CAAC,EAAE;SACnB,CAAC;IACJ,CAAC;IACD,IACE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,6BAA6B,CAAC;QACpD,OAAO;QACP,IAAI;QACJ,SAAS,EACT,CAAC;QACD,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,cAAc,CAAC,KAAK,EAAE,gBAAgB,CAAC,IAAI,KAAK,CAAC,KAAK;YAC/D,OAAO;YACP,IAAI;YACJ,SAAS;YACT,eAAe,EAAE,KAAK,CAAC,SAAS;SACjC,CAAC;IACJ,CAAC;IACD,IACE,CAAC,KAAK,CAAC,IAAI,KAAK,gCAAgC;QAC9C,KAAK,CAAC,IAAI,KAAK,mCAAmC;QAClD,KAAK,CAAC,IAAI,KAAK,oCAAoC,CAAC;QACtD,OAAO;QACP,SAAS,EACT,CAAC;QACD,OAAO;YACL,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,KAAK,CAAC,KAAK;YACpB,OAAO;YACP,SAAS;SACV,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,YAAY,KAAK,CAAC,EAAE,EAAE;QAC/B,aAAa,EAAE,KAAK,CAAC,EAAE;QACvB,SAAS,EAAE,KAAK,CAAC,IAAI;KACtB,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CACzB,KAAiB,EACjB,KAAgB;IAEhB,MAAM,UAAU,GAAoB;QAClC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE;QAClC,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE;KAC1C,CAAC;IACF,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACrC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACpC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACnC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,IACE,KAAK,CAAC,IAAI,KAAK,gCAAgC;QAC/C,KAAK,CAAC,IAAI,KAAK,mCAAmC,EAClD,CAAC;QACD,UAAU,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,kBAAkB;YACxB,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,KAAK,EAAE,KAAK,CAAC,OAAO;SACrB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,aAAa,CAAC,KAAiB;IACtC,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAChD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACrD,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED,SAAS,aAAa,CAAC,KAAiB;IACtC,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC/C,IACE,KAAK,KAAK,WAAW;QACrB,KAAK,KAAK,YAAY;QACtB,KAAK,KAAK,YAAY;QACtB,KAAK,KAAK,iBAAiB,EAC3B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,cAAc,CAAC,KAAiB,EAAE,GAAW;IACpD,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvE,CAAC"}
@@ -6,13 +6,32 @@ type HookEntry = {
6
6
  matcher: string;
7
7
  hooks: HookCommand[];
8
8
  };
9
- type ClaudeSettingsJson = {
9
+ export type ClaudeSettingsJson = {
10
10
  [key: string]: unknown;
11
11
  hooks?: {
12
12
  [key: string]: HookEntry[] | undefined;
13
13
  UserPromptSubmit?: HookEntry[];
14
14
  };
15
15
  };
16
+ export interface ClaudeSettingsWriteResult {
17
+ written: boolean;
18
+ settingsPath: string;
19
+ diagnostic?: {
20
+ code: "corrupted-json" | "write-error";
21
+ message: string;
22
+ };
23
+ }
24
+ /**
25
+ * Pure function: parses raw JSON string into Claude settings.
26
+ * Returns empty settings with a diagnostic when the JSON is corrupted.
27
+ */
28
+ export declare function parseClaudeSettingsJson(raw: string): {
29
+ settings: ClaudeSettingsJson;
30
+ diagnostic?: {
31
+ code: "corrupted-json";
32
+ message: string;
33
+ };
34
+ };
16
35
  /**
17
36
  * Pure function: upserts the orchestra UserPromptSubmit hook into an existing
18
37
  * settings object. Preserves all other hooks and settings.
@@ -21,7 +40,7 @@ export declare function mergeOrchestraHook(existing: ClaudeSettingsJson): Claude
21
40
  /**
22
41
  * Generates or updates `.claude/settings.json` with the UserPromptSubmit hook
23
42
  * that injects task/workflow state into Claude Code sessions at prompt start.
24
- * Returns true if the file was written.
43
+ * Fails open: corrupted existing settings are recovered and a diagnostic is returned.
25
44
  */
26
- export declare function initClaudeSettings(root: string): Promise<boolean>;
45
+ export declare function initClaudeSettings(root: string): Promise<ClaudeSettingsWriteResult>;
27
46
  export {};
@@ -6,10 +6,28 @@ const ORCHESTRA_HOOK = {
6
6
  hooks: [
7
7
  {
8
8
  type: "command",
9
- command: "(command -v orchestra >/dev/null 2>&1 && orchestra health --json && orchestra task list --json --status in_progress,pending) || true",
9
+ command: "(command -v orchestra >/dev/null 2>&1 && orchestra health --runtime claude-cli --json && orchestra task list --json --status in_progress,pending) || true",
10
10
  },
11
11
  ],
12
12
  };
13
+ /**
14
+ * Pure function: parses raw JSON string into Claude settings.
15
+ * Returns empty settings with a diagnostic when the JSON is corrupted.
16
+ */
17
+ export function parseClaudeSettingsJson(raw) {
18
+ try {
19
+ return { settings: JSON.parse(raw) };
20
+ }
21
+ catch (err) {
22
+ return {
23
+ settings: {},
24
+ diagnostic: {
25
+ code: "corrupted-json",
26
+ message: err instanceof Error ? err.message : String(err),
27
+ },
28
+ };
29
+ }
30
+ }
13
31
  /**
14
32
  * Pure function: upserts the orchestra UserPromptSubmit hook into an existing
15
33
  * settings object. Preserves all other hooks and settings.
@@ -32,23 +50,24 @@ export function mergeOrchestraHook(existing) {
32
50
  /**
33
51
  * Generates or updates `.claude/settings.json` with the UserPromptSubmit hook
34
52
  * that injects task/workflow state into Claude Code sessions at prompt start.
35
- * Returns true if the file was written.
53
+ * Fails open: corrupted existing settings are recovered and a diagnostic is returned.
36
54
  */
37
55
  export async function initClaudeSettings(root) {
38
56
  const claudeDir = path.join(root, ".claude");
39
57
  const settingsPath = path.join(claudeDir, "settings.json");
40
58
  let existing = {};
59
+ let diagnostic;
41
60
  if (await exists(settingsPath)) {
42
- try {
43
- existing = JSON.parse(await readFile(settingsPath, "utf8"));
44
- }
45
- catch {
46
- existing = {};
61
+ const raw = await readFile(settingsPath, "utf8");
62
+ const parsed = parseClaudeSettingsJson(raw);
63
+ existing = parsed.settings;
64
+ if (parsed.diagnostic) {
65
+ diagnostic = parsed.diagnostic;
47
66
  }
48
67
  }
49
68
  const merged = mergeOrchestraHook(existing);
50
69
  await ensureDir(claudeDir);
51
70
  await writeFile(settingsPath, `${JSON.stringify(merged, null, 2)}\n`, "utf8");
52
- return true;
71
+ return { written: true, settingsPath, ...(diagnostic ? { diagnostic } : {}) };
53
72
  }
54
- //# sourceMappingURL=workspace-claude-settings.js.map
73
+ //# sourceMappingURL=claude-settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-settings.js","sourceRoot":"","sources":["../src/claude-settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { CliIo, CliOptions } from "./types.js";
2
+ export declare function initCommand(options: CliOptions, io: CliIo): Promise<void>;