@pleri/olam-cli 0.1.144 → 0.1.146

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 (117) hide show
  1. package/dist/commands/doctor.d.ts +53 -23
  2. package/dist/commands/doctor.d.ts.map +1 -1
  3. package/dist/commands/doctor.js +117 -46
  4. package/dist/commands/doctor.js.map +1 -1
  5. package/dist/commands/logs.d.ts +17 -3
  6. package/dist/commands/logs.d.ts.map +1 -1
  7. package/dist/commands/logs.js +38 -35
  8. package/dist/commands/logs.js.map +1 -1
  9. package/dist/commands/memory/bridge.d.ts +57 -0
  10. package/dist/commands/memory/bridge.d.ts.map +1 -0
  11. package/dist/commands/memory/bridge.js +156 -0
  12. package/dist/commands/memory/bridge.js.map +1 -0
  13. package/dist/commands/memory/index.d.ts +3 -0
  14. package/dist/commands/memory/index.d.ts.map +1 -1
  15. package/dist/commands/memory/index.js +10 -1
  16. package/dist/commands/memory/index.js.map +1 -1
  17. package/dist/commands/memory/reclassify.d.ts +56 -0
  18. package/dist/commands/memory/reclassify.d.ts.map +1 -0
  19. package/dist/commands/memory/reclassify.js +177 -0
  20. package/dist/commands/memory/reclassify.js.map +1 -0
  21. package/dist/commands/memory/stats.d.ts +69 -0
  22. package/dist/commands/memory/stats.d.ts.map +1 -0
  23. package/dist/commands/memory/stats.js +164 -0
  24. package/dist/commands/memory/stats.js.map +1 -0
  25. package/dist/commands/skills-doctor.d.ts +14 -0
  26. package/dist/commands/skills-doctor.d.ts.map +1 -0
  27. package/dist/commands/skills-doctor.js +126 -0
  28. package/dist/commands/skills-doctor.js.map +1 -0
  29. package/dist/commands/skills-hook.d.ts +19 -0
  30. package/dist/commands/skills-hook.d.ts.map +1 -0
  31. package/dist/commands/skills-hook.js +99 -0
  32. package/dist/commands/skills-hook.js.map +1 -0
  33. package/dist/commands/skills-migrate-back.d.ts +21 -0
  34. package/dist/commands/skills-migrate-back.d.ts.map +1 -0
  35. package/dist/commands/skills-migrate-back.js +222 -0
  36. package/dist/commands/skills-migrate-back.js.map +1 -0
  37. package/dist/commands/skills-migrate.d.ts +33 -0
  38. package/dist/commands/skills-migrate.d.ts.map +1 -0
  39. package/dist/commands/skills-migrate.js +216 -0
  40. package/dist/commands/skills-migrate.js.map +1 -0
  41. package/dist/commands/skills-onboard.d.ts +26 -0
  42. package/dist/commands/skills-onboard.d.ts.map +1 -0
  43. package/dist/commands/skills-onboard.js +227 -0
  44. package/dist/commands/skills-onboard.js.map +1 -0
  45. package/dist/commands/skills-shadow-backups.d.ts +15 -0
  46. package/dist/commands/skills-shadow-backups.d.ts.map +1 -0
  47. package/dist/commands/skills-shadow-backups.js +132 -0
  48. package/dist/commands/skills-shadow-backups.js.map +1 -0
  49. package/dist/commands/skills-source.d.ts +37 -0
  50. package/dist/commands/skills-source.d.ts.map +1 -0
  51. package/dist/commands/skills-source.js +431 -0
  52. package/dist/commands/skills-source.js.map +1 -0
  53. package/dist/commands/skills.d.ts +11 -0
  54. package/dist/commands/skills.d.ts.map +1 -0
  55. package/dist/commands/skills.js +170 -0
  56. package/dist/commands/skills.js.map +1 -0
  57. package/dist/commands/status.d.ts +27 -0
  58. package/dist/commands/status.d.ts.map +1 -1
  59. package/dist/commands/status.js +102 -1
  60. package/dist/commands/status.js.map +1 -1
  61. package/dist/commands/substrate-audit-log.d.ts +49 -0
  62. package/dist/commands/substrate-audit-log.d.ts.map +1 -0
  63. package/dist/commands/substrate-audit-log.js +148 -0
  64. package/dist/commands/substrate-audit-log.js.map +1 -0
  65. package/dist/commands/substrate.d.ts +60 -0
  66. package/dist/commands/substrate.d.ts.map +1 -0
  67. package/dist/commands/substrate.js +175 -0
  68. package/dist/commands/substrate.js.map +1 -0
  69. package/dist/commands/upgrade.d.ts +10 -0
  70. package/dist/commands/upgrade.d.ts.map +1 -1
  71. package/dist/commands/upgrade.js +30 -0
  72. package/dist/commands/upgrade.js.map +1 -1
  73. package/dist/image-digests.json +7 -7
  74. package/dist/index.js +8394 -3876
  75. package/dist/index.js.map +1 -1
  76. package/dist/lib/config.d.ts +69 -0
  77. package/dist/lib/config.d.ts.map +1 -0
  78. package/dist/lib/config.js +146 -0
  79. package/dist/lib/config.js.map +1 -0
  80. package/dist/lib/health-probes.d.ts +72 -0
  81. package/dist/lib/health-probes.d.ts.map +1 -1
  82. package/dist/lib/health-probes.js +218 -0
  83. package/dist/lib/health-probes.js.map +1 -1
  84. package/dist/lib/instrumentation.d.ts +85 -0
  85. package/dist/lib/instrumentation.d.ts.map +1 -0
  86. package/dist/lib/instrumentation.js +104 -0
  87. package/dist/lib/instrumentation.js.map +1 -0
  88. package/dist/lib/kubectl-wrap.d.ts +59 -0
  89. package/dist/lib/kubectl-wrap.d.ts.map +1 -0
  90. package/dist/lib/kubectl-wrap.js +130 -0
  91. package/dist/lib/kubectl-wrap.js.map +1 -0
  92. package/dist/lib/manifest-refresh.d.ts +95 -0
  93. package/dist/lib/manifest-refresh.d.ts.map +1 -0
  94. package/dist/lib/manifest-refresh.js +222 -0
  95. package/dist/lib/manifest-refresh.js.map +1 -0
  96. package/dist/lib/port-forward.d.ts +101 -0
  97. package/dist/lib/port-forward.d.ts.map +1 -0
  98. package/dist/lib/port-forward.js +240 -0
  99. package/dist/lib/port-forward.js.map +1 -0
  100. package/dist/lib/upgrade-kubernetes.d.ts +77 -0
  101. package/dist/lib/upgrade-kubernetes.d.ts.map +1 -0
  102. package/dist/lib/upgrade-kubernetes.js +277 -0
  103. package/dist/lib/upgrade-kubernetes.js.map +1 -0
  104. package/dist/mcp-server.js +3328 -1166
  105. package/host-cp/k8s/manifests/00-namespace.yaml +7 -0
  106. package/host-cp/k8s/manifests/10-serviceaccount.yaml +8 -0
  107. package/host-cp/k8s/manifests/20-rbac.yaml +34 -0
  108. package/host-cp/k8s/manifests/30-configmap.yaml +30 -0
  109. package/host-cp/k8s/manifests/45-pvc.yaml +27 -0
  110. package/host-cp/k8s/manifests/50-deployment.yaml +148 -0
  111. package/host-cp/k8s/manifests/60-service.yaml +22 -0
  112. package/host-cp/k8s/templates/40-secret-template.yaml +32 -0
  113. package/host-cp/src/agent-runtime-trigger.mjs +74 -4
  114. package/host-cp/src/engine-identity.mjs +32 -0
  115. package/host-cp/src/plan-chat-service.mjs +31 -7
  116. package/host-cp/src/server.mjs +219 -9
  117. package/package.json +3 -2
