@pleri/olam-cli 0.1.7

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 (196) hide show
  1. package/dist/__tests__/auth-status.test.d.ts +2 -0
  2. package/dist/__tests__/auth-status.test.d.ts.map +1 -0
  3. package/dist/__tests__/auth-status.test.js +290 -0
  4. package/dist/__tests__/auth-status.test.js.map +1 -0
  5. package/dist/__tests__/auth-upgrade.test.d.ts +9 -0
  6. package/dist/__tests__/auth-upgrade.test.d.ts.map +1 -0
  7. package/dist/__tests__/auth-upgrade.test.js +161 -0
  8. package/dist/__tests__/auth-upgrade.test.js.map +1 -0
  9. package/dist/__tests__/create-app-urls.test.d.ts +2 -0
  10. package/dist/__tests__/create-app-urls.test.d.ts.map +1 -0
  11. package/dist/__tests__/create-app-urls.test.js +102 -0
  12. package/dist/__tests__/create-app-urls.test.js.map +1 -0
  13. package/dist/__tests__/enter.test.d.ts +2 -0
  14. package/dist/__tests__/enter.test.d.ts.map +1 -0
  15. package/dist/__tests__/enter.test.js +90 -0
  16. package/dist/__tests__/enter.test.js.map +1 -0
  17. package/dist/__tests__/host-cp-gh-token.test.d.ts +9 -0
  18. package/dist/__tests__/host-cp-gh-token.test.d.ts.map +1 -0
  19. package/dist/__tests__/host-cp-gh-token.test.js +119 -0
  20. package/dist/__tests__/host-cp-gh-token.test.js.map +1 -0
  21. package/dist/__tests__/host-cp.test.d.ts +9 -0
  22. package/dist/__tests__/host-cp.test.d.ts.map +1 -0
  23. package/dist/__tests__/host-cp.test.js +254 -0
  24. package/dist/__tests__/host-cp.test.js.map +1 -0
  25. package/dist/__tests__/keys.test.d.ts +9 -0
  26. package/dist/__tests__/keys.test.d.ts.map +1 -0
  27. package/dist/__tests__/keys.test.js +145 -0
  28. package/dist/__tests__/keys.test.js.map +1 -0
  29. package/dist/__tests__/logs.test.d.ts +9 -0
  30. package/dist/__tests__/logs.test.d.ts.map +1 -0
  31. package/dist/__tests__/logs.test.js +124 -0
  32. package/dist/__tests__/logs.test.js.map +1 -0
  33. package/dist/__tests__/ps.test.d.ts +2 -0
  34. package/dist/__tests__/ps.test.d.ts.map +1 -0
  35. package/dist/__tests__/ps.test.js +172 -0
  36. package/dist/__tests__/ps.test.js.map +1 -0
  37. package/dist/__tests__/status-app-urls.test.d.ts +2 -0
  38. package/dist/__tests__/status-app-urls.test.d.ts.map +1 -0
  39. package/dist/__tests__/status-app-urls.test.js +125 -0
  40. package/dist/__tests__/status-app-urls.test.js.map +1 -0
  41. package/dist/__tests__/upgrade.test.d.ts +9 -0
  42. package/dist/__tests__/upgrade.test.d.ts.map +1 -0
  43. package/dist/__tests__/upgrade.test.js +262 -0
  44. package/dist/__tests__/upgrade.test.js.map +1 -0
  45. package/dist/commands/__tests__/carry-uncommitted.test.d.ts +14 -0
  46. package/dist/commands/__tests__/carry-uncommitted.test.d.ts.map +1 -0
  47. package/dist/commands/__tests__/carry-uncommitted.test.js +83 -0
  48. package/dist/commands/__tests__/carry-uncommitted.test.js.map +1 -0
  49. package/dist/commands/__tests__/openHostCpUrl.test.d.ts +2 -0
  50. package/dist/commands/__tests__/openHostCpUrl.test.d.ts.map +1 -0
  51. package/dist/commands/__tests__/openHostCpUrl.test.js +63 -0
  52. package/dist/commands/__tests__/openHostCpUrl.test.js.map +1 -0
  53. package/dist/commands/__tests__/refresh.test.d.ts +13 -0
  54. package/dist/commands/__tests__/refresh.test.d.ts.map +1 -0
  55. package/dist/commands/__tests__/refresh.test.js +170 -0
  56. package/dist/commands/__tests__/refresh.test.js.map +1 -0
  57. package/dist/commands/auth-status.d.ts +43 -0
  58. package/dist/commands/auth-status.d.ts.map +1 -0
  59. package/dist/commands/auth-status.js +208 -0
  60. package/dist/commands/auth-status.js.map +1 -0
  61. package/dist/commands/auth-upgrade.d.ts +47 -0
  62. package/dist/commands/auth-upgrade.d.ts.map +1 -0
  63. package/dist/commands/auth-upgrade.js +277 -0
  64. package/dist/commands/auth-upgrade.js.map +1 -0
  65. package/dist/commands/auth.d.ts +16 -0
  66. package/dist/commands/auth.d.ts.map +1 -0
  67. package/dist/commands/auth.js +283 -0
  68. package/dist/commands/auth.js.map +1 -0
  69. package/dist/commands/create.d.ts +8 -0
  70. package/dist/commands/create.d.ts.map +1 -0
  71. package/dist/commands/create.js +512 -0
  72. package/dist/commands/create.js.map +1 -0
  73. package/dist/commands/crystallize.d.ts +8 -0
  74. package/dist/commands/crystallize.d.ts.map +1 -0
  75. package/dist/commands/crystallize.js +101 -0
  76. package/dist/commands/crystallize.js.map +1 -0
  77. package/dist/commands/destroy.d.ts +6 -0
  78. package/dist/commands/destroy.d.ts.map +1 -0
  79. package/dist/commands/destroy.js +54 -0
  80. package/dist/commands/destroy.js.map +1 -0
  81. package/dist/commands/dispatch.d.ts +9 -0
  82. package/dist/commands/dispatch.d.ts.map +1 -0
  83. package/dist/commands/dispatch.js +94 -0
  84. package/dist/commands/dispatch.js.map +1 -0
  85. package/dist/commands/enter.d.ts +63 -0
  86. package/dist/commands/enter.d.ts.map +1 -0
  87. package/dist/commands/enter.js +206 -0
  88. package/dist/commands/enter.js.map +1 -0
  89. package/dist/commands/host-cp.d.ts +191 -0
  90. package/dist/commands/host-cp.d.ts.map +1 -0
  91. package/dist/commands/host-cp.js +797 -0
  92. package/dist/commands/host-cp.js.map +1 -0
  93. package/dist/commands/init.d.ts +9 -0
  94. package/dist/commands/init.d.ts.map +1 -0
  95. package/dist/commands/init.js +143 -0
  96. package/dist/commands/init.js.map +1 -0
  97. package/dist/commands/install.d.ts +22 -0
  98. package/dist/commands/install.d.ts.map +1 -0
  99. package/dist/commands/install.js +203 -0
  100. package/dist/commands/install.js.map +1 -0
  101. package/dist/commands/keys.d.ts +26 -0
  102. package/dist/commands/keys.d.ts.map +1 -0
  103. package/dist/commands/keys.js +151 -0
  104. package/dist/commands/keys.js.map +1 -0
  105. package/dist/commands/lanes.d.ts +18 -0
  106. package/dist/commands/lanes.d.ts.map +1 -0
  107. package/dist/commands/lanes.js +122 -0
  108. package/dist/commands/lanes.js.map +1 -0
  109. package/dist/commands/list.d.ts +6 -0
  110. package/dist/commands/list.d.ts.map +1 -0
  111. package/dist/commands/list.js +39 -0
  112. package/dist/commands/list.js.map +1 -0
  113. package/dist/commands/logs.d.ts +38 -0
  114. package/dist/commands/logs.d.ts.map +1 -0
  115. package/dist/commands/logs.js +177 -0
  116. package/dist/commands/logs.js.map +1 -0
  117. package/dist/commands/observe.d.ts +9 -0
  118. package/dist/commands/observe.d.ts.map +1 -0
  119. package/dist/commands/observe.js +34 -0
  120. package/dist/commands/observe.js.map +1 -0
  121. package/dist/commands/policy-check.d.ts +14 -0
  122. package/dist/commands/policy-check.d.ts.map +1 -0
  123. package/dist/commands/policy-check.js +76 -0
  124. package/dist/commands/policy-check.js.map +1 -0
  125. package/dist/commands/pr.d.ts +17 -0
  126. package/dist/commands/pr.d.ts.map +1 -0
  127. package/dist/commands/pr.js +148 -0
  128. package/dist/commands/pr.js.map +1 -0
  129. package/dist/commands/ps.d.ts +25 -0
  130. package/dist/commands/ps.d.ts.map +1 -0
  131. package/dist/commands/ps.js +164 -0
  132. package/dist/commands/ps.js.map +1 -0
  133. package/dist/commands/refresh-helpers.d.ts +25 -0
  134. package/dist/commands/refresh-helpers.d.ts.map +1 -0
  135. package/dist/commands/refresh-helpers.js +56 -0
  136. package/dist/commands/refresh-helpers.js.map +1 -0
  137. package/dist/commands/refresh.d.ts +23 -0
  138. package/dist/commands/refresh.d.ts.map +1 -0
  139. package/dist/commands/refresh.js +237 -0
  140. package/dist/commands/refresh.js.map +1 -0
  141. package/dist/commands/status.d.ts +6 -0
  142. package/dist/commands/status.d.ts.map +1 -0
  143. package/dist/commands/status.js +51 -0
  144. package/dist/commands/status.js.map +1 -0
  145. package/dist/commands/upgrade.d.ts +67 -0
  146. package/dist/commands/upgrade.d.ts.map +1 -0
  147. package/dist/commands/upgrade.js +358 -0
  148. package/dist/commands/upgrade.js.map +1 -0
  149. package/dist/commands/workspace.d.ts +23 -0
  150. package/dist/commands/workspace.d.ts.map +1 -0
  151. package/dist/commands/workspace.js +198 -0
  152. package/dist/commands/workspace.js.map +1 -0
  153. package/dist/commands/world-snapshot.d.ts +18 -0
  154. package/dist/commands/world-snapshot.d.ts.map +1 -0
  155. package/dist/commands/world-snapshot.js +327 -0
  156. package/dist/commands/world-snapshot.js.map +1 -0
  157. package/dist/context.d.ts +26 -0
  158. package/dist/context.d.ts.map +1 -0
  159. package/dist/context.js +51 -0
  160. package/dist/context.js.map +1 -0
  161. package/dist/index.d.ts +9 -0
  162. package/dist/index.d.ts.map +1 -0
  163. package/dist/index.js +18007 -0
  164. package/dist/index.js.map +1 -0
  165. package/dist/mcp-server.js +32236 -0
  166. package/dist/output.d.ts +10 -0
  167. package/dist/output.d.ts.map +1 -0
  168. package/dist/output.js +31 -0
  169. package/dist/output.js.map +1 -0
  170. package/host-cp/compose.yaml +126 -0
  171. package/host-cp/src/auth-secret-hint.mjs +45 -0
  172. package/host-cp/src/auth.mjs +155 -0
  173. package/host-cp/src/compose-worlds-sources.mjs +170 -0
  174. package/host-cp/src/container-secret-fetcher.mjs +163 -0
  175. package/host-cp/src/docker-events.mjs +184 -0
  176. package/host-cp/src/local-worlds-source.mjs +83 -0
  177. package/host-cp/src/plan-orchestrator.mjs +829 -0
  178. package/host-cp/src/plan-progress.mjs +282 -0
  179. package/host-cp/src/pr-cache.mjs +201 -0
  180. package/host-cp/src/pr-merge-poller.mjs +154 -0
  181. package/host-cp/src/process-poller.mjs +250 -0
  182. package/host-cp/src/proxy.mjs +245 -0
  183. package/host-cp/src/pylon-worlds-source.mjs +68 -0
  184. package/host-cp/src/redact.mjs +67 -0
  185. package/host-cp/src/secret-cache.mjs +104 -0
  186. package/host-cp/src/server.mjs +2215 -0
  187. package/host-cp/src/sse-gate.mjs +117 -0
  188. package/host-cp/src/version-status.mjs +209 -0
  189. package/host-cp/src/workspace-catalog.mjs +149 -0
  190. package/host-cp/src/world-names-store.mjs +176 -0
  191. package/host-cp/src/world-pr-state.mjs +97 -0
  192. package/host-cp/src/world-progress.mjs +322 -0
  193. package/host-cp/src/world-tunnel-manager.mjs +288 -0
  194. package/host-cp/src/worlds-db-source.mjs +191 -0
  195. package/host-cp/src/worlds-source.mjs +59 -0
  196. package/package.json +38 -0
