@pleri/olam-cli 0.1.153 → 0.1.157

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 (116) hide show
  1. package/dist/commands/bootstrap.d.ts +2 -1
  2. package/dist/commands/bootstrap.d.ts.map +1 -1
  3. package/dist/commands/bootstrap.js +8 -10
  4. package/dist/commands/bootstrap.js.map +1 -1
  5. package/dist/commands/doctor.d.ts +22 -0
  6. package/dist/commands/doctor.d.ts.map +1 -1
  7. package/dist/commands/doctor.js +110 -7
  8. package/dist/commands/doctor.js.map +1 -1
  9. package/dist/commands/flywheel/check-persona-skeleton.d.ts +7 -0
  10. package/dist/commands/flywheel/check-persona-skeleton.d.ts.map +1 -0
  11. package/dist/commands/flywheel/check-persona-skeleton.js +14 -0
  12. package/dist/commands/flywheel/check-persona-skeleton.js.map +1 -0
  13. package/dist/commands/flywheel/diversity-check.d.ts +7 -0
  14. package/dist/commands/flywheel/diversity-check.d.ts.map +1 -0
  15. package/dist/commands/flywheel/diversity-check.js +14 -0
  16. package/dist/commands/flywheel/diversity-check.js.map +1 -0
  17. package/dist/commands/flywheel/emit-breadcrumb.d.ts +20 -0
  18. package/dist/commands/flywheel/emit-breadcrumb.d.ts.map +1 -0
  19. package/dist/commands/flywheel/emit-breadcrumb.js +137 -0
  20. package/dist/commands/flywheel/emit-breadcrumb.js.map +1 -0
  21. package/dist/commands/flywheel/index.d.ts +27 -0
  22. package/dist/commands/flywheel/index.d.ts.map +1 -0
  23. package/dist/commands/flywheel/index.js +48 -0
  24. package/dist/commands/flywheel/index.js.map +1 -0
  25. package/dist/commands/flywheel/install-shims.d.ts +8 -0
  26. package/dist/commands/flywheel/install-shims.d.ts.map +1 -0
  27. package/dist/commands/flywheel/install-shims.js +15 -0
  28. package/dist/commands/flywheel/install-shims.js.map +1 -0
  29. package/dist/commands/flywheel/k10-measure.d.ts +7 -0
  30. package/dist/commands/flywheel/k10-measure.d.ts.map +1 -0
  31. package/dist/commands/flywheel/k10-measure.js +14 -0
  32. package/dist/commands/flywheel/k10-measure.js.map +1 -0
  33. package/dist/commands/flywheel/k5-score.d.ts +14 -0
  34. package/dist/commands/flywheel/k5-score.d.ts.map +1 -0
  35. package/dist/commands/flywheel/k5-score.js +59 -0
  36. package/dist/commands/flywheel/k5-score.js.map +1 -0
  37. package/dist/commands/flywheel/k5-validate.d.ts +15 -0
  38. package/dist/commands/flywheel/k5-validate.d.ts.map +1 -0
  39. package/dist/commands/flywheel/k5-validate.js +185 -0
  40. package/dist/commands/flywheel/k5-validate.js.map +1 -0
  41. package/dist/commands/flywheel/ping.d.ts +21 -0
  42. package/dist/commands/flywheel/ping.d.ts.map +1 -0
  43. package/dist/commands/flywheel/ping.js +79 -0
  44. package/dist/commands/flywheel/ping.js.map +1 -0
  45. package/dist/commands/flywheel/sanitize-persona-output.d.ts +7 -0
  46. package/dist/commands/flywheel/sanitize-persona-output.d.ts.map +1 -0
  47. package/dist/commands/flywheel/sanitize-persona-output.js +14 -0
  48. package/dist/commands/flywheel/sanitize-persona-output.js.map +1 -0
  49. package/dist/commands/hermes-kg-hook.d.ts +36 -0
  50. package/dist/commands/hermes-kg-hook.d.ts.map +1 -0
  51. package/dist/commands/hermes-kg-hook.js +80 -0
  52. package/dist/commands/hermes-kg-hook.js.map +1 -0
  53. package/dist/commands/hermes.d.ts +46 -0
  54. package/dist/commands/hermes.d.ts.map +1 -0
  55. package/dist/commands/hermes.js +320 -0
  56. package/dist/commands/hermes.js.map +1 -0
  57. package/dist/commands/kg-install-hook.d.ts +7 -1
  58. package/dist/commands/kg-install-hook.d.ts.map +1 -1
  59. package/dist/commands/kg-install-hook.js +122 -6
  60. package/dist/commands/kg-install-hook.js.map +1 -1
  61. package/dist/commands/memory/_paths.d.ts +13 -3
  62. package/dist/commands/memory/_paths.d.ts.map +1 -1
  63. package/dist/commands/memory/_paths.js +25 -22
  64. package/dist/commands/memory/_paths.js.map +1 -1
  65. package/dist/commands/memory/logs.d.ts +8 -4
  66. package/dist/commands/memory/logs.d.ts.map +1 -1
  67. package/dist/commands/memory/logs.js +18 -13
  68. package/dist/commands/memory/logs.js.map +1 -1
  69. package/dist/commands/memory/mode.d.ts.map +1 -1
  70. package/dist/commands/memory/mode.js +7 -3
  71. package/dist/commands/memory/mode.js.map +1 -1
  72. package/dist/commands/memory/start.d.ts +16 -14
  73. package/dist/commands/memory/start.d.ts.map +1 -1
  74. package/dist/commands/memory/start.js +55 -189
  75. package/dist/commands/memory/start.js.map +1 -1
  76. package/dist/commands/memory/status.d.ts +10 -8
  77. package/dist/commands/memory/status.d.ts.map +1 -1
  78. package/dist/commands/memory/status.js +35 -38
  79. package/dist/commands/memory/status.js.map +1 -1
  80. package/dist/commands/memory/stop.d.ts +5 -4
  81. package/dist/commands/memory/stop.d.ts.map +1 -1
  82. package/dist/commands/memory/stop.js +26 -55
  83. package/dist/commands/memory/stop.js.map +1 -1
  84. package/dist/commands/memory-service-container.d.ts +78 -0
  85. package/dist/commands/memory-service-container.d.ts.map +1 -0
  86. package/dist/commands/memory-service-container.js +187 -0
  87. package/dist/commands/memory-service-container.js.map +1 -0
  88. package/dist/commands/services.d.ts +16 -1
  89. package/dist/commands/services.d.ts.map +1 -1
  90. package/dist/commands/services.js +88 -12
  91. package/dist/commands/services.js.map +1 -1
  92. package/dist/image-digests.json +7 -7
  93. package/dist/index.js +2572 -1376
  94. package/dist/index.js.map +1 -1
  95. package/dist/lib/memory-host-process-migration.d.ts +56 -0
  96. package/dist/lib/memory-host-process-migration.d.ts.map +1 -0
  97. package/dist/lib/memory-host-process-migration.js +156 -0
  98. package/dist/lib/memory-host-process-migration.js.map +1 -0
  99. package/dist/lib/upgrade-kubernetes.d.ts +19 -0
  100. package/dist/lib/upgrade-kubernetes.d.ts.map +1 -1
  101. package/dist/lib/upgrade-kubernetes.js +191 -2
  102. package/dist/lib/upgrade-kubernetes.js.map +1 -1
  103. package/dist/mcp-server.js +56 -22
  104. package/hermes-bundle/kg-first.sh +100 -0
  105. package/hermes-bundle/version.json +4 -0
  106. package/host-cp/k8s/manifests/50-deployment.yaml +54 -27
  107. package/host-cp/k8s/manifests/auth-service/30-configmap.yaml +5 -0
  108. package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +5 -1
  109. package/host-cp/k8s/manifests/kg-service/30-configmap.yaml +5 -0
  110. package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +5 -1
  111. package/host-cp/k8s/manifests/mcp-auth-service/30-configmap.yaml +4 -0
  112. package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +5 -1
  113. package/host-cp/k8s/manifests/memory-service/30-configmap.yaml +4 -0
  114. package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +5 -1
  115. package/package.json +3 -4
  116. package/memory-service-bundle/scripts/ensure-iii-engine.mjs +0 -179
