@openrig/cli 0.3.0 → 0.3.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.
Files changed (282) hide show
  1. package/daemon/assets/plugins/openrig-core/.claude-plugin/plugin.json +15 -0
  2. package/daemon/assets/plugins/openrig-core/.codex-plugin/plugin.json +24 -0
  3. package/daemon/assets/plugins/openrig-core/LICENSE +200 -0
  4. package/daemon/assets/plugins/openrig-core/README.md +42 -0
  5. package/daemon/assets/plugins/openrig-core/hooks/claude.json +78 -0
  6. package/daemon/assets/plugins/openrig-core/hooks/codex.json +37 -0
  7. package/daemon/assets/{openrig-activity-hook-relay.cjs → plugins/openrig-core/hooks/scripts/activity-relay.cjs} +12 -0
  8. package/daemon/assets/plugins/openrig-core/hooks/scripts/compaction-restore-bridge.cjs +172 -0
  9. package/daemon/assets/plugins/openrig-core/skills/agent-startup-and-context-ingestion/SKILL.md +104 -0
  10. package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/SKILL.md +131 -0
  11. package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/scripts/precompact-hook.mjs +174 -0
  12. package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/scripts/restore-from-jsonl.mjs +433 -0
  13. package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/templates/compact-instruction.md +1 -0
  14. package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/templates/post-compact-restore-instruction.md +1 -0
  15. package/daemon/assets/plugins/openrig-core/skills/forming-an-openrig-mental-model/SKILL.md +305 -0
  16. package/daemon/{specs/agents/shared/skills/rig-architect → assets/plugins/openrig-core/skills/openrig-architect}/SKILL.md +38 -19
  17. package/daemon/assets/plugins/openrig-core/skills/openrig-operator/SKILL.md +222 -0
  18. package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +597 -0
  19. package/daemon/assets/plugins/openrig-core/skills/queue-handoff/SKILL.md +122 -0
  20. package/daemon/assets/plugins/openrig-core/skills/seat-continuity-and-handover/SKILL.md +137 -0
  21. package/daemon/assets/vm-preview-fixtures/README.md +48 -0
  22. package/daemon/assets/vm-preview-fixtures/workflows/sample-basic-loop.yaml +79 -0
  23. package/daemon/dist/adapters/claude-code-adapter.d.ts +1 -3
  24. package/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
  25. package/daemon/dist/adapters/claude-code-adapter.js +17 -57
  26. package/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
  27. package/daemon/dist/adapters/cmux-transport.d.ts.map +1 -1
  28. package/daemon/dist/adapters/cmux-transport.js +81 -2
  29. package/daemon/dist/adapters/cmux-transport.js.map +1 -1
  30. package/daemon/dist/adapters/cmux.d.ts +4 -0
  31. package/daemon/dist/adapters/cmux.d.ts.map +1 -1
  32. package/daemon/dist/adapters/cmux.js +87 -0
  33. package/daemon/dist/adapters/cmux.js.map +1 -1
  34. package/daemon/dist/adapters/codex-runtime-adapter.d.ts +14 -3
  35. package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
  36. package/daemon/dist/adapters/codex-runtime-adapter.js +43 -57
  37. package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
  38. package/daemon/dist/db/migrations/040_workflow_specs_diagnostic.d.ts +32 -0
  39. package/daemon/dist/db/migrations/040_workflow_specs_diagnostic.d.ts.map +1 -0
  40. package/daemon/dist/db/migrations/040_workflow_specs_diagnostic.js +37 -0
  41. package/daemon/dist/db/migrations/040_workflow_specs_diagnostic.js.map +1 -0
  42. package/daemon/dist/domain/agent-manifest.d.ts.map +1 -1
  43. package/daemon/dist/domain/agent-manifest.js +116 -37
  44. package/daemon/dist/domain/agent-manifest.js.map +1 -1
  45. package/daemon/dist/domain/agent-resolver.js +1 -1
  46. package/daemon/dist/domain/agent-resolver.js.map +1 -1
  47. package/daemon/dist/domain/claude-compaction-enforcer.d.ts +81 -0
  48. package/daemon/dist/domain/claude-compaction-enforcer.d.ts.map +1 -0
  49. package/daemon/dist/domain/claude-compaction-enforcer.js +242 -0
  50. package/daemon/dist/domain/claude-compaction-enforcer.js.map +1 -0
  51. package/daemon/dist/domain/cmux-layout-service.d.ts +41 -0
  52. package/daemon/dist/domain/cmux-layout-service.d.ts.map +1 -0
  53. package/daemon/dist/domain/cmux-layout-service.js +184 -0
  54. package/daemon/dist/domain/cmux-layout-service.js.map +1 -0
  55. package/daemon/dist/domain/context-monitor.d.ts +15 -1
  56. package/daemon/dist/domain/context-monitor.d.ts.map +1 -1
  57. package/daemon/dist/domain/context-monitor.js +38 -3
  58. package/daemon/dist/domain/context-monitor.js.map +1 -1
  59. package/daemon/dist/domain/kernel-boot-tracker.d.ts +74 -0
  60. package/daemon/dist/domain/kernel-boot-tracker.d.ts.map +1 -0
  61. package/daemon/dist/domain/kernel-boot-tracker.js +213 -0
  62. package/daemon/dist/domain/kernel-boot-tracker.js.map +1 -0
  63. package/daemon/dist/domain/kernel-boot.d.ts +50 -0
  64. package/daemon/dist/domain/kernel-boot.d.ts.map +1 -0
  65. package/daemon/dist/domain/kernel-boot.js +147 -0
  66. package/daemon/dist/domain/kernel-boot.js.map +1 -0
  67. package/daemon/dist/domain/mission-control/mission-control-read-layer.d.ts +5 -0
  68. package/daemon/dist/domain/mission-control/mission-control-read-layer.d.ts.map +1 -1
  69. package/daemon/dist/domain/mission-control/mission-control-read-layer.js +16 -2
  70. package/daemon/dist/domain/mission-control/mission-control-read-layer.js.map +1 -1
  71. package/daemon/dist/domain/mission-control/mission-control-write-contract.d.ts.map +1 -1
  72. package/daemon/dist/domain/mission-control/mission-control-write-contract.js +3 -1
  73. package/daemon/dist/domain/mission-control/mission-control-write-contract.js.map +1 -1
  74. package/daemon/dist/domain/plugin-discovery-service.d.ts +150 -0
  75. package/daemon/dist/domain/plugin-discovery-service.d.ts.map +1 -0
  76. package/daemon/dist/domain/plugin-discovery-service.js +468 -0
  77. package/daemon/dist/domain/plugin-discovery-service.js.map +1 -0
  78. package/daemon/dist/domain/plugin-vendor-service.d.ts +54 -0
  79. package/daemon/dist/domain/plugin-vendor-service.d.ts.map +1 -0
  80. package/daemon/dist/domain/plugin-vendor-service.js +111 -0
  81. package/daemon/dist/domain/plugin-vendor-service.js.map +1 -0
  82. package/daemon/dist/domain/profile-resolver.d.ts +3 -3
  83. package/daemon/dist/domain/profile-resolver.d.ts.map +1 -1
  84. package/daemon/dist/domain/profile-resolver.js +7 -7
  85. package/daemon/dist/domain/profile-resolver.js.map +1 -1
  86. package/daemon/dist/domain/projection-planner.d.ts +7 -1
  87. package/daemon/dist/domain/projection-planner.d.ts.map +1 -1
  88. package/daemon/dist/domain/projection-planner.js +44 -4
  89. package/daemon/dist/domain/projection-planner.js.map +1 -1
  90. package/daemon/dist/domain/queue-repository.d.ts +8 -1
  91. package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  92. package/daemon/dist/domain/queue-repository.js +14 -5
  93. package/daemon/dist/domain/queue-repository.js.map +1 -1
  94. package/daemon/dist/domain/session-transport.d.ts.map +1 -1
  95. package/daemon/dist/domain/session-transport.js +33 -0
  96. package/daemon/dist/domain/session-transport.js.map +1 -1
  97. package/daemon/dist/domain/skill-library-discovery.d.ts +68 -0
  98. package/daemon/dist/domain/skill-library-discovery.d.ts.map +1 -0
  99. package/daemon/dist/domain/skill-library-discovery.js +144 -0
  100. package/daemon/dist/domain/skill-library-discovery.js.map +1 -0
  101. package/daemon/dist/domain/slices/slice-indexer.d.ts +19 -0
  102. package/daemon/dist/domain/slices/slice-indexer.d.ts.map +1 -1
  103. package/daemon/dist/domain/slices/slice-indexer.js +88 -6
  104. package/daemon/dist/domain/slices/slice-indexer.js.map +1 -1
  105. package/daemon/dist/domain/spec-library-service.d.ts +6 -0
  106. package/daemon/dist/domain/spec-library-service.d.ts.map +1 -1
  107. package/daemon/dist/domain/spec-library-service.js.map +1 -1
  108. package/daemon/dist/domain/spec-library-workflow-scanner.d.ts +43 -0
  109. package/daemon/dist/domain/spec-library-workflow-scanner.d.ts.map +1 -1
  110. package/daemon/dist/domain/spec-library-workflow-scanner.js +157 -3
  111. package/daemon/dist/domain/spec-library-workflow-scanner.js.map +1 -1
  112. package/daemon/dist/domain/spec-review-service.d.ts +1 -1
  113. package/daemon/dist/domain/spec-review-service.d.ts.map +1 -1
  114. package/daemon/dist/domain/spec-review-service.js +14 -1
  115. package/daemon/dist/domain/spec-review-service.js.map +1 -1
  116. package/daemon/dist/domain/types.d.ts +27 -7
  117. package/daemon/dist/domain/types.d.ts.map +1 -1
  118. package/daemon/dist/domain/types.js.map +1 -1
  119. package/daemon/dist/domain/user-settings/settings-store.d.ts +25 -1
  120. package/daemon/dist/domain/user-settings/settings-store.d.ts.map +1 -1
  121. package/daemon/dist/domain/user-settings/settings-store.js +186 -4
  122. package/daemon/dist/domain/user-settings/settings-store.js.map +1 -1
  123. package/daemon/dist/domain/workflow-spec-cache.d.ts +27 -0
  124. package/daemon/dist/domain/workflow-spec-cache.d.ts.map +1 -1
  125. package/daemon/dist/domain/workflow-spec-cache.js +59 -0
  126. package/daemon/dist/domain/workflow-spec-cache.js.map +1 -1
  127. package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
  128. package/daemon/dist/domain/workspace/default-workspace-scaffold.js +45 -0
  129. package/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
  130. package/daemon/dist/domain/workspace/getting-started-narrative.d.ts +15 -0
  131. package/daemon/dist/domain/workspace/getting-started-narrative.d.ts.map +1 -0
  132. package/daemon/dist/domain/workspace/getting-started-narrative.js +237 -0
  133. package/daemon/dist/domain/workspace/getting-started-narrative.js.map +1 -0
  134. package/daemon/dist/index.d.ts +2 -1
  135. package/daemon/dist/index.d.ts.map +1 -1
  136. package/daemon/dist/index.js +52 -17
  137. package/daemon/dist/index.js.map +1 -1
  138. package/daemon/dist/lib/pane-envelope.d.ts +7 -0
  139. package/daemon/dist/lib/pane-envelope.d.ts.map +1 -0
  140. package/daemon/dist/lib/pane-envelope.js +38 -0
  141. package/daemon/dist/lib/pane-envelope.js.map +1 -0
  142. package/daemon/dist/middleware/auth-bearer-token.d.ts +47 -5
  143. package/daemon/dist/middleware/auth-bearer-token.d.ts.map +1 -1
  144. package/daemon/dist/middleware/auth-bearer-token.js +109 -8
  145. package/daemon/dist/middleware/auth-bearer-token.js.map +1 -1
  146. package/daemon/dist/routes/kernel-status.d.ts +3 -0
  147. package/daemon/dist/routes/kernel-status.d.ts.map +1 -0
  148. package/daemon/dist/routes/kernel-status.js +40 -0
  149. package/daemon/dist/routes/kernel-status.js.map +1 -0
  150. package/daemon/dist/routes/mission-control.d.ts.map +1 -1
  151. package/daemon/dist/routes/mission-control.js +25 -2
  152. package/daemon/dist/routes/mission-control.js.map +1 -1
  153. package/daemon/dist/routes/missions.d.ts +3 -0
  154. package/daemon/dist/routes/missions.d.ts.map +1 -0
  155. package/daemon/dist/routes/missions.js +195 -0
  156. package/daemon/dist/routes/missions.js.map +1 -0
  157. package/daemon/dist/routes/plugins.d.ts +3 -0
  158. package/daemon/dist/routes/plugins.d.ts.map +1 -0
  159. package/daemon/dist/routes/plugins.js +223 -0
  160. package/daemon/dist/routes/plugins.js.map +1 -0
  161. package/daemon/dist/routes/rig-cmux.d.ts +3 -0
  162. package/daemon/dist/routes/rig-cmux.d.ts.map +1 -0
  163. package/daemon/dist/routes/rig-cmux.js +121 -0
  164. package/daemon/dist/routes/rig-cmux.js.map +1 -0
  165. package/daemon/dist/routes/skills.d.ts +3 -0
  166. package/daemon/dist/routes/skills.d.ts.map +1 -0
  167. package/daemon/dist/routes/skills.js +147 -0
  168. package/daemon/dist/routes/skills.js.map +1 -0
  169. package/daemon/dist/routes/slices.d.ts.map +1 -1
  170. package/daemon/dist/routes/slices.js +15 -0
  171. package/daemon/dist/routes/slices.js.map +1 -1
  172. package/daemon/dist/routes/spec-library.d.ts.map +1 -1
  173. package/daemon/dist/routes/spec-library.js +16 -1
  174. package/daemon/dist/routes/spec-library.js.map +1 -1
  175. package/daemon/dist/server.d.ts +31 -0
  176. package/daemon/dist/server.d.ts.map +1 -1
  177. package/daemon/dist/server.js +30 -0
  178. package/daemon/dist/server.js.map +1 -1
  179. package/daemon/dist/startup.d.ts.map +1 -1
  180. package/daemon/dist/startup.js +194 -5
  181. package/daemon/dist/startup.js.map +1 -1
  182. package/daemon/specs/agents/apps/vault-specialist/agent.yaml +0 -1
  183. package/daemon/specs/agents/conveyor/builder/agent.yaml +0 -1
  184. package/daemon/specs/agents/conveyor/lead/agent.yaml +0 -1
  185. package/daemon/specs/agents/conveyor/planner/agent.yaml +0 -1
  186. package/daemon/specs/agents/conveyor/reviewer/agent.yaml +0 -1
  187. package/daemon/specs/agents/design/product-designer/agent.yaml +0 -1
  188. package/daemon/specs/agents/development/implementer/agent.yaml +0 -1
  189. package/daemon/specs/agents/development/qa/agent.yaml +0 -1
  190. package/daemon/specs/agents/development/qa/guidance/role.md +0 -2
  191. package/daemon/specs/agents/orchestration/orchestrator/agent.yaml +0 -1
  192. package/daemon/specs/agents/research/analyst/agent.yaml +0 -1
  193. package/daemon/specs/agents/research/synthesizer/agent.yaml +0 -1
  194. package/daemon/specs/agents/review/independent-reviewer/agent.yaml +0 -1
  195. package/daemon/specs/agents/shared/agent.yaml +6 -6
  196. package/daemon/specs/agents/shared/skills/core/openrig-architect/SKILL.md +361 -0
  197. package/daemon/specs/agents/shared/skills/core/openrig-installer/SKILL.md +142 -0
  198. package/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md +6 -1
  199. package/daemon/specs/agents/shared/skills/core/openrig-user-settings/SKILL.md +4 -4
  200. package/daemon/specs/agents/shared/skills/core/rig-lifecycle/SKILL.md +116 -0
  201. package/daemon/specs/agents/shared/skills/pods/development-team/SKILL.md +0 -1
  202. package/daemon/specs/agents/shared/skills/pods/orchestration-team/SKILL.md +2 -2
  203. package/daemon/specs/agents/shared/skills/process/agent-browser/LOCAL-INSIGHTS.md +6 -6
  204. package/daemon/specs/agents/shared/skills/process/agent-browser/OPENRIG.md +40 -0
  205. package/daemon/specs/agents/shared/skills/process/agent-browser/SKILL.md +10 -0
  206. package/daemon/specs/agents/shared/skills/process/brainstorming/OPENRIG.md +48 -0
  207. package/daemon/specs/agents/shared/skills/process/brainstorming/SKILL.md +11 -0
  208. package/daemon/specs/agents/shared/skills/process/dogfood/SKILL.md +5 -0
  209. package/daemon/specs/agents/shared/skills/process/executing-plans/OPENRIG.md +56 -0
  210. package/daemon/specs/agents/shared/skills/process/executing-plans/SKILL.md +10 -0
  211. package/daemon/specs/agents/shared/skills/process/frontend-design/SKILL.md +5 -0
  212. package/daemon/specs/agents/shared/skills/process/systematic-debugging/SKILL.md +5 -0
  213. package/daemon/specs/agents/shared/skills/process/test-driven-development/SKILL.md +5 -0
  214. package/daemon/specs/agents/shared/skills/process/using-superpowers/OPENRIG.md +48 -0
  215. package/daemon/specs/agents/shared/skills/process/using-superpowers/SKILL.md +11 -0
  216. package/daemon/specs/agents/shared/skills/process/verification-before-completion/SKILL.md +5 -0
  217. package/daemon/specs/agents/shared/skills/process/writing-plans/OPENRIG.md +52 -0
  218. package/daemon/specs/agents/shared/skills/process/writing-plans/SKILL.md +12 -2
  219. package/daemon/specs/rigs/launch/kernel/agents/advisor/lead/agent.yaml +35 -0
  220. package/daemon/specs/rigs/launch/kernel/agents/advisor/lead/guidance/role.md +50 -0
  221. package/daemon/specs/rigs/launch/kernel/agents/advisor/lead/startup/context.md +37 -0
  222. package/daemon/specs/rigs/launch/kernel/agents/operator/agent/agent.yaml +35 -0
  223. package/daemon/specs/rigs/launch/kernel/agents/operator/agent/guidance/role.md +49 -0
  224. package/daemon/specs/rigs/launch/kernel/agents/operator/agent/startup/context.md +63 -0
  225. package/daemon/specs/rigs/launch/kernel/agents/queue/worker/agent.yaml +35 -0
  226. package/daemon/specs/rigs/launch/kernel/agents/queue/worker/guidance/role.md +33 -0
  227. package/daemon/specs/rigs/launch/kernel/agents/queue/worker/startup/context.md +30 -0
  228. package/daemon/specs/rigs/launch/kernel/culture/CULTURE.md +69 -0
  229. package/daemon/specs/rigs/launch/kernel/rig-claude-only.yaml +59 -0
  230. package/daemon/specs/rigs/launch/kernel/rig-codex-only.yaml +59 -0
  231. package/daemon/specs/rigs/launch/kernel/rig.yaml +69 -0
  232. package/dist/commands/config-init-workspace.d.ts.map +1 -1
  233. package/dist/commands/config-init-workspace.js +253 -0
  234. package/dist/commands/config-init-workspace.js.map +1 -1
  235. package/dist/commands/config.d.ts.map +1 -1
  236. package/dist/commands/config.js +11 -3
  237. package/dist/commands/config.js.map +1 -1
  238. package/dist/commands/daemon.d.ts.map +1 -1
  239. package/dist/commands/daemon.js +53 -1
  240. package/dist/commands/daemon.js.map +1 -1
  241. package/dist/commands/heartbeat.d.ts.map +1 -1
  242. package/dist/commands/heartbeat.js +0 -5
  243. package/dist/commands/heartbeat.js.map +1 -1
  244. package/dist/commands/plugin.d.ts +4 -0
  245. package/dist/commands/plugin.d.ts.map +1 -0
  246. package/dist/commands/plugin.js +395 -0
  247. package/dist/commands/plugin.js.map +1 -0
  248. package/dist/commands/send.d.ts +8 -0
  249. package/dist/commands/send.d.ts.map +1 -1
  250. package/dist/commands/send.js +8 -0
  251. package/dist/commands/send.js.map +1 -1
  252. package/dist/commands/up.d.ts.map +1 -1
  253. package/dist/commands/up.js +13 -1
  254. package/dist/commands/up.js.map +1 -1
  255. package/dist/config-store.d.ts +18 -1
  256. package/dist/config-store.d.ts.map +1 -1
  257. package/dist/config-store.js +167 -4
  258. package/dist/config-store.js.map +1 -1
  259. package/dist/daemon-lifecycle.d.ts +20 -1
  260. package/dist/daemon-lifecycle.d.ts.map +1 -1
  261. package/dist/daemon-lifecycle.js +57 -7
  262. package/dist/daemon-lifecycle.js.map +1 -1
  263. package/dist/host-registry.d.ts +1 -1
  264. package/dist/host-registry.js +1 -1
  265. package/dist/index.d.ts +1 -0
  266. package/dist/index.d.ts.map +1 -1
  267. package/dist/index.js +2 -0
  268. package/dist/index.js.map +1 -1
  269. package/package.json +1 -1
  270. package/ui/dist/assets/index-C_Q5FczU.css +1 -0
  271. package/ui/dist/assets/index-Rl3ZBrUg.js +547 -0
  272. package/ui/dist/index.html +2 -2
  273. package/daemon/specs/agents/shared/skills/claude-compact-in-place/SKILL.md +0 -100
  274. package/daemon/specs/agents/shared/skills/process/containerized-e2e/SKILL.md +0 -256
  275. package/daemon/specs/agents/shared/skills/process/containerized-e2e/scripts/Dockerfile +0 -39
  276. package/daemon/specs/agents/shared/skills/process/containerized-e2e/scripts/build-e2e-image.sh +0 -37
  277. package/daemon/specs/agents/shared/skills/process/containerized-e2e/templates/control-plane-test.yaml +0 -40
  278. package/daemon/specs/agents/shared/skills/process/containerized-e2e/templates/e2e-report-template.md +0 -94
  279. package/daemon/specs/agents/shared/skills/process/containerized-e2e/templates/expansion-collision-fragment.yaml +0 -13
  280. package/daemon/specs/agents/shared/skills/process/containerized-e2e/templates/expansion-pod-fragment.yaml +0 -14
  281. package/ui/dist/assets/index-BDHU1JUK.js +0 -412
  282. package/ui/dist/assets/index-DXTyJSqu.css +0 -1
