@pleri/olam-cli 0.1.128 → 0.1.131

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 (51) hide show
  1. package/dist/commands/bootstrap.d.ts +8 -0
  2. package/dist/commands/bootstrap.d.ts.map +1 -1
  3. package/dist/commands/bootstrap.js +14 -0
  4. package/dist/commands/bootstrap.js.map +1 -1
  5. package/dist/commands/kg-build.d.ts.map +1 -1
  6. package/dist/commands/kg-build.js +10 -0
  7. package/dist/commands/kg-build.js.map +1 -1
  8. package/dist/commands/kg-classify.d.ts +10 -0
  9. package/dist/commands/kg-classify.d.ts.map +1 -0
  10. package/dist/commands/kg-classify.js +51 -0
  11. package/dist/commands/kg-classify.js.map +1 -0
  12. package/dist/commands/kg-doctor.d.ts +15 -0
  13. package/dist/commands/kg-doctor.d.ts.map +1 -0
  14. package/dist/commands/kg-doctor.js +182 -0
  15. package/dist/commands/kg-doctor.js.map +1 -0
  16. package/dist/commands/kg-install-hook.d.ts +14 -0
  17. package/dist/commands/kg-install-hook.d.ts.map +1 -0
  18. package/dist/commands/kg-install-hook.js +92 -0
  19. package/dist/commands/kg-install-hook.js.map +1 -0
  20. package/dist/commands/kg-service-container.d.ts +68 -0
  21. package/dist/commands/kg-service-container.d.ts.map +1 -0
  22. package/dist/commands/kg-service-container.js +181 -0
  23. package/dist/commands/kg-service-container.js.map +1 -0
  24. package/dist/commands/kg-uninstall-hook.d.ts +12 -0
  25. package/dist/commands/kg-uninstall-hook.d.ts.map +1 -0
  26. package/dist/commands/kg-uninstall-hook.js +121 -0
  27. package/dist/commands/kg-uninstall-hook.js.map +1 -0
  28. package/dist/commands/memory/index.d.ts.map +1 -1
  29. package/dist/commands/memory/index.js +2 -0
  30. package/dist/commands/memory/index.js.map +1 -1
  31. package/dist/commands/memory/mode.d.ts +47 -0
  32. package/dist/commands/memory/mode.d.ts.map +1 -0
  33. package/dist/commands/memory/mode.js +181 -0
  34. package/dist/commands/memory/mode.js.map +1 -0
  35. package/dist/commands/rekey.d.ts +84 -0
  36. package/dist/commands/rekey.d.ts.map +1 -0
  37. package/dist/commands/rekey.js +209 -0
  38. package/dist/commands/rekey.js.map +1 -0
  39. package/dist/commands/services.d.ts +5 -5
  40. package/dist/commands/services.d.ts.map +1 -1
  41. package/dist/commands/services.js +70 -6
  42. package/dist/commands/services.js.map +1 -1
  43. package/dist/image-digests.json +3 -3
  44. package/dist/index.js +2091 -667
  45. package/dist/index.js.map +1 -1
  46. package/dist/lib/memory-secret.d.ts +22 -0
  47. package/dist/lib/memory-secret.d.ts.map +1 -1
  48. package/dist/lib/memory-secret.js +38 -0
  49. package/dist/lib/memory-secret.js.map +1 -1
  50. package/dist/mcp-server.js +18499 -17383
  51. package/package.json +1 -1