@@ -0,0 +1,79 @@
1
+ /**
2
+ * `olam flywheel ping` — no-op subcommand for cold-start telemetry.
3
+ *
4
+ * Establishes the measurement baseline OQ12 references: before porting any
5
+ * subcommand from atlas-toolbox to olam, we need to know what cold-start
6
+ * overhead the shim → olam binary path adds vs the current bash-invoked
7
+ * scripts. Operators run `time olam flywheel ping` on a representative
8
+ * machine + record the result.
9
+ *
10
+ * Branch decision (per plan A2):
11
+ * ≤200ms total invocation → full-port for A3+ subcommands (drop hybrid hedge S2)
12
+ * 200-500ms → full-port with follow-up perf-investigation tagged
13
+ * >500ms → escalate to hybrid model (heavy helpers ported;
14
+ * emit-breadcrumb stays as native script delegating)
15
+ *
16
+ * Telemetry baseline written to ~/.local/share/olam/flywheel-baseline.json.
17
+ * Permanent telemetry surface for `olam doctor` (promoted in task A13).
18
+ */
19
+ import { mkdirSync, writeFileSync } from 'node:fs';
20
+ import { homedir } from 'node:os';
21
+ import { dirname, join } from 'node:path';
22
+ const COLD_START_BUDGET_GOOD_MS = 200;
23
+ const COLD_START_BUDGET_FAIR_MS = 500;
24
+ function classifyColdStart(coldStartMs) {
25
+ if (coldStartMs <= COLD_START_BUDGET_GOOD_MS)
26
+ return 'good';
27
+ if (coldStartMs <= COLD_START_BUDGET_FAIR_MS)
28
+ return 'fair';
29
+ return 'over-budget';
30
+ }
31
+ function readOlamVersion() {
32
+ try {
33
+ // packageVersion is injected at build time by the bundle script;
34
+ // fall back to env when running via `npm run dev`.
35
+ return process.env.npm_package_version ?? '0.0.0-dev';
36
+ }
37
+ catch {
38
+ return '0.0.0-dev';
39
+ }
40
+ }
41
+ function writeBaseline(record) {
42
+ const baselinePath = join(homedir(), '.local', 'share', 'olam', 'flywheel-baseline.json');
43
+ mkdirSync(dirname(baselinePath), { recursive: true });
44
+ writeFileSync(baselinePath, JSON.stringify(record, null, 2) + '\n', 'utf8');
45
+ return baselinePath;
46
+ }
47
+ export function registerFlywheelPing(parent) {
48
+ parent
49
+ .command('ping')
50
+ .description('No-op cold-start telemetry surface (measures + records flywheel CLI baseline)')
51
+ .option('--json', 'emit baseline record as JSON instead of human-readable status')
52
+ .option('--no-record-baseline', 'do not write ~/.local/share/olam/flywheel-baseline.json (default: record)')
53
+ .action((opts) => {
54
+ // We measure from the Node process load tick. uptime() returns seconds since
55
+ // the process started, including module-resolution + commander parsing —
56
+ // exactly the operator-visible cold-start surface we want to measure.
57
+ const coldStartMs = Math.round(process.uptime() * 1000);
58
+ const record = {
59
+ cold_start_ms: coldStartMs,
60
+ olam_version: readOlamVersion(),
61
+ measured_at: new Date().toISOString(),
62
+ classification: classifyColdStart(coldStartMs),
63
+ };
64
+ let baselinePath;
65
+ if (opts.recordBaseline !== false) {
66
+ baselinePath = writeBaseline(record);
67
+ }
68
+ if (opts.json) {
69
+ process.stdout.write(JSON.stringify(record) + '\n');
70
+ }
71
+ else {
72
+ process.stdout.write(`flywheel ping: cold_start=${record.cold_start_ms}ms classification=${record.classification} version=${record.olam_version}\n`);
73
+ if (baselinePath !== undefined) {
74
+ process.stdout.write(`baseline recorded: ${baselinePath}\n`);
75
+ }
76
+ }
77
+ });
78
+ }
79
+ //# sourceMappingURL=ping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ping.js","sourceRoot":"","sources":["../../../src/commands/flywheel/ping.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG1C,MAAM,yBAAyB,GAAG,GAAG,CAAC;AACtC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AActC,SAAS,iBAAiB,CAAC,WAAmB;IAC5C,IAAI,WAAW,IAAI,yBAAyB;QAAE,OAAO,MAAM,CAAC;IAC5D,IAAI,WAAW,IAAI,yBAAyB;QAAE,OAAO,MAAM,CAAC;IAC5D,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,SAAS,eAAe;IACtB,IAAI,CAAC;QACH,iEAAiE;QACjE,mDAAmD;QACnD,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,WAAW,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,MAAwB;IAC7C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,wBAAwB,CAAC,CAAC;IAC1F,SAAS,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5E,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAe;IAClD,MAAM;SACH,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,+EAA+E,CAAC;SAC5F,MAAM,CAAC,QAAQ,EAAE,+DAA+D,CAAC;SACjF,MAAM,CACL,sBAAsB,EACtB,2EAA2E,CAC5E;SACA,MAAM,CAAC,CAAC,IAAyB,EAAE,EAAE;QACpC,6EAA6E;QAC7E,yEAAyE;QACzE,sEAAsE;QACtE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;QACxD,MAAM,MAAM,GAAqB;YAC/B,aAAa,EAAE,WAAW;YAC1B,YAAY,EAAE,eAAe,EAAE;YAC/B,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACrC,cAAc,EAAE,iBAAiB,CAAC,WAAW,CAAC;SAC/C,CAAC;QAEF,IAAI,YAAgC,CAAC;QACrC,IAAI,IAAI,CAAC,cAAc,KAAK,KAAK,EAAE,CAAC;YAClC,YAAY,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;QACtD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,6BAA6B,MAAM,CAAC,aAAa,qBAAqB,MAAM,CAAC,cAAc,YAAY,MAAM,CAAC,YAAY,IAAI,CAC/H,CAAC;YACF,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;gBAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,YAAY,IAAI,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * `olam flywheel sanitize-persona-output` — stub registered in task A1.
3
+ * Implementation lands in task A6 (port from `shared/engineering/scripts/sanitize-persona-output.py`).
4
+ */
5
+ import type { Command } from 'commander';
6
+ export declare function registerFlywheelSanitizePersonaOutput(parent: Command): void;
7
+ //# sourceMappingURL=sanitize-persona-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize-persona-output.d.ts","sourceRoot":"","sources":["../../../src/commands/flywheel/sanitize-persona-output.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,wBAAgB,qCAAqC,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAY3E"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `olam flywheel sanitize-persona-output` — stub registered in task A1.
3
+ * Implementation lands in task A6 (port from `shared/engineering/scripts/sanitize-persona-output.py`).
4
+ */
5
+ export function registerFlywheelSanitizePersonaOutput(parent) {
6
+ parent
7
+ .command('sanitize-persona-output')
8
+ .description('Pipe persona output through sanitization rules (stdin→stdout; rejects header-injection, slug-mismatch) (stub — implemented in task A6)')
9
+ .action(() => {
10
+ console.error('olam flywheel sanitize-persona-output: not yet implemented (task A6). See docs/plans/olam-flywheel-cli-namespace/phase-a-tasks.md');
11
+ process.exit(2);
12
+ });
13
+ }
14
+ //# sourceMappingURL=sanitize-persona-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize-persona-output.js","sourceRoot":"","sources":["../../../src/commands/flywheel/sanitize-persona-output.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,UAAU,qCAAqC,CAAC,MAAe;IACnE,MAAM;SACH,OAAO,CAAC,yBAAyB,CAAC;SAClC,WAAW,CACV,wIAAwI,CACzI;SACA,MAAM,CAAC,GAAG,EAAE;QACX,OAAO,CAAC,KAAK,CACX,mIAAmI,CACpI,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * hermes-kg-hook.ts — install / uninstall the kg-first.sh hook for Hermes.
3
+ *
4
+ * Shared by:
5
+ * - `olam hermes bootstrap` (via runHermesBootstrap)
6
+ * - `olam kg install-hook --for hermes`
7
+ * - `olam kg uninstall-hook --for hermes`
8
+ *
9
+ * Writes the bundled kg-first.sh template from hermes-bundle/ into
10
+ * ~/.hermes/hooks/kg-first.sh and makes it executable. Idempotent:
11
+ * re-installing over an identical file is detected via content hash.
12
+ *
13
+ * HERMES_KG_HOOK_SENTINEL is embedded in the script body (the comment
14
+ * `# OLAM_KG_HOOK` present in the template). It is the stable string
15
+ * both this module and the config-entry writer use to detect presence.
16
+ */
17
+ /** Stable sentinel that appears in both the hook script and config entry. */
18
+ export declare const HERMES_KG_HOOK_SENTINEL = "OLAM_KG_HOOK";
19
+ type HermesKgHookStatus = 'installed' | 'already-present' | 'dry-run';
20
+ export interface HermesKgHookResult {
21
+ readonly status: HermesKgHookStatus;
22
+ readonly destPath: string;
23
+ }
24
+ /**
25
+ * Install kg-first.sh into hooksDir.
26
+ * Returns 'already-present' when an identical script is already there.
27
+ * Returns 'dry-run' when dryRun=true.
28
+ */
29
+ export declare function installKgFirstHookForHermes(hooksDir: string, dryRun: boolean): HermesKgHookResult;
30
+ /**
31
+ * Uninstall: remove kg-first.sh if it contains the sentinel.
32
+ * Returns 'already-present' (noop) when the file doesn't exist or lacks the sentinel.
33
+ */
34
+ export declare function uninstallKgFirstHookForHermes(hooksDir: string, dryRun: boolean): HermesKgHookResult;
35
+ export {};
36
+ //# sourceMappingURL=hermes-kg-hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hermes-kg-hook.d.ts","sourceRoot":"","sources":["../../src/commands/hermes-kg-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,6EAA6E;AAC7E,eAAO,MAAM,uBAAuB,iBAAiB,CAAC;AAEtD,KAAK,kBAAkB,GAAG,WAAW,GAAG,iBAAiB,GAAG,SAAS,CAAC;AAEtE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAmBD;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,GACd,kBAAkB,CAqBpB;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,GACd,kBAAkB,CAmBpB"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * hermes-kg-hook.ts — install / uninstall the kg-first.sh hook for Hermes.
3
+ *
4
+ * Shared by:
5
+ * - `olam hermes bootstrap` (via runHermesBootstrap)
6
+ * - `olam kg install-hook --for hermes`
7
+ * - `olam kg uninstall-hook --for hermes`
8
+ *
9
+ * Writes the bundled kg-first.sh template from hermes-bundle/ into
10
+ * ~/.hermes/hooks/kg-first.sh and makes it executable. Idempotent:
11
+ * re-installing over an identical file is detected via content hash.
12
+ *
13
+ * HERMES_KG_HOOK_SENTINEL is embedded in the script body (the comment
14
+ * `# OLAM_KG_HOOK` present in the template). It is the stable string
15
+ * both this module and the config-entry writer use to detect presence.
16
+ */
17
+ import * as fs from 'node:fs';
18
+ import * as path from 'node:path';
19
+ import { createHash } from 'node:crypto';
20
+ import { fileURLToPath } from 'node:url';
21
+ /** Stable sentinel that appears in both the hook script and config entry. */
22
+ export const HERMES_KG_HOOK_SENTINEL = 'OLAM_KG_HOOK';
23
+ function bundleDir() {
24
+ // Resolve hermes-bundle/ relative to this source file.
25
+ // In the published tarball: dist/commands/hermes-kg-hook.js → ../../hermes-bundle/
26
+ // In source (tsx): src/commands/hermes-kg-hook.ts → ../../hermes-bundle/
27
+ const thisFile = fileURLToPath(import.meta.url);
28
+ return path.resolve(path.dirname(thisFile), '..', '..', 'hermes-bundle');
29
+ }
30
+ function templateContent() {
31
+ const templatePath = path.join(bundleDir(), 'kg-first.sh');
32
+ return fs.readFileSync(templatePath);
33
+ }
34
+ function sha256(buf) {
35
+ return createHash('sha256').update(buf).digest('hex');
36
+ }
37
+ /**
38
+ * Install kg-first.sh into hooksDir.
39
+ * Returns 'already-present' when an identical script is already there.
40
+ * Returns 'dry-run' when dryRun=true.
41
+ */
42
+ export function installKgFirstHookForHermes(hooksDir, dryRun) {
43
+ const destPath = path.join(hooksDir, 'kg-first.sh');
44
+ const template = templateContent();
45
+ // Idempotency: compare content hashes
46
+ if (fs.existsSync(destPath)) {
47
+ const existing = fs.readFileSync(destPath);
48
+ if (sha256(existing) === sha256(template)) {
49
+ return { status: 'already-present', destPath };
50
+ }
51
+ }
52
+ if (dryRun) {
53
+ return { status: 'dry-run', destPath };
54
+ }
55
+ fs.mkdirSync(hooksDir, { recursive: true });
56
+ fs.writeFileSync(destPath, template);
57
+ fs.chmodSync(destPath, 0o755);
58
+ return { status: 'installed', destPath };
59
+ }
60
+ /**
61
+ * Uninstall: remove kg-first.sh if it contains the sentinel.
62
+ * Returns 'already-present' (noop) when the file doesn't exist or lacks the sentinel.
63
+ */
64
+ export function uninstallKgFirstHookForHermes(hooksDir, dryRun) {
65
+ const destPath = path.join(hooksDir, 'kg-first.sh');
66
+ if (!fs.existsSync(destPath)) {
67
+ return { status: 'already-present', destPath };
68
+ }
69
+ const content = fs.readFileSync(destPath, 'utf-8');
70
+ if (!content.includes(HERMES_KG_HOOK_SENTINEL)) {
71
+ // Not ours — do not remove
72
+ return { status: 'already-present', destPath };
73
+ }
74
+ if (dryRun) {
75
+ return { status: 'dry-run', destPath };
76
+ }
77
+ fs.unlinkSync(destPath);
78
+ return { status: 'installed', destPath };
79
+ }
80
+ //# sourceMappingURL=hermes-kg-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hermes-kg-hook.js","sourceRoot":"","sources":["../../src/commands/hermes-kg-hook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * `olam hermes bootstrap` — one-shot wiring of a fresh Hermes install to olam.
3
+ *
4
+ * Performs:
5
+ * 1. Validates ~/.hermes/config.yaml exists (refuses with actionable message if not).
6
+ * 2. Adds mcp_servers.olam (resolved via `which olam` or argv[1] fallback).
7
+ * 3. Optionally adds mcp_servers.agentmemory-atlas when bridge URL + secret
8
+ * are available (env vars or --bridge-url / --bridge-secret flags).
9
+ * 4. Installs kg-first.sh hook via installKgFirstHookForHermes.
10
+ * 5. Mirrors ~/.claude/skills/* symlinks into ~/.hermes/skills/.
11
+ * 6. Sets terminal.backend = 'local' (unless --keep-docker is given).
12
+ * 7. Prints a summary of added / skipped / next-steps.
13
+ *
14
+ * All mutations are idempotent: re-running is safe.
15
+ * --dry-run prints the planned diff without writing anything.
16
+ */
17
+ import type { Command } from 'commander';
18
+ import { type HermesKgHookResult } from './hermes-kg-hook.js';
19
+ interface HermesBootstrapOptions {
20
+ readonly dryRun?: boolean;
21
+ readonly keepDocker?: boolean;
22
+ readonly bridgeUrl?: string;
23
+ readonly bridgeSecret?: string;
24
+ }
25
+ type HermesConfig = Record<string, unknown>;
26
+ export declare function hermesConfigPath(): string;
27
+ export declare function hermesHooksDir(): string;
28
+ export declare function hermesSkillsDir(): string;
29
+ export declare function claudeSkillsDir(): string;
30
+ interface BootstrapSummary {
31
+ added: string[];
32
+ skipped: string[];
33
+ nextSteps: string[];
34
+ }
35
+ export declare function runHermesBootstrap(opts: HermesBootstrapOptions, deps?: {
36
+ readonly configPath?: string;
37
+ readonly olamBin?: string;
38
+ readonly workspaceDir?: string;
39
+ readonly readConfig?: (p: string) => HermesConfig;
40
+ readonly writeConfig?: (p: string, c: HermesConfig) => void;
41
+ readonly mirrorSkills?: (dryRun: boolean, summary: BootstrapSummary) => void;
42
+ readonly installHook?: (hooksDir: string, dryRun: boolean) => HermesKgHookResult;
43
+ }): Promise<void>;
44
+ export declare function registerHermes(program: Command): void;
45
+ export {};
46
+ //# sourceMappingURL=hermes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hermes.d.ts","sourceRoot":"","sources":["../../src/commands/hermes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,qBAAqB,CAAC;AAI7B,UAAU,sBAAsB;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAID,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAI5C,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAoDD,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AA6HD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,sBAAsB,EAC5B,IAAI,GAAE;IACJ,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC;IAClD,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;IAC5D,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC7E,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,kBAAkB,CAAC;CAC7E,GACL,OAAO,CAAC,IAAI,CAAC,CAwGf;AA+CD,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAerD"}
@@ -0,0 +1,320 @@
1
+ /**
2
+ * `olam hermes bootstrap` — one-shot wiring of a fresh Hermes install to olam.
3
+ *
4
+ * Performs:
5
+ * 1. Validates ~/.hermes/config.yaml exists (refuses with actionable message if not).
6
+ * 2. Adds mcp_servers.olam (resolved via `which olam` or argv[1] fallback).
7
+ * 3. Optionally adds mcp_servers.agentmemory-atlas when bridge URL + secret
8
+ * are available (env vars or --bridge-url / --bridge-secret flags).
9
+ * 4. Installs kg-first.sh hook via installKgFirstHookForHermes.
10
+ * 5. Mirrors ~/.claude/skills/* symlinks into ~/.hermes/skills/.
11
+ * 6. Sets terminal.backend = 'local' (unless --keep-docker is given).
12
+ * 7. Prints a summary of added / skipped / next-steps.
13
+ *
14
+ * All mutations are idempotent: re-running is safe.
15
+ * --dry-run prints the planned diff without writing anything.
16
+ */
17
+ import * as fs from 'node:fs';
18
+ import * as os from 'node:os';
19
+ import * as path from 'node:path';
20
+ import * as child_process from 'node:child_process';
21
+ import { parse as yamlParse, stringify as yamlStringify } from 'yaml';
22
+ import { printError, printInfo, printSuccess, printWarning } from '../output.js';
23
+ import { installKgFirstHookForHermes, uninstallKgFirstHookForHermes, HERMES_KG_HOOK_SENTINEL, } from './hermes-kg-hook.js';
24
+ // ── Paths ─────────────────────────────────────────────────────────────────────
25
+ export function hermesConfigPath() {
26
+ return path.join(os.homedir(), '.hermes', 'config.yaml');
27
+ }
28
+ export function hermesHooksDir() {
29
+ return path.join(os.homedir(), '.hermes', 'hooks');
30
+ }
31
+ export function hermesSkillsDir() {
32
+ return path.join(os.homedir(), '.hermes', 'skills');
33
+ }
34
+ export function claudeSkillsDir() {
35
+ return path.join(os.homedir(), '.claude', 'skills');
36
+ }
37
+ // ── YAML helpers ──────────────────────────────────────────────────────────────
38
+ function readHermesConfig(configPath) {
39
+ const raw = fs.readFileSync(configPath, 'utf-8');
40
+ const parsed = yamlParse(raw);
41
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
42
+ throw new Error(`${configPath} is not a YAML mapping`);
43
+ }
44
+ return parsed;
45
+ }
46
+ function writeHermesConfig(configPath, config) {
47
+ fs.writeFileSync(configPath, yamlStringify(config), 'utf-8');
48
+ }
49
+ // ── Olam binary resolution ────────────────────────────────────────────────────
50
+ function resolveOlamBinary() {
51
+ // Prefer `which olam` from PATH.
52
+ try {
53
+ const result = child_process.spawnSync('which', ['olam'], { encoding: 'utf-8' });
54
+ const found = result.stdout.trim();
55
+ if (found && fs.existsSync(found))
56
+ return found;
57
+ }
58
+ catch {
59
+ // fall through
60
+ }
61
+ // Fallback to process.argv[1] (the running CLI binary).
62
+ return process.argv[1] ?? 'olam';
63
+ }
64
+ // ── Workspace dir resolution ──────────────────────────────────────────────────
65
+ function resolveWorkspaceDir() {
66
+ // Try `olam config get workspace.dir`; fall back to cwd.
67
+ try {
68
+ const result = child_process.spawnSync(process.argv[0] ?? 'node', [process.argv[1] ?? 'olam', 'config', 'get', 'workspace.dir'], { encoding: 'utf-8' });
69
+ const out = result.stdout.trim();
70
+ if (out && fs.existsSync(out))
71
+ return out;
72
+ }
73
+ catch {
74
+ // fall through
75
+ }
76
+ return process.cwd();
77
+ }
78
+ // ── Sub-operations ────────────────────────────────────────────────────────────
79
+ function ensureMcpOlam(config, olamBin, workspaceDir, dryRun, summary) {
80
+ const mcpServers = (config['mcp_servers'] ?? {});
81
+ if (mcpServers['olam'] !== undefined) {
82
+ summary.skipped.push('mcp_servers.olam (already present)');
83
+ return config;
84
+ }
85
+ if (dryRun) {
86
+ summary.added.push(`mcp_servers.olam → { command: "${olamBin}", args: ["mcp","serve"], cwd: "${workspaceDir}" }`);
87
+ return config;
88
+ }
89
+ const updated = {
90
+ ...config,
91
+ mcp_servers: {
92
+ ...mcpServers,
93
+ olam: {
94
+ command: olamBin,
95
+ args: ['mcp', 'serve'],
96
+ cwd: workspaceDir,
97
+ },
98
+ },
99
+ };
100
+ summary.added.push('mcp_servers.olam');
101
+ return updated;
102
+ }
103
+ function ensureMcpAgentMemory(config, bridgeUrl, bridgeSecret, dryRun, summary) {
104
+ const mcpServers = (config['mcp_servers'] ?? {});
105
+ const key = 'agentmemory-atlas';
106
+ if (mcpServers[key] !== undefined) {
107
+ summary.skipped.push(`mcp_servers.${key} (already present)`);
108
+ return config;
109
+ }
110
+ if (dryRun) {
111
+ summary.added.push(`mcp_servers.${key} → { bridge_url, bridge_secret }`);
112
+ return config;
113
+ }
114
+ const updated = {
115
+ ...config,
116
+ mcp_servers: {
117
+ ...mcpServers,
118
+ [key]: {
119
+ bridge_url: bridgeUrl,
120
+ bridge_secret: bridgeSecret,
121
+ },
122
+ },
123
+ };
124
+ summary.added.push(`mcp_servers.${key}`);
125
+ return updated;
126
+ }
127
+ function ensureTerminalBackendLocal(config, dryRun, summary) {
128
+ const terminal = (config['terminal'] ?? {});
129
+ if (terminal['backend'] === 'local') {
130
+ summary.skipped.push('terminal.backend (already local)');
131
+ return config;
132
+ }
133
+ if (dryRun) {
134
+ summary.added.push('terminal.backend = local');
135
+ return config;
136
+ }
137
+ return {
138
+ ...config,
139
+ terminal: { ...terminal, backend: 'local' },
140
+ };
141
+ }
142
+ function mirrorSkillSymlinks(dryRun, summary) {
143
+ const srcDir = claudeSkillsDir();
144
+ if (!fs.existsSync(srcDir)) {
145
+ summary.skipped.push('skills mirror (no ~/.claude/skills/ found)');
146
+ return;
147
+ }
148
+ const destDir = hermesSkillsDir();
149
+ if (!dryRun) {
150
+ fs.mkdirSync(destDir, { recursive: true });
151
+ }
152
+ const entries = fs.readdirSync(srcDir);
153
+ let mirrored = 0;
154
+ let collisions = 0;
155
+ for (const entry of entries) {
156
+ const srcPath = path.join(srcDir, entry);
157
+ const destPath = path.join(destDir, entry);
158
+ if (fs.existsSync(destPath) || fs.lstatSync(srcPath).isFile()) {
159
+ // Skip collisions and non-directory entries (skills are dirs)
160
+ if (fs.existsSync(destPath))
161
+ collisions++;
162
+ continue;
163
+ }
164
+ if (dryRun) {
165
+ mirrored++;
166
+ continue;
167
+ }
168
+ try {
169
+ fs.symlinkSync(srcPath, destPath);
170
+ mirrored++;
171
+ }
172
+ catch (err) {
173
+ printWarning(`skills mirror: skipping ${entry} — ${err instanceof Error ? err.message : String(err)}`);
174
+ }
175
+ }
176
+ if (mirrored > 0)
177
+ summary.added.push(`${mirrored} skill symlink(s) → ~/.hermes/skills/`);
178
+ if (collisions > 0)
179
+ summary.skipped.push(`${collisions} skill symlink collision(s)`);
180
+ }
181
+ // ── Bootstrap action ──────────────────────────────────────────────────────────
182
+ export async function runHermesBootstrap(opts, deps = {}) {
183
+ const dryRun = opts.dryRun ?? false;
184
+ const keepDocker = opts.keepDocker ?? false;
185
+ const configPath = deps.configPath ?? hermesConfigPath();
186
+ const olamBin = deps.olamBin ?? resolveOlamBinary();
187
+ const workspaceDir = deps.workspaceDir ?? resolveWorkspaceDir();
188
+ const readConfig = deps.readConfig ?? readHermesConfig;
189
+ const writeConfig = deps.writeConfig ?? writeHermesConfig;
190
+ const mirrorSkillsFn = deps.mirrorSkills ?? mirrorSkillSymlinks;
191
+ const installHookFn = deps.installHook ?? installKgFirstHookForHermes;
192
+ // Guard: ~/.hermes/config.yaml must exist
193
+ if (!fs.existsSync(configPath)) {
194
+ printError(`~/.hermes/config.yaml not found at ${configPath}`);
195
+ printInfo('remedy', 'Install Hermes first: https://hermes.ai/docs/install — then re-run `olam hermes bootstrap`');
196
+ process.exitCode = 1;
197
+ return;
198
+ }
199
+ const summary = { added: [], skipped: [], nextSteps: [] };
200
+ // Load current config
201
+ let config;
202
+ try {
203
+ config = readConfig(configPath);
204
+ }
205
+ catch (err) {
206
+ printError(`Could not parse ${configPath}: ${err instanceof Error ? err.message : String(err)}`);
207
+ process.exitCode = 1;
208
+ return;
209
+ }
210
+ // Step 2: mcp_servers.olam
211
+ config = ensureMcpOlam(config, olamBin, workspaceDir, dryRun, summary);
212
+ // Step 3: mcp_servers.agentmemory-atlas (optional)
213
+ const bridgeUrl = opts.bridgeUrl ?? process.env['AGENTMEMORY_BRIDGE_URL'];
214
+ const bridgeSecret = opts.bridgeSecret ?? process.env['AGENTMEMORY_BRIDGE_SECRET'];
215
+ if (bridgeUrl && bridgeSecret) {
216
+ config = ensureMcpAgentMemory(config, bridgeUrl, bridgeSecret, dryRun, summary);
217
+ }
218
+ else {
219
+ summary.skipped.push('mcp_servers.agentmemory-atlas (AGENTMEMORY_BRIDGE_URL/SECRET not set; use --bridge-url/--bridge-secret to add)');
220
+ }
221
+ // Step 4: kg-first hook
222
+ const hooksDir = path.join(path.dirname(configPath), 'hooks');
223
+ const hookResult = installHookFn(hooksDir, dryRun);
224
+ switch (hookResult.status) {
225
+ case 'installed':
226
+ summary.added.push('kg-first.sh hook');
227
+ break;
228
+ case 'already-present':
229
+ summary.skipped.push('kg-first.sh hook (already installed)');
230
+ break;
231
+ case 'dry-run':
232
+ summary.added.push('kg-first.sh hook (dry-run)');
233
+ break;
234
+ }
235
+ // Ensure hooks.pre_tool_call entry in config
236
+ config = ensureHermesHookEntry(config, hooksDir, dryRun, summary);
237
+ // Step 5: mirror skill symlinks
238
+ mirrorSkillsFn(dryRun, summary);
239
+ // Step 6: terminal.backend = local
240
+ if (!keepDocker) {
241
+ config = ensureTerminalBackendLocal(config, dryRun, summary);
242
+ }
243
+ else {
244
+ summary.skipped.push('terminal.backend (--keep-docker)');
245
+ }
246
+ // Write updated config
247
+ if (!dryRun) {
248
+ try {
249
+ writeConfig(configPath, config);
250
+ }
251
+ catch (err) {
252
+ printError(`Could not write ${configPath}: ${err instanceof Error ? err.message : String(err)}`);
253
+ process.exitCode = 1;
254
+ return;
255
+ }
256
+ }
257
+ // Step 7: print summary
258
+ if (dryRun) {
259
+ printInfo('dry-run', 'No changes written. Planned additions:');
260
+ }
261
+ else {
262
+ printSuccess('Hermes bootstrap complete');
263
+ }
264
+ for (const item of summary.added) {
265
+ printInfo(dryRun ? 'would add' : 'added', item);
266
+ }
267
+ for (const item of summary.skipped) {
268
+ printInfo('skipped', item);
269
+ }
270
+ summary.nextSteps.push('hermes gateway restart');
271
+ for (const step of summary.nextSteps) {
272
+ printInfo('next', step);
273
+ }
274
+ }
275
+ // ── Hook config entry ─────────────────────────────────────────────────────────
276
+ const HOOK_MATCHERS = ['terminal', 'bash', 'shell', 'search_files', 'grep', 'ripgrep'];
277
+ function ensureHermesHookEntry(config, hooksDir, dryRun, summary) {
278
+ const hookScriptPath = path.join(hooksDir, 'kg-first.sh');
279
+ const hooks = (config['hooks'] ?? {});
280
+ const preToolCall = Array.isArray(hooks['pre_tool_call'])
281
+ ? hooks['pre_tool_call']
282
+ : [];
283
+ // Idempotency: check if our sentinel command is already present
284
+ const alreadyPresent = preToolCall.some((entry) => typeof entry['command'] === 'string' && entry['command'].includes(HERMES_KG_HOOK_SENTINEL));
285
+ if (alreadyPresent) {
286
+ summary.skipped.push('hooks.pre_tool_call entry (already present)');
287
+ return config;
288
+ }
289
+ const newEntry = {
290
+ matcher: HOOK_MATCHERS.join('|'),
291
+ command: `${hookScriptPath} # ${HERMES_KG_HOOK_SENTINEL}`,
292
+ };
293
+ if (dryRun) {
294
+ summary.added.push(`hooks.pre_tool_call entry (matcher: ${HOOK_MATCHERS.join('|')})`);
295
+ return config;
296
+ }
297
+ const updatedPreToolCall = [...preToolCall, newEntry];
298
+ return {
299
+ ...config,
300
+ hooks: { ...hooks, pre_tool_call: updatedPreToolCall },
301
+ hooks_auto_accept: true,
302
+ };
303
+ }
304
+ // ── Command registration ──────────────────────────────────────────────────────
305
+ export function registerHermes(program) {
306
+ const hermes = program
307
+ .command('hermes')
308
+ .description('Hermes integration commands');
309
+ hermes
310
+ .command('bootstrap')
311
+ .description('One-shot wiring of a fresh Hermes install to olam (MCP + KG hook + skill mirror)')
312
+ .option('--dry-run', 'Print planned changes without writing anything')
313
+ .option('--keep-docker', 'Skip setting terminal.backend = local')
314
+ .option('--bridge-url <url>', 'agentmemory bridge URL (overrides AGENTMEMORY_BRIDGE_URL env)')
315
+ .option('--bridge-secret <secret>', 'agentmemory bridge secret (overrides AGENTMEMORY_BRIDGE_SECRET env)')
316
+ .action(async (opts) => {
317
+ await runHermesBootstrap(opts);
318
+ });
319
+ }
320
+ //# sourceMappingURL=hermes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hermes.js","sourceRoot":"","sources":["../../src/commands/hermes.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,13 @@
1
1
  /**
2
- * `olam kg install-hook [--scope project|user]` wire the kg-service PreToolUse
2
+ * `olam kg install-hook [--scope project|user] [--for claude|hermes]`
3
+ *
4
+ * Default (--for claude, --scope project): wire the kg-service PreToolUse
3
5
  * hook into .claude/settings.json.
4
6
  *
7
+ * --for hermes: install kg-first.sh into ~/.hermes/hooks/ and patch
8
+ * ~/.hermes/config.yaml hooks.pre_tool_call. Refuses if
9
+ * ~/.hermes/config.yaml doesn't exist.
10
+ *
5
11
  * Default scope=project writes to `<cwd>/.claude/settings.json`. Per-repo
6
12
  * opt-in keeps blast radius small (operator can try it on one repo before
7
13
  * promoting to --scope user which targets `~/.claude/settings.json`).