@pleri/olam-cli 0.1.175 → 0.1.182

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 (130) hide show
  1. package/README.md +19 -0
  2. package/bin/olam.cjs +22 -0
  3. package/dist/commands/auth.d.ts.map +1 -1
  4. package/dist/commands/auth.js +67 -19
  5. package/dist/commands/auth.js.map +1 -1
  6. package/dist/commands/config.d.ts.map +1 -1
  7. package/dist/commands/config.js +93 -0
  8. package/dist/commands/config.js.map +1 -1
  9. package/dist/commands/destroy.d.ts +41 -0
  10. package/dist/commands/destroy.d.ts.map +1 -1
  11. package/dist/commands/destroy.js +81 -33
  12. package/dist/commands/destroy.js.map +1 -1
  13. package/dist/commands/dispatch-resolve.d.ts +54 -0
  14. package/dist/commands/dispatch-resolve.d.ts.map +1 -0
  15. package/dist/commands/dispatch-resolve.js +105 -0
  16. package/dist/commands/dispatch-resolve.js.map +1 -0
  17. package/dist/commands/dispatch.d.ts.map +1 -1
  18. package/dist/commands/dispatch.js +40 -9
  19. package/dist/commands/dispatch.js.map +1 -1
  20. package/dist/commands/flywheel/index.d.ts.map +1 -1
  21. package/dist/commands/flywheel/index.js +4 -0
  22. package/dist/commands/flywheel/index.js.map +1 -1
  23. package/dist/commands/flywheel/install-sessionstart-hook.d.ts +64 -0
  24. package/dist/commands/flywheel/install-sessionstart-hook.d.ts.map +1 -0
  25. package/dist/commands/flywheel/install-sessionstart-hook.js +197 -0
  26. package/dist/commands/flywheel/install-sessionstart-hook.js.map +1 -0
  27. package/dist/commands/flywheel/k5-validate.d.ts +31 -0
  28. package/dist/commands/flywheel/k5-validate.d.ts.map +1 -1
  29. package/dist/commands/flywheel/k5-validate.js +80 -19
  30. package/dist/commands/flywheel/k5-validate.js.map +1 -1
  31. package/dist/commands/flywheel/session-start.d.ts +26 -0
  32. package/dist/commands/flywheel/session-start.d.ts.map +1 -0
  33. package/dist/commands/flywheel/session-start.js +119 -0
  34. package/dist/commands/flywheel/session-start.js.map +1 -0
  35. package/dist/commands/host-cp.d.ts +0 -3
  36. package/dist/commands/host-cp.d.ts.map +1 -1
  37. package/dist/commands/host-cp.js +27 -2
  38. package/dist/commands/host-cp.js.map +1 -1
  39. package/dist/commands/kg-classify.d.ts.map +1 -1
  40. package/dist/commands/kg-classify.js +20 -0
  41. package/dist/commands/kg-classify.js.map +1 -1
  42. package/dist/commands/kg-doctor.d.ts +67 -6
  43. package/dist/commands/kg-doctor.d.ts.map +1 -1
  44. package/dist/commands/kg-doctor.js +126 -46
  45. package/dist/commands/kg-doctor.js.map +1 -1
  46. package/dist/commands/list.d.ts +27 -0
  47. package/dist/commands/list.d.ts.map +1 -1
  48. package/dist/commands/list.js +67 -19
  49. package/dist/commands/list.js.map +1 -1
  50. package/dist/commands/memory/status.d.ts +18 -0
  51. package/dist/commands/memory/status.d.ts.map +1 -1
  52. package/dist/commands/memory/status.js +38 -2
  53. package/dist/commands/memory/status.js.map +1 -1
  54. package/dist/commands/memory-service-container.d.ts +44 -0
  55. package/dist/commands/memory-service-container.d.ts.map +1 -1
  56. package/dist/commands/memory-service-container.js +49 -0
  57. package/dist/commands/memory-service-container.js.map +1 -1
  58. package/dist/commands/ps.d.ts +32 -0
  59. package/dist/commands/ps.d.ts.map +1 -1
  60. package/dist/commands/ps.js +34 -0
  61. package/dist/commands/ps.js.map +1 -1
  62. package/dist/commands/runbooks.d.ts +32 -0
  63. package/dist/commands/runbooks.d.ts.map +1 -1
  64. package/dist/commands/runbooks.js +79 -22
  65. package/dist/commands/runbooks.js.map +1 -1
  66. package/dist/commands/skills-source.d.ts.map +1 -1
  67. package/dist/commands/skills-source.js +77 -2
  68. package/dist/commands/skills-source.js.map +1 -1
  69. package/dist/commands/upgrade-history.d.ts +0 -2
  70. package/dist/commands/upgrade-history.d.ts.map +1 -1
  71. package/dist/commands/upgrade-history.js +0 -6
  72. package/dist/commands/upgrade-history.js.map +1 -1
  73. package/dist/commands/upgrade-lock.d.ts +0 -9
  74. package/dist/commands/upgrade-lock.d.ts.map +1 -1
  75. package/dist/commands/upgrade-lock.js +1 -1
  76. package/dist/commands/upgrade-lock.js.map +1 -1
  77. package/dist/commands/world-snapshot.d.ts +13 -0
  78. package/dist/commands/world-snapshot.d.ts.map +1 -1
  79. package/dist/commands/world-snapshot.js +81 -1
  80. package/dist/commands/world-snapshot.js.map +1 -1
  81. package/dist/commands/yolo.d.ts +95 -0
  82. package/dist/commands/yolo.d.ts.map +1 -0
  83. package/dist/commands/yolo.js +377 -0
  84. package/dist/commands/yolo.js.map +1 -0
  85. package/dist/image-digests.json +8 -8
  86. package/dist/index.js +3990 -2445
  87. package/dist/index.js.map +1 -1
  88. package/dist/lib/anthropic-base-url-file.d.ts +37 -0
  89. package/dist/lib/anthropic-base-url-file.d.ts.map +1 -0
  90. package/dist/lib/anthropic-base-url-file.js +46 -0
  91. package/dist/lib/anthropic-base-url-file.js.map +1 -0
  92. package/dist/lib/auth-remote.d.ts +9 -17
  93. package/dist/lib/auth-remote.d.ts.map +1 -1
  94. package/dist/lib/auth-remote.js +25 -20
  95. package/dist/lib/auth-remote.js.map +1 -1
  96. package/dist/lib/cf-access-token.d.ts +32 -0
  97. package/dist/lib/cf-access-token.d.ts.map +1 -0
  98. package/dist/lib/cf-access-token.js +52 -0
  99. package/dist/lib/cf-access-token.js.map +1 -0
  100. package/dist/lib/config.d.ts +17 -3
  101. package/dist/lib/config.d.ts.map +1 -1
  102. package/dist/lib/config.js +28 -4
  103. package/dist/lib/config.js.map +1 -1
  104. package/dist/lib/kubectl-context.d.ts +49 -0
  105. package/dist/lib/kubectl-context.d.ts.map +1 -1
  106. package/dist/lib/kubectl-context.js +64 -2
  107. package/dist/lib/kubectl-context.js.map +1 -1
  108. package/dist/lib/upgrade-kubernetes.d.ts +7 -0
  109. package/dist/lib/upgrade-kubernetes.d.ts.map +1 -1
  110. package/dist/lib/upgrade-kubernetes.js +35 -8
  111. package/dist/lib/upgrade-kubernetes.js.map +1 -1
  112. package/dist/mcp-server.js +1470 -991
  113. package/hermes-bundle/version.json +1 -1
  114. package/host-cp/k8s/manifests/45-pvc.yaml +6 -2
  115. package/host-cp/k8s/manifests/50-deployment.yaml +1 -1
  116. package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
  117. package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +1 -1
  118. package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +1 -1
  119. package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +1 -1
  120. package/host-cp/observability/trace-summary.mjs +267 -0
  121. package/host-cp/src/bootstrap-selective.mjs +58 -0
  122. package/host-cp/src/host-stream.mjs +52 -0
  123. package/host-cp/src/plan-chat-service.mjs +51 -0
  124. package/host-cp/src/redirect.mjs +159 -0
  125. package/host-cp/src/resolver.mjs +121 -0
  126. package/host-cp/src/router.mjs +168 -0
  127. package/host-cp/src/serve-only-config.mjs +85 -0
  128. package/host-cp/src/server.mjs +375 -205
  129. package/host-cp/src/world-services.mjs +136 -0
  130. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"destroy.js","sourceRoot":"","sources":["../../src/commands/destroy.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvE,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,wCAAwC,CAAC;SACrD,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;SAC/B,MAAM,CAAC,oBAAoB,EAAE,8BAA8B,CAAC;SAC5D,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,IAAmC,EAAE,EAAE;QACrE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,MAAM,WAAW,EAAE,CAAC;QAC3C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,UAAU,CAAC,KAAK,EAAE,OAAO,IAAI,gDAAgD,CAAC,CAAC;YAC/E,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,UAAU,CAAC,UAAU,OAAO,+CAA+C,CAAC,CAAC;YAC7E,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;QAE3D,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,YAAY,CAAC,YAAY,CAAC,OAAO,EAAE;gBAC3C,eAAe,EAAE,IAAI,CAAC,eAAe;aACtC,CAAC,CAAC;YACH,OAAO,CAAC,OAAO,CAAC,aAAa,KAAK,CAAC,IAAI,KAAK,OAAO,GAAG,CAAC,CAAC;YACxD,8DAA8D;YAC9D,yDAAyD;YACzD,6DAA6D;YAC7D,6CAA6C;YAC7C,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,mBAAmB,EAAE,CAAC;gBAC3C,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;oBACzC,MAAM,kBAAkB,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,6DAA6D;YAC/D,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YACxC,UAAU,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"destroy.js","sourceRoot":"","sources":["../../src/commands/destroy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Pure resolution + validation helpers for `olam dispatch`.
3
+ *
4
+ * Extracted so the operator-facing ergonomics (resolve-by-name,
5
+ * "did you mean" suggestions, mode validation) can be unit-tested
6
+ * without the container/IO surface of the command action.
7
+ */
8
+ /** Minimal world shape these helpers need (subset of WorldMetadata). */
9
+ export interface DispatchWorldRef {
10
+ readonly id: string;
11
+ readonly name: string;
12
+ readonly status: string;
13
+ }
14
+ /** The execution modes `olam dispatch --mode` accepts. */
15
+ export declare const DISPATCH_MODES: readonly ["auto", "deep", "fast"];
16
+ export type DispatchMode = (typeof DISPATCH_MODES)[number];
17
+ /**
18
+ * Resolve a world by the user-supplied argument.
19
+ *
20
+ * Precedence (backward-compatible — exact ID still wins):
21
+ * 1. Exact ID match.
22
+ * 2. Exact name match (operators usually remember the name, not the id).
23
+ *
24
+ * Returns the matched world, or `undefined` when nothing matches.
25
+ * When two worlds share a name, the first registered wins — callers
26
+ * should fall back to the unambiguous ID, which is surfaced in the
27
+ * not-found suggestion list.
28
+ */
29
+ export declare function resolveWorld<T extends DispatchWorldRef>(worlds: readonly T[], arg: string): T | undefined;
30
+ /**
31
+ * Rank worlds by how likely the operator meant them, given a typo'd or
32
+ * partial argument. Used to build a "did you mean" hint on not-found.
33
+ *
34
+ * Matching signal (lower score = better):
35
+ * - substring match on id or name (case-insensitive) → strong signal
36
+ * - small edit distance to id or name → typo signal
37
+ *
38
+ * Returns at most `limit` candidates, best first. Worlds with no
39
+ * plausible relationship to the argument are dropped, so an empty
40
+ * result is meaningful ("nothing close").
41
+ */
42
+ export declare function suggestWorlds<T extends DispatchWorldRef>(worlds: readonly T[], arg: string, limit?: number): T[];
43
+ /**
44
+ * Validate a `--mode` value. Returns the canonical mode on success, or
45
+ * an `error` describing the valid set on failure. Unknown modes used to
46
+ * silently fall through to non-deep behaviour; surfacing them prevents
47
+ * a typo (`--mode dep`) from quietly running the wrong execution shape.
48
+ */
49
+ export declare function validateMode(raw: string): {
50
+ mode: DispatchMode;
51
+ } | {
52
+ error: string;
53
+ };
54
+ //# sourceMappingURL=dispatch-resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch-resolve.d.ts","sourceRoot":"","sources":["../../src/commands/dispatch-resolve.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,0DAA0D;AAC1D,eAAO,MAAM,cAAc,mCAAoC,CAAC;AAChE,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,gBAAgB,EACrD,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,GAAG,EAAE,MAAM,GACV,CAAC,GAAG,SAAS,CAIf;AAgCD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,gBAAgB,EACtD,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,GAAG,EAAE,MAAM,EACX,KAAK,SAAI,GACR,CAAC,EAAE,CAoBL;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,MAAM,GACV;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAQ5C"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Pure resolution + validation helpers for `olam dispatch`.
3
+ *
4
+ * Extracted so the operator-facing ergonomics (resolve-by-name,
5
+ * "did you mean" suggestions, mode validation) can be unit-tested
6
+ * without the container/IO surface of the command action.
7
+ */
8
+ /** The execution modes `olam dispatch --mode` accepts. */
9
+ export const DISPATCH_MODES = ['auto', 'deep', 'fast'];
10
+ /**
11
+ * Resolve a world by the user-supplied argument.
12
+ *
13
+ * Precedence (backward-compatible — exact ID still wins):
14
+ * 1. Exact ID match.
15
+ * 2. Exact name match (operators usually remember the name, not the id).
16
+ *
17
+ * Returns the matched world, or `undefined` when nothing matches.
18
+ * When two worlds share a name, the first registered wins — callers
19
+ * should fall back to the unambiguous ID, which is surfaced in the
20
+ * not-found suggestion list.
21
+ */
22
+ export function resolveWorld(worlds, arg) {
23
+ const byId = worlds.find((w) => w.id === arg);
24
+ if (byId)
25
+ return byId;
26
+ return worlds.find((w) => w.name === arg);
27
+ }
28
+ /**
29
+ * Case-insensitive Levenshtein distance, capped — we only care about
30
+ * "close enough to be a typo", not the exact edit count.
31
+ */
32
+ function editDistance(a, b) {
33
+ const s = a.toLowerCase();
34
+ const t = b.toLowerCase();
35
+ if (s === t)
36
+ return 0;
37
+ const m = s.length;
38
+ const n = t.length;
39
+ if (m === 0)
40
+ return n;
41
+ if (n === 0)
42
+ return m;
43
+ // Single-row DP. `row[j]` holds the distance for the previous source
44
+ // prefix; `prevDiag` carries the diagonal value across the inner loop.
45
+ const row = Array.from({ length: n + 1 }, (_, i) => i);
46
+ for (let i = 1; i <= m; i += 1) {
47
+ let prevDiag = row[0]; // row[0] before overwrite = D[i-1][0]
48
+ row[0] = i;
49
+ for (let j = 1; j <= n; j += 1) {
50
+ const cost = s.charCodeAt(i - 1) === t.charCodeAt(j - 1) ? 0 : 1;
51
+ const above = row[j]; // D[i-1][j]
52
+ const left = row[j - 1]; // D[i][j-1]
53
+ row[j] = Math.min(left + 1, above + 1, prevDiag + cost);
54
+ prevDiag = above;
55
+ }
56
+ }
57
+ return row[n];
58
+ }
59
+ /**
60
+ * Rank worlds by how likely the operator meant them, given a typo'd or
61
+ * partial argument. Used to build a "did you mean" hint on not-found.
62
+ *
63
+ * Matching signal (lower score = better):
64
+ * - substring match on id or name (case-insensitive) → strong signal
65
+ * - small edit distance to id or name → typo signal
66
+ *
67
+ * Returns at most `limit` candidates, best first. Worlds with no
68
+ * plausible relationship to the argument are dropped, so an empty
69
+ * result is meaningful ("nothing close").
70
+ */
71
+ export function suggestWorlds(worlds, arg, limit = 3) {
72
+ const needle = arg.toLowerCase();
73
+ // Typos within ~40% of the token length are plausible; clamp to >=2 so
74
+ // short ids/names still tolerate a one-char slip.
75
+ const threshold = Math.max(2, Math.ceil(needle.length * 0.4));
76
+ const scored = worlds
77
+ .map((w) => {
78
+ const id = w.id.toLowerCase();
79
+ const name = w.name.toLowerCase();
80
+ const substring = id.includes(needle) || name.includes(needle);
81
+ const dist = Math.min(editDistance(arg, w.id), editDistance(arg, w.name));
82
+ // Substring matches sort ahead of pure edit-distance matches.
83
+ const score = substring ? -1000 + dist : dist;
84
+ return { world: w, score, plausible: substring || dist <= threshold };
85
+ })
86
+ .filter((c) => c.plausible)
87
+ .sort((a, b) => a.score - b.score);
88
+ return scored.slice(0, limit).map((c) => c.world);
89
+ }
90
+ /**
91
+ * Validate a `--mode` value. Returns the canonical mode on success, or
92
+ * an `error` describing the valid set on failure. Unknown modes used to
93
+ * silently fall through to non-deep behaviour; surfacing them prevents
94
+ * a typo (`--mode dep`) from quietly running the wrong execution shape.
95
+ */
96
+ export function validateMode(raw) {
97
+ const normalized = raw.trim().toLowerCase();
98
+ if (DISPATCH_MODES.includes(normalized)) {
99
+ return { mode: normalized };
100
+ }
101
+ return {
102
+ error: `Invalid --mode "${raw}". Valid modes: ${DISPATCH_MODES.join(', ')}.`,
103
+ };
104
+ }
105
+ //# sourceMappingURL=dispatch-resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch-resolve.js","sourceRoot":"","sources":["../../src/commands/dispatch-resolve.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/commands/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgHvD"}
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/commands/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQzC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8IvD"}
@@ -9,34 +9,65 @@ import pc from 'picocolors';
9
9
  import { loadContext } from '../context.js';
10
10
  import { printError, printInfo, printHeader } from '../output.js';
11
11
  import { DEEP_MODE_SUFFIX, COMPLEX_PROMPT_RE } from '@olam/core/src/orchestrator/dispatch.js';
12
+ import { resolveWorld, suggestWorlds, validateMode, DISPATCH_MODES } from './dispatch-resolve.js';
12
13
  export function registerDispatch(program) {
13
14
  program
14
15
  .command('dispatch')
15
16
  .description('Send a prompt to a world for execution')
16
- .argument('<world>', 'World ID')
17
+ .argument('<world>', 'World ID or name')
17
18
  .argument('<prompt>', 'Task prompt')
18
- .option('--mode <mode>', 'Execution mode: deep, fast, auto', 'auto')
19
+ .option('--mode <mode>', `Execution mode: ${DISPATCH_MODES.join(', ')}`, 'auto')
19
20
  .option('--max-turns <n>', 'Maximum turns', parseInt)
20
- .action(async (worldId, prompt, opts) => {
21
+ .action(async (world, prompt, opts) => {
22
+ // Validate --mode up front: a typo (`--mode dep`) used to fall
23
+ // through to non-deep behaviour silently. Fail loud instead.
24
+ const modeResult = validateMode(opts.mode);
25
+ if ('error' in modeResult) {
26
+ printError(modeResult.error);
27
+ process.exitCode = 1;
28
+ return;
29
+ }
30
+ const mode = modeResult.mode;
21
31
  const { ctx, error } = await loadContext();
22
32
  if (!ctx) {
23
33
  printError(error?.message ?? 'Olam is not configured. Run `olam init` first.');
24
34
  process.exitCode = 1;
25
35
  return;
26
36
  }
27
- const worldMeta = ctx.worldManager.getWorld(worldId);
37
+ const worlds = ctx.worldManager.listWorlds();
38
+ // Accept either a world ID (existing contract) or a name — operators
39
+ // usually remember the name, not the generated id.
40
+ const worldMeta = resolveWorld(worlds, world);
28
41
  if (!worldMeta) {
29
- printError(`World "${worldId}" not found. Run \`olam list\` to see worlds.`);
42
+ printError(`World "${world}" not found.`);
43
+ const suggestions = suggestWorlds(worlds, world);
44
+ if (suggestions.length > 0) {
45
+ console.error(pc.dim('\n Did you mean:'));
46
+ for (const s of suggestions) {
47
+ console.error(` ${pc.bold(s.name)} ${pc.dim(`(${s.id})`)} ${pc.dim(s.status)}`);
48
+ }
49
+ }
50
+ console.error(pc.dim('\n Run `olam list` to see all worlds.'));
30
51
  process.exitCode = 1;
31
52
  return;
32
53
  }
54
+ const worldId = worldMeta.id;
33
55
  // D3: warn-not-block version pin check (once per world per session).
34
56
  {
35
57
  const { checkVersionPin } = await import('@olam/core/src/world/version-pin.js');
36
58
  checkVersionPin(worldId, worldMeta.workspacePath);
37
59
  }
38
60
  if (worldMeta.status !== 'running') {
39
- printError(`World "${worldId}" is ${worldMeta.status}. Only running worlds accept dispatches.`);
61
+ printError(`World "${worldMeta.name}" (${worldId}) is ${worldMeta.status}. Only running worlds accept dispatches.`);
62
+ if (worldMeta.status === 'paused') {
63
+ console.error(pc.dim(`\n Resume it first: olam resume ${worldId}`));
64
+ }
65
+ else if (worldMeta.status === 'destroyed') {
66
+ console.error(pc.dim('\n This world was destroyed. Create a fresh one with `olam create`.'));
67
+ }
68
+ else {
69
+ console.error(pc.dim(`\n Check what it's doing: olam status ${worldId}`));
70
+ }
40
71
  process.exitCode = 1;
41
72
  return;
42
73
  }
@@ -53,10 +84,10 @@ export function registerDispatch(program) {
53
84
  await computeWorld.exec('curl -s -X POST http://localhost:8080/api/claude/start');
54
85
  // Enhance prompt based on mode (shared regex with MCP server)
55
86
  let finalPrompt = prompt;
56
- if (opts.mode === 'deep') {
87
+ if (mode === 'deep') {
57
88
  finalPrompt += DEEP_MODE_SUFFIX;
58
89
  }
59
- else if (opts.mode === 'auto') {
90
+ else if (mode === 'auto') {
60
91
  const isComplex = prompt.length > 100 ||
61
92
  COMPLEX_PROMPT_RE.test(prompt);
62
93
  if (isComplex) {
@@ -83,7 +114,7 @@ export function registerDispatch(program) {
83
114
  const terminalPort = 17681 + worldMeta.portOffset;
84
115
  printHeader('Dispatch');
85
116
  printInfo('World', `${worldMeta.name} (${worldId})`);
86
- printInfo('Mode', opts.mode);
117
+ printInfo('Mode', mode);
87
118
  printInfo('Dashboard', `http://localhost:${dashboardPort}`);
88
119
  printInfo('Terminal', `http://localhost:${terminalPort}`);
89
120
  const containerName = `olam-${worldId}-devbox`;
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../src/commands/dispatch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../src/commands/dispatch.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/flywheel/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYzC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiBvD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/flywheel/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmBvD"}
@@ -32,6 +32,8 @@ import { registerFlywheelDiversityCheck } from './diversity-check.js';
32
32
  import { registerFlywheelPing } from './ping.js';
33
33
  import { registerFlywheelInstallShims } from './install-shims.js';
34
34
  import { registerFlywheelMigrateOverlays } from './migrate-overlays.js';
35
+ import { registerFlywheelSessionStart } from './session-start.js';
36
+ import { registerFlywheelInstallSessionStartHook } from './install-sessionstart-hook.js';
35
37
  export function registerFlywheel(program) {
36
38
  const flywheel = program
37
39
  .command('flywheel')
@@ -46,5 +48,7 @@ export function registerFlywheel(program) {
46
48
  registerFlywheelPing(flywheel);
47
49
  registerFlywheelInstallShims(flywheel);
48
50
  registerFlywheelMigrateOverlays(flywheel);
51
+ registerFlywheelSessionStart(flywheel);
52
+ registerFlywheelInstallSessionStartHook(flywheel);
49
53
  }
50
54
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/flywheel/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAE,8BAA8B,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,qCAAqC,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,oCAAoC,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,8BAA8B,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,+BAA+B,EAAE,MAAM,uBAAuB,CAAC;AAExE,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,MAAM,QAAQ,GAAG,OAAO;SACrB,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CACV,qNAAqN,CACtN,CAAC;IAEJ,8BAA8B,CAAC,QAAQ,CAAC,CAAC;IACzC,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAClC,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IACrC,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IACrC,qCAAqC,CAAC,QAAQ,CAAC,CAAC;IAChD,oCAAoC,CAAC,QAAQ,CAAC,CAAC;IAC/C,8BAA8B,CAAC,QAAQ,CAAC,CAAC;IACzC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC/B,4BAA4B,CAAC,QAAQ,CAAC,CAAC;IACvC,+BAA+B,CAAC,QAAQ,CAAC,CAAC;AAC5C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/flywheel/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAE,8BAA8B,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,qCAAqC,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,oCAAoC,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,8BAA8B,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,+BAA+B,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,uCAAuC,EAAE,MAAM,gCAAgC,CAAC;AAEzF,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,MAAM,QAAQ,GAAG,OAAO;SACrB,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CACV,qNAAqN,CACtN,CAAC;IAEJ,8BAA8B,CAAC,QAAQ,CAAC,CAAC;IACzC,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAClC,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IACrC,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IACrC,qCAAqC,CAAC,QAAQ,CAAC,CAAC;IAChD,oCAAoC,CAAC,QAAQ,CAAC,CAAC;IAC/C,8BAA8B,CAAC,QAAQ,CAAC,CAAC;IACzC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC/B,4BAA4B,CAAC,QAAQ,CAAC,CAAC;IACvC,+BAA+B,CAAC,QAAQ,CAAC,CAAC;IAC1C,4BAA4B,CAAC,QAAQ,CAAC,CAAC;IACvC,uCAAuC,CAAC,QAAQ,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * `olam flywheel install-sessionstart-hook [--scope project|user] [--uninstall]`
3
+ *
4
+ * Wires `olam flywheel session-start` into `<scope>/.claude/settings.json`
5
+ * hooks.SessionStart so Claude Code injects operator-state context (active
6
+ * workspace + active world + most-recent wake-brief) before the first user
7
+ * prompt. The 4th defense layer in Olam's hook chain (FF / PreToolUse /
8
+ * PostToolUse / Stop).
9
+ *
10
+ * Coexists with the existing skills-sync SessionStart hook
11
+ * (sentinel `olam-skills-sync-hook-v1`). Both entries sit side-by-side in
12
+ * the SessionStart array; Claude Code runs each matcher in order and merges
13
+ * their `additionalContext` outputs into the first turn's system prompt.
14
+ *
15
+ * Idempotent: re-running over an existing install is a no-op (sentinel match
16
+ * via `mergeHomeSettingsJson`).
17
+ *
18
+ * Pairs with: `docs/runbooks/install-sessionstart-hook.md`,
19
+ * `docs/decisions/051-sessionstart-hook-4th-defense.md`.
20
+ */
21
+ import type { Command } from 'commander';
22
+ export declare const SESSIONSTART_HOOK_STAGE = "SessionStart";
23
+ export declare const SESSIONSTART_HOOK_TIMEOUT_MS = 5000;
24
+ interface SessionStartHookMatcher {
25
+ readonly matcher: string;
26
+ readonly hooks: ReadonlyArray<{
27
+ readonly type: 'command';
28
+ readonly command: string;
29
+ readonly timeout: number;
30
+ }>;
31
+ }
32
+ /**
33
+ * Build the matcher-entry object that lands under hooks.SessionStart in
34
+ * .claude/settings.json. Embeds the sentinel as a leading no-op shell
35
+ * assignment so `command.includes(sentinel)` works for idempotent install +
36
+ * surgical uninstall, then guards against uninstalled-olam to keep the hook
37
+ * silent when the CLI is missing (audited by `audit:hook-guards`).
38
+ */
39
+ export declare function buildSessionStartHookEntry(): SessionStartHookMatcher;
40
+ export interface InstallResult {
41
+ readonly status: 'installed' | 'already-present' | 'no-op';
42
+ readonly filePath: string;
43
+ readonly backupPath: string | null;
44
+ }
45
+ /**
46
+ * Install (idempotent) — programmatic API for both the CLI action and tests.
47
+ * Creates parent dir if needed; backs up an existing settings.json before
48
+ * writing (auto-deletes the backup when the install is a no-op).
49
+ */
50
+ export declare function installSessionStartHook(filePath: string): InstallResult;
51
+ export interface UninstallResult {
52
+ readonly status: 'removed' | 'not-found' | 'no-settings';
53
+ readonly filePath: string;
54
+ }
55
+ /**
56
+ * Uninstall (surgical) — walks hooks.SessionStart, drops inner entries whose
57
+ * command contains the sentinel, drops the outer matcher when its hooks
58
+ * array becomes empty. Other SessionStart entries (e.g. the skills-sync
59
+ * hook) are preserved verbatim.
60
+ */
61
+ export declare function uninstallSessionStartHook(filePath: string): UninstallResult;
62
+ export declare function registerFlywheelInstallSessionStartHook(parent: Command): void;
63
+ export {};
64
+ //# sourceMappingURL=install-sessionstart-hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-sessionstart-hook.d.ts","sourceRoot":"","sources":["../../../src/commands/flywheel/install-sessionstart-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,eAAO,MAAM,uBAAuB,iBAAiB,CAAC;AACtD,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAIjD,UAAU,uBAAuB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;QAC5B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;QACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,CAAC,CAAC;CACJ;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,IAAI,uBAAuB,CAWpE;AAsBD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,GAAG,OAAO,CAAC;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAsBvE;AAOD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAiD3E;AAED,wBAAgB,uCAAuC,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAsD7E"}
@@ -0,0 +1,197 @@
1
+ /**
2
+ * `olam flywheel install-sessionstart-hook [--scope project|user] [--uninstall]`
3
+ *
4
+ * Wires `olam flywheel session-start` into `<scope>/.claude/settings.json`
5
+ * hooks.SessionStart so Claude Code injects operator-state context (active
6
+ * workspace + active world + most-recent wake-brief) before the first user
7
+ * prompt. The 4th defense layer in Olam's hook chain (FF / PreToolUse /
8
+ * PostToolUse / Stop).
9
+ *
10
+ * Coexists with the existing skills-sync SessionStart hook
11
+ * (sentinel `olam-skills-sync-hook-v1`). Both entries sit side-by-side in
12
+ * the SessionStart array; Claude Code runs each matcher in order and merges
13
+ * their `additionalContext` outputs into the first turn's system prompt.
14
+ *
15
+ * Idempotent: re-running over an existing install is a no-op (sentinel match
16
+ * via `mergeHomeSettingsJson`).
17
+ *
18
+ * Pairs with: `docs/runbooks/install-sessionstart-hook.md`,
19
+ * `docs/decisions/051-sessionstart-hook-4th-defense.md`.
20
+ */
21
+ import { existsSync, copyFileSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
22
+ import { homedir } from 'node:os';
23
+ import { dirname, join } from 'node:path';
24
+ import { mergeHomeSettingsJson } from '@olam/core/src/world/merge-settings.js';
25
+ import { printError, printInfo, printSuccess, printWarning } from '../../output.js';
26
+ import { SESSIONSTART_HOOK_SENTINEL } from './session-start.js';
27
+ export const SESSIONSTART_HOOK_STAGE = 'SessionStart';
28
+ export const SESSIONSTART_HOOK_TIMEOUT_MS = 5000;
29
+ const NOOP_GUARD = 'command -v olam >/dev/null 2>&1 || exit 0;';
30
+ /**
31
+ * Build the matcher-entry object that lands under hooks.SessionStart in
32
+ * .claude/settings.json. Embeds the sentinel as a leading no-op shell
33
+ * assignment so `command.includes(sentinel)` works for idempotent install +
34
+ * surgical uninstall, then guards against uninstalled-olam to keep the hook
35
+ * silent when the CLI is missing (audited by `audit:hook-guards`).
36
+ */
37
+ export function buildSessionStartHookEntry() {
38
+ return {
39
+ matcher: '',
40
+ hooks: [
41
+ {
42
+ type: 'command',
43
+ command: `OLAM_SESSIONSTART_SENTINEL=${SESSIONSTART_HOOK_SENTINEL}; ${NOOP_GUARD} olam flywheel session-start`,
44
+ timeout: SESSIONSTART_HOOK_TIMEOUT_MS,
45
+ },
46
+ ],
47
+ };
48
+ }
49
+ function settingsPathFor(scope, cwd) {
50
+ if (scope === 'user')
51
+ return join(homedir(), '.claude', 'settings.json');
52
+ return join(cwd ?? process.cwd(), '.claude', 'settings.json');
53
+ }
54
+ function backup(filePath) {
55
+ if (!existsSync(filePath))
56
+ return null;
57
+ const ts = new Date().toISOString().replace(/[:.]/g, '-');
58
+ const backupPath = `${filePath}.olam-bak.${ts}`;
59
+ copyFileSync(filePath, backupPath);
60
+ return backupPath;
61
+ }
62
+ /**
63
+ * Install (idempotent) — programmatic API for both the CLI action and tests.
64
+ * Creates parent dir if needed; backs up an existing settings.json before
65
+ * writing (auto-deletes the backup when the install is a no-op).
66
+ */
67
+ export function installSessionStartHook(filePath) {
68
+ mkdirSync(dirname(filePath), { recursive: true });
69
+ const backupPath = backup(filePath);
70
+ const result = mergeHomeSettingsJson(filePath, {
71
+ ensureHook: {
72
+ stage: SESSIONSTART_HOOK_STAGE,
73
+ sentinel: SESSIONSTART_HOOK_SENTINEL,
74
+ entry: buildSessionStartHookEntry(),
75
+ },
76
+ });
77
+ if (result.status === 'already-present' && backupPath) {
78
+ try {
79
+ unlinkSync(backupPath);
80
+ }
81
+ catch {
82
+ // best-effort
83
+ }
84
+ return { status: 'already-present', filePath, backupPath: null };
85
+ }
86
+ return { status: result.status, filePath, backupPath };
87
+ }
88
+ /**
89
+ * Uninstall (surgical) — walks hooks.SessionStart, drops inner entries whose
90
+ * command contains the sentinel, drops the outer matcher when its hooks
91
+ * array becomes empty. Other SessionStart entries (e.g. the skills-sync
92
+ * hook) are preserved verbatim.
93
+ */
94
+ export function uninstallSessionStartHook(filePath) {
95
+ if (!existsSync(filePath))
96
+ return { status: 'no-settings', filePath };
97
+ const raw = readFileSync(filePath, 'utf-8');
98
+ const settings = raw.trim() ? JSON.parse(raw) : {};
99
+ const matchers = settings.hooks?.SessionStart;
100
+ if (!Array.isArray(matchers) || matchers.length === 0) {
101
+ return { status: 'not-found', filePath };
102
+ }
103
+ let changed = false;
104
+ const kept = [];
105
+ for (const matcher of matchers) {
106
+ const inner = matcher.hooks ?? [];
107
+ const keptInner = inner.filter((h) => {
108
+ if (typeof h.command === 'string' && h.command.includes(SESSIONSTART_HOOK_SENTINEL)) {
109
+ changed = true;
110
+ return false;
111
+ }
112
+ return true;
113
+ });
114
+ if (keptInner.length === 0 && inner.length > 0) {
115
+ changed = true;
116
+ continue;
117
+ }
118
+ if (keptInner.length === inner.length) {
119
+ kept.push(matcher);
120
+ }
121
+ else {
122
+ kept.push({ ...matcher, hooks: keptInner });
123
+ }
124
+ }
125
+ if (!changed)
126
+ return { status: 'not-found', filePath };
127
+ const next = {
128
+ ...settings,
129
+ hooks: { ...settings.hooks, SessionStart: kept },
130
+ };
131
+ if (kept.length === 0) {
132
+ const otherStages = Object.keys(next.hooks ?? {}).filter((k) => k !== 'SessionStart');
133
+ if (otherStages.length === 0) {
134
+ delete next.hooks;
135
+ }
136
+ else {
137
+ delete next.hooks.SessionStart;
138
+ }
139
+ }
140
+ writeFileSync(filePath, JSON.stringify(next, null, 2) + '\n');
141
+ return { status: 'removed', filePath };
142
+ }
143
+ export function registerFlywheelInstallSessionStartHook(parent) {
144
+ parent
145
+ .command('install-sessionstart-hook')
146
+ .description('Install (or --uninstall) the SessionStart context hook into .claude/settings.json. Idempotent. 4th defense layer — preloads operator state before the first prompt.')
147
+ .option('--scope <scope>', 'project (default; <cwd>/.claude/settings.json) or user (~/.claude/settings.json)', 'project')
148
+ .option('--uninstall', 'Remove the hook instead of installing it')
149
+ .action((opts) => {
150
+ const scope = opts.scope === 'user' ? 'user' : 'project';
151
+ const filePath = settingsPathFor(scope);
152
+ if (opts.uninstall) {
153
+ try {
154
+ const r = uninstallSessionStartHook(filePath);
155
+ switch (r.status) {
156
+ case 'removed':
157
+ printSuccess(`SessionStart context hook removed from ${filePath}`);
158
+ return;
159
+ case 'not-found':
160
+ printInfo('sessionstart hook', `not found in ${filePath} — already uninstalled`);
161
+ return;
162
+ case 'no-settings':
163
+ printInfo('sessionstart hook', `no settings.json at ${filePath} — nothing to remove`);
164
+ return;
165
+ }
166
+ }
167
+ catch (err) {
168
+ printError(`uninstall failed: ${err instanceof Error ? err.message : String(err)}`);
169
+ process.exitCode = 1;
170
+ }
171
+ return;
172
+ }
173
+ try {
174
+ const r = installSessionStartHook(filePath);
175
+ switch (r.status) {
176
+ case 'installed':
177
+ printSuccess(`SessionStart context hook installed (${scope} scope)`);
178
+ printInfo('settings', r.filePath);
179
+ if (r.backupPath)
180
+ printInfo('backup', r.backupPath);
181
+ printInfo('next', 'open a new Claude Code session — Olam state will preload via additionalContext');
182
+ return;
183
+ case 'already-present':
184
+ printInfo('sessionstart hook', `already installed at ${r.filePath}`);
185
+ return;
186
+ case 'no-op':
187
+ printWarning(`no change made to ${r.filePath}`);
188
+ return;
189
+ }
190
+ }
191
+ catch (err) {
192
+ printError(`install failed: ${err instanceof Error ? err.message : String(err)}`);
193
+ process.exitCode = 1;
194
+ }
195
+ });
196
+ }
197
+ //# sourceMappingURL=install-sessionstart-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-sessionstart-hook.js","sourceRoot":"","sources":["../../../src/commands/flywheel/install-sessionstart-hook.ts"],"names":[],"mappings":"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"}