@@ -0,0 +1,164 @@
1
+ /**
2
+ * olam memory stats — operator-facing formatter over `/bridge/stats`.
3
+ *
4
+ * $ olam memory stats
5
+ * # human-readable counters + derived cache_error_rate
6
+ *
7
+ * $ olam memory stats --json
8
+ * # raw /bridge/stats response (for jq / monitoring scripts)
9
+ *
10
+ * Config (env vars):
11
+ * AGENTMEMORY_BRIDGE_URL bridge base URL
12
+ * (default: https://olam-agent-memory.ernestcodes.workers.dev)
13
+ * AGENTMEMORY_BRIDGE_SECRET bearer token
14
+ *
15
+ * Derived metric: cache_error_rate =
16
+ * (cache_busted_hash + cache_busted_version) / max(writes_observed, 1)
17
+ *
18
+ * Interpretation: high rates (>5%) mean operators have been forced to
19
+ * reclassify a lot of recent writes — usually a sign that the prompt
20
+ * template / classifier_version is churning. The denominator is
21
+ * classifier_writes_observed (NOT bridge writes_observed).
22
+ *
23
+ * Plan reference:
24
+ * docs/plans/agentmemory-classifier-and-regret/phase-b-tasks.md (B5/B6)
25
+ */
26
+ import { printError, printHeader, printInfo } from '../../output.js';
27
+ const DEFAULT_BRIDGE_URL = 'https://olam-agent-memory.ernestcodes.workers.dev';
28
+ const STATS_TIMEOUT_MS = 10_000;
29
+ /**
30
+ * Pure helper — separated so it's unit-testable without HTTP.
31
+ * Guards divide-by-zero (returns 0 when writes_observed === 0, even
32
+ * if busts are nonzero — Infinity / NaN would be operator-hostile).
33
+ */
34
+ export function computeCacheErrorRate(counters) {
35
+ if (counters.writes_observed <= 0)
36
+ return 0;
37
+ const busted = counters.cache_busted_hash + counters.cache_busted_version;
38
+ return busted / counters.writes_observed;
39
+ }
40
+ function resolveBridgeUrl(opts) {
41
+ return opts.bridgeUrl
42
+ ?? process.env['AGENTMEMORY_BRIDGE_URL']
43
+ ?? DEFAULT_BRIDGE_URL;
44
+ }
45
+ function resolveBearer(opts) {
46
+ const fromOpt = opts.bearer;
47
+ if (fromOpt && fromOpt.length > 0)
48
+ return fromOpt;
49
+ const fromEnv = process.env['AGENTMEMORY_BRIDGE_SECRET'];
50
+ if (fromEnv && fromEnv.length > 0)
51
+ return fromEnv;
52
+ return null;
53
+ }
54
+ function intOrZero(v) {
55
+ if (typeof v !== 'number' || !Number.isFinite(v))
56
+ return 0;
57
+ return Math.trunc(v);
58
+ }
59
+ function extractCounters(stats) {
60
+ return {
61
+ writes_observed: intOrZero(stats.classifier_writes_observed),
62
+ writes_deduped_hash: intOrZero(stats.classifier_writes_deduped_hash),
63
+ writes_deduped_semantic: intOrZero(stats.classifier_writes_deduped_semantic),
64
+ recalls_observed: intOrZero(stats.classifier_recalls_observed),
65
+ cache_busted_hash: intOrZero(stats.classifier_cache_busted_hash),
66
+ cache_busted_version: intOrZero(stats.classifier_cache_busted_version),
67
+ };
68
+ }
69
+ /**
70
+ * Run the stats call. Pure-ish: takes opts + fetch (so tests can stub) +
71
+ * returns a structured result. Mirrors `runReclassify` for symmetry.
72
+ */
73
+ export async function runStats(opts, fetchImpl = fetch) {
74
+ const bridgeUrl = resolveBridgeUrl(opts);
75
+ const bearer = resolveBearer(opts);
76
+ if (!bearer) {
77
+ return {
78
+ ok: false,
79
+ error: 'AGENTMEMORY_BRIDGE_SECRET not set (or --bearer not passed)',
80
+ };
81
+ }
82
+ try {
83
+ const res = await fetchImpl(`${bridgeUrl}/bridge/stats`, {
84
+ method: 'GET',
85
+ headers: {
86
+ authorization: `Bearer ${bearer}`,
87
+ },
88
+ signal: AbortSignal.timeout(STATS_TIMEOUT_MS),
89
+ });
90
+ if (!res.ok) {
91
+ const detail = await res.text().catch(() => '');
92
+ return {
93
+ ok: false,
94
+ error: `bridge returned ${res.status} ${res.statusText}${detail ? `: ${detail.slice(0, 200)}` : ''}`,
95
+ };
96
+ }
97
+ const payload = (await res.json());
98
+ if (!payload || typeof payload !== 'object' || !payload.stats || typeof payload.stats !== 'object') {
99
+ return {
100
+ ok: false,
101
+ error: 'bridge response missing stats envelope',
102
+ };
103
+ }
104
+ const counters = extractCounters(payload.stats);
105
+ const cacheErrorRate = computeCacheErrorRate(counters);
106
+ return {
107
+ ok: true,
108
+ counters,
109
+ cacheErrorRate,
110
+ raw: payload,
111
+ };
112
+ }
113
+ catch (err) {
114
+ return {
115
+ ok: false,
116
+ error: err instanceof Error ? err.message : String(err),
117
+ };
118
+ }
119
+ }
120
+ function formatPct(numerator, denominator) {
121
+ if (denominator <= 0)
122
+ return '0.0%';
123
+ return `${((numerator / denominator) * 100).toFixed(1)}%`;
124
+ }
125
+ /** Run + render. Returns the process exit code. */
126
+ export async function runStatsCli(opts) {
127
+ const result = await runStats(opts);
128
+ if (opts.json) {
129
+ // Preserve the raw bridge envelope when possible so jq pipelines
130
+ // see the same shape they'd get from curl. Fall back to the
131
+ // structured result on error so callers can still inspect.
132
+ const out = result.ok && result.raw !== undefined ? result.raw : result;
133
+ process.stdout.write(JSON.stringify(out, null, 2) + '\n');
134
+ return result.ok ? 0 : 1;
135
+ }
136
+ printHeader('olam memory stats — bridge counters');
137
+ if (!result.ok) {
138
+ printError(`stats failed: ${result.error ?? '(unknown error)'}`);
139
+ return 1;
140
+ }
141
+ const c = result.counters;
142
+ printInfo('writes_observed', String(c.writes_observed));
143
+ printInfo('writes_deduped_hash', `${c.writes_deduped_hash} (${formatPct(c.writes_deduped_hash, c.writes_observed)})`);
144
+ printInfo('writes_deduped_semantic', `${c.writes_deduped_semantic} (${formatPct(c.writes_deduped_semantic, c.writes_observed)})`);
145
+ printInfo('recalls_observed', String(c.recalls_observed));
146
+ printInfo('cache_busted_hash', String(c.cache_busted_hash));
147
+ printInfo('cache_busted_version', String(c.cache_busted_version));
148
+ printInfo('cache_error_rate', `${(result.cacheErrorRate * 100).toFixed(1)}%`);
149
+ return 0;
150
+ }
151
+ export function registerMemoryStats(cmd) {
152
+ cmd
153
+ .command('stats')
154
+ .description('Fetch /bridge/stats from the agent-memory bridge and format classifier counters (writes_observed, dedup rates, recalls, cache busts, derived cache_error_rate)')
155
+ .option('--bridge-url <url>', 'Override AGENTMEMORY_BRIDGE_URL')
156
+ .option('--bearer <token>', 'Override AGENTMEMORY_BRIDGE_SECRET')
157
+ .option('--json', 'Machine-readable JSON output (raw bridge envelope)', false)
158
+ .action(async (opts) => {
159
+ const rc = await runStatsCli(opts);
160
+ if (rc !== 0)
161
+ process.exitCode = rc;
162
+ });
163
+ }
164
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/commands/memory/stats.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * olam skills doctor — diagnostic + auto-repair for the skills surface.
3
+ *
4
+ * olam skills doctor # print report; interactive prompts
5
+ * # per issue when TTY
6
+ * olam skills doctor --auto-fix # apply every repair without prompt
7
+ * olam skills doctor --check-only # exit 1 on any issue; never modify
8
+ * # state (read-only health probe)
9
+ *
10
+ * Mirrors `olam kg doctor`'s shape; per OQ12 [assumed].
11
+ */
12
+ import type { Command } from 'commander';
13
+ export declare function registerSkillsDoctor(program: Command): void;
14
+ //# sourceMappingURL=skills-doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills-doctor.d.ts","sourceRoot":"","sources":["../../src/commands/skills-doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgDzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6E3D"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * olam skills doctor — diagnostic + auto-repair for the skills surface.
3
+ *
4
+ * olam skills doctor # print report; interactive prompts
5
+ * # per issue when TTY
6
+ * olam skills doctor --auto-fix # apply every repair without prompt
7
+ * olam skills doctor --check-only # exit 1 on any issue; never modify
8
+ * # state (read-only health probe)
9
+ *
10
+ * Mirrors `olam kg doctor`'s shape; per OQ12 [assumed].
11
+ */
12
+ import * as readline from 'node:readline';
13
+ import pc from 'picocolors';
14
+ import { runAllDoctorChecks, } from '@olam/core/src/skill-sources/index.js';
15
+ import { printError, printHeader, printSuccess, printWarning } from '../output.js';
16
+ function asMessage(err) {
17
+ return err instanceof Error ? err.message : String(err);
18
+ }
19
+ function defaultDoctorPrompt(question) {
20
+ return new Promise((resolve) => {
21
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
22
+ rl.question(question, (a) => {
23
+ rl.close();
24
+ resolve(a);
25
+ });
26
+ });
27
+ }
28
+ async function confirmRepair(check) {
29
+ const testFn = globalThis.__olamTestDoctorPrompt;
30
+ const prompt = testFn ?? (() => defaultDoctorPrompt(`Apply repair for "${check.name}"? [y/N] `));
31
+ const answer = (await prompt()).trim().toLowerCase();
32
+ return answer === 'y' || answer === 'yes';
33
+ }
34
+ function printCheck(check) {
35
+ if (check.healthy) {
36
+ console.log(` ${pc.green('✓')} ${pc.bold(check.name.padEnd(22))} ${pc.dim(check.description)}`);
37
+ if (check.details && check.details.length > 0) {
38
+ for (const d of check.details)
39
+ console.log(` ${pc.dim(d)}`);
40
+ }
41
+ }
42
+ else {
43
+ console.log(` ${pc.red('✗')} ${pc.bold(check.name.padEnd(22))} ${pc.yellow(check.issue ?? 'unhealthy')}`);
44
+ console.log(` ${pc.dim(check.description)}`);
45
+ if (check.details) {
46
+ for (const d of check.details.slice(0, 10))
47
+ console.log(` ${pc.dim('· ' + d)}`);
48
+ if (check.details.length > 10)
49
+ console.log(` ${pc.dim(`… and ${check.details.length - 10} more`)}`);
50
+ }
51
+ }
52
+ }
53
+ export function registerSkillsDoctor(program) {
54
+ const skills = program.commands.find((c) => c.name() === 'skills') ??
55
+ program.command('skills').description('Manage skill sources and synchronization');
56
+ skills
57
+ .command('doctor')
58
+ .description('Diagnose 4 corruption classes; auto-repair available with --auto-fix')
59
+ .option('--auto-fix', 'Apply each repair without prompting')
60
+ .option('--check-only', 'Report issues + exit non-zero without modifying state')
61
+ .action(async (opts) => {
62
+ if (opts.autoFix && opts.checkOnly) {
63
+ printError('--auto-fix and --check-only are mutually exclusive');
64
+ process.exitCode = 1;
65
+ return;
66
+ }
67
+ printHeader('skills doctor');
68
+ let checks;
69
+ try {
70
+ checks = runAllDoctorChecks();
71
+ }
72
+ catch (err) {
73
+ printError(`doctor checks crashed: ${asMessage(err)}`);
74
+ process.exitCode = 1;
75
+ return;
76
+ }
77
+ for (const c of checks)
78
+ printCheck(c);
79
+ const unhealthy = checks.filter((c) => !c.healthy);
80
+ if (unhealthy.length === 0) {
81
+ console.log();
82
+ printSuccess('all 4 checks PASS');
83
+ return;
84
+ }
85
+ console.log();
86
+ printWarning(`${unhealthy.length} of ${checks.length} check(s) report issues`);
87
+ if (opts.checkOnly) {
88
+ console.log(pc.dim('(--check-only — exiting without repair)'));
89
+ process.exitCode = 1;
90
+ return;
91
+ }
92
+ let repaired = 0;
93
+ let skipped = 0;
94
+ for (const check of unhealthy) {
95
+ if (!check.repair) {
96
+ console.log(pc.dim(` (no auto-repair for ${check.name} — operator-attention required)`));
97
+ skipped += 1;
98
+ continue;
99
+ }
100
+ const shouldRepair = opts.autoFix ? true : await confirmRepair(check);
101
+ if (!shouldRepair) {
102
+ console.log(pc.dim(` skipped: ${check.name}`));
103
+ skipped += 1;
104
+ continue;
105
+ }
106
+ try {
107
+ await check.repair();
108
+ console.log(pc.green(` repaired: ${check.name}`));
109
+ repaired += 1;
110
+ }
111
+ catch (err) {
112
+ printError(` repair failed for ${check.name}: ${asMessage(err)}`);
113
+ skipped += 1;
114
+ }
115
+ }
116
+ console.log();
117
+ if (skipped > 0) {
118
+ printWarning(`repaired ${repaired}; skipped ${skipped}. Re-run doctor to verify.`);
119
+ process.exitCode = skipped > 0 ? 1 : 0;
120
+ }
121
+ else {
122
+ printSuccess(`repaired ${repaired} issue(s). Re-run doctor to verify.`);
123
+ }
124
+ });
125
+ }
126
+ //# sourceMappingURL=skills-doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills-doctor.js","sourceRoot":"","sources":["../../src/commands/skills-doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `olam skills install-hook [--scope project|user]` — install the
3
+ * SessionStart hook that runs `olam skills sync --quiet` on every
4
+ * Claude Code session start.
5
+ *
6
+ * `olam skills uninstall-hook [--scope project|user]` — surgical
7
+ * sentinel-matched removal.
8
+ *
9
+ * Mirrors `olam kg install-hook` / `olam kg uninstall-hook` shape:
10
+ * - `--scope project` (default) → <cwd>/.claude/settings.json
11
+ * - `--scope user` → ~/.claude/settings.json
12
+ *
13
+ * Idempotent install via OLAM_SKILLS_HOOK_SENTINEL substring-match.
14
+ * Surgical uninstall: only entries whose command contains the sentinel
15
+ * are dropped; user-authored hooks are preserved.
16
+ */
17
+ import type { Command } from 'commander';
18
+ export declare function registerSkillsHook(program: Command): void;
19
+ //# sourceMappingURL=skills-hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills-hook.d.ts","sourceRoot":"","sources":["../../src/commands/skills-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuEzD"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * `olam skills install-hook [--scope project|user]` — install the
3
+ * SessionStart hook that runs `olam skills sync --quiet` on every
4
+ * Claude Code session start.
5
+ *
6
+ * `olam skills uninstall-hook [--scope project|user]` — surgical
7
+ * sentinel-matched removal.
8
+ *
9
+ * Mirrors `olam kg install-hook` / `olam kg uninstall-hook` shape:
10
+ * - `--scope project` (default) → <cwd>/.claude/settings.json
11
+ * - `--scope user` → ~/.claude/settings.json
12
+ *
13
+ * Idempotent install via OLAM_SKILLS_HOOK_SENTINEL substring-match.
14
+ * Surgical uninstall: only entries whose command contains the sentinel
15
+ * are dropped; user-authored hooks are preserved.
16
+ */
17
+ import { installSkillsHookToFile, skillsHookSettingsPathFor, uninstallSkillsHookFromFile, } from '@olam/core/src/skill-sources/index.js';
18
+ import * as fs from 'node:fs';
19
+ import { printError, printInfo, printSuccess, printWarning } from '../output.js';
20
+ function backup(filePath) {
21
+ if (!fs.existsSync(filePath))
22
+ return null;
23
+ const ts = new Date().toISOString().replace(/[:.]/g, '-');
24
+ const backupPath = `${filePath}.olam-bak.${ts}`;
25
+ fs.copyFileSync(filePath, backupPath);
26
+ return backupPath;
27
+ }
28
+ export function registerSkillsHook(program) {
29
+ const skills = program.commands.find((c) => c.name() === 'skills') ??
30
+ program.command('skills').description('Manage skill sources and synchronization');
31
+ skills
32
+ .command('install-hook')
33
+ .description('Install the SessionStart hook that runs `olam skills sync --quiet` on session start')
34
+ .option('--scope <scope>', 'project (default; <cwd>/.claude/settings.json) or user (~/.claude/settings.json)', 'project')
35
+ .action((opts) => {
36
+ const scope = opts.scope === 'user' ? 'user' : 'project';
37
+ const filePath = skillsHookSettingsPathFor(scope);
38
+ try {
39
+ const result = installSkillsHookToFile(filePath);
40
+ switch (result.status) {
41
+ case 'installed':
42
+ printSuccess(`olam-skills SessionStart hook installed (${scope} scope)`);
43
+ printInfo('settings', filePath);
44
+ if (result.backupPath)
45
+ printInfo('backup', result.backupPath);
46
+ printInfo('next', 'open a new Claude Code session; `olam skills sync --quiet` will run on start');
47
+ return;
48
+ case 'already-present':
49
+ printInfo('olam-skills hook', `already installed at ${filePath}`);
50
+ return;
51
+ case 'no-op':
52
+ printWarning(`no change made to ${filePath}`);
53
+ return;
54
+ }
55
+ }
56
+ catch (err) {
57
+ printError(`install-hook failed: ${err instanceof Error ? err.message : String(err)}`);
58
+ process.exitCode = 1;
59
+ }
60
+ });
61
+ skills
62
+ .command('uninstall-hook')
63
+ .description('Remove the olam-skills SessionStart hook from settings.json (sentinel-matched; surgical)')
64
+ .option('--scope <scope>', 'project (default) or user', 'project')
65
+ .action((opts) => {
66
+ const scope = opts.scope === 'user' ? 'user' : 'project';
67
+ const filePath = skillsHookSettingsPathFor(scope);
68
+ const backupPath = backup(filePath);
69
+ try {
70
+ const result = uninstallSkillsHookFromFile(filePath);
71
+ switch (result.status) {
72
+ case 'removed':
73
+ printSuccess(`olam-skills SessionStart hook removed from ${filePath}`);
74
+ if (backupPath)
75
+ printInfo('backup', backupPath);
76
+ return;
77
+ case 'not-found':
78
+ printInfo('olam-skills hook', `not found in ${filePath} — already uninstalled`);
79
+ if (backupPath) {
80
+ try {
81
+ fs.unlinkSync(backupPath);
82
+ }
83
+ catch { /* best-effort */ }
84
+ }
85
+ return;
86
+ case 'no-settings':
87
+ printInfo('olam-skills hook', `no settings.json at ${filePath} — nothing to remove`);
88
+ return;
89
+ }
90
+ }
91
+ catch (err) {
92
+ printError(`uninstall-hook failed: ${err instanceof Error ? err.message : String(err)}`);
93
+ if (backupPath)
94
+ printInfo('backup', `settings.json preserved at ${backupPath}`);
95
+ process.exitCode = 1;
96
+ }
97
+ });
98
+ }
99
+ //# sourceMappingURL=skills-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills-hook.js","sourceRoot":"","sources":["../../src/commands/skills-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,2BAA2B,GAE5B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAIjF,SAAS,MAAM,CAAC,QAAgB;IAC9B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,UAAU,GAAG,GAAG,QAAQ,aAAa,EAAE,EAAE,CAAC;IAChD,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACtC,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,MAAM,MAAM,GACV,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,QAAQ,CAAC;QACnD,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,0CAA0C,CAAC,CAAC;IAEpF,MAAM;SACH,OAAO,CAAC,cAAc,CAAC;SACvB,WAAW,CAAC,qFAAqF,CAAC;SAClG,MAAM,CACL,iBAAiB,EACjB,kFAAkF,EAClF,SAAS,CACV;SACA,MAAM,CAAC,CAAC,IAAwB,EAAE,EAAE;QACnC,MAAM,KAAK,GAAU,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QAChE,MAAM,QAAQ,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;QAElD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;YACjD,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;gBACtB,KAAK,WAAW;oBACd,YAAY,CAAC,4CAA4C,KAAK,SAAS,CAAC,CAAC;oBACzE,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;oBAChC,IAAI,MAAM,CAAC,UAAU;wBAAE,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;oBAC9D,SAAS,CAAC,MAAM,EAAE,8EAA8E,CAAC,CAAC;oBAClG,OAAO;gBACT,KAAK,iBAAiB;oBACpB,SAAS,CAAC,kBAAkB,EAAE,wBAAwB,QAAQ,EAAE,CAAC,CAAC;oBAClE,OAAO;gBACT,KAAK,OAAO;oBACV,YAAY,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;oBAC9C,OAAO;YACX,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,CAAC,wBAAwB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACvF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,MAAM;SACH,OAAO,CAAC,gBAAgB,CAAC;SACzB,WAAW,CAAC,0FAA0F,CAAC;SACvG,MAAM,CAAC,iBAAiB,EAAE,2BAA2B,EAAE,SAAS,CAAC;SACjE,MAAM,CAAC,CAAC,IAAwB,EAAE,EAAE;QACnC,MAAM,KAAK,GAAU,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QAChE,MAAM,QAAQ,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;QAElD,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;YACrD,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;gBACtB,KAAK,SAAS;oBACZ,YAAY,CAAC,8CAA8C,QAAQ,EAAE,CAAC,CAAC;oBACvE,IAAI,UAAU;wBAAE,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;oBAChD,OAAO;gBACT,KAAK,WAAW;oBACd,SAAS,CAAC,kBAAkB,EAAE,gBAAgB,QAAQ,wBAAwB,CAAC,CAAC;oBAChF,IAAI,UAAU,EAAE,CAAC;wBACf,IAAI,CAAC;4BAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;wBAAC,CAAC;wBAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;oBAChE,CAAC;oBACD,OAAO;gBACT,KAAK,aAAa;oBAChB,SAAS,CAAC,kBAAkB,EAAE,uBAAuB,QAAQ,sBAAsB,CAAC,CAAC;oBACrF,OAAO;YACX,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,CAAC,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACzF,IAAI,UAAU;gBAAE,SAAS,CAAC,QAAQ,EAAE,8BAA8B,UAAU,EAAE,CAAC,CAAC;YAChF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `olam skills migrate-back-to-toolbox` — reverse the migration performed
3
+ * by `migrate-from-toolbox`, consuming the pre-migration snapshot written
4
+ * at ~/.olam/state/migration-snapshots/<namespace>-<ISO>.json.
5
+ *
6
+ * Reverse order of migrate-from-toolbox operations:
7
+ * 1. resolve snapshot (latest matching --path / --namespace / --snapshot)
8
+ * 2. uninstall olam-skills SessionStart hook (sentinel-matched)
9
+ * 3. delete olam-managed symlinks under ~/.claude/ (any symlink whose
10
+ * target lives under ~/.olam/state/skill-sources/<id>/)
11
+ * 4. restore the original SessionStart hook block from snapshot
12
+ * 5. restore the toolbox-managed symlinks from snapshot
13
+ * 6. restore ~/.claude/.atlas-user from snapshot (atlas-shape only)
14
+ * 7. unless --keep-source: remove the toolbox olam source registration
15
+ * (skill-sources slice + clone dir)
16
+ */
17
+ import type { Command } from 'commander';
18
+ /** Stable command identifier — referenced by tests to keep them rename-resilient. */
19
+ export declare const MIGRATE_BACK_TO_TOOLBOX_COMMAND = "migrate-back-to-toolbox";
20
+ export declare function registerSkillsMigrateBack(program: Command): void;
21
+ //# sourceMappingURL=skills-migrate-back.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills-migrate-back.d.ts","sourceRoot":"","sources":["../../src/commands/skills-migrate-back.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAezC,qFAAqF;AACrF,eAAO,MAAM,+BAA+B,4BAA4B,CAAC;AAiGzE,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoHhE"}