@@ -0,0 +1,433 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { spawnSync } from "node:child_process";
6
+
7
+ const TEXT_LIMIT = 4000;
8
+ const DEFAULT_OUT = "/tmp/claude-compaction-restore";
9
+
10
+ function parseArgs(argv) {
11
+ const args = {
12
+ jsonl: null,
13
+ out: DEFAULT_OUT,
14
+ cwd: process.cwd(),
15
+ json: false,
16
+ };
17
+
18
+ for (let i = 0; i < argv.length; i += 1) {
19
+ const arg = argv[i];
20
+ if (arg === "--jsonl") args.jsonl = argv[++i];
21
+ else if (arg === "--out") args.out = argv[++i];
22
+ else if (arg === "--cwd") args.cwd = argv[++i];
23
+ else if (arg === "--json") args.json = true;
24
+ else if (!arg.startsWith("-") && !args.jsonl) args.jsonl = arg;
25
+ else throw new Error(`unknown argument: ${arg}`);
26
+ }
27
+
28
+ return args;
29
+ }
30
+
31
+ function readJsonLines(file) {
32
+ const raw = fs.readFileSync(file, "utf8");
33
+ return raw
34
+ .split(/\r?\n/)
35
+ .filter(Boolean)
36
+ .map((line, index) => {
37
+ try {
38
+ return JSON.parse(line);
39
+ } catch (error) {
40
+ return { type: "parse-error", line: index + 1, error: String(error), raw: line };
41
+ }
42
+ });
43
+ }
44
+
45
+ function findLatestJsonl(cwd) {
46
+ const projectsRoot = path.join(os.homedir(), ".claude", "projects");
47
+ if (!fs.existsSync(projectsRoot)) return null;
48
+
49
+ const encoded = cwd ? cwd.replaceAll("/", "-") : null;
50
+ const candidates = [];
51
+ const roots = [];
52
+
53
+ if (encoded) {
54
+ const exact = path.join(projectsRoot, encoded);
55
+ if (fs.existsSync(exact)) roots.push(exact);
56
+ }
57
+ roots.push(projectsRoot);
58
+
59
+ for (const root of roots) {
60
+ const result = spawnSync("find", [root, "-name", "*.jsonl", "-maxdepth", root === projectsRoot ? "4" : "2"], {
61
+ encoding: "utf8",
62
+ });
63
+ if (result.status !== 0 && !result.stdout) continue;
64
+ for (const file of result.stdout.split(/\r?\n/).filter(Boolean)) {
65
+ try {
66
+ const stat = fs.statSync(file);
67
+ candidates.push({ file, mtimeMs: stat.mtimeMs });
68
+ } catch {
69
+ // Ignore raced/deleted transcript files.
70
+ }
71
+ }
72
+ if (candidates.length) break;
73
+ }
74
+
75
+ candidates.sort((a, b) => b.mtimeMs - a.mtimeMs);
76
+ return candidates[0]?.file ?? null;
77
+ }
78
+
79
+ function stringifyContent(content) {
80
+ if (typeof content === "string") return content;
81
+ if (Array.isArray(content)) {
82
+ return content
83
+ .map((block) => {
84
+ if (typeof block === "string") return block;
85
+ if (block?.type === "text") return block.text ?? "";
86
+ if (block?.type === "tool_use") return `[tool_use:${block.name}] ${JSON.stringify(block.input ?? {})}`;
87
+ if (block?.type === "tool_result") return `[tool_result] ${truncate(stringifyContent(block.content), TEXT_LIMIT)}`;
88
+ return JSON.stringify(block);
89
+ })
90
+ .join("\n");
91
+ }
92
+ if (content == null) return "";
93
+ return JSON.stringify(content);
94
+ }
95
+
96
+ function truncate(text, max) {
97
+ const s = String(text ?? "");
98
+ if (s.length <= max) return s;
99
+ return `${s.slice(0, max)}\n[...truncated ${s.length - max} chars...]`;
100
+ }
101
+
102
+ function walkStrings(value, acc = []) {
103
+ if (typeof value === "string") acc.push(value);
104
+ else if (Array.isArray(value)) value.forEach((item) => walkStrings(item, acc));
105
+ else if (value && typeof value === "object") Object.values(value).forEach((item) => walkStrings(item, acc));
106
+ return acc;
107
+ }
108
+
109
+ function normalizeFile(candidate, cwd) {
110
+ let file = candidate.trim().replace(/[),.;:'"`\]\}>]+$/g, "").replace(/^[('"`<\[]+/g, "");
111
+ if (!file || file.includes("\n")) return null;
112
+ if (/\.(?:md|mdx|txt|json|jsonl|yaml|yml|toml|ts|tsx|js|jsx|mjs|cjs|py|sh|rs|go|sql|css|scss|html|xml|svg|csv|log|lock)\//i.test(file)) return null;
113
+ if (file.startsWith("~")) file = path.join(os.homedir(), file.slice(1));
114
+ let normalized = null;
115
+ if (file.startsWith("/")) normalized = path.normalize(file);
116
+ else if (file.startsWith("./") || file.startsWith("../")) normalized = path.normalize(path.resolve(cwd, file));
117
+ else if (/^[A-Za-z0-9_@.+-][A-Za-z0-9_@.+/\-:]*\.[A-Za-z0-9]+$/.test(file)) {
118
+ normalized = path.normalize(path.resolve(cwd, file));
119
+ } else if (/^(CLAUDE|AGENTS|README|DESIGN|CULTURE|MEMORY)\.md$/.test(file)) {
120
+ normalized = path.normalize(path.resolve(cwd, file));
121
+ }
122
+
123
+ if (!normalized) return null;
124
+ try {
125
+ if (fs.existsSync(normalized) && fs.statSync(normalized).isDirectory()) return null;
126
+ } catch {
127
+ // Keep the candidate if stat races; the restore agent can decide.
128
+ }
129
+ return normalized;
130
+ }
131
+
132
+ function extractPaths(text, cwd) {
133
+ const paths = new Set();
134
+ const s = String(text ?? "");
135
+ const absolute = /(?:^|[\s"'(<\[])(\/(?:Users|private|tmp|var|opt|Volumes)\/[^\s"'()\]<>]+)/g;
136
+ const relative = /(?:^|[\s"'(<\[])((?:\.{1,2}\/)?[A-Za-z0-9_@.+-][A-Za-z0-9_@.+/\-:]*\.(?:md|mdx|txt|json|jsonl|yaml|yml|toml|ts|tsx|js|jsx|mjs|cjs|py|sh|rs|go|sql|css|scss|html|xml|svg|csv|log|lock))(?:$|[\s"')>\],.;:])/g;
137
+ const namedMarkdown = /(?:^|[\s"'(<\[])((?:CLAUDE|AGENTS|README|DESIGN|CULTURE|MEMORY)\.md)(?:$|[\s"')>\],.;:])/g;
138
+
139
+ for (const regex of [absolute, relative, namedMarkdown]) {
140
+ let match;
141
+ while ((match = regex.exec(s)) !== null) {
142
+ const normalized = normalizeFile(match[1], cwd);
143
+ if (normalized) paths.add(normalized);
144
+ }
145
+ }
146
+ return [...paths];
147
+ }
148
+
149
+ function createRegistry() {
150
+ const files = new Map();
151
+ let sequence = 0;
152
+
153
+ return {
154
+ add(file, kind, source) {
155
+ if (!file) return;
156
+ const existing = files.get(file) ?? {
157
+ path: file,
158
+ kinds: {},
159
+ sources: new Set(),
160
+ firstSeen: sequence,
161
+ lastSeen: sequence,
162
+ };
163
+ existing.kinds[kind] = (existing.kinds[kind] ?? 0) + 1;
164
+ existing.sources.add(source);
165
+ existing.lastSeen = sequence;
166
+ files.set(file, existing);
167
+ },
168
+ tick() {
169
+ sequence += 1;
170
+ },
171
+ values() {
172
+ return [...files.values()].map((entry) => ({
173
+ ...entry,
174
+ sources: [...entry.sources].slice(0, 8),
175
+ }));
176
+ },
177
+ };
178
+ }
179
+
180
+ function toolKind(name, input) {
181
+ if (["Write", "Edit", "MultiEdit", "NotebookEdit"].includes(name)) return "written";
182
+ if (name === "Read") return "read";
183
+ if (["Grep", "Glob", "LS"].includes(name)) return "discovered";
184
+ if (name === "Bash") {
185
+ const command = input?.command ?? "";
186
+ if (/\b(apply_patch|tee|touch|mkdir|mv|cp|rm)\b|(^|[^>])>{1,2}[^>]/.test(command)) return "shell-write";
187
+ return "shell-mentioned";
188
+ }
189
+ return "mentioned";
190
+ }
191
+
192
+ function scoreFile(entry) {
193
+ const ext = path.extname(entry.path).toLowerCase();
194
+ let score = 0;
195
+ if (entry.kinds.written) score += 40;
196
+ if (entry.kinds["shell-write"]) score += 30;
197
+ if (entry.kinds["file-history"]) score += 35;
198
+ if (ext === ".md" || ext === ".mdx") score += 20;
199
+ if (entry.kinds.read) score += 10;
200
+ if (entry.kinds.discovered) score += 4;
201
+ if (/\/docs\/as-built\//.test(entry.path)) score += 25;
202
+ if (/(codemap|architecture|CLAUDE|AGENTS|README|DESIGN|CULTURE|session\.log|queue\.md)/i.test(entry.path)) score += 15;
203
+ score += Math.min(10, Object.values(entry.kinds).reduce((a, b) => a + b, 0));
204
+ return score;
205
+ }
206
+
207
+ function discoverDocs(cwd) {
208
+ const candidates = [
209
+ "CLAUDE.md",
210
+ "AGENTS.md",
211
+ "README.md",
212
+ "docs/as-built",
213
+ "docs",
214
+ ];
215
+ const docs = new Set();
216
+
217
+ for (const candidate of candidates) {
218
+ const full = path.resolve(cwd, candidate);
219
+ if (!fs.existsSync(full)) continue;
220
+ const stat = fs.statSync(full);
221
+ if (stat.isFile()) docs.add(full);
222
+ if (stat.isDirectory()) {
223
+ const result = spawnSync("find", [full, "-maxdepth", candidate === "docs" ? "2" : "1", "-type", "f", "-name", "*.md"], {
224
+ encoding: "utf8",
225
+ });
226
+ for (const file of result.stdout.split(/\r?\n/).filter(Boolean)) {
227
+ if (/as-built|codemap|architecture|README|overview/i.test(file)) docs.add(path.normalize(file));
228
+ }
229
+ }
230
+ }
231
+
232
+ return [...docs].sort();
233
+ }
234
+
235
+ function analyze(jsonlPath, cwd) {
236
+ const records = readJsonLines(jsonlPath);
237
+ const registry = createRegistry();
238
+ const transcript = [];
239
+ const cwdCounts = new Map();
240
+ let sessionId = null;
241
+
242
+ for (const record of records) {
243
+ registry.tick();
244
+ if (record.sessionId || record.session_id) sessionId = record.sessionId ?? record.session_id;
245
+ if (record.cwd) {
246
+ cwdCounts.set(record.cwd, (cwdCounts.get(record.cwd) ?? 0) + 1);
247
+ cwd = record.cwd;
248
+ }
249
+
250
+ if (record.type === "file-history-snapshot") {
251
+ const backups = record.snapshot?.trackedFileBackups ?? {};
252
+ for (const file of Object.keys(backups)) registry.add(path.normalize(file), "file-history", "file-history-snapshot");
253
+ }
254
+
255
+ const message = record.message;
256
+ if (!message) continue;
257
+ const role = message.role ?? record.type ?? "unknown";
258
+ const content = message.content;
259
+
260
+ if (typeof content === "string") {
261
+ transcript.push(`\n## ${role}\n\n${content}`);
262
+ for (const file of extractPaths(content, cwd)) registry.add(file, "mentioned", `${role}:text`);
263
+ continue;
264
+ }
265
+
266
+ if (!Array.isArray(content)) continue;
267
+ const parts = [];
268
+ for (const block of content) {
269
+ if (block?.type === "text") {
270
+ parts.push(block.text ?? "");
271
+ for (const file of extractPaths(block.text ?? "", cwd)) registry.add(file, "mentioned", `${role}:text`);
272
+ } else if (block?.type === "tool_use") {
273
+ const name = block.name ?? "unknown";
274
+ const input = block.input ?? {};
275
+ parts.push(`\n[tool_use:${name}]\n${JSON.stringify(input, null, 2)}`);
276
+ const kind = toolKind(name, input);
277
+ if (input.file_path) registry.add(normalizeFile(input.file_path, cwd), kind, `tool:${name}:file_path`);
278
+ if (input.path) registry.add(normalizeFile(input.path, cwd), kind, `tool:${name}:path`);
279
+ if (input.notebook_path) registry.add(normalizeFile(input.notebook_path, cwd), kind, `tool:${name}:notebook_path`);
280
+ for (const text of walkStrings(input)) {
281
+ for (const file of extractPaths(text, cwd)) registry.add(file, kind, `tool:${name}:input`);
282
+ }
283
+ } else if (block?.type === "tool_result") {
284
+ const resultText = stringifyContent(block.content);
285
+ parts.push(`\n[tool_result]\n${truncate(resultText, TEXT_LIMIT)}`);
286
+ for (const file of extractPaths(resultText, cwd)) registry.add(file, "mentioned", "tool_result");
287
+ }
288
+ }
289
+ if (parts.length) transcript.push(`\n## ${role}\n\n${parts.join("\n")}`);
290
+ }
291
+
292
+ const rankedFiles = registry
293
+ .values()
294
+ .map((entry) => ({ ...entry, score: scoreFile(entry), markdown: [".md", ".mdx"].includes(path.extname(entry.path).toLowerCase()) }))
295
+ .sort((a, b) => b.score - a.score || a.path.localeCompare(b.path));
296
+
297
+ const cwdRanked = [...cwdCounts.entries()].sort((a, b) => b[1] - a[1]);
298
+ const effectiveCwd = cwdRanked[0]?.[0] ?? cwd;
299
+
300
+ return {
301
+ sessionId,
302
+ jsonlPath,
303
+ cwd: effectiveCwd,
304
+ records: records.length,
305
+ transcript: transcript.join("\n"),
306
+ files: rankedFiles,
307
+ docs: discoverDocs(effectiveCwd),
308
+ };
309
+ }
310
+
311
+ function markdownFileList(files) {
312
+ const lines = [];
313
+ lines.push("# Touched Files");
314
+ lines.push("");
315
+ lines.push("Files are ranked for restore relevance. Markdown and written files are the first candidates to read in full.");
316
+ lines.push("");
317
+
318
+ const sections = [
319
+ ["Highest-priority Markdown/state files", (f) => f.markdown && (f.kinds.written || f.kinds["shell-write"] || f.kinds["file-history"])],
320
+ ["Other written/tracked files", (f) => !f.markdown && (f.kinds.written || f.kinds["shell-write"] || f.kinds["file-history"])],
321
+ ["Read/discovered/mentioned files", (f) => !(f.kinds.written || f.kinds["shell-write"] || f.kinds["file-history"])],
322
+ ];
323
+
324
+ for (const [title, predicate] of sections) {
325
+ const group = files.filter(predicate);
326
+ if (!group.length) continue;
327
+ lines.push(`## ${title}`);
328
+ lines.push("");
329
+ for (const file of group) {
330
+ const kinds = Object.entries(file.kinds).map(([kind, count]) => `${kind}:${count}`).join(", ");
331
+ lines.push(`- score ${file.score} — \`${file.path}\` — ${kinds}`);
332
+ }
333
+ lines.push("");
334
+ }
335
+
336
+ return lines.join("\n");
337
+ }
338
+
339
+ function restoreInstructions(summary, outputPaths) {
340
+ const lines = [];
341
+ lines.push("# Claude Compaction Restore Instructions");
342
+ lines.push("");
343
+ lines.push("You have just been compacted or are restoring a compacted Claude Code seat. Your mental model is compressed and unreliable.");
344
+ lines.push("");
345
+ lines.push(`- JSONL transcript: \`${summary.jsonlPath}\``);
346
+ lines.push(`- Reconstructed transcript: \`${outputPaths.transcript}\``);
347
+ lines.push(`- Touched-file triage: \`${outputPaths.touchedFiles}\``);
348
+ lines.push(`- Working directory inferred: \`${summary.cwd}\``);
349
+ lines.push("");
350
+ lines.push("## Required Sequence");
351
+ lines.push("");
352
+ lines.push("1. Read this file and `touched-files.md`.");
353
+ lines.push("2. Ask yourself: which files do I recognize as important to the work and project state?");
354
+ lines.push("3. Mark those files mentally or in a short note.");
355
+ lines.push("4. Read every important Markdown/state/planning file in full.");
356
+ lines.push("5. Read project root docs in full when present: `CLAUDE.md`, `AGENTS.md`, `README.md`.");
357
+ lines.push("6. Read as-built docs and codemaps in full before product work, code review, or architecture decisions.");
358
+ lines.push("7. State exactly: `restored from packet at <path>; resumed at step <X>`.");
359
+ lines.push("");
360
+ lines.push("## Documentation Candidates");
361
+ lines.push("");
362
+ if (summary.docs.length) {
363
+ for (const doc of summary.docs) lines.push(`- \`${doc}\``);
364
+ } else {
365
+ lines.push("- No root/as-built/codemap candidates were found automatically. Search manually before resuming code/review work.");
366
+ }
367
+ lines.push("");
368
+ lines.push("## Top File Candidates");
369
+ lines.push("");
370
+ for (const file of summary.files.slice(0, 30)) {
371
+ lines.push(`- \`${file.path}\` — score ${file.score}`);
372
+ }
373
+ lines.push("");
374
+ lines.push("Do not continue from fuzzy memory alone.");
375
+ return lines.join("\n");
376
+ }
377
+
378
+ function writeOutputs(summary, outRoot) {
379
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
380
+ const base = path.join(outRoot, `${summary.sessionId ?? "unknown-session"}-${stamp}`);
381
+ fs.mkdirSync(base, { recursive: true });
382
+
383
+ const outputPaths = {
384
+ dir: base,
385
+ transcript: path.join(base, "transcript.txt"),
386
+ touchedFiles: path.join(base, "touched-files.md"),
387
+ instructions: path.join(base, "restore-instructions.md"),
388
+ summary: path.join(base, "restore-summary.json"),
389
+ };
390
+
391
+ fs.writeFileSync(outputPaths.transcript, summary.transcript || "(no message transcript reconstructed)\n");
392
+ fs.writeFileSync(outputPaths.touchedFiles, markdownFileList(summary.files));
393
+ fs.writeFileSync(outputPaths.instructions, restoreInstructions(summary, outputPaths));
394
+ fs.writeFileSync(outputPaths.summary, JSON.stringify({ ...summary, transcript: undefined, outputPaths }, null, 2));
395
+
396
+ return outputPaths;
397
+ }
398
+
399
+ function main() {
400
+ const args = parseArgs(process.argv.slice(2));
401
+ const cwd = path.resolve(args.cwd);
402
+ const jsonlPath = args.jsonl ? path.resolve(args.jsonl) : findLatestJsonl(cwd);
403
+ if (!jsonlPath) throw new Error("could not find a Claude JSONL transcript; pass one explicitly");
404
+ if (!fs.existsSync(jsonlPath)) throw new Error(`JSONL transcript not found: ${jsonlPath}`);
405
+
406
+ const summary = analyze(jsonlPath, cwd);
407
+ const outputPaths = writeOutputs(summary, path.resolve(args.out));
408
+ const result = {
409
+ ok: true,
410
+ jsonlPath,
411
+ outputDir: outputPaths.dir,
412
+ transcript: outputPaths.transcript,
413
+ touchedFiles: outputPaths.touchedFiles,
414
+ instructions: outputPaths.instructions,
415
+ fileCount: summary.files.length,
416
+ topFiles: summary.files.slice(0, 12).map((file) => file.path),
417
+ };
418
+
419
+ if (args.json) console.log(JSON.stringify(result, null, 2));
420
+ else {
421
+ console.log(`Restore packet: ${result.outputDir}`);
422
+ console.log(`Instructions: ${result.instructions}`);
423
+ console.log(`Touched files: ${result.touchedFiles}`);
424
+ console.log(`Transcript: ${result.transcript}`);
425
+ }
426
+ }
427
+
428
+ try {
429
+ main();
430
+ } catch (error) {
431
+ console.error(`claude-compaction-restore failed: ${error.message}`);
432
+ process.exit(1);
433
+ }
@@ -0,0 +1 @@
1
+ Optional. Leave blank to use Claude Code's native compaction summary behavior; OpenRig's pre-compaction preparation and post-compaction restore prompts carry the durable continuity protocol.
@@ -0,0 +1 @@
1
+ Read the claude-compaction-restore skill and follow its "If You Just Compacted" protocol.