@@ -0,0 +1,148 @@
1
+ /**
2
+ * olam pr — inspect and decide PR-gate requests opened by in-world hooks.
3
+ *
4
+ * Each running world's PreToolUse hook intercepts `gh pr create` and
5
+ * POSTs a gate to its own control plane. This CLI surface lets the
6
+ * human fan out across all running worlds, pick a gate, and approve
7
+ * or block it. Codex adversarial review (future) will plug in beside
8
+ * this as a second decision source.
9
+ *
10
+ * olam pr list list all pending gates
11
+ * olam pr show <id> full detail (diff, cmd)
12
+ * olam pr approve <id> [--reason <r>] let the PR proceed
13
+ * olam pr reject <id> [--reason <r>] block with a reason
14
+ */
15
+ import pc from 'picocolors';
16
+ import { WorldRegistry } from '@olam/core/src/world/registry.js';
17
+ import { decideGate, getGate, listGates, } from '@olam/core/src/pr-gate/index.js';
18
+ import { printError, printHeader, printInfo, printSuccess } from '../output.js';
19
+ function runningWorlds() {
20
+ const registry = new WorldRegistry();
21
+ try {
22
+ return registry.list({ status: 'running' });
23
+ }
24
+ finally {
25
+ registry.close();
26
+ }
27
+ }
28
+ async function fanoutList() {
29
+ const worlds = runningWorlds();
30
+ const results = [];
31
+ await Promise.all(worlds.map(async (world) => {
32
+ try {
33
+ const gates = await listGates(world.portOffset);
34
+ for (const gate of gates)
35
+ results.push({ world, gate });
36
+ }
37
+ catch {
38
+ // World control plane unreachable — skip, don't fail the whole list
39
+ }
40
+ }));
41
+ results.sort((a, b) => b.gate.openedAt.localeCompare(a.gate.openedAt));
42
+ return results;
43
+ }
44
+ async function findGate(id) {
45
+ const worlds = runningWorlds();
46
+ for (const world of worlds) {
47
+ try {
48
+ const gate = await getGate(world.portOffset, id);
49
+ if (gate)
50
+ return { world, gate };
51
+ }
52
+ catch {
53
+ // Skip unreachable worlds
54
+ }
55
+ }
56
+ return null;
57
+ }
58
+ function formatStateBadge(state) {
59
+ if (state === 'approve')
60
+ return pc.green('approve');
61
+ if (state === 'block')
62
+ return pc.red('block');
63
+ // Phase C C2 (CP3 ADV-C2-HIGH3 fix): explicit branch for the new
64
+ // 'denied' state so `olam pr list` shows the C2-era reaper-takes-over
65
+ // gates as gray 'denied' instead of falling through to the default
66
+ // yellow 'pending' badge — which would have misled operators into
67
+ // running `olam pr approve <id>` and getting a 409 because
68
+ // handlePrGateDecide rejects non-pending gates.
69
+ if (state === 'denied')
70
+ return pc.gray('denied');
71
+ return pc.yellow('pending');
72
+ }
73
+ export function registerPr(program) {
74
+ const pr = program.command('pr').description('Review and decide PR-gate requests from running worlds');
75
+ pr.command('list')
76
+ .description('List all PR-gate requests across every running world')
77
+ .action(async () => {
78
+ const all = await fanoutList();
79
+ if (all.length === 0) {
80
+ console.log(pc.dim('No gates open.'));
81
+ return;
82
+ }
83
+ printHeader(`${all.length} gate(s)`);
84
+ for (const { world, gate } of all) {
85
+ const badge = formatStateBadge(gate.state);
86
+ console.log(` ${pc.bold(gate.id.slice(0, 8))} ${badge.padEnd(20)} ${pc.dim(world.name)} ${pc.dim(gate.branch)}`);
87
+ console.log(` ${pc.dim(gate.command.slice(0, 100))}`);
88
+ }
89
+ });
90
+ pr.command('show')
91
+ .description('Show full gate detail (diff, command, commits)')
92
+ .argument('<id>', 'Gate id (prefix match ok)')
93
+ .action(async (id) => {
94
+ const found = await findGate(id);
95
+ if (!found) {
96
+ printError(`No gate found with id "${id}" in any running world.`);
97
+ process.exitCode = 1;
98
+ return;
99
+ }
100
+ const { world, gate } = found;
101
+ printHeader(`Gate ${gate.id}`);
102
+ printInfo('World', `${world.name} (${world.id})`);
103
+ printInfo('State', gate.state);
104
+ printInfo('Branch', gate.branch);
105
+ printInfo('Base', gate.base);
106
+ printInfo('Command', gate.command);
107
+ printInfo('Opened', gate.openedAt);
108
+ if (gate.decidedAt) {
109
+ printInfo('Decided', `${gate.decidedAt} by ${gate.decidedBy ?? 'unknown'}`);
110
+ if (gate.reason)
111
+ printInfo('Reason', gate.reason);
112
+ }
113
+ printHeader('Commits');
114
+ console.log(gate.commitLog || pc.dim(' (empty)'));
115
+ printHeader('Diff stat');
116
+ console.log(gate.diffStat || pc.dim(' (empty)'));
117
+ });
118
+ function decideCommand(verb, decision) {
119
+ pr.command(verb)
120
+ .description(`${verb[0].toUpperCase()}${verb.slice(1)} a pending gate`)
121
+ .argument('<id>', 'Gate id')
122
+ .option('--reason <reason>', 'Short free-text reason')
123
+ .option('--by <name>', 'Deciding identity (defaults to $USER)', process.env['USER'] ?? 'human')
124
+ .action(async (id, opts) => {
125
+ const found = await findGate(id);
126
+ if (!found) {
127
+ printError(`No gate found with id "${id}" in any running world.`);
128
+ process.exitCode = 1;
129
+ return;
130
+ }
131
+ try {
132
+ const result = await decideGate(found.world.portOffset, found.gate.id, {
133
+ decision,
134
+ by: opts.by,
135
+ ...(opts.reason ? { reason: opts.reason } : {}),
136
+ });
137
+ printSuccess(`Gate ${result.id}: ${result.state}`);
138
+ }
139
+ catch (err) {
140
+ printError(err instanceof Error ? err.message : String(err));
141
+ process.exitCode = 1;
142
+ }
143
+ });
144
+ }
145
+ decideCommand('approve', 'approve');
146
+ decideCommand('reject', 'block');
147
+ }
148
+ //# sourceMappingURL=pr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr.js","sourceRoot":"","sources":["../../src/commands/pr.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { Command } from 'commander';
2
+ interface ProcessRow {
3
+ pid: string;
4
+ user: string;
5
+ cpu: string;
6
+ mem: string;
7
+ started: string;
8
+ state: string;
9
+ command: string;
10
+ }
11
+ type SortKey = 'cpu' | 'mem' | 'pid';
12
+ /**
13
+ * Parse docker top stdout into ProcessRow[].
14
+ * Accepts two formats:
15
+ * 1. JSON: {"Titles":[...],"Processes":[[...],...]} (HTTP API / docker daemon)
16
+ * 2. Tabular text with a header line (bare CLI spawnSync path)
17
+ *
18
+ * The tabular format uses stime (single-word start time like "10:00" or "Feb11")
19
+ * to avoid multi-word timestamp parsing issues.
20
+ */
21
+ export declare function parseDockerTop(stdout: string): ProcessRow[];
22
+ export declare function sortRows(rows: ProcessRow[], key: SortKey): ProcessRow[];
23
+ export declare function registerPs(program: Command): void;
24
+ export {};
25
+ //# sourceMappingURL=ps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ps.d.ts","sourceRoot":"","sources":["../../src/commands/ps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMzC,UAAU,UAAU;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,KAAK,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAKrC;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,CAoD3D;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,UAAU,EAAE,CAKvE;AA0CD,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkEjD"}
@@ -0,0 +1,164 @@
1
+ import pc from 'picocolors';
2
+ import { spawnSync } from 'node:child_process';
3
+ import { loadContext } from '../context.js';
4
+ import { printError } from '../output.js';
5
+ // Matches valid world IDs — same invariant enforced by enter.ts, destroy.ts, etc.
6
+ const SAFE_IDENT = /^[a-z0-9][a-z0-9-]{0,63}$/;
7
+ /**
8
+ * Parse docker top stdout into ProcessRow[].
9
+ * Accepts two formats:
10
+ * 1. JSON: {"Titles":[...],"Processes":[[...],...]} (HTTP API / docker daemon)
11
+ * 2. Tabular text with a header line (bare CLI spawnSync path)
12
+ *
13
+ * The tabular format uses stime (single-word start time like "10:00" or "Feb11")
14
+ * to avoid multi-word timestamp parsing issues.
15
+ */
16
+ export function parseDockerTop(stdout) {
17
+ const trimmed = stdout.trim();
18
+ if (!trimmed)
19
+ return [];
20
+ let titles;
21
+ let processes;
22
+ if (trimmed.startsWith('{')) {
23
+ try {
24
+ const parsed = JSON.parse(trimmed);
25
+ titles = (parsed.Titles ?? []).map((t) => t.toLowerCase().trim());
26
+ processes = parsed.Processes ?? [];
27
+ }
28
+ catch {
29
+ return [];
30
+ }
31
+ }
32
+ else {
33
+ const lines = trimmed.split('\n');
34
+ if (lines.length < 2)
35
+ return [];
36
+ titles = (lines[0] ?? '').trim().toLowerCase().split(/\s+/);
37
+ processes = lines.slice(1).map((l) => l.trim().split(/\s+/));
38
+ }
39
+ const idx = (candidates) => {
40
+ for (const c of candidates) {
41
+ const i = titles.indexOf(c);
42
+ if (i !== -1)
43
+ return i;
44
+ }
45
+ return -1;
46
+ };
47
+ const pidIdx = idx(['pid']);
48
+ const userIdx = idx(['user', 'uid']);
49
+ const cpuIdx = idx(['%cpu', 'cpu', 'pcpu']);
50
+ const memIdx = idx(['%mem', 'mem', 'pmem']);
51
+ const startIdx = idx(['stime', 'lstart', 'start_time', 'started', 'start']);
52
+ const stateIdx = idx(['stat', 'state', 's']);
53
+ const cmdIdx = idx(['cmd', 'command', 'args']);
54
+ if (pidIdx === -1 || cmdIdx === -1)
55
+ return [];
56
+ return processes.map((parts) => {
57
+ const cmdFull = parts.slice(cmdIdx).join(' ');
58
+ return {
59
+ pid: parts[pidIdx] ?? '',
60
+ user: userIdx !== -1 ? (parts[userIdx] ?? '') : '',
61
+ cpu: cpuIdx !== -1 ? (parts[cpuIdx] ?? '0.0') : '0.0',
62
+ mem: memIdx !== -1 ? (parts[memIdx] ?? '0.0') : '0.0',
63
+ started: startIdx !== -1 ? (parts[startIdx] ?? '') : '',
64
+ state: stateIdx !== -1 ? (parts[stateIdx] ?? '') : '',
65
+ command: cmdFull,
66
+ };
67
+ }).filter((r) => r.pid !== '');
68
+ }
69
+ export function sortRows(rows, key) {
70
+ return [...rows].sort((a, b) => {
71
+ if (key === 'pid')
72
+ return parseInt(b.pid, 10) - parseInt(a.pid, 10);
73
+ return parseFloat(b[key]) - parseFloat(a[key]);
74
+ });
75
+ }
76
+ function printTable(rows) {
77
+ const cols = process.stdout.columns ?? 80;
78
+ const fixedWidth = 5 + 1 + 8 + 1 + 6 + 1 + 6 + 1 + 10 + 1 + 6 + 1;
79
+ const cmdWidth = Math.max(20, cols - fixedWidth);
80
+ const header = [
81
+ pc.bold(pc.dim('PID'.padEnd(5))),
82
+ pc.bold(pc.dim('USER'.padEnd(8))),
83
+ pc.bold(pc.dim('%CPU'.padEnd(6))),
84
+ pc.bold(pc.dim('%MEM'.padEnd(6))),
85
+ pc.bold(pc.dim('STARTED'.padEnd(10))),
86
+ pc.bold(pc.dim('STATE'.padEnd(6))),
87
+ pc.bold(pc.dim('COMMAND')),
88
+ ].join(' ');
89
+ console.log(header);
90
+ for (const row of rows) {
91
+ const cmd = row.command.length > cmdWidth
92
+ ? row.command.slice(0, cmdWidth - 1) + '…'
93
+ : row.command;
94
+ const stateFn = row.state.startsWith('R')
95
+ ? pc.green
96
+ : row.state.startsWith('Z')
97
+ ? pc.red
98
+ : pc.dim;
99
+ console.log([
100
+ row.pid.padEnd(5),
101
+ row.user.slice(0, 8).padEnd(8),
102
+ row.cpu.slice(0, 5).padEnd(6),
103
+ row.mem.slice(0, 5).padEnd(6),
104
+ row.started.slice(0, 10).padEnd(10),
105
+ stateFn(row.state.slice(0, 6).padEnd(6)),
106
+ cmd,
107
+ ].join(' '));
108
+ }
109
+ }
110
+ export function registerPs(program) {
111
+ program
112
+ .command('ps')
113
+ .description('List running processes in a world container')
114
+ .argument('<world>', 'World ID')
115
+ .option('--watch', 'Refresh every 5 seconds (Ctrl-C to exit)')
116
+ .option('--sort <key>', 'Sort column: cpu, mem, pid', 'cpu')
117
+ .action(async (worldId, opts) => {
118
+ if (!SAFE_IDENT.test(worldId)) {
119
+ printError(`Invalid world ID "${worldId}". World IDs must match [a-z0-9][a-z0-9-]{0,63}.`);
120
+ process.exitCode = 1;
121
+ return;
122
+ }
123
+ const { ctx, error } = await loadContext();
124
+ if (!ctx) {
125
+ printError(error?.message ?? 'Olam is not configured. Run `olam init` first.');
126
+ process.exitCode = 1;
127
+ return;
128
+ }
129
+ const sortKey = ['cpu', 'mem', 'pid'].includes(opts.sort)
130
+ ? opts.sort
131
+ : 'cpu';
132
+ const containerName = `olam-${worldId}-devbox`;
133
+ let watchInterval;
134
+ function fetchAndPrint() {
135
+ const result = spawnSync('docker', ['top', containerName, 'pid', 'user', 'pcpu', 'pmem', 'stime', 'stat', 'cmd'], { encoding: 'utf-8', timeout: 3000 });
136
+ if (result.status !== 0 || result.error) {
137
+ const msg = result.stderr?.trim() || result.error?.message || 'docker top failed';
138
+ printError(`ps failed for "${worldId}": ${msg}`);
139
+ if (watchInterval !== undefined) {
140
+ clearInterval(watchInterval);
141
+ process.exit(1);
142
+ }
143
+ process.exitCode = 1;
144
+ return;
145
+ }
146
+ const rows = sortRows(parseDockerTop(result.stdout ?? ''), sortKey);
147
+ if (opts.watch)
148
+ process.stdout.write('\x1b[2J\x1b[H');
149
+ printTable(rows);
150
+ if (opts.watch) {
151
+ process.stdout.write(`\n${pc.dim(`world: ${worldId} sort: ${sortKey} refresh: 5s Ctrl-C to exit`)}\n`);
152
+ }
153
+ }
154
+ fetchAndPrint();
155
+ if (opts.watch) {
156
+ watchInterval = setInterval(fetchAndPrint, 5000);
157
+ process.on('SIGINT', () => {
158
+ clearInterval(watchInterval);
159
+ process.exit(0);
160
+ });
161
+ }
162
+ });
163
+ }
164
+ //# sourceMappingURL=ps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ps.js","sourceRoot":"","sources":["../../src/commands/ps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Pure helper functions for `olam refresh`.
3
+ *
4
+ * Kept in a separate file so unit tests can import them without
5
+ * pulling in @olam/adapters (which requires a built package).
6
+ */
7
+ export interface CpSourceEntry {
8
+ readonly srcPath: string;
9
+ /** Relative to /opt/olam/control-plane/ inside the container. */
10
+ readonly destRelPath: string;
11
+ }
12
+ /**
13
+ * Collect the CP source files to copy — mirrors build-devbox.sh:38-77.
14
+ *
15
+ * Includes:
16
+ * - standalone/*.mjs (excluding *.test.mjs)
17
+ * - standalone/lib/*.mjs (excluding *.test.mjs) when lib/ exists
18
+ */
19
+ export declare function collectCpSourceFiles(standaloneDir: string): CpSourceEntry[];
20
+ /**
21
+ * Validate server.mjs is present — mirrors build-devbox.sh:62-66.
22
+ * Throws if missing so the caller gets a clear, actionable error.
23
+ */
24
+ export declare function validateServerMjsPresent(entries: CpSourceEntry[]): void;
25
+ //# sourceMappingURL=refresh-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh-helpers.d.ts","sourceRoot":"","sources":["../../src/commands/refresh-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,EAAE,CAmC3E;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI,CAOvE"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Pure helper functions for `olam refresh`.
3
+ *
4
+ * Kept in a separate file so unit tests can import them without
5
+ * pulling in @olam/adapters (which requires a built package).
6
+ */
7
+ import * as fs from 'node:fs';
8
+ import * as path from 'node:path';
9
+ /**
10
+ * Collect the CP source files to copy — mirrors build-devbox.sh:38-77.
11
+ *
12
+ * Includes:
13
+ * - standalone/*.mjs (excluding *.test.mjs)
14
+ * - standalone/lib/*.mjs (excluding *.test.mjs) when lib/ exists
15
+ */
16
+ export function collectCpSourceFiles(standaloneDir) {
17
+ if (!fs.existsSync(standaloneDir)) {
18
+ throw new Error(`CP standalone dir not found: ${standaloneDir}`);
19
+ }
20
+ const entries = [];
21
+ // Top-level *.mjs (except *.test.mjs) — mirrors build-devbox.sh:39-44
22
+ const topLevel = fs.readdirSync(standaloneDir)
23
+ .filter(f => {
24
+ const stat = fs.statSync(path.join(standaloneDir, f));
25
+ return stat.isFile() && f.endsWith('.mjs') && !f.endsWith('.test.mjs');
26
+ })
27
+ .sort();
28
+ for (const f of topLevel) {
29
+ entries.push({ srcPath: path.join(standaloneDir, f), destRelPath: f });
30
+ }
31
+ // lib/*.mjs (except *.test.mjs) — mirrors build-devbox.sh:53-61
32
+ const libDir = path.join(standaloneDir, 'lib');
33
+ if (fs.existsSync(libDir) && fs.statSync(libDir).isDirectory()) {
34
+ const libFiles = fs.readdirSync(libDir)
35
+ .filter(f => {
36
+ const stat = fs.statSync(path.join(libDir, f));
37
+ return stat.isFile() && f.endsWith('.mjs') && !f.endsWith('.test.mjs');
38
+ })
39
+ .sort();
40
+ for (const f of libFiles) {
41
+ entries.push({ srcPath: path.join(libDir, f), destRelPath: `lib/${f}` });
42
+ }
43
+ }
44
+ return entries;
45
+ }
46
+ /**
47
+ * Validate server.mjs is present — mirrors build-devbox.sh:62-66.
48
+ * Throws if missing so the caller gets a clear, actionable error.
49
+ */
50
+ export function validateServerMjsPresent(entries) {
51
+ if (!entries.some(e => e.destRelPath === 'server.mjs')) {
52
+ throw new Error('server.mjs not found in the source list — standalone/ may not be built. ' +
53
+ 'Use --skip-build to bypass this check.');
54
+ }
55
+ }
56
+ //# sourceMappingURL=refresh-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh-helpers.js","sourceRoot":"","sources":["../../src/commands/refresh-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAQlC;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,aAAqB;IACxD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,gCAAgC,aAAa,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,OAAO,GAAoB,EAAE,CAAC;IAEpC,sEAAsE;IACtE,MAAM,QAAQ,GAAG,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC;SAC3C,MAAM,CAAC,CAAC,CAAC,EAAE;QACV,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACzE,CAAC,CAAC;SACD,IAAI,EAAE,CAAC;IAEV,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,gEAAgE;IAChE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QAC/D,MAAM,QAAQ,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC;aACpC,MAAM,CAAC,CAAC,CAAC,EAAE;YACV,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;YAC/C,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACzE,CAAC,CAAC;aACD,IAAI,EAAE,CAAC;QAEV,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAwB;IAC/D,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,YAAY,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CACb,0EAA0E;YAC1E,wCAAwC,CACzC,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * olam refresh <world> — Hot-refresh per-world CP from the local checkout.
3
+ *
4
+ * Copies the latest packages/control-plane/standalone/ source into a running
5
+ * devbox container, then restarts the CP via `docker restart`.
6
+ *
7
+ * Restart mechanism: the devbox CMD is `node /opt/olam/control-plane/server.mjs`
8
+ * (PID 1 via entrypoint.sh's `exec "$@"`). No supervisor wrapper exists — killing
9
+ * PID 1 stops the container. `docker restart` is therefore the correct mechanism:
10
+ * it stops the container, re-runs entrypoint.sh + CMD, which reinstalls hooks
11
+ * and starts the CP cleanly.
12
+ *
13
+ * Side-effect: any running tmux sessions (including active claude sessions) are
14
+ * killed on restart. Operators should re-dispatch if needed afterward.
15
+ * This is the accepted tradeoff for a maintenance operation.
16
+ *
17
+ * Source parity: the file list mirrors build-devbox.sh:38-77 exactly. Any
18
+ * drift between this file and that script will produce a broken world.
19
+ */
20
+ import type { Command } from 'commander';
21
+ export { collectCpSourceFiles, validateServerMjsPresent, type CpSourceEntry } from './refresh-helpers.js';
22
+ export declare function registerRefresh(program: Command): void;
23
+ //# sourceMappingURL=refresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../src/commands/refresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAezC,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAqI1G,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6HtD"}