@@ -0,0 +1,68 @@
1
+ /**
2
+ * KgServiceContainerController — lifecycle for olam-kg-service.
3
+ *
4
+ * Mirrors McpAuthContainerController (./services.ts) since kg-service, like
5
+ * mcp-auth-service, is not a @olam/core package. The persistent HTTP classifier
6
+ * inside the container holds bge-small-en-v1.5 in memory; we pre-warm at
7
+ * start() to eliminate the first-call cold cliff (see Phase A latency bench at
8
+ * ~/kg-benchmark/kg-service-poc/latency-results.json).
9
+ */
10
+ export declare const KG_SERVICE_PORT = 9997;
11
+ export declare const KG_SERVICE_CONTAINER = "olam-kg-service";
12
+ export declare const KG_SERVICE_LOCAL_TAG = "olam-kg-service:local";
13
+ export declare const KG_SERVICE_PUBLISHED_TAG = "ghcr.io/pleri/olam-kg-service:latest";
14
+ export declare const KG_SERVICE_DEV_TAG = "olam-kg-service:dev";
15
+ export declare const KG_SERVICE_HEALTH_URL = "http://127.0.0.1:9997/health";
16
+ export declare const KG_SERVICE_CLASSIFY_URL = "http://127.0.0.1:9997/classify";
17
+ export declare const KG_SERVICE_HEALTH_TIMEOUT_MS = 60000;
18
+ type ContainerState = 'running' | 'stopped' | 'missing';
19
+ export interface KgServiceStatus {
20
+ readonly state: ContainerState;
21
+ readonly port: number;
22
+ readonly containerId?: string;
23
+ readonly ready?: boolean;
24
+ }
25
+ export declare class KgServiceContainerController {
26
+ private imageTag;
27
+ status(): KgServiceStatus;
28
+ private imageExists;
29
+ /**
30
+ * Resolve the first available image tag: local → dev → published.
31
+ * Throws if none exist (operator should run `olam bootstrap` to pull).
32
+ */
33
+ private resolveImage;
34
+ /**
35
+ * Idempotent start. If already running → return. If stopped → docker start.
36
+ * If missing → docker run with port-forward + kg-data volume mount + restart
37
+ * policy. The container's CMD is `python -u /app/src/server.py` which begins
38
+ * loading bge-small immediately; the model is warm by the time /health
39
+ * returns ready=true. We additionally fire a synthetic /classify after
40
+ * readiness to JIT-warm the embedding hot path.
41
+ */
42
+ start(): void;
43
+ /**
44
+ * Returns true when no kg-service image exists locally — useful for callers
45
+ * (e.g. servicesUp) to distinguish "operator opted out of kg-service" from
46
+ * "kg-service was supposed to work but is broken". The opted-out case
47
+ * should be silent; the broken case should warn.
48
+ */
49
+ imageMissingEverywhere(): boolean;
50
+ stop(): void;
51
+ remove(): void;
52
+ /**
53
+ * Poll /health until ready=true OR timeoutMs elapses. The container reports
54
+ * ready=true only after the bge-small model + 31 exemplars have loaded
55
+ * (~1.3s on a warm machine; longer on first pull where the image needs to
56
+ * unpack).
57
+ */
58
+ waitForReady(timeoutMs?: number): Promise<boolean>;
59
+ /**
60
+ * Fire a synthetic classify against the warm server. Called by `servicesUp`
61
+ * after `waitForReady` succeeds — extra insurance that the embedding
62
+ * inference hot path is JITted before the first operator-driven call.
63
+ * Errors are swallowed; pre-warm is best-effort.
64
+ */
65
+ prewarm(): Promise<void>;
66
+ }
67
+ export {};
68
+ //# sourceMappingURL=kg-service-container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kg-service-container.d.ts","sourceRoot":"","sources":["../../src/commands/kg-service-container.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AACtD,eAAO,MAAM,oBAAoB,0BAA0B,CAAC;AAC5D,eAAO,MAAM,wBAAwB,yCAAyC,CAAC;AAC/E,eAAO,MAAM,kBAAkB,wBAAwB,CAAC;AACxD,eAAO,MAAM,qBAAqB,iCAA+C,CAAC;AAClF,eAAO,MAAM,uBAAuB,mCAAiD,CAAC;AAMtF,eAAO,MAAM,4BAA4B,QAAS,CAAC;AAMnD,KAAK,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAExD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAoBD,qBAAa,4BAA4B;IACvC,OAAO,CAAC,QAAQ,CAAgC;IAEhD,MAAM,IAAI,eAAe;IAiBzB,OAAO,CAAC,WAAW;IAInB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAUpB;;;;;;;OAOG;IACH,KAAK,IAAI,IAAI;IAsCb;;;;;OAKG;IACH,sBAAsB,IAAI,OAAO;IAQjC,IAAI,IAAI,IAAI;IAMZ,MAAM,IAAI,IAAI;IAId;;;;;OAKG;IACG,YAAY,CAAC,SAAS,SAA+B,GAAG,OAAO,CAAC,OAAO,CAAC;IAiB9E;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAY/B"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * KgServiceContainerController — lifecycle for olam-kg-service.
3
+ *
4
+ * Mirrors McpAuthContainerController (./services.ts) since kg-service, like
5
+ * mcp-auth-service, is not a @olam/core package. The persistent HTTP classifier
6
+ * inside the container holds bge-small-en-v1.5 in memory; we pre-warm at
7
+ * start() to eliminate the first-call cold cliff (see Phase A latency bench at
8
+ * ~/kg-benchmark/kg-service-poc/latency-results.json).
9
+ */
10
+ import { execFileSync, spawnSync } from 'node:child_process';
11
+ import * as fs from 'node:fs';
12
+ import { KG_PATHS_INTERNALS } from '@olam/core/src/kg/storage-paths.js';
13
+ export const KG_SERVICE_PORT = 9997;
14
+ export const KG_SERVICE_CONTAINER = 'olam-kg-service';
15
+ export const KG_SERVICE_LOCAL_TAG = 'olam-kg-service:local';
16
+ export const KG_SERVICE_PUBLISHED_TAG = 'ghcr.io/pleri/olam-kg-service:latest';
17
+ export const KG_SERVICE_DEV_TAG = 'olam-kg-service:dev';
18
+ export const KG_SERVICE_HEALTH_URL = `http://127.0.0.1:${KG_SERVICE_PORT}/health`;
19
+ export const KG_SERVICE_CLASSIFY_URL = `http://127.0.0.1:${KG_SERVICE_PORT}/classify`;
20
+ // Cold-start path measured at ~1.3s (bge-small load + warmup probe). On flaky
21
+ // CI runners with no Docker layer cache we've seen 60s+; mirror McpAuth's
22
+ // 60s timeout so the failure mode is the same operator-visible "took too long"
23
+ // rather than spurious flake.
24
+ export const KG_SERVICE_HEALTH_TIMEOUT_MS = 60_000;
25
+ // kg-data is the host-mounted `~/.olam/kg/` so the container's /build can
26
+ // write graphs back to the operator's pristine workspace KG store.
27
+ const KG_SERVICE_VOLUME_TARGET = '/kg-data';
28
+ /**
29
+ * Resolves the operator's KG storage root for the host bind-mount.
30
+ *
31
+ * Consumes `KG_PATHS_INTERNALS.kgRoot()` from @olam/core/src/kg/storage-paths.js
32
+ * so this controller honours OLAM_HOME redirection (tests, per-world
33
+ * overrides). Naively reading $HOME would cause split-brain: kg-service's
34
+ * /build endpoint would write to ~/.olam/kg while host-side `olam kg
35
+ * status` (which DOES consult OLAM_HOME via kgPristinePath) reports the
36
+ * KG as missing.
37
+ *
38
+ * Caller is responsible for ensuring the directory exists pre-bind-mount
39
+ * (Linux dockerd auto-creates as root:root if absent, which breaks
40
+ * subsequent host-side writes from the operator's UID).
41
+ */
42
+ function kgDataHostPath() {
43
+ return KG_PATHS_INTERNALS.kgRoot();
44
+ }
45
+ export class KgServiceContainerController {
46
+ imageTag = KG_SERVICE_LOCAL_TAG;
47
+ status() {
48
+ const r = spawnSync('docker', ['inspect', '--format', '{{.State.Status}}|{{.Id}}', KG_SERVICE_CONTAINER], { encoding: 'utf-8' });
49
+ if (r.status === 0) {
50
+ const [stateRaw, id] = r.stdout.trim().split('|');
51
+ return {
52
+ state: stateRaw === 'running' ? 'running' : 'stopped',
53
+ port: KG_SERVICE_PORT,
54
+ containerId: id,
55
+ };
56
+ }
57
+ return { state: 'missing', port: KG_SERVICE_PORT };
58
+ }
59
+ imageExists(tag = this.imageTag) {
60
+ return spawnSync('docker', ['image', 'inspect', tag], { encoding: 'utf-8' }).status === 0;
61
+ }
62
+ /**
63
+ * Resolve the first available image tag: local → dev → published.
64
+ * Throws if none exist (operator should run `olam bootstrap` to pull).
65
+ */
66
+ resolveImage() {
67
+ for (const tag of [KG_SERVICE_LOCAL_TAG, KG_SERVICE_DEV_TAG, KG_SERVICE_PUBLISHED_TAG]) {
68
+ if (this.imageExists(tag))
69
+ return tag;
70
+ }
71
+ throw new Error(`kg-service image not found. Tried: ${KG_SERVICE_LOCAL_TAG}, ${KG_SERVICE_DEV_TAG}, ${KG_SERVICE_PUBLISHED_TAG}. ` +
72
+ 'Run `olam bootstrap` to pull the published image, or `npm --workspace @olam/kg-service run build` to build locally.');
73
+ }
74
+ /**
75
+ * Idempotent start. If already running → return. If stopped → docker start.
76
+ * If missing → docker run with port-forward + kg-data volume mount + restart
77
+ * policy. The container's CMD is `python -u /app/src/server.py` which begins
78
+ * loading bge-small immediately; the model is warm by the time /health
79
+ * returns ready=true. We additionally fire a synthetic /classify after
80
+ * readiness to JIT-warm the embedding hot path.
81
+ */
82
+ start() {
83
+ const current = this.status();
84
+ if (current.state === 'running')
85
+ return;
86
+ if (current.state === 'stopped') {
87
+ execFileSync('docker', ['start', KG_SERVICE_CONTAINER], { stdio: 'pipe' });
88
+ return;
89
+ }
90
+ this.imageTag = this.resolveImage();
91
+ const kgData = kgDataHostPath();
92
+ // Pre-create the host path with the operator's UID. Without this,
93
+ // dockerd on Linux auto-creates the bind-mount target as root:root,
94
+ // which breaks subsequent host-side `olam kg build` writes from the
95
+ // operator's UID (EACCES). macOS Docker Desktop's user-mapped binds
96
+ // don't bite here but the explicit mkdir is portable + cheap.
97
+ fs.mkdirSync(kgData, { recursive: true });
98
+ execFileSync('docker', [
99
+ 'run',
100
+ '--detach',
101
+ '--name', KG_SERVICE_CONTAINER,
102
+ '--restart', 'unless-stopped',
103
+ // Bind to 127.0.0.1 ONLY at the host port level — local-only by design.
104
+ '--publish', `127.0.0.1:${KG_SERVICE_PORT}:${KG_SERVICE_PORT}`,
105
+ // host-gateway lets this container reach the host (e.g. for diagnostic
106
+ // probes). Worlds reach kg-service via the published 127.0.0.1:9997
107
+ // PLUS their OWN --add-host flag configured in the world-create code path.
108
+ '--add-host', 'host.docker.internal:host-gateway',
109
+ // Mount the operator's KG root (OLAM_HOME-aware) so /build can persist graphs.
110
+ '--volume', `${kgData}:${KG_SERVICE_VOLUME_TARGET}`,
111
+ this.imageTag,
112
+ ], { stdio: 'pipe' });
113
+ }
114
+ /**
115
+ * Returns true when no kg-service image exists locally — useful for callers
116
+ * (e.g. servicesUp) to distinguish "operator opted out of kg-service" from
117
+ * "kg-service was supposed to work but is broken". The opted-out case
118
+ * should be silent; the broken case should warn.
119
+ */
120
+ imageMissingEverywhere() {
121
+ return (!this.imageExists(KG_SERVICE_LOCAL_TAG) &&
122
+ !this.imageExists(KG_SERVICE_DEV_TAG) &&
123
+ !this.imageExists(KG_SERVICE_PUBLISHED_TAG));
124
+ }
125
+ stop() {
126
+ const current = this.status();
127
+ if (current.state !== 'running')
128
+ return;
129
+ execFileSync('docker', ['stop', KG_SERVICE_CONTAINER], { stdio: 'pipe' });
130
+ }
131
+ remove() {
132
+ spawnSync('docker', ['rm', '-f', KG_SERVICE_CONTAINER], { stdio: 'pipe' });
133
+ }
134
+ /**
135
+ * Poll /health until ready=true OR timeoutMs elapses. The container reports
136
+ * ready=true only after the bge-small model + 31 exemplars have loaded
137
+ * (~1.3s on a warm machine; longer on first pull where the image needs to
138
+ * unpack).
139
+ */
140
+ async waitForReady(timeoutMs = KG_SERVICE_HEALTH_TIMEOUT_MS) {
141
+ const deadline = Date.now() + timeoutMs;
142
+ while (Date.now() < deadline) {
143
+ try {
144
+ const res = await fetch(KG_SERVICE_HEALTH_URL, { signal: AbortSignal.timeout(1_500) });
145
+ if (res.ok) {
146
+ const body = (await res.json());
147
+ if (body.ready === true)
148
+ return true;
149
+ }
150
+ }
151
+ catch {
152
+ // not ready yet
153
+ }
154
+ await sleep(500);
155
+ }
156
+ return false;
157
+ }
158
+ /**
159
+ * Fire a synthetic classify against the warm server. Called by `servicesUp`
160
+ * after `waitForReady` succeeds — extra insurance that the embedding
161
+ * inference hot path is JITted before the first operator-driven call.
162
+ * Errors are swallowed; pre-warm is best-effort.
163
+ */
164
+ async prewarm() {
165
+ try {
166
+ await fetch(KG_SERVICE_CLASSIFY_URL, {
167
+ method: 'POST',
168
+ headers: { 'Content-Type': 'application/json' },
169
+ body: JSON.stringify({ q: 'prewarm probe' }),
170
+ signal: AbortSignal.timeout(5_000),
171
+ });
172
+ }
173
+ catch {
174
+ // best-effort
175
+ }
176
+ }
177
+ }
178
+ function sleep(ms) {
179
+ return new Promise((resolve) => setTimeout(resolve, ms));
180
+ }
181
+ //# sourceMappingURL=kg-service-container.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kg-service-container.js","sourceRoot":"","sources":["../../src/commands/kg-service-container.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * `olam kg uninstall-hook [--scope project|user]` — surgical removal of the
3
+ * kg-service PreToolUse hook from .claude/settings.json.
4
+ *
5
+ * Matches by sentinel — only removes hook entries whose command contains
6
+ * KG_HOOK_SENTINEL. Other PreToolUse entries (e.g. operator-installed
7
+ * custom hooks) are left intact. Idempotent: running on a non-installed
8
+ * file is a no-op.
9
+ */
10
+ import type { Command } from 'commander';
11
+ export declare function registerKgUninstallHookCommand(kg: Command): void;
12
+ //# sourceMappingURL=kg-uninstall-hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kg-uninstall-hook.d.ts","sourceRoot":"","sources":["../../src/commands/kg-uninstall-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiEzC,wBAAgB,8BAA8B,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAsEhE"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * `olam kg uninstall-hook [--scope project|user]` — surgical removal of the
3
+ * kg-service PreToolUse hook from .claude/settings.json.
4
+ *
5
+ * Matches by sentinel — only removes hook entries whose command contains
6
+ * KG_HOOK_SENTINEL. Other PreToolUse entries (e.g. operator-installed
7
+ * custom hooks) are left intact. Idempotent: running on a non-installed
8
+ * file is a no-op.
9
+ */
10
+ import * as fs from 'node:fs';
11
+ import * as path from 'node:path';
12
+ import * as os from 'node:os';
13
+ import { KG_HOOK_SENTINEL } from '@olam/core/src/kg/hook-template.js';
14
+ import { printError, printInfo, printSuccess } from '../output.js';
15
+ function settingsPathFor(scope) {
16
+ if (scope === 'user') {
17
+ return path.join(os.homedir(), '.claude', 'settings.json');
18
+ }
19
+ return path.join(process.cwd(), '.claude', 'settings.json');
20
+ }
21
+ /**
22
+ * Walk a PreToolUse matcher array and drop:
23
+ * - inner hook entries whose `command` contains the sentinel
24
+ * - outer matcher entries left empty after the inner-drop
25
+ * Returns the filtered array + a boolean "did anything change".
26
+ */
27
+ function dropSentinel(matchers) {
28
+ let changed = false;
29
+ const out = [];
30
+ for (const matcher of matchers) {
31
+ const innerHooks = matcher.hooks ?? [];
32
+ const keptInner = innerHooks.filter((h) => {
33
+ if (typeof h.command === 'string' && h.command.includes(KG_HOOK_SENTINEL)) {
34
+ changed = true;
35
+ return false;
36
+ }
37
+ return true;
38
+ });
39
+ if (keptInner.length === 0 && innerHooks.length > 0) {
40
+ // The matcher had hooks but they were all kg-service; drop the matcher entirely.
41
+ changed = true;
42
+ continue;
43
+ }
44
+ if (keptInner.length === innerHooks.length) {
45
+ out.push(matcher);
46
+ }
47
+ else {
48
+ out.push({ ...matcher, hooks: keptInner });
49
+ }
50
+ }
51
+ return { matchers: out, changed };
52
+ }
53
+ export function registerKgUninstallHookCommand(kg) {
54
+ kg.command('uninstall-hook')
55
+ .description('Remove kg-service PreToolUse hook from .claude/settings.json (sentinel-matched; surgical)')
56
+ .option('--scope <scope>', 'project (default) or user', 'project')
57
+ .action((opts) => {
58
+ const scope = opts.scope === 'user' ? 'user' : 'project';
59
+ const filePath = settingsPathFor(scope);
60
+ if (!fs.existsSync(filePath)) {
61
+ printInfo('kg-service hook', `no settings.json at ${filePath} — nothing to remove`);
62
+ return;
63
+ }
64
+ let settings;
65
+ try {
66
+ const raw = fs.readFileSync(filePath, 'utf-8');
67
+ settings = raw.trim() ? JSON.parse(raw) : {};
68
+ }
69
+ catch (err) {
70
+ printError(`could not parse ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
71
+ process.exitCode = 1;
72
+ return;
73
+ }
74
+ const preToolUse = settings.hooks?.PreToolUse;
75
+ if (!Array.isArray(preToolUse) || preToolUse.length === 0) {
76
+ printInfo('kg-service hook', `no PreToolUse hooks at ${filePath} — nothing to remove`);
77
+ return;
78
+ }
79
+ const { matchers, changed } = dropSentinel(preToolUse);
80
+ if (!changed) {
81
+ printInfo('kg-service hook', `not found in ${filePath} — already uninstalled`);
82
+ return;
83
+ }
84
+ // Back up before writing the filtered result.
85
+ const ts = new Date().toISOString().replace(/[:.]/g, '-');
86
+ const backupPath = `${filePath}.olam-bak.${ts}`;
87
+ try {
88
+ fs.copyFileSync(filePath, backupPath);
89
+ }
90
+ catch {
91
+ // best-effort backup
92
+ }
93
+ const next = {
94
+ ...settings,
95
+ hooks: {
96
+ ...settings.hooks,
97
+ PreToolUse: matchers,
98
+ },
99
+ };
100
+ // If PreToolUse is now empty AND there are no other hook stages, drop the key entirely.
101
+ if (matchers.length === 0) {
102
+ const otherStages = Object.keys(next.hooks ?? {}).filter((k) => k !== 'PreToolUse');
103
+ if (otherStages.length === 0) {
104
+ delete next.hooks;
105
+ }
106
+ else {
107
+ delete next.hooks.PreToolUse;
108
+ }
109
+ }
110
+ try {
111
+ fs.writeFileSync(filePath, JSON.stringify(next, null, 2) + '\n');
112
+ printSuccess(`kg-service hook removed from ${filePath}`);
113
+ printInfo('backup', backupPath);
114
+ }
115
+ catch (err) {
116
+ printError(`could not write ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
117
+ process.exitCode = 1;
118
+ }
119
+ });
120
+ }
121
+ //# sourceMappingURL=kg-uninstall-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kg-uninstall-hook.js","sourceRoot":"","sources":["../../src/commands/kg-uninstall-hook.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzC,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAcrD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUzC,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAerD"}
@@ -19,6 +19,7 @@ import { registerMemoryLogs } from './logs.js';
19
19
  import { registerMemorySecret } from './secret.js';
20
20
  import { registerMemoryInstall } from './install.js';
21
21
  import { registerMemoryUninstall } from './uninstall.js';
22
+ import { registerMemoryMode } from './mode.js';
22
23
  export function registerMemory(program) {
23
24
  const memory = program
24
25
  .command('memory')
@@ -30,5 +31,6 @@ export function registerMemory(program) {
30
31
  registerMemorySecret(memory);
31
32
  registerMemoryInstall(memory);
32
33
  registerMemoryUninstall(memory);
34
+ registerMemoryMode(memory);
33
35
  }
34
36
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,MAAM,MAAM,GAAG,OAAO;SACnB,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CACV,8GAA8G,CAC/G,CAAC;IAEJ,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,MAAM,MAAM,GAAG,OAAO;SACnB,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CACV,8GAA8G,CAC/G,CAAC;IAEJ,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * olam memory mode <local|cloud> — flip the workspace's agent-memory
3
+ * source between the host-process (Phase A) and a remote agentmemory
4
+ * deployment (Phase C).
5
+ *
6
+ * Reads + rewrites `.olam/config.yaml`'s `memory:` block via the schema
7
+ * defined in C1. Idempotent: re-running the same mode is a noop.
8
+ *
9
+ * mode local → memory.mode = "local"; ensures host-process running
10
+ * mode cloud [--url ...] → prompts for URL + bearer secret, writes both to
11
+ * config + ~/.olam/cloud-memory-secret, stops the
12
+ * local host-process. Operator must re-create
13
+ * active worlds for the new env to take effect.
14
+ *
15
+ * Plan reference: docs/plans/olam-agent-memory-distributed/phase-c-tasks.md C3
16
+ */
17
+ import type { Command } from 'commander';
18
+ /** Test seam: prompts + IO injection. */
19
+ export interface ModeDeps {
20
+ readonly cwd?: string;
21
+ /** Returns a string (or null on EOF). Defaults to readline.question. */
22
+ readonly promptText?: (q: string) => Promise<string>;
23
+ /** Returns the bearer secret. Default: readline (NOT echoed by terminal). */
24
+ readonly promptSecret?: (q: string) => Promise<string>;
25
+ /** Default: writeCloudMemorySecret. Lets tests redirect to a tmpdir. */
26
+ readonly writeSecret?: (value: string) => void;
27
+ /** Bypass interactive prompts. */
28
+ readonly url?: string;
29
+ /** Bypass interactive prompts. */
30
+ readonly secret?: string;
31
+ /** Test seam: replace start/stop invocations. */
32
+ readonly runStart?: () => Promise<number>;
33
+ readonly runStop?: () => Promise<number>;
34
+ }
35
+ export type ModeOutcome = {
36
+ outcome: 'noop';
37
+ mode: 'local' | 'cloud';
38
+ } | {
39
+ outcome: 'flipped-to-local';
40
+ } | {
41
+ outcome: 'flipped-to-cloud';
42
+ url: string;
43
+ };
44
+ export declare function runMemoryModeLocal(deps?: ModeDeps): Promise<ModeOutcome>;
45
+ export declare function runMemoryModeCloud(deps?: ModeDeps): Promise<ModeOutcome>;
46
+ export declare function registerMemoryMode(cmd: Command): void;
47
+ //# sourceMappingURL=mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode.d.ts","sourceRoot":"","sources":["../../../src/commands/memory/mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAazC,yCAAyC;AACzC,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,wEAAwE;IACxE,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,kCAAkC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1C;AAoDD,MAAM,MAAM,WAAW,GACnB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;CAAE,GAC5C;IAAE,OAAO,EAAE,kBAAkB,CAAA;CAAE,GAC/B;IAAE,OAAO,EAAE,kBAAkB,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,wBAAsB,kBAAkB,CAAC,IAAI,GAAE,QAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CA0BlF;AAED,wBAAsB,kBAAkB,CAAC,IAAI,GAAE,QAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CA2ElF;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CA+BrD"}