@pleri/olam-cli 0.1.120 → 0.1.126
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.
- package/dist/commands/bootstrap.d.ts +4 -0
- package/dist/commands/bootstrap.d.ts.map +1 -1
- package/dist/commands/bootstrap.js +64 -0
- package/dist/commands/bootstrap.js.map +1 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +43 -0
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/mcp/install-shared.d.ts +2 -0
- package/dist/commands/mcp/install-shared.d.ts.map +1 -1
- package/dist/commands/mcp/install-shared.js +13 -0
- package/dist/commands/mcp/install-shared.js.map +1 -1
- package/dist/commands/mcp/uninstall.d.ts.map +1 -1
- package/dist/commands/mcp/uninstall.js +1 -10
- package/dist/commands/mcp/uninstall.js.map +1 -1
- package/dist/commands/memory/_paths.d.ts +15 -0
- package/dist/commands/memory/_paths.d.ts.map +1 -0
- package/dist/commands/memory/_paths.js +34 -0
- package/dist/commands/memory/_paths.js.map +1 -0
- package/dist/commands/memory/index.d.ts +17 -0
- package/dist/commands/memory/index.d.ts.map +1 -0
- package/dist/commands/memory/index.js +34 -0
- package/dist/commands/memory/index.js.map +1 -0
- package/dist/commands/memory/install.d.ts +57 -0
- package/dist/commands/memory/install.d.ts.map +1 -0
- package/dist/commands/memory/install.js +114 -0
- package/dist/commands/memory/install.js.map +1 -0
- package/dist/commands/memory/logs.d.ts +15 -0
- package/dist/commands/memory/logs.d.ts.map +1 -0
- package/dist/commands/memory/logs.js +45 -0
- package/dist/commands/memory/logs.js.map +1 -0
- package/dist/commands/memory/secret.d.ts +16 -0
- package/dist/commands/memory/secret.d.ts.map +1 -0
- package/dist/commands/memory/secret.js +79 -0
- package/dist/commands/memory/secret.js.map +1 -0
- package/dist/commands/memory/start.d.ts +23 -0
- package/dist/commands/memory/start.d.ts.map +1 -0
- package/dist/commands/memory/start.js +166 -0
- package/dist/commands/memory/start.js.map +1 -0
- package/dist/commands/memory/status.d.ts +25 -0
- package/dist/commands/memory/status.d.ts.map +1 -0
- package/dist/commands/memory/status.js +101 -0
- package/dist/commands/memory/status.js.map +1 -0
- package/dist/commands/memory/stop.d.ts +12 -0
- package/dist/commands/memory/stop.d.ts.map +1 -0
- package/dist/commands/memory/stop.js +81 -0
- package/dist/commands/memory/stop.js.map +1 -0
- package/dist/commands/memory/uninstall.d.ts +19 -0
- package/dist/commands/memory/uninstall.d.ts.map +1 -0
- package/dist/commands/memory/uninstall.js +60 -0
- package/dist/commands/memory/uninstall.js.map +1 -0
- package/dist/commands/seed.d.ts +27 -0
- package/dist/commands/seed.d.ts.map +1 -0
- package/dist/commands/seed.js +303 -0
- package/dist/commands/seed.js.map +1 -0
- package/dist/image-digests.json +3 -3
- package/dist/index.js +1835 -259
- package/dist/index.js.map +1 -1
- package/dist/lib/memory-secret.d.ts +48 -0
- package/dist/lib/memory-secret.d.ts.map +1 -0
- package/dist/lib/memory-secret.js +92 -0
- package/dist/lib/memory-secret.js.map +1 -0
- package/dist/lib/world-mcp-register.d.ts +98 -0
- package/dist/lib/world-mcp-register.d.ts.map +1 -0
- package/dist/lib/world-mcp-register.js +117 -0
- package/dist/lib/world-mcp-register.js.map +1 -0
- package/dist/mcp-server.js +502 -65
- package/package.json +1 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* olam memory install — Register `agentmemory` as an MCP server with the
|
|
3
|
+
* operator's host claude.
|
|
4
|
+
*
|
|
5
|
+
* Shells to:
|
|
6
|
+
* claude mcp add agentmemory --scope <s>
|
|
7
|
+
* --env AGENTMEMORY_URL=http://localhost:3111
|
|
8
|
+
* --env AGENTMEMORY_SECRET=<from-file>
|
|
9
|
+
* -- npx -y @agentmemory/mcp
|
|
10
|
+
*
|
|
11
|
+
* The secret is read from ~/.olam/memory-secret (generated by A2 start or
|
|
12
|
+
* A3 secret rotate). Missing secret → exit 1 with remedy.
|
|
13
|
+
*
|
|
14
|
+
* Rotation note: claude stores the env value at install-time. After
|
|
15
|
+
* `olam memory secret rotate`, re-run `olam memory install` so claude
|
|
16
|
+
* picks up the new value (the rotate command surfaces this as a warning).
|
|
17
|
+
*
|
|
18
|
+
* Security note (CP3 audit, 2026-05-13): the bearer secret transits as
|
|
19
|
+
* an argv element of the spawned `claude` invocation. On Linux + macOS,
|
|
20
|
+
* argv is briefly readable via `/proc/<pid>/cmdline` (Linux) or `ps -E`
|
|
21
|
+
* (macOS) by any local user during the few ms claude runs. Blast radius:
|
|
22
|
+
* operator's own machine (single-user dev laptop = effectively nil;
|
|
23
|
+
* shared dev VM / interactive tmux = full secret disclosure to anyone
|
|
24
|
+
* on the box). Same shape as every other `--env KEY=VAL` CLI. Operator
|
|
25
|
+
* docs (A6) call this out + name the mitigation: don't run install on
|
|
26
|
+
* boxes with untrusted local users. If/when `claude mcp add` grows a
|
|
27
|
+
* `--env-stdin` form upstream, switch to it.
|
|
28
|
+
*
|
|
29
|
+
* Plan reference: docs/plans/olam-agent-memory-distributed/phase-a-tasks.md A4
|
|
30
|
+
*/
|
|
31
|
+
import { printError, printSuccess } from '../../output.js';
|
|
32
|
+
import { DEFAULT_CLAUDE_SHELL_DEPS, REMEDY_CLAUDE_MISSING, isOnPath, normaliseScope, } from '../mcp/install-shared.js';
|
|
33
|
+
import { MEMORY_REST_PORT } from './_paths.js';
|
|
34
|
+
import { MEMORY_SECRET_PATH, readMemorySecretOrNull, } from '../../lib/memory-secret.js';
|
|
35
|
+
const MCP_NAME = 'agentmemory';
|
|
36
|
+
const NPM_PACKAGE_NAME = '@agentmemory/mcp';
|
|
37
|
+
export const DEFAULT_SECRET_READER = () => readMemorySecretOrNull();
|
|
38
|
+
export function buildClaudeMcpAddArgs(scope, agentmemoryUrl, secret) {
|
|
39
|
+
return {
|
|
40
|
+
command: 'claude',
|
|
41
|
+
args: [
|
|
42
|
+
'mcp',
|
|
43
|
+
'add',
|
|
44
|
+
MCP_NAME,
|
|
45
|
+
'--scope',
|
|
46
|
+
scope,
|
|
47
|
+
'--env',
|
|
48
|
+
`AGENTMEMORY_URL=${agentmemoryUrl}`,
|
|
49
|
+
'--env',
|
|
50
|
+
`AGENTMEMORY_SECRET=${secret}`,
|
|
51
|
+
'--',
|
|
52
|
+
'npx',
|
|
53
|
+
'-y',
|
|
54
|
+
NPM_PACKAGE_NAME,
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const REMEDY_SECRET_MISSING = `No memory-secret found at ${MEMORY_SECRET_PATH}. ` +
|
|
59
|
+
`Run 'olam memory start' first — it generates the secret on first launch.`;
|
|
60
|
+
/**
|
|
61
|
+
* Defensive redaction for any stderr/stdout we echo back. If `claude`
|
|
62
|
+
* (or an upstream bug) ever prints the env values on parse failure, we
|
|
63
|
+
* don't want the secret hitting the operator's terminal scrollback.
|
|
64
|
+
*/
|
|
65
|
+
function redactSecretInText(text) {
|
|
66
|
+
return text.replace(/AGENTMEMORY_SECRET=\S+/g, 'AGENTMEMORY_SECRET=<redacted>');
|
|
67
|
+
}
|
|
68
|
+
export async function runInstall(opts, deps = DEFAULT_CLAUDE_SHELL_DEPS) {
|
|
69
|
+
if (!isOnPath(deps, 'claude')) {
|
|
70
|
+
printError(REMEDY_CLAUDE_MISSING);
|
|
71
|
+
return 1;
|
|
72
|
+
}
|
|
73
|
+
const readSecret = opts.readSecret ?? DEFAULT_SECRET_READER;
|
|
74
|
+
const secret = opts.secret ?? readSecret();
|
|
75
|
+
if (!secret) {
|
|
76
|
+
printError(REMEDY_SECRET_MISSING);
|
|
77
|
+
return 1;
|
|
78
|
+
}
|
|
79
|
+
const agentmemoryUrl = `http://localhost:${MEMORY_REST_PORT}`;
|
|
80
|
+
const { command, args } = buildClaudeMcpAddArgs(opts.scope, agentmemoryUrl, secret);
|
|
81
|
+
// Log without leaking the secret. Replace the AGENTMEMORY_SECRET arg with a redacted shape.
|
|
82
|
+
const redacted = args.map((a) => a.startsWith('AGENTMEMORY_SECRET=') ? 'AGENTMEMORY_SECRET=<redacted>' : a);
|
|
83
|
+
deps.log(`Wiring: ${command} ${redacted.join(' ')}`);
|
|
84
|
+
const result = deps.spawn(command, args, {
|
|
85
|
+
encoding: 'utf8',
|
|
86
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
87
|
+
});
|
|
88
|
+
if (result.status !== 0) {
|
|
89
|
+
const detail = redactSecretInText(result.stderr?.trim() || result.stdout?.trim() || '(no output)');
|
|
90
|
+
printError(`claude mcp add failed (rc=${result.status ?? 'unknown'}): ${detail}`);
|
|
91
|
+
return result.status ?? 1;
|
|
92
|
+
}
|
|
93
|
+
printSuccess(`agentmemory MCP registered with claude (--scope ${opts.scope}; url ${agentmemoryUrl}).`);
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
export function registerMemoryInstall(cmd) {
|
|
97
|
+
cmd
|
|
98
|
+
.command('install')
|
|
99
|
+
.description('Register agentmemory as an MCP server with the operator\'s host claude (shells to `claude mcp add`)')
|
|
100
|
+
.option('--scope <scope>', 'claude mcp scope: user | project | local', 'user')
|
|
101
|
+
.action(async (rawOpts) => {
|
|
102
|
+
const scope = normaliseScope(rawOpts.scope);
|
|
103
|
+
if (scope === null) {
|
|
104
|
+
printError(`--scope must be one of: user, project, local (got: ${rawOpts.scope})`);
|
|
105
|
+
process.exitCode = 1;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const rc = await runInstall({ scope });
|
|
109
|
+
if (rc !== 0) {
|
|
110
|
+
process.exitCode = rc;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/commands/memory/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* olam memory logs — tail ~/.olam/memory-service.log.
|
|
3
|
+
*
|
|
4
|
+
* --follow (alias -f): tail -f-style; Ctrl-C to stop.
|
|
5
|
+
* --tail N (default 50): last N lines.
|
|
6
|
+
*
|
|
7
|
+
* Plan reference: docs/plans/olam-agent-memory-distributed/phase-a-tasks.md A2
|
|
8
|
+
*/
|
|
9
|
+
import type { Command } from 'commander';
|
|
10
|
+
export declare function runMemoryLogs(opts: {
|
|
11
|
+
follow?: boolean;
|
|
12
|
+
tail?: string;
|
|
13
|
+
}): Promise<number>;
|
|
14
|
+
export declare function registerMemoryLogs(cmd: Command): void;
|
|
15
|
+
//# sourceMappingURL=logs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/commands/memory/logs.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMzC,wBAAsB,aAAa,CAAC,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAmB9F;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAUrD"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* olam memory logs — tail ~/.olam/memory-service.log.
|
|
3
|
+
*
|
|
4
|
+
* --follow (alias -f): tail -f-style; Ctrl-C to stop.
|
|
5
|
+
* --tail N (default 50): last N lines.
|
|
6
|
+
*
|
|
7
|
+
* Plan reference: docs/plans/olam-agent-memory-distributed/phase-a-tasks.md A2
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync } from 'node:fs';
|
|
10
|
+
import { spawn } from 'node:child_process';
|
|
11
|
+
import { printWarning, printHeader } from '../../output.js';
|
|
12
|
+
import { MEMORY_LOG_PATH } from './_paths.js';
|
|
13
|
+
export async function runMemoryLogs(opts) {
|
|
14
|
+
if (!existsSync(MEMORY_LOG_PATH)) {
|
|
15
|
+
printWarning(`no log at ${MEMORY_LOG_PATH} (start the service first via 'olam memory start')`);
|
|
16
|
+
return 1;
|
|
17
|
+
}
|
|
18
|
+
const tailN = opts.tail ? parseInt(opts.tail, 10) : 50;
|
|
19
|
+
if (!Number.isFinite(tailN) || tailN < 0) {
|
|
20
|
+
printWarning(`invalid --tail value: ${opts.tail}`);
|
|
21
|
+
return 1;
|
|
22
|
+
}
|
|
23
|
+
const args = ['-n', `${tailN}`];
|
|
24
|
+
if (opts.follow)
|
|
25
|
+
args.push('-f');
|
|
26
|
+
args.push(MEMORY_LOG_PATH);
|
|
27
|
+
printHeader(`olam memory logs (${opts.follow ? 'follow' : `tail -n ${tailN}`})`);
|
|
28
|
+
const child = spawn('tail', args, { stdio: 'inherit' });
|
|
29
|
+
return new Promise((resolve) => {
|
|
30
|
+
child.on('exit', (code) => resolve(code ?? 0));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
export function registerMemoryLogs(cmd) {
|
|
34
|
+
cmd
|
|
35
|
+
.command('logs')
|
|
36
|
+
.description('Tail the memory service log file at ~/.olam/memory-service.log')
|
|
37
|
+
.option('-f, --follow', 'Stream new log lines (Ctrl-C to stop)', false)
|
|
38
|
+
.option('--tail <n>', 'Number of trailing lines (default 50)', '50')
|
|
39
|
+
.action(async (opts) => {
|
|
40
|
+
const rc = await runMemoryLogs(opts);
|
|
41
|
+
if (rc !== 0)
|
|
42
|
+
process.exitCode = rc;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../../src/commands/memory/logs.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAyC;IAC3E,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACjC,YAAY,CAAC,aAAa,eAAe,oDAAoD,CAAC,CAAC;QAC/F,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACzC,YAAY,CAAC,yBAAyB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IAChC,IAAI,IAAI,CAAC,MAAM;QAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAE3B,WAAW,CAAC,qBAAqB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,KAAK,EAAE,GAAG,CAAC,CAAC;IACjF,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACxD,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;QACrC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,GAAG;SACA,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,gEAAgE,CAAC;SAC7E,MAAM,CAAC,cAAc,EAAE,uCAAuC,EAAE,KAAK,CAAC;SACtE,MAAM,CAAC,YAAY,EAAE,uCAAuC,EAAE,IAAI,CAAC;SACnE,MAAM,CAAC,KAAK,EAAE,IAAyC,EAAE,EAAE;QAC1D,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,EAAE,KAAK,CAAC;YAAE,OAAO,CAAC,QAAQ,GAAG,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* olam memory secret — show or rotate the bearer secret at ~/.olam/memory-secret.
|
|
3
|
+
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* show — print the current secret value (use with care; do not pipe to logs)
|
|
6
|
+
* rotate — generate a fresh secret + restart the running memory service so
|
|
7
|
+
* it picks up the new value. Worlds created BEFORE the rotation
|
|
8
|
+
* continue to use the old value until they're re-created.
|
|
9
|
+
*
|
|
10
|
+
* Plan reference: docs/plans/olam-agent-memory-distributed/phase-a-tasks.md A3
|
|
11
|
+
*/
|
|
12
|
+
import type { Command } from 'commander';
|
|
13
|
+
export declare function runMemorySecretShow(): Promise<number>;
|
|
14
|
+
export declare function runMemorySecretRotate(): Promise<number>;
|
|
15
|
+
export declare function registerMemorySecret(cmd: Command): void;
|
|
16
|
+
//# sourceMappingURL=secret.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret.d.ts","sourceRoot":"","sources":["../../../src/commands/memory/secret.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAazC,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAU3D;AAED,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC,CAoC7D;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAsBvD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* olam memory secret — show or rotate the bearer secret at ~/.olam/memory-secret.
|
|
3
|
+
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* show — print the current secret value (use with care; do not pipe to logs)
|
|
6
|
+
* rotate — generate a fresh secret + restart the running memory service so
|
|
7
|
+
* it picks up the new value. Worlds created BEFORE the rotation
|
|
8
|
+
* continue to use the old value until they're re-created.
|
|
9
|
+
*
|
|
10
|
+
* Plan reference: docs/plans/olam-agent-memory-distributed/phase-a-tasks.md A3
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync } from 'node:fs';
|
|
13
|
+
import { MEMORY_SECRET_PATH, hasMemorySecret, readMemorySecret, rotateMemorySecret, } from '../../lib/memory-secret.js';
|
|
14
|
+
import { printError, printSuccess, printInfo, printWarning, printHeader } from '../../output.js';
|
|
15
|
+
import { runMemoryStart } from './start.js';
|
|
16
|
+
import { runMemoryStop } from './stop.js';
|
|
17
|
+
import { MEMORY_PID_PATH } from './_paths.js';
|
|
18
|
+
export async function runMemorySecretShow() {
|
|
19
|
+
if (!hasMemorySecret()) {
|
|
20
|
+
printError(`secret missing at ${MEMORY_SECRET_PATH}. Run 'olam memory start' to generate it.`);
|
|
21
|
+
return 1;
|
|
22
|
+
}
|
|
23
|
+
// Plain stdout so it's pipeable; helper helpers go to stderr in the lib.
|
|
24
|
+
process.stdout.write(`${readMemorySecret()}\n`);
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
export async function runMemorySecretRotate() {
|
|
28
|
+
printHeader('olam memory secret rotate');
|
|
29
|
+
const wasRunning = existsSync(MEMORY_PID_PATH);
|
|
30
|
+
if (wasRunning) {
|
|
31
|
+
printInfo('current state', 'service running; will restart with new secret');
|
|
32
|
+
const stopRc = await runMemoryStop();
|
|
33
|
+
if (stopRc !== 0) {
|
|
34
|
+
printError('failed to stop the running service; rotation aborted to avoid split-brain');
|
|
35
|
+
return stopRc;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
printInfo('current state', 'service stopped');
|
|
40
|
+
}
|
|
41
|
+
const fresh = rotateMemorySecret();
|
|
42
|
+
printSuccess(`secret rotated (${fresh.length / 2}-byte hex written to ${MEMORY_SECRET_PATH})`);
|
|
43
|
+
if (wasRunning) {
|
|
44
|
+
printInfo('restarting', 'memory service with new secret');
|
|
45
|
+
const startRc = await runMemoryStart();
|
|
46
|
+
if (startRc !== 0) {
|
|
47
|
+
printError('service failed to restart after rotation. The new secret is on disk; run `olam memory start` once you fix the underlying issue.');
|
|
48
|
+
return startRc;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
printWarning('service was not running; new secret will be picked up on next `olam memory start`');
|
|
53
|
+
}
|
|
54
|
+
// Heads-up: worlds created before this rotation still have the old value in env.
|
|
55
|
+
printWarning('worlds created BEFORE this rotation still have the old secret in their env. Re-create them (olam destroy + olam create) to pick up the new value.');
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
58
|
+
export function registerMemorySecret(cmd) {
|
|
59
|
+
const secret = cmd
|
|
60
|
+
.command('secret')
|
|
61
|
+
.description('Show or rotate the bearer secret at ~/.olam/memory-secret');
|
|
62
|
+
secret
|
|
63
|
+
.command('show')
|
|
64
|
+
.description('Print the current secret value (use with care; do not pipe to logs)')
|
|
65
|
+
.action(async () => {
|
|
66
|
+
const rc = await runMemorySecretShow();
|
|
67
|
+
if (rc !== 0)
|
|
68
|
+
process.exitCode = rc;
|
|
69
|
+
});
|
|
70
|
+
secret
|
|
71
|
+
.command('rotate')
|
|
72
|
+
.description('Regenerate the secret and restart the running memory service (worlds created before rotation must be re-created)')
|
|
73
|
+
.action(async () => {
|
|
74
|
+
const rc = await runMemorySecretRotate();
|
|
75
|
+
if (rc !== 0)
|
|
76
|
+
process.exitCode = rc;
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=secret.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret.js","sourceRoot":"","sources":["../../../src/commands/memory/secret.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* olam memory start — spawn agentmemory as a managed host child process.
|
|
3
|
+
*
|
|
4
|
+
* Flow:
|
|
5
|
+
* 1. Ensure iii v0.11.2 binary at ~/.olam/bin/iii (calls A1's ensure-iii-engine.mjs equivalent)
|
|
6
|
+
* 2. Ensure ~/.olam/memory-secret (0600) exists
|
|
7
|
+
* 3. Locate packages/memory-service/ (the npm-installed agentmemory)
|
|
8
|
+
* 4. Spawn `agentmemory` (the bin from @agentmemory/agentmemory@0.9.6) with:
|
|
9
|
+
* env: { AGENTMEMORY_SECRET, PATH: ~/.olam/bin:$PATH, ...inherit }
|
|
10
|
+
* cwd: ~/.olam (so agentmemory writes state under ~/.olam/data/)
|
|
11
|
+
* stdio: append to ~/.olam/memory-service.log
|
|
12
|
+
* detached: true so the child outlives this CLI invocation
|
|
13
|
+
* 5. Write child pid to ~/.olam/memory.pid
|
|
14
|
+
* 6. Poll http://localhost:3111/agentmemory/livez until 200 (timeout 30s)
|
|
15
|
+
*
|
|
16
|
+
* Idempotent: re-running while the service is healthy prints status and exits 0.
|
|
17
|
+
*
|
|
18
|
+
* Plan reference: docs/plans/olam-agent-memory-distributed/phase-a-tasks.md A2
|
|
19
|
+
*/
|
|
20
|
+
import type { Command } from 'commander';
|
|
21
|
+
export declare function runMemoryStart(): Promise<number>;
|
|
22
|
+
export declare function registerMemoryStart(cmd: Command): void;
|
|
23
|
+
//# sourceMappingURL=start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/commands/memory/start.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwFzC,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CA6EtD;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAQtD"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* olam memory start — spawn agentmemory as a managed host child process.
|
|
3
|
+
*
|
|
4
|
+
* Flow:
|
|
5
|
+
* 1. Ensure iii v0.11.2 binary at ~/.olam/bin/iii (calls A1's ensure-iii-engine.mjs equivalent)
|
|
6
|
+
* 2. Ensure ~/.olam/memory-secret (0600) exists
|
|
7
|
+
* 3. Locate packages/memory-service/ (the npm-installed agentmemory)
|
|
8
|
+
* 4. Spawn `agentmemory` (the bin from @agentmemory/agentmemory@0.9.6) with:
|
|
9
|
+
* env: { AGENTMEMORY_SECRET, PATH: ~/.olam/bin:$PATH, ...inherit }
|
|
10
|
+
* cwd: ~/.olam (so agentmemory writes state under ~/.olam/data/)
|
|
11
|
+
* stdio: append to ~/.olam/memory-service.log
|
|
12
|
+
* detached: true so the child outlives this CLI invocation
|
|
13
|
+
* 5. Write child pid to ~/.olam/memory.pid
|
|
14
|
+
* 6. Poll http://localhost:3111/agentmemory/livez until 200 (timeout 30s)
|
|
15
|
+
*
|
|
16
|
+
* Idempotent: re-running while the service is healthy prints status and exits 0.
|
|
17
|
+
*
|
|
18
|
+
* Plan reference: docs/plans/olam-agent-memory-distributed/phase-a-tasks.md A2
|
|
19
|
+
*/
|
|
20
|
+
import { spawn } from 'node:child_process';
|
|
21
|
+
import { existsSync, mkdirSync, openSync, readFileSync, writeFileSync } from 'node:fs';
|
|
22
|
+
import { join } from 'node:path';
|
|
23
|
+
import { printError, printSuccess, printInfo, printHeader } from '../../output.js';
|
|
24
|
+
import { ensureMemorySecret } from '../../lib/memory-secret.js';
|
|
25
|
+
import { III_BINARY_PATH, MEMORY_DATA_DIR, MEMORY_LIVEZ_URL, MEMORY_LOG_PATH, MEMORY_PID_PATH, MEMORY_SERVICE_CANDIDATES, OLAM_BIN_DIR, OLAM_HOME, } from './_paths.js';
|
|
26
|
+
const READINESS_TIMEOUT_MS = 30_000;
|
|
27
|
+
const READINESS_POLL_MS = 500;
|
|
28
|
+
function resolveMemoryServiceDir() {
|
|
29
|
+
for (const c of MEMORY_SERVICE_CANDIDATES) {
|
|
30
|
+
if (existsSync(c))
|
|
31
|
+
return c;
|
|
32
|
+
}
|
|
33
|
+
throw new Error(`Could not find packages/memory-service/. Searched: ${MEMORY_SERVICE_CANDIDATES.join(', ')}. ` +
|
|
34
|
+
`If running from a published @pleri/olam-cli tarball, this is a packaging bug — please file an issue.`);
|
|
35
|
+
}
|
|
36
|
+
function resolveAgentMemoryBin(serviceDir) {
|
|
37
|
+
// npm hoists @agentmemory/agentmemory to the workspace root in monorepo mode.
|
|
38
|
+
// Search likely locations in order.
|
|
39
|
+
const candidates = [
|
|
40
|
+
join(serviceDir, 'node_modules', '.bin', 'agentmemory'),
|
|
41
|
+
join(serviceDir, '..', '..', 'node_modules', '.bin', 'agentmemory'),
|
|
42
|
+
join(serviceDir, '..', '..', '..', 'node_modules', '.bin', 'agentmemory'),
|
|
43
|
+
];
|
|
44
|
+
for (const c of candidates) {
|
|
45
|
+
if (existsSync(c))
|
|
46
|
+
return c;
|
|
47
|
+
}
|
|
48
|
+
throw new Error(`Could not find agentmemory bin. Searched: ${candidates.join(', ')}. ` +
|
|
49
|
+
`Run 'npm install' from the repo root.`);
|
|
50
|
+
}
|
|
51
|
+
function isProcessAlive(pid) {
|
|
52
|
+
try {
|
|
53
|
+
// signal 0 doesn't deliver; just tests existence + permission
|
|
54
|
+
process.kill(pid, 0);
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function readPidFromFile() {
|
|
62
|
+
if (!existsSync(MEMORY_PID_PATH))
|
|
63
|
+
return null;
|
|
64
|
+
const raw = readFileSync(MEMORY_PID_PATH, 'utf8').trim();
|
|
65
|
+
const pid = parseInt(raw, 10);
|
|
66
|
+
if (!Number.isFinite(pid) || pid <= 0)
|
|
67
|
+
return null;
|
|
68
|
+
return pid;
|
|
69
|
+
}
|
|
70
|
+
async function probeLivez(secret, signal) {
|
|
71
|
+
try {
|
|
72
|
+
const resp = await fetch(MEMORY_LIVEZ_URL, {
|
|
73
|
+
headers: { authorization: `Bearer ${secret}` },
|
|
74
|
+
signal,
|
|
75
|
+
});
|
|
76
|
+
if (!resp.ok)
|
|
77
|
+
return false;
|
|
78
|
+
const body = (await resp.json());
|
|
79
|
+
return body.status === 'ok';
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function waitForReady(secret) {
|
|
86
|
+
const deadline = Date.now() + READINESS_TIMEOUT_MS;
|
|
87
|
+
while (Date.now() < deadline) {
|
|
88
|
+
if (await probeLivez(secret))
|
|
89
|
+
return true;
|
|
90
|
+
await new Promise((r) => setTimeout(r, READINESS_POLL_MS));
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
export async function runMemoryStart() {
|
|
95
|
+
printHeader('olam memory start');
|
|
96
|
+
// 1. iii binary (A1's deliverable)
|
|
97
|
+
if (!existsSync(III_BINARY_PATH)) {
|
|
98
|
+
printError(`iii binary missing at ${III_BINARY_PATH}. Run: node packages/memory-service/scripts/ensure-iii-engine.mjs`);
|
|
99
|
+
return 1;
|
|
100
|
+
}
|
|
101
|
+
printInfo('iii binary', III_BINARY_PATH);
|
|
102
|
+
// 2. Secret (A3 lib)
|
|
103
|
+
const secret = ensureMemorySecret();
|
|
104
|
+
printInfo('secret', '~/.olam/memory-secret (0600)');
|
|
105
|
+
// 3. Locate the service + agentmemory bin
|
|
106
|
+
const serviceDir = resolveMemoryServiceDir();
|
|
107
|
+
const agentmemoryBin = resolveAgentMemoryBin(serviceDir);
|
|
108
|
+
printInfo('agentmemory', agentmemoryBin);
|
|
109
|
+
// 4. Idempotency: already running?
|
|
110
|
+
const existingPid = readPidFromFile();
|
|
111
|
+
if (existingPid !== null && isProcessAlive(existingPid)) {
|
|
112
|
+
const ready = await probeLivez(secret);
|
|
113
|
+
if (ready) {
|
|
114
|
+
printSuccess(`already running (pid ${existingPid}); /agentmemory/livez ok`);
|
|
115
|
+
return 0;
|
|
116
|
+
}
|
|
117
|
+
// Pidfile points at a live process that isn't responding — leave it alone, error out.
|
|
118
|
+
printError(`pid ${existingPid} is alive but /agentmemory/livez isn't responding. ` +
|
|
119
|
+
`Run 'olam memory stop' to clear, then retry.`);
|
|
120
|
+
return 1;
|
|
121
|
+
}
|
|
122
|
+
// 5. Ensure dirs exist
|
|
123
|
+
mkdirSync(OLAM_HOME, { recursive: true });
|
|
124
|
+
mkdirSync(MEMORY_DATA_DIR, { recursive: true });
|
|
125
|
+
// 6. Spawn detached, redirect output to log file (append).
|
|
126
|
+
const logFd = openSync(MEMORY_LOG_PATH, 'a');
|
|
127
|
+
const child = spawn(agentmemoryBin, [], {
|
|
128
|
+
cwd: OLAM_HOME,
|
|
129
|
+
env: {
|
|
130
|
+
...process.env,
|
|
131
|
+
AGENTMEMORY_SECRET: secret,
|
|
132
|
+
PATH: `${OLAM_BIN_DIR}:${process.env.PATH ?? ''}`,
|
|
133
|
+
},
|
|
134
|
+
stdio: ['ignore', logFd, logFd],
|
|
135
|
+
detached: true,
|
|
136
|
+
});
|
|
137
|
+
child.unref();
|
|
138
|
+
if (child.pid === undefined) {
|
|
139
|
+
printError('spawn returned no pid (process failed to start)');
|
|
140
|
+
return 1;
|
|
141
|
+
}
|
|
142
|
+
// 7. Persist pid
|
|
143
|
+
writeFileSync(MEMORY_PID_PATH, `${child.pid}\n`, { mode: 0o644 });
|
|
144
|
+
printInfo('pid', `${child.pid}`);
|
|
145
|
+
// 8. Wait for readiness
|
|
146
|
+
printInfo('readiness', `polling ${MEMORY_LIVEZ_URL}`);
|
|
147
|
+
const ready = await waitForReady(secret);
|
|
148
|
+
if (!ready) {
|
|
149
|
+
printError(`agentmemory failed to come up within ${READINESS_TIMEOUT_MS / 1000}s. ` +
|
|
150
|
+
`Inspect ${MEMORY_LOG_PATH} for engine errors.`);
|
|
151
|
+
return 1;
|
|
152
|
+
}
|
|
153
|
+
printSuccess(`memory service ready (pid ${child.pid}; logs at ${MEMORY_LOG_PATH})`);
|
|
154
|
+
return 0;
|
|
155
|
+
}
|
|
156
|
+
export function registerMemoryStart(cmd) {
|
|
157
|
+
cmd
|
|
158
|
+
.command('start')
|
|
159
|
+
.description('Start the host agent-memory process (idempotent; polls livez until ready)')
|
|
160
|
+
.action(async () => {
|
|
161
|
+
const rc = await runMemoryStart();
|
|
162
|
+
if (rc !== 0)
|
|
163
|
+
process.exitCode = rc;
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/commands/memory/start.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* olam memory status — diagnostic dump for the host memory service.
|
|
3
|
+
*
|
|
4
|
+
* Reports: pidfile state, process liveness, /agentmemory/livez response,
|
|
5
|
+
* secret-set Y/N, iii binary location, REST port. Intended for both
|
|
6
|
+
* humans (default output) and machines (--json).
|
|
7
|
+
*
|
|
8
|
+
* Plan reference: docs/plans/olam-agent-memory-distributed/phase-a-tasks.md A2
|
|
9
|
+
*/
|
|
10
|
+
import type { Command } from 'commander';
|
|
11
|
+
interface MemoryStatus {
|
|
12
|
+
pid: number | null;
|
|
13
|
+
alive: boolean | null;
|
|
14
|
+
livez: 'ok' | 'unreachable' | 'unauthorized' | 'unknown';
|
|
15
|
+
secretSet: boolean;
|
|
16
|
+
iiiBinary: string | null;
|
|
17
|
+
port: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function collectMemoryStatus(): Promise<MemoryStatus>;
|
|
20
|
+
export declare function runMemoryStatus(opts?: {
|
|
21
|
+
json?: boolean;
|
|
22
|
+
}): Promise<number>;
|
|
23
|
+
export declare function registerMemoryStatus(cmd: Command): void;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/memory/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWzC,UAAU,YAAY;IACpB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,IAAI,GAAG,aAAa,GAAG,cAAc,GAAG,SAAS,CAAC;IACzD,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CACd;AAyBD,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,YAAY,CAAC,CAkBjE;AAED,wBAAsB,eAAe,CAAC,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAgCpF;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CASvD"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* olam memory status — diagnostic dump for the host memory service.
|
|
3
|
+
*
|
|
4
|
+
* Reports: pidfile state, process liveness, /agentmemory/livez response,
|
|
5
|
+
* secret-set Y/N, iii binary location, REST port. Intended for both
|
|
6
|
+
* humans (default output) and machines (--json).
|
|
7
|
+
*
|
|
8
|
+
* Plan reference: docs/plans/olam-agent-memory-distributed/phase-a-tasks.md A2
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
11
|
+
import { printError, printInfo, printHeader, printWarning } from '../../output.js';
|
|
12
|
+
import { hasMemorySecret, readMemorySecretOrNull } from '../../lib/memory-secret.js';
|
|
13
|
+
import { III_BINARY_PATH, MEMORY_LIVEZ_URL, MEMORY_PID_PATH, MEMORY_REST_PORT, } from './_paths.js';
|
|
14
|
+
function isAlive(pid) {
|
|
15
|
+
try {
|
|
16
|
+
process.kill(pid, 0);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async function probe(secret) {
|
|
24
|
+
try {
|
|
25
|
+
const headers = {};
|
|
26
|
+
if (secret)
|
|
27
|
+
headers.authorization = `Bearer ${secret}`;
|
|
28
|
+
const resp = await fetch(MEMORY_LIVEZ_URL, { headers });
|
|
29
|
+
if (resp.status === 401)
|
|
30
|
+
return 'unauthorized';
|
|
31
|
+
if (!resp.ok)
|
|
32
|
+
return 'unknown';
|
|
33
|
+
const body = (await resp.json());
|
|
34
|
+
return body.status === 'ok' ? 'ok' : 'unknown';
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return 'unreachable';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export async function collectMemoryStatus() {
|
|
41
|
+
let pid = null;
|
|
42
|
+
if (existsSync(MEMORY_PID_PATH)) {
|
|
43
|
+
const raw = readFileSync(MEMORY_PID_PATH, 'utf8').trim();
|
|
44
|
+
const parsed = parseInt(raw, 10);
|
|
45
|
+
pid = Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
46
|
+
}
|
|
47
|
+
const alive = pid === null ? null : isAlive(pid);
|
|
48
|
+
const secret = readMemorySecretOrNull();
|
|
49
|
+
const livez = await probe(secret);
|
|
50
|
+
return {
|
|
51
|
+
pid,
|
|
52
|
+
alive,
|
|
53
|
+
livez,
|
|
54
|
+
secretSet: hasMemorySecret(),
|
|
55
|
+
iiiBinary: existsSync(III_BINARY_PATH) ? III_BINARY_PATH : null,
|
|
56
|
+
port: MEMORY_REST_PORT,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export async function runMemoryStatus(opts = {}) {
|
|
60
|
+
const s = await collectMemoryStatus();
|
|
61
|
+
if (opts.json) {
|
|
62
|
+
process.stdout.write(JSON.stringify(s, null, 2) + '\n');
|
|
63
|
+
return s.livez === 'ok' ? 0 : 1;
|
|
64
|
+
}
|
|
65
|
+
printHeader('olam memory status');
|
|
66
|
+
printInfo('pid', s.pid === null ? '(no pidfile)' : `${s.pid}`);
|
|
67
|
+
printInfo('alive', s.alive === null ? 'n/a' : s.alive ? 'yes' : 'no (stale pidfile)');
|
|
68
|
+
printInfo('livez', s.livez);
|
|
69
|
+
printInfo('secret', s.secretSet ? '~/.olam/memory-secret (set)' : '(missing)');
|
|
70
|
+
printInfo('iii', s.iiiBinary ?? '(not installed)');
|
|
71
|
+
printInfo('port', `${s.port}`);
|
|
72
|
+
if (s.livez === 'ok' && s.alive)
|
|
73
|
+
return 0;
|
|
74
|
+
if (s.livez === 'unauthorized') {
|
|
75
|
+
printWarning('livez returned 401 — the memory service is up but the local secret does not match. Try `olam memory secret rotate`.');
|
|
76
|
+
return 1;
|
|
77
|
+
}
|
|
78
|
+
if (s.alive === false && s.pid !== null) {
|
|
79
|
+
printWarning('pidfile points at a dead process; run `olam memory stop` to clean up');
|
|
80
|
+
return 1;
|
|
81
|
+
}
|
|
82
|
+
if (!s.iiiBinary) {
|
|
83
|
+
printWarning('iii binary missing; run `node packages/memory-service/scripts/ensure-iii-engine.mjs`');
|
|
84
|
+
}
|
|
85
|
+
if (!s.secretSet) {
|
|
86
|
+
printWarning('secret missing; `olam memory start` will generate it');
|
|
87
|
+
}
|
|
88
|
+
return s.livez === 'ok' ? 0 : 1;
|
|
89
|
+
}
|
|
90
|
+
export function registerMemoryStatus(cmd) {
|
|
91
|
+
cmd
|
|
92
|
+
.command('status')
|
|
93
|
+
.description('Diagnostic dump for the host memory service (pid + livez + secret-set check)')
|
|
94
|
+
.option('--json', 'Machine-readable JSON output', false)
|
|
95
|
+
.action(async (opts) => {
|
|
96
|
+
const rc = await runMemoryStatus(opts);
|
|
97
|
+
if (rc !== 0)
|
|
98
|
+
process.exitCode = rc;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/commands/memory/status.ts"],"names":[],"mappings":"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"}
|