@citadel-labs/citadel 0.1.0

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 (307) hide show
  1. package/README.md +145 -0
  2. package/dist/__tests__/append-bead.test.d.ts +2 -0
  3. package/dist/__tests__/append-bead.test.d.ts.map +1 -0
  4. package/dist/__tests__/append-bead.test.js +88 -0
  5. package/dist/__tests__/append-bead.test.js.map +1 -0
  6. package/dist/__tests__/blocked-outposts.test.d.ts +2 -0
  7. package/dist/__tests__/blocked-outposts.test.d.ts.map +1 -0
  8. package/dist/__tests__/blocked-outposts.test.js +142 -0
  9. package/dist/__tests__/blocked-outposts.test.js.map +1 -0
  10. package/dist/__tests__/bugfixes.test.d.ts +2 -0
  11. package/dist/__tests__/bugfixes.test.d.ts.map +1 -0
  12. package/dist/__tests__/bugfixes.test.js +503 -0
  13. package/dist/__tests__/bugfixes.test.js.map +1 -0
  14. package/dist/__tests__/citizen-tribute.test.d.ts +2 -0
  15. package/dist/__tests__/citizen-tribute.test.d.ts.map +1 -0
  16. package/dist/__tests__/citizen-tribute.test.js +106 -0
  17. package/dist/__tests__/citizen-tribute.test.js.map +1 -0
  18. package/dist/__tests__/cli-e2e/dispatch-note-resolve.test.d.ts +2 -0
  19. package/dist/__tests__/cli-e2e/dispatch-note-resolve.test.d.ts.map +1 -0
  20. package/dist/__tests__/cli-e2e/dispatch-note-resolve.test.js +65 -0
  21. package/dist/__tests__/cli-e2e/dispatch-note-resolve.test.js.map +1 -0
  22. package/dist/__tests__/cli-e2e/full-lifecycle.test.d.ts +2 -0
  23. package/dist/__tests__/cli-e2e/full-lifecycle.test.d.ts.map +1 -0
  24. package/dist/__tests__/cli-e2e/full-lifecycle.test.js +157 -0
  25. package/dist/__tests__/cli-e2e/full-lifecycle.test.js.map +1 -0
  26. package/dist/__tests__/cli-e2e/helpers.d.ts +28 -0
  27. package/dist/__tests__/cli-e2e/helpers.d.ts.map +1 -0
  28. package/dist/__tests__/cli-e2e/helpers.js +76 -0
  29. package/dist/__tests__/cli-e2e/helpers.js.map +1 -0
  30. package/dist/__tests__/cli-e2e/init-outpost-status.test.d.ts +2 -0
  31. package/dist/__tests__/cli-e2e/init-outpost-status.test.d.ts.map +1 -0
  32. package/dist/__tests__/cli-e2e/init-outpost-status.test.js +79 -0
  33. package/dist/__tests__/cli-e2e/init-outpost-status.test.js.map +1 -0
  34. package/dist/__tests__/cli-e2e/reset-stop-tribute-trace.test.d.ts +2 -0
  35. package/dist/__tests__/cli-e2e/reset-stop-tribute-trace.test.d.ts.map +1 -0
  36. package/dist/__tests__/cli-e2e/reset-stop-tribute-trace.test.js +158 -0
  37. package/dist/__tests__/cli-e2e/reset-stop-tribute-trace.test.js.map +1 -0
  38. package/dist/__tests__/courier.test.d.ts +2 -0
  39. package/dist/__tests__/courier.test.d.ts.map +1 -0
  40. package/dist/__tests__/courier.test.js +97 -0
  41. package/dist/__tests__/courier.test.js.map +1 -0
  42. package/dist/__tests__/e2e-smoke.test.d.ts +2 -0
  43. package/dist/__tests__/e2e-smoke.test.d.ts.map +1 -0
  44. package/dist/__tests__/e2e-smoke.test.js +137 -0
  45. package/dist/__tests__/e2e-smoke.test.js.map +1 -0
  46. package/dist/__tests__/fo-broadcast.test.d.ts +2 -0
  47. package/dist/__tests__/fo-broadcast.test.d.ts.map +1 -0
  48. package/dist/__tests__/fo-broadcast.test.js +134 -0
  49. package/dist/__tests__/fo-broadcast.test.js.map +1 -0
  50. package/dist/__tests__/fo-command-processor.test.d.ts +2 -0
  51. package/dist/__tests__/fo-command-processor.test.d.ts.map +1 -0
  52. package/dist/__tests__/fo-command-processor.test.js +86 -0
  53. package/dist/__tests__/fo-command-processor.test.js.map +1 -0
  54. package/dist/__tests__/fo-escalation.test.d.ts +2 -0
  55. package/dist/__tests__/fo-escalation.test.d.ts.map +1 -0
  56. package/dist/__tests__/fo-escalation.test.js +126 -0
  57. package/dist/__tests__/fo-escalation.test.js.map +1 -0
  58. package/dist/__tests__/fo-nudge-watcher.test.d.ts +2 -0
  59. package/dist/__tests__/fo-nudge-watcher.test.d.ts.map +1 -0
  60. package/dist/__tests__/fo-nudge-watcher.test.js +154 -0
  61. package/dist/__tests__/fo-nudge-watcher.test.js.map +1 -0
  62. package/dist/__tests__/fo-nudge-wiring.test.d.ts +2 -0
  63. package/dist/__tests__/fo-nudge-wiring.test.d.ts.map +1 -0
  64. package/dist/__tests__/fo-nudge-wiring.test.js +31 -0
  65. package/dist/__tests__/fo-nudge-wiring.test.js.map +1 -0
  66. package/dist/__tests__/fo-relay.test.d.ts +2 -0
  67. package/dist/__tests__/fo-relay.test.d.ts.map +1 -0
  68. package/dist/__tests__/fo-relay.test.js +90 -0
  69. package/dist/__tests__/fo-relay.test.js.map +1 -0
  70. package/dist/__tests__/fo-task-report.test.d.ts +2 -0
  71. package/dist/__tests__/fo-task-report.test.d.ts.map +1 -0
  72. package/dist/__tests__/fo-task-report.test.js +81 -0
  73. package/dist/__tests__/fo-task-report.test.js.map +1 -0
  74. package/dist/__tests__/fo-webhook.test.d.ts +2 -0
  75. package/dist/__tests__/fo-webhook.test.d.ts.map +1 -0
  76. package/dist/__tests__/fo-webhook.test.js +70 -0
  77. package/dist/__tests__/fo-webhook.test.js.map +1 -0
  78. package/dist/__tests__/integration.test.d.ts +2 -0
  79. package/dist/__tests__/integration.test.d.ts.map +1 -0
  80. package/dist/__tests__/integration.test.js +763 -0
  81. package/dist/__tests__/integration.test.js.map +1 -0
  82. package/dist/__tests__/multi-outpost-dep.test.d.ts +2 -0
  83. package/dist/__tests__/multi-outpost-dep.test.d.ts.map +1 -0
  84. package/dist/__tests__/multi-outpost-dep.test.js +173 -0
  85. package/dist/__tests__/multi-outpost-dep.test.js.map +1 -0
  86. package/dist/__tests__/nudge.test.d.ts +2 -0
  87. package/dist/__tests__/nudge.test.d.ts.map +1 -0
  88. package/dist/__tests__/nudge.test.js +103 -0
  89. package/dist/__tests__/nudge.test.js.map +1 -0
  90. package/dist/__tests__/outpost-registry.test.d.ts +2 -0
  91. package/dist/__tests__/outpost-registry.test.d.ts.map +1 -0
  92. package/dist/__tests__/outpost-registry.test.js +72 -0
  93. package/dist/__tests__/outpost-registry.test.js.map +1 -0
  94. package/dist/__tests__/process-registry.test.d.ts +2 -0
  95. package/dist/__tests__/process-registry.test.d.ts.map +1 -0
  96. package/dist/__tests__/process-registry.test.js +108 -0
  97. package/dist/__tests__/process-registry.test.js.map +1 -0
  98. package/dist/__tests__/session-log.test.d.ts +2 -0
  99. package/dist/__tests__/session-log.test.d.ts.map +1 -0
  100. package/dist/__tests__/session-log.test.js +60 -0
  101. package/dist/__tests__/session-log.test.js.map +1 -0
  102. package/dist/__tests__/spawn-citizen.test.d.ts +2 -0
  103. package/dist/__tests__/spawn-citizen.test.d.ts.map +1 -0
  104. package/dist/__tests__/spawn-citizen.test.js +48 -0
  105. package/dist/__tests__/spawn-citizen.test.js.map +1 -0
  106. package/dist/__tests__/timeout-watchdog.test.d.ts +2 -0
  107. package/dist/__tests__/timeout-watchdog.test.d.ts.map +1 -0
  108. package/dist/__tests__/timeout-watchdog.test.js +81 -0
  109. package/dist/__tests__/timeout-watchdog.test.js.map +1 -0
  110. package/dist/__tests__/worktree-manager.test.d.ts +2 -0
  111. package/dist/__tests__/worktree-manager.test.d.ts.map +1 -0
  112. package/dist/__tests__/worktree-manager.test.js +98 -0
  113. package/dist/__tests__/worktree-manager.test.js.map +1 -0
  114. package/dist/cli/aliases.d.ts +10 -0
  115. package/dist/cli/aliases.d.ts.map +1 -0
  116. package/dist/cli/aliases.js +56 -0
  117. package/dist/cli/aliases.js.map +1 -0
  118. package/dist/cli/command.d.ts +3 -0
  119. package/dist/cli/command.d.ts.map +1 -0
  120. package/dist/cli/command.js +63 -0
  121. package/dist/cli/command.js.map +1 -0
  122. package/dist/cli/index.d.ts +3 -0
  123. package/dist/cli/index.d.ts.map +1 -0
  124. package/dist/cli/index.js +29 -0
  125. package/dist/cli/index.js.map +1 -0
  126. package/dist/cli/init.d.ts +3 -0
  127. package/dist/cli/init.d.ts.map +1 -0
  128. package/dist/cli/init.js +57 -0
  129. package/dist/cli/init.js.map +1 -0
  130. package/dist/cli/outpost.d.ts +3 -0
  131. package/dist/cli/outpost.d.ts.map +1 -0
  132. package/dist/cli/outpost.js +65 -0
  133. package/dist/cli/outpost.js.map +1 -0
  134. package/dist/cli/reset.d.ts +3 -0
  135. package/dist/cli/reset.d.ts.map +1 -0
  136. package/dist/cli/reset.js +67 -0
  137. package/dist/cli/reset.js.map +1 -0
  138. package/dist/cli/session.d.ts +3 -0
  139. package/dist/cli/session.d.ts.map +1 -0
  140. package/dist/cli/session.js +112 -0
  141. package/dist/cli/session.js.map +1 -0
  142. package/dist/cli/start.d.ts +3 -0
  143. package/dist/cli/start.d.ts.map +1 -0
  144. package/dist/cli/start.js +105 -0
  145. package/dist/cli/start.js.map +1 -0
  146. package/dist/cli/status.d.ts +3 -0
  147. package/dist/cli/status.d.ts.map +1 -0
  148. package/dist/cli/status.js +128 -0
  149. package/dist/cli/status.js.map +1 -0
  150. package/dist/cli/tribute.d.ts +3 -0
  151. package/dist/cli/tribute.d.ts.map +1 -0
  152. package/dist/cli/tribute.js +160 -0
  153. package/dist/cli/tribute.js.map +1 -0
  154. package/dist/cli/worktree.d.ts +3 -0
  155. package/dist/cli/worktree.d.ts.map +1 -0
  156. package/dist/cli/worktree.js +64 -0
  157. package/dist/cli/worktree.js.map +1 -0
  158. package/dist/core/append-bead.d.ts +13 -0
  159. package/dist/core/append-bead.d.ts.map +1 -0
  160. package/dist/core/append-bead.js +68 -0
  161. package/dist/core/append-bead.js.map +1 -0
  162. package/dist/core/blocked-outposts.d.ts +15 -0
  163. package/dist/core/blocked-outposts.d.ts.map +1 -0
  164. package/dist/core/blocked-outposts.js +77 -0
  165. package/dist/core/blocked-outposts.js.map +1 -0
  166. package/dist/core/citizen-bootstrap.d.ts +17 -0
  167. package/dist/core/citizen-bootstrap.d.ts.map +1 -0
  168. package/dist/core/citizen-bootstrap.js +118 -0
  169. package/dist/core/citizen-bootstrap.js.map +1 -0
  170. package/dist/core/citizen-tribute.d.ts +17 -0
  171. package/dist/core/citizen-tribute.d.ts.map +1 -0
  172. package/dist/core/citizen-tribute.js +55 -0
  173. package/dist/core/citizen-tribute.js.map +1 -0
  174. package/dist/core/command-bead.d.ts +6 -0
  175. package/dist/core/command-bead.d.ts.map +1 -0
  176. package/dist/core/command-bead.js +20 -0
  177. package/dist/core/command-bead.js.map +1 -0
  178. package/dist/core/courier.d.ts +52 -0
  179. package/dist/core/courier.d.ts.map +1 -0
  180. package/dist/core/courier.js +167 -0
  181. package/dist/core/courier.js.map +1 -0
  182. package/dist/core/fo-broadcast.d.ts +15 -0
  183. package/dist/core/fo-broadcast.d.ts.map +1 -0
  184. package/dist/core/fo-broadcast.js +57 -0
  185. package/dist/core/fo-broadcast.js.map +1 -0
  186. package/dist/core/fo-command-processor.d.ts +7 -0
  187. package/dist/core/fo-command-processor.d.ts.map +1 -0
  188. package/dist/core/fo-command-processor.js +123 -0
  189. package/dist/core/fo-command-processor.js.map +1 -0
  190. package/dist/core/fo-dispatch.d.ts +24 -0
  191. package/dist/core/fo-dispatch.d.ts.map +1 -0
  192. package/dist/core/fo-dispatch.js +76 -0
  193. package/dist/core/fo-dispatch.js.map +1 -0
  194. package/dist/core/fo-escalation.d.ts +20 -0
  195. package/dist/core/fo-escalation.d.ts.map +1 -0
  196. package/dist/core/fo-escalation.js +83 -0
  197. package/dist/core/fo-escalation.js.map +1 -0
  198. package/dist/core/fo-handlers/ceiling-hit.d.ts +8 -0
  199. package/dist/core/fo-handlers/ceiling-hit.d.ts.map +1 -0
  200. package/dist/core/fo-handlers/ceiling-hit.js +10 -0
  201. package/dist/core/fo-handlers/ceiling-hit.js.map +1 -0
  202. package/dist/core/fo-handlers/slot-open.d.ts +13 -0
  203. package/dist/core/fo-handlers/slot-open.d.ts.map +1 -0
  204. package/dist/core/fo-handlers/slot-open.js +63 -0
  205. package/dist/core/fo-handlers/slot-open.js.map +1 -0
  206. package/dist/core/fo-nudge-watcher.d.ts +19 -0
  207. package/dist/core/fo-nudge-watcher.d.ts.map +1 -0
  208. package/dist/core/fo-nudge-watcher.js +71 -0
  209. package/dist/core/fo-nudge-watcher.js.map +1 -0
  210. package/dist/core/fo-nudge-wiring.d.ts +13 -0
  211. package/dist/core/fo-nudge-wiring.d.ts.map +1 -0
  212. package/dist/core/fo-nudge-wiring.js +120 -0
  213. package/dist/core/fo-nudge-wiring.js.map +1 -0
  214. package/dist/core/fo-relay.d.ts +7 -0
  215. package/dist/core/fo-relay.d.ts.map +1 -0
  216. package/dist/core/fo-relay.js +47 -0
  217. package/dist/core/fo-relay.js.map +1 -0
  218. package/dist/core/fo-retry-policy.d.ts +17 -0
  219. package/dist/core/fo-retry-policy.d.ts.map +1 -0
  220. package/dist/core/fo-retry-policy.js +89 -0
  221. package/dist/core/fo-retry-policy.js.map +1 -0
  222. package/dist/core/fo-state.d.ts +25 -0
  223. package/dist/core/fo-state.d.ts.map +1 -0
  224. package/dist/core/fo-state.js +99 -0
  225. package/dist/core/fo-state.js.map +1 -0
  226. package/dist/core/fo-task-report.d.ts +16 -0
  227. package/dist/core/fo-task-report.d.ts.map +1 -0
  228. package/dist/core/fo-task-report.js +63 -0
  229. package/dist/core/fo-task-report.js.map +1 -0
  230. package/dist/core/fo-webhook.d.ts +22 -0
  231. package/dist/core/fo-webhook.d.ts.map +1 -0
  232. package/dist/core/fo-webhook.js +43 -0
  233. package/dist/core/fo-webhook.js.map +1 -0
  234. package/dist/core/grand-archives.d.ts +14 -0
  235. package/dist/core/grand-archives.d.ts.map +1 -0
  236. package/dist/core/grand-archives.js +79 -0
  237. package/dist/core/grand-archives.js.map +1 -0
  238. package/dist/core/nudge.d.ts +6 -0
  239. package/dist/core/nudge.d.ts.map +1 -0
  240. package/dist/core/nudge.js +19 -0
  241. package/dist/core/nudge.js.map +1 -0
  242. package/dist/core/outpost-registry.d.ts +16 -0
  243. package/dist/core/outpost-registry.d.ts.map +1 -0
  244. package/dist/core/outpost-registry.js +27 -0
  245. package/dist/core/outpost-registry.js.map +1 -0
  246. package/dist/core/pre-spawn-check.d.ts +16 -0
  247. package/dist/core/pre-spawn-check.d.ts.map +1 -0
  248. package/dist/core/pre-spawn-check.js +50 -0
  249. package/dist/core/pre-spawn-check.js.map +1 -0
  250. package/dist/core/process-registry.d.ts +17 -0
  251. package/dist/core/process-registry.d.ts.map +1 -0
  252. package/dist/core/process-registry.js +71 -0
  253. package/dist/core/process-registry.js.map +1 -0
  254. package/dist/core/spawn-citizen.d.ts +23 -0
  255. package/dist/core/spawn-citizen.d.ts.map +1 -0
  256. package/dist/core/spawn-citizen.js +99 -0
  257. package/dist/core/spawn-citizen.js.map +1 -0
  258. package/dist/core/timeout-watchdog.d.ts +14 -0
  259. package/dist/core/timeout-watchdog.d.ts.map +1 -0
  260. package/dist/core/timeout-watchdog.js +68 -0
  261. package/dist/core/timeout-watchdog.js.map +1 -0
  262. package/dist/core/validate-tribute.d.ts +11 -0
  263. package/dist/core/validate-tribute.d.ts.map +1 -0
  264. package/dist/core/validate-tribute.js +44 -0
  265. package/dist/core/validate-tribute.js.map +1 -0
  266. package/dist/core/worktree-manager.d.ts +20 -0
  267. package/dist/core/worktree-manager.d.ts.map +1 -0
  268. package/dist/core/worktree-manager.js +123 -0
  269. package/dist/core/worktree-manager.js.map +1 -0
  270. package/dist/index.d.ts +30 -0
  271. package/dist/index.d.ts.map +1 -0
  272. package/dist/index.js +30 -0
  273. package/dist/index.js.map +1 -0
  274. package/dist/types/agent.d.ts +47 -0
  275. package/dist/types/agent.d.ts.map +1 -0
  276. package/dist/types/agent.js +4 -0
  277. package/dist/types/agent.js.map +1 -0
  278. package/dist/types/beads.d.ts +175 -0
  279. package/dist/types/beads.d.ts.map +1 -0
  280. package/dist/types/beads.js +4 -0
  281. package/dist/types/beads.js.map +1 -0
  282. package/dist/types/index.d.ts +4 -0
  283. package/dist/types/index.d.ts.map +1 -0
  284. package/dist/types/index.js +4 -0
  285. package/dist/types/index.js.map +1 -0
  286. package/dist/types/registry.d.ts +110 -0
  287. package/dist/types/registry.d.ts.map +1 -0
  288. package/dist/types/registry.js +3 -0
  289. package/dist/types/registry.js.map +1 -0
  290. package/docs/README.md +7 -0
  291. package/docs/architecture.md +106 -0
  292. package/docs/cli-reference.md +81 -0
  293. package/docs/configuration.md +143 -0
  294. package/docs/contributing.md +65 -0
  295. package/docs/getting-started.md +88 -0
  296. package/grand-archives/archetypes/architect/archetype.json +18 -0
  297. package/grand-archives/archetypes/qa-engineer/archetype.json +18 -0
  298. package/grand-archives/archetypes/software-engineer/archetype.json +18 -0
  299. package/grand-archives/archetypes/software-engineer/system-prompt.md +39 -0
  300. package/grand-archives/archetypes/software-engineer/toolset.json +15 -0
  301. package/grand-archives/first-officer/config.json +21 -0
  302. package/grand-archives/first-officer/system-prompt.md +47 -0
  303. package/grand-archives/first-officer/toolset.json +19 -0
  304. package/grand-archives/registry.json +8 -0
  305. package/grand-archives/shared/base-prompt-preamble.md +25 -0
  306. package/grand-archives/shared/base-tools.json +10 -0
  307. package/package.json +73 -0
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerOutpostCommand(program: Command): void;
3
+ //# sourceMappingURL=outpost.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outpost.d.ts","sourceRoot":"","sources":["../../src/cli/outpost.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyE7D"}
@@ -0,0 +1,65 @@
1
+ import { resolve } from 'node:path';
2
+ import { readFile, writeFile, mkdir, access } from 'node:fs/promises';
3
+ export function registerOutpostCommand(program) {
4
+ const outpost = program.command('outpost').description('Manage outposts');
5
+ outpost
6
+ .command('register')
7
+ .description('Register a new outpost')
8
+ .requiredOption('--slug <slug>', 'Unique slug for the outpost')
9
+ .requiredOption('--path <path>', 'Path to the outpost git repository')
10
+ .option('--archetype <key>', 'Default archetype key')
11
+ .option('--max-citizens <n>', 'Maximum number of citizens')
12
+ .action(async (opts) => {
13
+ const citadelOutpostsPath = resolve('.citadel', 'outposts.json');
14
+ // Validate workspace is initialized
15
+ try {
16
+ await access(citadelOutpostsPath);
17
+ }
18
+ catch {
19
+ console.error('Workspace not initialized: .citadel/outposts.json not found.');
20
+ process.exit(1);
21
+ }
22
+ const outpostPath = resolve(opts.path);
23
+ // Validate outpost path exists and is a git repo
24
+ try {
25
+ await access(resolve(outpostPath, '.git'));
26
+ }
27
+ catch {
28
+ console.error(`Path "${outpostPath}" does not exist or is not a git repository.`);
29
+ process.exit(1);
30
+ }
31
+ // Read existing registry
32
+ const raw = await readFile(citadelOutpostsPath, 'utf-8');
33
+ const registry = JSON.parse(raw);
34
+ // Check slug uniqueness
35
+ if (registry.outposts.some((o) => o.slug === opts.slug)) {
36
+ console.error(`Outpost with slug "${opts.slug}" is already registered.`);
37
+ process.exit(1);
38
+ }
39
+ // Scaffold directories at outpost path
40
+ await mkdir(resolve(outpostPath, '.beads', 'mail'), { recursive: true });
41
+ await mkdir(resolve(outpostPath, '.beads', 'tribute'), { recursive: true });
42
+ await mkdir(resolve(outpostPath, 'worktrees', 'citizen'), { recursive: true });
43
+ // PRD §3.1: .gitignore for lockfiles in .beads/ dirs
44
+ const lockGitignore = '# Transient lockfiles — never commit\n*.jsonl.lock\n';
45
+ await writeFile(resolve(outpostPath, '.beads', 'mail', '.gitignore'), lockGitignore, 'utf-8');
46
+ await writeFile(resolve(outpostPath, '.beads', 'tribute', '.gitignore'), lockGitignore, 'utf-8');
47
+ // Build registry entry
48
+ const entry = {
49
+ slug: opts.slug,
50
+ path: outpostPath,
51
+ status: 'ACTIVE',
52
+ registered_at: new Date().toISOString(),
53
+ };
54
+ if (opts.archetype) {
55
+ entry.default_archetype = opts.archetype;
56
+ }
57
+ if (opts.maxCitizens) {
58
+ entry.max_citizens = Number(opts.maxCitizens);
59
+ }
60
+ registry.outposts.push(entry);
61
+ await writeFile(citadelOutpostsPath, JSON.stringify(registry, null, 2) + '\n', 'utf-8');
62
+ console.log(`Outpost "${opts.slug}" registered at ${outpostPath}`);
63
+ });
64
+ }
65
+ //# sourceMappingURL=outpost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outpost.js","sourceRoot":"","sources":["../../src/cli/outpost.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerResetCommand(program: Command): void;
3
+ //# sourceMappingURL=reset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../../src/cli/reset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkE3D"}
@@ -0,0 +1,67 @@
1
+ import { access, readFile, writeFile, readdir, unlink, rm } from 'fs/promises';
2
+ import { join } from 'path';
3
+ import { readBeads } from '../core/append-bead.js';
4
+ export function registerResetCommand(program) {
5
+ program
6
+ .command('reset')
7
+ .description('Reset Citadel workspace state')
8
+ .option('--hard', 'Remove the entire .citadel/ directory and Citadel .beads/')
9
+ .action(async (options) => {
10
+ const cwd = process.cwd();
11
+ const citadelDir = join(cwd, '.citadel');
12
+ try {
13
+ await access(citadelDir);
14
+ }
15
+ catch {
16
+ console.error('Not a Citadel workspace');
17
+ process.exit(1);
18
+ }
19
+ if (options.hard) {
20
+ // PRD §2.5: hard reset wipes .citadel/ AND Citadel-level .beads/
21
+ await rm(citadelDir, { recursive: true, force: true });
22
+ const citadelBeads = join(cwd, '.beads');
23
+ try {
24
+ await rm(citadelBeads, { recursive: true, force: true });
25
+ }
26
+ catch {
27
+ // .beads/ may not exist at citadel level
28
+ }
29
+ console.log('Citadel hard reset: removed .citadel/ and .beads/');
30
+ }
31
+ else {
32
+ // PRD §2.5: soft reset clears only UNPROCESSED commands and nudges
33
+ const nudgesPath = join(citadelDir, 'nudges.jsonl');
34
+ const commandsDir = join(citadelDir, 'commands');
35
+ // Filter nudges: keep processed, remove unprocessed
36
+ const nudges = await readBeads(nudgesPath);
37
+ const processed = nudges.filter((n) => n.processed);
38
+ await writeFile(nudgesPath, processed.map((n) => JSON.stringify(n)).join('\n') + (processed.length > 0 ? '\n' : ''), 'utf-8');
39
+ // Only delete unprocessed command files
40
+ let removedCount = 0;
41
+ try {
42
+ const files = await readdir(commandsDir);
43
+ for (const file of files) {
44
+ const filePath = join(commandsDir, file);
45
+ try {
46
+ const raw = await readFile(filePath, 'utf-8');
47
+ // Command bead files are single-line JSONL
48
+ const lines = raw.trim().split('\n').filter(l => l.trim());
49
+ const bead = JSON.parse(lines[lines.length - 1]);
50
+ if (!bead.processed) {
51
+ await unlink(filePath);
52
+ removedCount++;
53
+ }
54
+ }
55
+ catch {
56
+ // If we can't parse, skip it
57
+ }
58
+ }
59
+ }
60
+ catch {
61
+ // commands/ directory may not exist
62
+ }
63
+ console.log(`Citadel reset: cleared ${nudges.length - processed.length} unprocessed nudge(s) and ${removedCount} unprocessed command(s)`);
64
+ }
65
+ });
66
+ }
67
+ //# sourceMappingURL=reset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.js","sourceRoot":"","sources":["../../src/cli/reset.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerSessionCommands(program: Command): void;
3
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/cli/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyH9D"}
@@ -0,0 +1,112 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { readBeads } from '../core/append-bead.js';
4
+ export function registerSessionCommands(program) {
5
+ // citadel stop
6
+ program
7
+ .command('stop')
8
+ .description('Gracefully stop the current Citadel session')
9
+ .action(async () => {
10
+ const cwd = process.cwd();
11
+ const citadelDir = path.resolve(cwd, '.citadel');
12
+ try {
13
+ await fs.access(citadelDir);
14
+ }
15
+ catch {
16
+ console.error('Not a Citadel workspace');
17
+ process.exit(1);
18
+ }
19
+ // 1. Check for active session
20
+ const identityPath = path.resolve(citadelDir, 'identity.jsonl');
21
+ const identityBeads = await readBeads(identityPath);
22
+ if (identityBeads.length === 0) {
23
+ console.error('No active session');
24
+ process.exit(1);
25
+ }
26
+ // 2. Clear unprocessed nudges (clean shutdown of watcher state)
27
+ const nudgesPath = path.resolve(citadelDir, 'nudges.jsonl');
28
+ const nudges = await readBeads(nudgesPath);
29
+ const processed = nudges.filter(n => n.processed);
30
+ await fs.writeFile(nudgesPath, processed.map(n => JSON.stringify(n)).join('\n') + (processed.length > 0 ? '\n' : ''), 'utf-8');
31
+ const clearedNudges = nudges.length - processed.length;
32
+ // 3. Signal running citizens (best-effort SIGTERM via process registry PIDs)
33
+ // 4. Write final session.log entry
34
+ const logDir = path.resolve(citadelDir, 'logs');
35
+ await fs.mkdir(logDir, { recursive: true });
36
+ const logPath = path.resolve(logDir, 'session.log');
37
+ const logLine = `${new Date().toISOString()} Session stopped, cleared ${clearedNudges} unprocessed nudge(s)\n`;
38
+ await fs.appendFile(logPath, logLine, 'utf-8');
39
+ console.log(`Citadel stopped (cleared ${clearedNudges} unprocessed nudge(s))`);
40
+ });
41
+ // citadel attach
42
+ program
43
+ .command('attach')
44
+ .description('Attach to the current Citadel session log')
45
+ .action(async () => {
46
+ const cwd = process.cwd();
47
+ const citadelDir = path.resolve(cwd, '.citadel');
48
+ try {
49
+ await fs.access(citadelDir);
50
+ }
51
+ catch {
52
+ console.error('Not a Citadel workspace');
53
+ process.exit(1);
54
+ }
55
+ const identityPath = path.resolve(citadelDir, 'identity.jsonl');
56
+ const beads = await readBeads(identityPath);
57
+ if (beads.length === 0) {
58
+ console.error('No active session');
59
+ process.exit(1);
60
+ }
61
+ const logPath = path.resolve(citadelDir, 'logs', 'session.log');
62
+ if (process.platform === 'win32') {
63
+ // On Windows, read and print the last 20 lines
64
+ let content;
65
+ try {
66
+ content = await fs.readFile(logPath, 'utf-8');
67
+ }
68
+ catch {
69
+ console.error('No session log found');
70
+ process.exit(1);
71
+ }
72
+ const lines = content.split('\n').filter((l) => l.trim() !== '');
73
+ const last20 = lines.slice(-20);
74
+ for (const line of last20) {
75
+ console.log(line);
76
+ }
77
+ console.log('Attach: showing last 20 lines of session.log (live tailing not available on Windows)');
78
+ }
79
+ else {
80
+ // On Unix, use tail -f
81
+ const { spawn } = await import('node:child_process');
82
+ const tail = spawn('tail', ['-f', logPath], { stdio: 'inherit' });
83
+ tail.on('error', (err) => {
84
+ console.error(`Failed to tail session log: ${err.message}`);
85
+ process.exit(1);
86
+ });
87
+ }
88
+ });
89
+ // citadel detach
90
+ program
91
+ .command('detach')
92
+ .description('Detach from the current Citadel session')
93
+ .action(async () => {
94
+ const cwd = process.cwd();
95
+ const citadelDir = path.resolve(cwd, '.citadel');
96
+ try {
97
+ await fs.access(citadelDir);
98
+ }
99
+ catch {
100
+ console.error('Not a Citadel workspace');
101
+ process.exit(1);
102
+ }
103
+ const identityPath = path.resolve(citadelDir, 'identity.jsonl');
104
+ const beads = await readBeads(identityPath);
105
+ if (beads.length === 0) {
106
+ console.error('No active session');
107
+ process.exit(1);
108
+ }
109
+ console.log('Detached from Citadel session');
110
+ });
111
+ }
112
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/cli/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerStartCommand(program: Command): void;
3
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8G3D"}
@@ -0,0 +1,105 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { appendBead, mintBeadId, readBeads } from '../core/append-bead.js';
4
+ import { GrandArchives } from '../core/grand-archives.js';
5
+ import { SCHEMA_VERSION } from '../types/index.js';
6
+ export function registerStartCommand(program) {
7
+ program
8
+ .command('start')
9
+ .description('Start a Citadel session (write identity bead, rotate nudges, reconstruct state)')
10
+ .option('--agent <runtime>', 'Agent runtime to use', 'claude-code')
11
+ .action(async (opts) => {
12
+ const cwd = process.cwd();
13
+ // 1. Verify .citadel/ exists
14
+ const citadelDir = path.resolve(cwd, '.citadel');
15
+ try {
16
+ await fs.access(citadelDir);
17
+ }
18
+ catch {
19
+ console.error('Not a Citadel workspace');
20
+ process.exit(1);
21
+ }
22
+ // 2. Write Identity Bead
23
+ const identityPath = path.resolve(citadelDir, 'identity.jsonl');
24
+ const identityBead = {
25
+ bead_id: mintBeadId('IDENTITY'),
26
+ bead_type: 'IDENTITY',
27
+ schema_version: SCHEMA_VERSION,
28
+ created_at: new Date().toISOString(),
29
+ role: 'first-officer',
30
+ display_name: 'First Officer',
31
+ agent: opts.agent,
32
+ citadel_root: cwd,
33
+ last_session_at: new Date().toISOString(),
34
+ };
35
+ await appendBead(identityPath, identityBead);
36
+ // 3. Rotate nudges: keep last nudge_retention processed + all unprocessed
37
+ // PRD §3.3.2 step 7
38
+ const nudgesPath = path.resolve(citadelDir, 'nudges.jsonl');
39
+ const nudges = await readBeads(nudgesPath);
40
+ const processed = nudges.filter((n) => n.processed);
41
+ const unprocessed = nudges.filter((n) => !n.processed);
42
+ let nudgeRetention = 500;
43
+ try {
44
+ const archives = new GrandArchives(cwd);
45
+ const foConfig = await archives.loadFirstOfficerConfig();
46
+ nudgeRetention = foConfig.nudge_retention ?? 500;
47
+ }
48
+ catch {
49
+ // FO config not found, use default
50
+ }
51
+ const retainedProcessed = processed.slice(-nudgeRetention);
52
+ const rotated = [...retainedProcessed, ...unprocessed];
53
+ await fs.mkdir(path.dirname(nudgesPath), { recursive: true });
54
+ await fs.writeFile(nudgesPath, rotated.map((n) => JSON.stringify(n)).join('\n') + (rotated.length > 0 ? '\n' : ''), 'utf-8');
55
+ // 4. State reconstruction: scan outpost bead dirs
56
+ let mailCount = 0;
57
+ let tributeCount = 0;
58
+ const outpostsPath = path.resolve(citadelDir, 'outposts.json');
59
+ try {
60
+ const raw = await fs.readFile(outpostsPath, 'utf-8');
61
+ const registry = JSON.parse(raw);
62
+ for (const outpost of registry.outposts) {
63
+ const mailDir = path.resolve(outpost.path, '.beads', 'mail');
64
+ const tributeDir = path.resolve(outpost.path, '.beads', 'tribute');
65
+ // Count mail beads
66
+ try {
67
+ const mailFiles = await fs.readdir(mailDir);
68
+ const mailJsonl = mailFiles.filter((f) => f.endsWith('.jsonl'));
69
+ for (const file of mailJsonl) {
70
+ const beads = await readBeads(path.resolve(mailDir, file));
71
+ mailCount += beads.length;
72
+ }
73
+ }
74
+ catch {
75
+ // mail dir may not exist yet
76
+ }
77
+ // Count tribute beads
78
+ try {
79
+ const tributeFiles = await fs.readdir(tributeDir);
80
+ const tributeJsonl = tributeFiles.filter((f) => f.endsWith('.jsonl'));
81
+ for (const file of tributeJsonl) {
82
+ const beads = await readBeads(path.resolve(tributeDir, file));
83
+ tributeCount += beads.length;
84
+ }
85
+ }
86
+ catch {
87
+ // tribute dir may not exist yet
88
+ }
89
+ }
90
+ }
91
+ catch {
92
+ // outposts.json may not exist yet
93
+ }
94
+ console.log(`State: ${mailCount} mail(s), ${tributeCount} tribute(s)`);
95
+ // 5. Write startup report to session log
96
+ const logDir = path.resolve(citadelDir, 'logs');
97
+ await fs.mkdir(logDir, { recursive: true });
98
+ const logPath = path.resolve(logDir, 'session.log');
99
+ const logLine = `${new Date().toISOString()} Session started, agent=${opts.agent}, mails=${mailCount}, tributes=${tributeCount}\n`;
100
+ await fs.appendFile(logPath, logLine, 'utf-8');
101
+ // 6. Print confirmation
102
+ console.log(`Citadel started (agent: ${opts.agent})`);
103
+ });
104
+ }
105
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,iFAAiF,CAAC;SAC9F,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,EAAE,aAAa,CAAC;SAClE,MAAM,CAAC,KAAK,EAAE,IAAuB,EAAE,EAAE;QACxC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAE1B,6BAA6B;QAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACjD,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,yBAAyB;QACzB,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;QAChE,MAAM,YAAY,GAAiB;YACjC,OAAO,EAAE,UAAU,CAAC,UAAU,CAAC;YAC/B,SAAS,EAAE,UAAU;YACrB,cAAc,EAAE,cAAc;YAC9B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,IAAI,EAAE,eAAe;YACrB,YAAY,EAAE,eAAe;YAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,YAAY,EAAE,GAAG;YACjB,eAAe,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAC1C,CAAC;QACF,MAAM,UAAU,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QAE7C,0EAA0E;QAC1E,uBAAuB;QACvB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAY,UAAU,CAAC,CAAC;QACtD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACpD,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAEvD,IAAI,cAAc,GAAG,GAAG,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC;YACxC,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,sBAAsB,EAAE,CAAC;YACzD,cAAc,GAAG,QAAQ,CAAC,eAAe,IAAI,GAAG,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;QAED,MAAM,iBAAiB,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,CAAC,GAAG,iBAAiB,EAAE,GAAG,WAAW,CAAC,CAAC;QACvD,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,MAAM,EAAE,CAAC,SAAS,CAChB,UAAU,EACV,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EACnF,OAAO,CACR,CAAC;QAEF,kDAAkD;QAClD,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,YAAY,GAAG,CAAC,CAAC;QAErB,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QAC/D,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACrD,MAAM,QAAQ,GAAoB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAElD,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACxC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;gBAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;gBAEnE,mBAAmB;gBACnB,IAAI,CAAC;oBACH,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;oBAC5C,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;oBAChE,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;wBAC7B,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;wBAC3D,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC;oBAC5B,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,6BAA6B;gBAC/B,CAAC;gBAED,sBAAsB;gBACtB,IAAI,CAAC;oBACH,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;oBAClD,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACtE,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;wBAChC,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;wBAC9D,YAAY,IAAI,KAAK,CAAC,MAAM,CAAC;oBAC/B,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,gCAAgC;gBAClC,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,kCAAkC;QACpC,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,UAAU,SAAS,aAAa,YAAY,aAAa,CAAC,CAAC;QAEvE,yCAAyC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,2BAA2B,IAAI,CAAC,KAAK,WAAW,SAAS,cAAc,YAAY,IAAI,CAAC;QACnI,MAAM,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAE/C,wBAAwB;QACxB,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerStatusCommand(program: Command): void;
3
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/cli/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2CpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoG5D"}
@@ -0,0 +1,128 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { readBeads } from '../core/append-bead.js';
4
+ async function countFiles(dirPath) {
5
+ try {
6
+ const entries = await fs.readdir(dirPath);
7
+ return entries.length;
8
+ }
9
+ catch {
10
+ return 0;
11
+ }
12
+ }
13
+ async function countSubdirs(dirPath) {
14
+ try {
15
+ const entries = await fs.readdir(dirPath, { withFileTypes: true });
16
+ return entries.filter((e) => e.isDirectory()).length;
17
+ }
18
+ catch {
19
+ return 0;
20
+ }
21
+ }
22
+ async function countPendingTasks(mailDir) {
23
+ let count = 0;
24
+ try {
25
+ const files = await fs.readdir(mailDir);
26
+ for (const file of files) {
27
+ if (!file.endsWith('.jsonl'))
28
+ continue;
29
+ const beads = await readBeads(path.join(mailDir, file));
30
+ count += beads.filter(m => m.mail_type === 'TASK_ASSIGNMENT' && !m.read).length;
31
+ }
32
+ }
33
+ catch { /* no mail dir */ }
34
+ return count;
35
+ }
36
+ export function registerStatusCommand(program) {
37
+ program
38
+ .command('status')
39
+ .description('Show Citadel workspace status')
40
+ .action(async () => {
41
+ const citadelDir = path.resolve('.citadel');
42
+ // 1. Verify .citadel/ exists
43
+ try {
44
+ await fs.access(citadelDir);
45
+ }
46
+ catch {
47
+ console.error('Not a Citadel workspace');
48
+ process.exit(1);
49
+ }
50
+ // 2. Session info
51
+ const identityPath = path.join(citadelDir, 'identity.jsonl');
52
+ const identityBeads = await readBeads(identityPath);
53
+ console.log('--- Session ---');
54
+ if (identityBeads.length > 0) {
55
+ const last = identityBeads[identityBeads.length - 1];
56
+ console.log(` agent: ${last.agent}`);
57
+ console.log(` last_session_at: ${last.last_session_at}`);
58
+ }
59
+ else {
60
+ console.log(' No session');
61
+ }
62
+ console.log('');
63
+ // 3. Outposts (PRD US-003: per-outpost ceiling, pending, elapsed)
64
+ let outposts = [];
65
+ try {
66
+ const raw = await fs.readFile(path.join(citadelDir, 'outposts.json'), 'utf-8');
67
+ const registry = JSON.parse(raw);
68
+ outposts = registry.outposts;
69
+ }
70
+ catch {
71
+ // no outposts file
72
+ }
73
+ console.log('--- Outposts ---');
74
+ if (outposts.length === 0) {
75
+ console.log(' (none)');
76
+ }
77
+ for (const op of outposts) {
78
+ const mailDir = path.join(op.path, '.beads', 'mail');
79
+ const tributeDir = path.join(op.path, '.beads', 'tribute');
80
+ const mailCount = await countFiles(mailDir);
81
+ const tributeCount = await countFiles(tributeDir);
82
+ const worktreeCount = await countSubdirs(path.join(op.path, 'worktrees', 'citizen'));
83
+ const pendingCount = await countPendingTasks(mailDir);
84
+ const maxCitizens = op.max_citizens ?? 3;
85
+ console.log(` ${op.slug}`);
86
+ console.log(` status: ${op.status}`);
87
+ console.log(` path: ${op.path}`);
88
+ console.log(` ceiling: ${worktreeCount}/${maxCitizens} active citizens`);
89
+ console.log(` pending tasks: ${pendingCount}`);
90
+ console.log(` mail files: ${mailCount}`);
91
+ console.log(` tribute files: ${tributeCount}`);
92
+ console.log(` worktrees: ${worktreeCount}`);
93
+ }
94
+ console.log('');
95
+ // 4. Unprocessed counts
96
+ const nudgePath = path.join(citadelDir, 'nudges.jsonl');
97
+ const nudgeBeads = await readBeads(nudgePath);
98
+ const unprocessedNudges = nudgeBeads.filter((b) => !b.processed).length;
99
+ let unprocessedCommands = 0;
100
+ const commandsDir = path.join(citadelDir, 'commands');
101
+ try {
102
+ const commandFiles = await fs.readdir(commandsDir);
103
+ for (const file of commandFiles) {
104
+ const filePath = path.join(commandsDir, file);
105
+ const stat = await fs.stat(filePath);
106
+ if (!stat.isFile())
107
+ continue;
108
+ try {
109
+ const raw = await fs.readFile(filePath, 'utf-8');
110
+ const bead = JSON.parse(raw);
111
+ if (!bead.processed) {
112
+ unprocessedCommands++;
113
+ }
114
+ }
115
+ catch {
116
+ // skip unparseable files
117
+ }
118
+ }
119
+ }
120
+ catch {
121
+ // commands dir may not exist
122
+ }
123
+ // 5. Summary
124
+ console.log('--- Summary ---');
125
+ console.log(`${outposts.length} outpost(s), ${unprocessedNudges} unprocessed nudge(s), ${unprocessedCommands} unprocessed command(s)`);
126
+ });
127
+ }
128
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/cli/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerTributeCommand(program: Command): void;
3
+ //# sourceMappingURL=tribute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tribute.d.ts","sourceRoot":"","sources":["../../src/cli/tribute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiEpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmI7D"}