@pleri/olam-cli 0.1.135 → 0.1.137
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/kg-build.d.ts +29 -31
- package/dist/commands/kg-build.d.ts.map +1 -1
- package/dist/commands/kg-build.js +102 -190
- package/dist/commands/kg-build.js.map +1 -1
- package/dist/commands/kg-service-container.d.ts.map +1 -1
- package/dist/commands/kg-service-container.js +10 -0
- package/dist/commands/kg-service-container.js.map +1 -1
- package/dist/commands/memory/start.d.ts.map +1 -1
- package/dist/commands/memory/start.js +6 -0
- package/dist/commands/memory/start.js.map +1 -1
- package/dist/image-digests.json +6 -6
- package/dist/index.js +324 -306
- package/dist/mcp-server.js +209 -51
- package/host-cp/src/plan-chat-secret.mjs +92 -0
- package/host-cp/src/plan-chat-service.mjs +271 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4420,7 +4420,7 @@ function loadRepoManifest(repoDir) {
|
|
|
4420
4420
|
}
|
|
4421
4421
|
return { ...body, source };
|
|
4422
4422
|
}
|
|
4423
|
-
var runtimeSchema, appSchema, serviceSchema, deploySchema, BootstrapKindSchema, BootstrapStepSchema, RepoManifestSchema, KNOWN_TOP_LEVEL_KEYS, FORBIDDEN_KEYS;
|
|
4423
|
+
var runtimeSchema, appSchema, serviceSchema, deploySchema, planChatSchema, BootstrapKindSchema, BootstrapStepSchema, RepoManifestSchema, KNOWN_TOP_LEVEL_KEYS, FORBIDDEN_KEYS;
|
|
4424
4424
|
var init_repo_manifest = __esm({
|
|
4425
4425
|
"../core/dist/world/repo-manifest.js"() {
|
|
4426
4426
|
"use strict";
|
|
@@ -4526,6 +4526,9 @@ var init_repo_manifest = __esm({
|
|
|
4526
4526
|
deploySchema = external_exports.object({
|
|
4527
4527
|
tags: external_exports.array(external_exports.string()).optional()
|
|
4528
4528
|
}).passthrough();
|
|
4529
|
+
planChatSchema = external_exports.object({
|
|
4530
|
+
enabled: external_exports.boolean()
|
|
4531
|
+
}).strict();
|
|
4529
4532
|
BootstrapKindSchema = external_exports.enum(["gems", "node", "pg"]);
|
|
4530
4533
|
BootstrapStepSchema = external_exports.union([
|
|
4531
4534
|
external_exports.string(),
|
|
@@ -4548,7 +4551,8 @@ var init_repo_manifest = __esm({
|
|
|
4548
4551
|
secrets: external_exports.string().optional(),
|
|
4549
4552
|
bootstrap: external_exports.array(BootstrapStepSchema).optional(),
|
|
4550
4553
|
start: external_exports.string().optional(),
|
|
4551
|
-
deploy: deploySchema.optional()
|
|
4554
|
+
deploy: deploySchema.optional(),
|
|
4555
|
+
plan_chat: planChatSchema.optional()
|
|
4552
4556
|
// TODO(phase-C): runtime field consumed by stack-install.ts (T16).
|
|
4553
4557
|
// TODO(phase-D): app.fixed (sticky port) consumed by port-allocation.
|
|
4554
4558
|
// TODO(phase-D): idempotent_check on bootstrap steps in bootstrap-runner.
|
|
@@ -4556,11 +4560,11 @@ var init_repo_manifest = __esm({
|
|
|
4556
4560
|
}).passthrough().superRefine((val, ctx) => {
|
|
4557
4561
|
refineForbiddenKeys(val, [], ctx, true);
|
|
4558
4562
|
}).superRefine((val, ctx) => {
|
|
4559
|
-
const hasContent = val.version !== void 0 || val.runtime !== void 0 || val.app !== void 0 || val.services !== void 0 || val.env !== void 0 || val.secrets !== void 0 || val.bootstrap !== void 0 || val.start !== void 0 || val.deploy !== void 0;
|
|
4563
|
+
const hasContent = val.version !== void 0 || val.runtime !== void 0 || val.app !== void 0 || val.services !== void 0 || val.env !== void 0 || val.secrets !== void 0 || val.bootstrap !== void 0 || val.start !== void 0 || val.deploy !== void 0 || val.plan_chat !== void 0;
|
|
4560
4564
|
if (!hasContent) {
|
|
4561
4565
|
ctx.addIssue({
|
|
4562
4566
|
code: external_exports.ZodIssueCode.custom,
|
|
4563
|
-
message: "Manifest must declare at least one of: version, runtime, app, services, env, secrets, bootstrap, start, deploy"
|
|
4567
|
+
message: "Manifest must declare at least one of: version, runtime, app, services, env, secrets, bootstrap, start, deploy, plan_chat"
|
|
4564
4568
|
});
|
|
4565
4569
|
}
|
|
4566
4570
|
});
|
|
@@ -4574,6 +4578,10 @@ var init_repo_manifest = __esm({
|
|
|
4574
4578
|
"bootstrap",
|
|
4575
4579
|
"start",
|
|
4576
4580
|
"deploy",
|
|
4581
|
+
// olam-plan-chat-chunks-substrate Phase A task A4: opt-in for the chunks
|
|
4582
|
+
// thought substrate. Read by `resolveThoughtSubstrate` in
|
|
4583
|
+
// `packages/core/src/thought/substrate-router.ts`.
|
|
4584
|
+
"plan_chat",
|
|
4577
4585
|
// F-7 (olam-hybrid-shared-postgres dogfood finding): native inheritance —
|
|
4578
4586
|
// `.olam.yaml` may declare `inherits: .adb.yaml` to deep-merge an adb-shaped
|
|
4579
4587
|
// base manifest into itself. Retires the atlas-one `bin/olam-create-wrap.sh`
|
|
@@ -5025,7 +5033,24 @@ var init_schema2 = __esm({
|
|
|
5025
5033
|
* (B1/C4) reads this file and forwards the value as
|
|
5026
5034
|
* `AGENTMEMORY_SECRET` into worlds.
|
|
5027
5035
|
*/
|
|
5028
|
-
secret_ref: external_exports.string().min(1).optional().default("~/.olam/cloud-memory-secret")
|
|
5036
|
+
secret_ref: external_exports.string().min(1).optional().default("~/.olam/cloud-memory-secret"),
|
|
5037
|
+
/**
|
|
5038
|
+
* DO SQLite write-through bridge toggle. Defaults to `true` (bridge
|
|
5039
|
+
* active — every state-mutating call captures the engine's export to
|
|
5040
|
+
* a DO snapshot, restored on cold-start).
|
|
5041
|
+
*
|
|
5042
|
+
* Operators set `bridge: false` to bisect bridge vs engine bugs:
|
|
5043
|
+
* the CLI threads this into the Worker as `OLAM_BRIDGE_DISABLED=1`,
|
|
5044
|
+
* which makes `AgentMemoryContainer.fetch` a plain pass-through
|
|
5045
|
+
* (no capture, no restore). The next deploy with `bridge: true`
|
|
5046
|
+
* resumes captures automatically.
|
|
5047
|
+
*
|
|
5048
|
+
* See `docs/design/olam-agent-memory-do-bridge-schema.md` for the
|
|
5049
|
+
* full storage contract; the bridge is OFF only as a diagnosis aid.
|
|
5050
|
+
*
|
|
5051
|
+
* Plan reference: docs/plans/olam-agent-memory-do-sqlite-bridge/phase-c-tasks.md C3
|
|
5052
|
+
*/
|
|
5053
|
+
bridge: external_exports.boolean().optional().default(true)
|
|
5029
5054
|
});
|
|
5030
5055
|
MemorySchema = external_exports.object({
|
|
5031
5056
|
mode: external_exports.enum(["local", "cloud"]).optional().default("local"),
|
|
@@ -5370,7 +5395,7 @@ async function safeText(res) {
|
|
|
5370
5395
|
}
|
|
5371
5396
|
}
|
|
5372
5397
|
function sleep(ms) {
|
|
5373
|
-
return new Promise((
|
|
5398
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
5374
5399
|
}
|
|
5375
5400
|
var DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, RETRY_COUNT, RETRY_BACKOFF_MS, AuthClient;
|
|
5376
5401
|
var init_client = __esm({
|
|
@@ -5522,7 +5547,7 @@ function resolveAuthServicePath() {
|
|
|
5522
5547
|
return path9.join(pkgsDir, "auth-service");
|
|
5523
5548
|
}
|
|
5524
5549
|
function sleep2(ms) {
|
|
5525
|
-
return new Promise((
|
|
5550
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
5526
5551
|
}
|
|
5527
5552
|
var DEFAULT_PORT, DEFAULT_VOLUME, DEFAULT_CONTAINER, DEFAULT_IMAGE, AuthContainerController;
|
|
5528
5553
|
var init_container = __esm({
|
|
@@ -5820,7 +5845,7 @@ var init_network = __esm({
|
|
|
5820
5845
|
// ../adapters/dist/docker/pull.js
|
|
5821
5846
|
import { spawn } from "node:child_process";
|
|
5822
5847
|
function spawnAsync(cmd, args, opts = {}) {
|
|
5823
|
-
return new Promise((
|
|
5848
|
+
return new Promise((resolve15) => {
|
|
5824
5849
|
const child = spawn(cmd, [...args], {
|
|
5825
5850
|
stdio: ["ignore", "pipe", "pipe"],
|
|
5826
5851
|
signal: opts.signal
|
|
@@ -5834,10 +5859,10 @@ function spawnAsync(cmd, args, opts = {}) {
|
|
|
5834
5859
|
stderr += chunk.toString();
|
|
5835
5860
|
});
|
|
5836
5861
|
child.on("error", (err) => {
|
|
5837
|
-
|
|
5862
|
+
resolve15({ exitCode: -1, stdout, stderr: stderr + err.message });
|
|
5838
5863
|
});
|
|
5839
5864
|
child.on("close", (code) => {
|
|
5840
|
-
|
|
5865
|
+
resolve15({ exitCode: code ?? -1, stdout, stderr });
|
|
5841
5866
|
});
|
|
5842
5867
|
});
|
|
5843
5868
|
}
|
|
@@ -6272,6 +6297,10 @@ var init_container2 = __esm({
|
|
|
6272
6297
|
opts.push(`size=${m.size}`);
|
|
6273
6298
|
if (m.mode !== void 0)
|
|
6274
6299
|
opts.push(`mode=${m.mode.toString(8).padStart(4, "0")}`);
|
|
6300
|
+
if (m.uid !== void 0)
|
|
6301
|
+
opts.push(`uid=${m.uid}`);
|
|
6302
|
+
if (m.gid !== void 0)
|
|
6303
|
+
opts.push(`gid=${m.gid}`);
|
|
6275
6304
|
acc[m.target] = opts.join(",");
|
|
6276
6305
|
return acc;
|
|
6277
6306
|
}, {})
|
|
@@ -6307,7 +6336,7 @@ var demuxStream, execInContainer;
|
|
|
6307
6336
|
var init_exec = __esm({
|
|
6308
6337
|
"../adapters/dist/docker/exec.js"() {
|
|
6309
6338
|
"use strict";
|
|
6310
|
-
demuxStream = (stream) => new Promise((
|
|
6339
|
+
demuxStream = (stream) => new Promise((resolve15, reject) => {
|
|
6311
6340
|
const stdoutChunks = [];
|
|
6312
6341
|
const stderrChunks = [];
|
|
6313
6342
|
const stdout = new PassThrough();
|
|
@@ -6321,7 +6350,7 @@ var init_exec = __esm({
|
|
|
6321
6350
|
stream.pipe(stdout);
|
|
6322
6351
|
}
|
|
6323
6352
|
stream.on("end", () => {
|
|
6324
|
-
|
|
6353
|
+
resolve15({
|
|
6325
6354
|
stdout: Buffer.concat(stdoutChunks).toString("utf-8"),
|
|
6326
6355
|
stderr: Buffer.concat(stderrChunks).toString("utf-8")
|
|
6327
6356
|
});
|
|
@@ -6781,7 +6810,7 @@ var init_connection = __esm({
|
|
|
6781
6810
|
// -----------------------------------------------------------------------
|
|
6782
6811
|
async exec(host, command) {
|
|
6783
6812
|
const client = await this.getConnection(host);
|
|
6784
|
-
return new Promise((
|
|
6813
|
+
return new Promise((resolve15, reject) => {
|
|
6785
6814
|
client.exec(command, (err, stream) => {
|
|
6786
6815
|
if (err) {
|
|
6787
6816
|
reject(new Error(`SSH exec failed on ${host}: ${err.message}`));
|
|
@@ -6796,7 +6825,7 @@ var init_connection = __esm({
|
|
|
6796
6825
|
stderr += data.toString();
|
|
6797
6826
|
});
|
|
6798
6827
|
stream.on("close", (code) => {
|
|
6799
|
-
|
|
6828
|
+
resolve15({
|
|
6800
6829
|
exitCode: code ?? 0,
|
|
6801
6830
|
stdout: stdout.trimEnd(),
|
|
6802
6831
|
stderr: stderr.trimEnd()
|
|
@@ -6827,10 +6856,10 @@ var init_connection = __esm({
|
|
|
6827
6856
|
throw new Error(`No SSH configuration found for host: ${host}`);
|
|
6828
6857
|
}
|
|
6829
6858
|
const client = new SSHClient();
|
|
6830
|
-
return new Promise((
|
|
6859
|
+
return new Promise((resolve15, reject) => {
|
|
6831
6860
|
client.on("ready", () => {
|
|
6832
6861
|
this.connections.set(host, client);
|
|
6833
|
-
|
|
6862
|
+
resolve15(client);
|
|
6834
6863
|
}).on("error", (err) => {
|
|
6835
6864
|
this.connections.delete(host);
|
|
6836
6865
|
reject(new Error(`SSH connection to ${host} failed: ${err.message}`));
|
|
@@ -8461,8 +8490,8 @@ function copyMatchingFiles(sourcePath, destPath, pattern) {
|
|
|
8461
8490
|
try {
|
|
8462
8491
|
const matches2 = globSync(fullPattern);
|
|
8463
8492
|
for (const match2 of matches2) {
|
|
8464
|
-
const
|
|
8465
|
-
const dest = path14.join(destPath,
|
|
8493
|
+
const relative4 = path14.relative(sourcePath, match2);
|
|
8494
|
+
const dest = path14.join(destPath, relative4);
|
|
8466
8495
|
fs13.mkdirSync(path14.dirname(dest), { recursive: true });
|
|
8467
8496
|
fs13.copyFileSync(match2, dest);
|
|
8468
8497
|
}
|
|
@@ -8742,8 +8771,8 @@ import { execFileSync as execFileSync4 } from "node:child_process";
|
|
|
8742
8771
|
import * as fs15 from "node:fs";
|
|
8743
8772
|
import * as os9 from "node:os";
|
|
8744
8773
|
import * as path16 from "node:path";
|
|
8745
|
-
function expandHome2(p,
|
|
8746
|
-
return p.replace(/^~(?=$|\/|\\)/,
|
|
8774
|
+
function expandHome2(p, homedir36) {
|
|
8775
|
+
return p.replace(/^~(?=$|\/|\\)/, homedir36());
|
|
8747
8776
|
}
|
|
8748
8777
|
function sanitizeRepoFilename(name) {
|
|
8749
8778
|
const sanitized = name.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
@@ -8766,7 +8795,7 @@ ${stderr}`;
|
|
|
8766
8795
|
}
|
|
8767
8796
|
function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
8768
8797
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync4(cmd, args, opts));
|
|
8769
|
-
const
|
|
8798
|
+
const homedir36 = deps.homedir ?? (() => os9.homedir());
|
|
8770
8799
|
const baselineDir = path16.join(workspacePath, ".olam", "baseline");
|
|
8771
8800
|
try {
|
|
8772
8801
|
fs15.mkdirSync(baselineDir, { recursive: true });
|
|
@@ -8782,7 +8811,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
8782
8811
|
continue;
|
|
8783
8812
|
const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
|
|
8784
8813
|
const outPath = path16.join(baselineDir, filename);
|
|
8785
|
-
const repoPath = expandHome2(repo.path,
|
|
8814
|
+
const repoPath = expandHome2(repo.path, homedir36);
|
|
8786
8815
|
if (!fs15.existsSync(repoPath)) {
|
|
8787
8816
|
writeBaselineFile(outPath, `# repo: ${repo.name}
|
|
8788
8817
|
# (skipped: path ${repoPath} does not exist)
|
|
@@ -8902,17 +8931,17 @@ function extractStderr(err) {
|
|
|
8902
8931
|
}
|
|
8903
8932
|
function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
8904
8933
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync4(cmd, args, opts));
|
|
8905
|
-
const
|
|
8934
|
+
const homedir36 = deps.homedir ?? (() => os9.homedir());
|
|
8906
8935
|
const existsSync64 = deps.existsSync ?? ((p) => fs15.existsSync(p));
|
|
8907
8936
|
const copyFileSync9 = deps.copyFileSync ?? ((src, dest) => fs15.copyFileSync(src, dest));
|
|
8908
|
-
const
|
|
8937
|
+
const mkdirSync36 = deps.mkdirSync ?? ((dirPath, opts) => {
|
|
8909
8938
|
fs15.mkdirSync(dirPath, opts);
|
|
8910
8939
|
});
|
|
8911
8940
|
const plans = [];
|
|
8912
8941
|
for (const repo of repos) {
|
|
8913
8942
|
if (!repo.path)
|
|
8914
8943
|
continue;
|
|
8915
|
-
const repoPath = expandHome2(repo.path,
|
|
8944
|
+
const repoPath = expandHome2(repo.path, homedir36);
|
|
8916
8945
|
const worktreePath = path16.join(workspacePath, repo.name);
|
|
8917
8946
|
if (!existsSync64(repoPath))
|
|
8918
8947
|
continue;
|
|
@@ -8979,7 +9008,7 @@ function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
|
8979
9008
|
if (!existsSync64(src))
|
|
8980
9009
|
continue;
|
|
8981
9010
|
try {
|
|
8982
|
-
|
|
9011
|
+
mkdirSync36(path16.dirname(dest), { recursive: true });
|
|
8983
9012
|
copyFileSync9(src, dest);
|
|
8984
9013
|
} catch (err) {
|
|
8985
9014
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -9422,18 +9451,18 @@ function computeFingerprint(runtimes) {
|
|
|
9422
9451
|
const joined = parts.join("_");
|
|
9423
9452
|
return sanitizeTag(joined);
|
|
9424
9453
|
}
|
|
9425
|
-
function computeImageTag(runtimes) {
|
|
9426
|
-
const baseDigest =
|
|
9454
|
+
function computeImageTag(runtimes, baseImageRef = `${BASE_IMAGE}:latest`) {
|
|
9455
|
+
const baseDigest = getImageDigest(baseImageRef);
|
|
9427
9456
|
const prefix = baseDigest.slice(0, 8);
|
|
9428
9457
|
const fingerprint = computeFingerprint(runtimes);
|
|
9429
9458
|
const tag = `${prefix}_${fingerprint}`;
|
|
9430
9459
|
return sanitizeTag(tag);
|
|
9431
9460
|
}
|
|
9432
|
-
function computeImageName(runtimes) {
|
|
9433
|
-
return `${BASE_IMAGE}:${computeImageTag(runtimes)}`;
|
|
9461
|
+
function computeImageName(runtimes, baseImageRef = `${BASE_IMAGE}:latest`) {
|
|
9462
|
+
return `${BASE_IMAGE}:${computeImageTag(runtimes, baseImageRef)}`;
|
|
9434
9463
|
}
|
|
9435
|
-
function lookupCachedImage(runtimes) {
|
|
9436
|
-
const tag = computeImageTag(runtimes);
|
|
9464
|
+
function lookupCachedImage(runtimes, baseImageRef = `${BASE_IMAGE}:latest`) {
|
|
9465
|
+
const tag = computeImageTag(runtimes, baseImageRef);
|
|
9437
9466
|
const imageName = `${BASE_IMAGE}:${tag}`;
|
|
9438
9467
|
try {
|
|
9439
9468
|
execSync2(`docker image inspect ${imageName} > /dev/null 2>&1`, {
|
|
@@ -9450,18 +9479,24 @@ function commitAsImage(containerName, imageName) {
|
|
|
9450
9479
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
9451
9480
|
execSync2(`docker commit --change 'LABEL ${LABEL_PREFIX}=true' --change 'LABEL ${LABEL_PREFIX}.created-at=${now}' --change 'LABEL ${LABEL_PREFIX}.base-digest=${baseDigest}' ${containerName} ${imageName}`, { stdio: "pipe", timeout: 12e4 });
|
|
9452
9481
|
}
|
|
9453
|
-
function
|
|
9454
|
-
|
|
9455
|
-
|
|
9482
|
+
function getImageDigest(imageRef) {
|
|
9483
|
+
const memo = cachedImageDigests.get(imageRef);
|
|
9484
|
+
if (memo)
|
|
9485
|
+
return memo;
|
|
9456
9486
|
try {
|
|
9457
|
-
const digest = execSync2(`docker inspect ${
|
|
9458
|
-
|
|
9459
|
-
|
|
9487
|
+
const digest = execSync2(`docker inspect ${imageRef} --format '{{.Id}}'`, { encoding: "utf-8", timeout: 5e3 }).trim();
|
|
9488
|
+
const short = digest.replace("sha256:", "").slice(0, 16);
|
|
9489
|
+
cachedImageDigests.set(imageRef, short);
|
|
9490
|
+
return short;
|
|
9460
9491
|
} catch {
|
|
9461
|
-
|
|
9462
|
-
|
|
9492
|
+
const fallback = crypto3.createHash("sha256").update(imageRef).digest("hex").slice(0, 16);
|
|
9493
|
+
cachedImageDigests.set(imageRef, fallback);
|
|
9494
|
+
return fallback;
|
|
9463
9495
|
}
|
|
9464
9496
|
}
|
|
9497
|
+
function getBaseImageDigest() {
|
|
9498
|
+
return getImageDigest(`${BASE_IMAGE}:latest`);
|
|
9499
|
+
}
|
|
9465
9500
|
function sanitizeTag(raw) {
|
|
9466
9501
|
let tag = raw.toLowerCase().replace(/[^a-z0-9._-]/g, "-");
|
|
9467
9502
|
if (tag.length > MAX_TAG_LENGTH) {
|
|
@@ -9470,13 +9505,14 @@ function sanitizeTag(raw) {
|
|
|
9470
9505
|
}
|
|
9471
9506
|
return tag;
|
|
9472
9507
|
}
|
|
9473
|
-
var BASE_IMAGE, LABEL_PREFIX, MAX_TAG_LENGTH,
|
|
9508
|
+
var BASE_IMAGE, LABEL_PREFIX, MAX_TAG_LENGTH, cachedImageDigests;
|
|
9474
9509
|
var init_stack_image = __esm({
|
|
9475
9510
|
"../core/dist/world/stack-image.js"() {
|
|
9476
9511
|
"use strict";
|
|
9477
9512
|
BASE_IMAGE = "olam-devbox";
|
|
9478
9513
|
LABEL_PREFIX = "olam.stack-image";
|
|
9479
9514
|
MAX_TAG_LENGTH = 128;
|
|
9515
|
+
cachedImageDigests = /* @__PURE__ */ new Map();
|
|
9480
9516
|
}
|
|
9481
9517
|
});
|
|
9482
9518
|
|
|
@@ -10556,7 +10592,7 @@ var init_auto_dispatch_task = __esm({
|
|
|
10556
10592
|
this.name = "TaskDispatchError";
|
|
10557
10593
|
}
|
|
10558
10594
|
};
|
|
10559
|
-
DEFAULT_SLEEP = (ms) => new Promise((
|
|
10595
|
+
DEFAULT_SLEEP = (ms) => new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
10560
10596
|
}
|
|
10561
10597
|
});
|
|
10562
10598
|
|
|
@@ -12239,9 +12275,32 @@ ${detail}`);
|
|
|
12239
12275
|
}
|
|
12240
12276
|
}
|
|
12241
12277
|
const repoSecretUrls = enrichedRepos.filter((r) => typeof r.manifest?.secrets === "string" && r.manifest.secrets.length > 0).map((r) => ({ repoName: r.name, secretsUrl: r.manifest.secrets }));
|
|
12242
|
-
let stackCacheHit = false;
|
|
12243
12278
|
let selectedImage;
|
|
12279
|
+
let cacheArchOverride;
|
|
12280
|
+
const selected = selectDevboxImageForWorld({
|
|
12281
|
+
config: this.config,
|
|
12282
|
+
repos,
|
|
12283
|
+
worldspec: opts.worldspec
|
|
12284
|
+
});
|
|
12285
|
+
if (selected) {
|
|
12286
|
+
selectedImage = selected.image;
|
|
12287
|
+
cacheArchOverride = selected.cacheArch;
|
|
12288
|
+
if (selected.source === "worldspec") {
|
|
12289
|
+
console.log(`[WorldManager] worldspec override \u2014 using ${selected.image} (tag=${selected.tag})`);
|
|
12290
|
+
} else {
|
|
12291
|
+
console.log(`[WorldManager] image_selector matched \u2014 using ${selected.image} (tag=${selected.tag}${selected.cacheArch ? `, cache_arch=${selected.cacheArch}` : ""})`);
|
|
12292
|
+
}
|
|
12293
|
+
} else {
|
|
12294
|
+
const hasRailsRepo = repos.some((r) => r.type === "rails");
|
|
12295
|
+
if (hasRailsRepo) {
|
|
12296
|
+
selectedImage = resolveDevboxImage(this.config, "amd64");
|
|
12297
|
+
cacheArchOverride = "x64";
|
|
12298
|
+
console.log(`[WorldManager] Rails repo detected \u2014 using ${selectedImage} + x64 mise-cache (Rosetta path)`);
|
|
12299
|
+
}
|
|
12300
|
+
}
|
|
12301
|
+
let stackCacheHit = false;
|
|
12244
12302
|
const preDetectedStacks = /* @__PURE__ */ new Map();
|
|
12303
|
+
const cacheBaseRef = selectedImage ?? "olam-devbox:latest";
|
|
12245
12304
|
if (this.provider.capabilities.supportsCustomImages) {
|
|
12246
12305
|
try {
|
|
12247
12306
|
const hostExec = makeHostExecFn();
|
|
@@ -12256,7 +12315,7 @@ ${detail}`);
|
|
|
12256
12315
|
}
|
|
12257
12316
|
const runtimes = collectUniqueRuntimes(Array.from(preDetectedStacks.values()));
|
|
12258
12317
|
if (runtimes.size > 0) {
|
|
12259
|
-
const cacheResult = lookupCachedImage(runtimes);
|
|
12318
|
+
const cacheResult = lookupCachedImage(runtimes, cacheBaseRef);
|
|
12260
12319
|
if (cacheResult.hit) {
|
|
12261
12320
|
selectedImage = cacheResult.imageName;
|
|
12262
12321
|
stackCacheHit = true;
|
|
@@ -12270,30 +12329,6 @@ ${detail}`);
|
|
|
12270
12329
|
console.warn(`[WorldManager] host-side stack detection failed: ${msg}`);
|
|
12271
12330
|
}
|
|
12272
12331
|
}
|
|
12273
|
-
let cacheArchOverride;
|
|
12274
|
-
if (!stackCacheHit) {
|
|
12275
|
-
const selected = selectDevboxImageForWorld({
|
|
12276
|
-
config: this.config,
|
|
12277
|
-
repos,
|
|
12278
|
-
worldspec: opts.worldspec
|
|
12279
|
-
});
|
|
12280
|
-
if (selected) {
|
|
12281
|
-
selectedImage = selected.image;
|
|
12282
|
-
cacheArchOverride = selected.cacheArch;
|
|
12283
|
-
if (selected.source === "worldspec") {
|
|
12284
|
-
console.log(`[WorldManager] worldspec override \u2014 using ${selected.image} (tag=${selected.tag})`);
|
|
12285
|
-
} else {
|
|
12286
|
-
console.log(`[WorldManager] image_selector matched \u2014 using ${selected.image} (tag=${selected.tag}${selected.cacheArch ? `, cache_arch=${selected.cacheArch}` : ""})`);
|
|
12287
|
-
}
|
|
12288
|
-
} else {
|
|
12289
|
-
const hasRailsRepo = repos.some((r) => r.type === "rails");
|
|
12290
|
-
if (hasRailsRepo) {
|
|
12291
|
-
selectedImage = resolveDevboxImage(this.config, "amd64");
|
|
12292
|
-
cacheArchOverride = "x64";
|
|
12293
|
-
console.log(`[WorldManager] Rails repo detected \u2014 using ${selectedImage} + x64 mise-cache (Rosetta path)`);
|
|
12294
|
-
}
|
|
12295
|
-
}
|
|
12296
|
-
}
|
|
12297
12332
|
const appPorts = [];
|
|
12298
12333
|
for (const repo of enrichedRepos) {
|
|
12299
12334
|
const manifestPort = repo.manifest?.app?.port;
|
|
@@ -12447,12 +12482,22 @@ ${detail}`);
|
|
|
12447
12482
|
...extraNetworks ? { extraNetworks } : {},
|
|
12448
12483
|
// Closes SEC-002 residual: hybrid worlds get a tmpfs mount at
|
|
12449
12484
|
// /run/olam to receive the per-world postgres credentials. Size
|
|
12450
|
-
// 256K is generous for a few env files; mode 0700
|
|
12451
|
-
//
|
|
12452
|
-
//
|
|
12453
|
-
//
|
|
12485
|
+
// 256K is generous for a few env files; mode 0700 keeps the dir
|
|
12486
|
+
// owner-only. uid/gid 999 matches the `olam` user from the Phase
|
|
12487
|
+
// E E4 base image contract — without setting these, the tmpfs is
|
|
12488
|
+
// root-owned and `docker exec` (which runs as the image's USER,
|
|
12489
|
+
// i.e. olam) hits EACCES on credential writes. Non-hybrid worlds
|
|
12490
|
+
// skip the mount entirely — no behavior change.
|
|
12454
12491
|
...tmpfsPostgresCredContent ? {
|
|
12455
|
-
tmpfsMounts: [
|
|
12492
|
+
tmpfsMounts: [
|
|
12493
|
+
{
|
|
12494
|
+
target: "/run/olam",
|
|
12495
|
+
size: 256 * 1024,
|
|
12496
|
+
mode: 448,
|
|
12497
|
+
uid: 999,
|
|
12498
|
+
gid: 999
|
|
12499
|
+
}
|
|
12500
|
+
],
|
|
12456
12501
|
tmpfsCredentialWrites: [
|
|
12457
12502
|
{ path: "/run/olam/postgres.env", content: tmpfsPostgresCredContent }
|
|
12458
12503
|
]
|
|
@@ -14179,7 +14224,7 @@ function isCloudflaredAvailable() {
|
|
|
14179
14224
|
}
|
|
14180
14225
|
}
|
|
14181
14226
|
function startTunnel(port2) {
|
|
14182
|
-
return new Promise((
|
|
14227
|
+
return new Promise((resolve15, reject) => {
|
|
14183
14228
|
const child = spawn3("cloudflared", ["tunnel", "--url", `http://localhost:${port2}`], {
|
|
14184
14229
|
stdio: ["ignore", "pipe", "pipe"],
|
|
14185
14230
|
detached: false
|
|
@@ -14201,7 +14246,7 @@ function startTunnel(port2) {
|
|
|
14201
14246
|
if (match2) {
|
|
14202
14247
|
resolved = true;
|
|
14203
14248
|
clearTimeout(timeout);
|
|
14204
|
-
|
|
14249
|
+
resolve15(match2[0]);
|
|
14205
14250
|
}
|
|
14206
14251
|
}
|
|
14207
14252
|
child.stdout?.on("data", scan);
|
|
@@ -14288,8 +14333,8 @@ var init_dashboard = __esm({
|
|
|
14288
14333
|
}
|
|
14289
14334
|
throw err;
|
|
14290
14335
|
}
|
|
14291
|
-
await new Promise((
|
|
14292
|
-
this.server.on("listening",
|
|
14336
|
+
await new Promise((resolve15, reject) => {
|
|
14337
|
+
this.server.on("listening", resolve15);
|
|
14293
14338
|
this.server.on("error", reject);
|
|
14294
14339
|
});
|
|
14295
14340
|
this.info = { localUrl: `http://localhost:${port2}` };
|
|
@@ -14335,8 +14380,8 @@ var init_dashboard = __esm({
|
|
|
14335
14380
|
async stop() {
|
|
14336
14381
|
stopTunnel();
|
|
14337
14382
|
if (this.server) {
|
|
14338
|
-
await new Promise((
|
|
14339
|
-
this.server.close(() =>
|
|
14383
|
+
await new Promise((resolve15) => {
|
|
14384
|
+
this.server.close(() => resolve15());
|
|
14340
14385
|
});
|
|
14341
14386
|
this.server = null;
|
|
14342
14387
|
}
|
|
@@ -15422,7 +15467,7 @@ async function ensureOlamPostgresSingleton(options = {}) {
|
|
|
15422
15467
|
};
|
|
15423
15468
|
}
|
|
15424
15469
|
function sleep3(ms) {
|
|
15425
|
-
return new Promise((
|
|
15470
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
15426
15471
|
}
|
|
15427
15472
|
var DEFAULT_POSTGRES_NETWORK, DEFAULT_POSTGRES_CONTAINER, DEFAULT_POSTGRES_HOST_PORT, DEFAULT_POSTGRES_IMAGE, DEFAULT_POSTGRES_USER, DEFAULT_POSTGRES_PASSWORD, DEFAULT_POSTGRES_DB, DEFAULT_POSTGRES_READY_TIMEOUT_MS;
|
|
15428
15473
|
var init_postgres_init_helpers = __esm({
|
|
@@ -16695,10 +16740,10 @@ async function confirm(message) {
|
|
|
16695
16740
|
if (!process.stdin.isTTY) return true;
|
|
16696
16741
|
const { createInterface: createInterface7 } = await import("node:readline");
|
|
16697
16742
|
const rl = createInterface7({ input: process.stdin, output: process.stdout });
|
|
16698
|
-
return new Promise((
|
|
16743
|
+
return new Promise((resolve15) => {
|
|
16699
16744
|
rl.question(`${message} [y/N] `, (answer) => {
|
|
16700
16745
|
rl.close();
|
|
16701
|
-
|
|
16746
|
+
resolve15(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
16702
16747
|
});
|
|
16703
16748
|
});
|
|
16704
16749
|
}
|
|
@@ -17076,6 +17121,17 @@ var KgServiceContainerController = class {
|
|
|
17076
17121
|
// Mount the operator's KG root (OLAM_HOME-aware) so /build can persist graphs.
|
|
17077
17122
|
"--volume",
|
|
17078
17123
|
`${kgData}:${KG_SERVICE_VOLUME_TARGET}`,
|
|
17124
|
+
// kg-service-container-v2 Phase F: read-only mount of $HOME so /build
|
|
17125
|
+
// can ingest any project under the operator's home as the source repo.
|
|
17126
|
+
// Read-only is sufficient: server-side scratch in /tmp/ holds the
|
|
17127
|
+
// working copy + receives graphify's output before persisting to
|
|
17128
|
+
// /kg-data. Operator's source tree is never written. Mount path
|
|
17129
|
+
// `/host-home` is referenced by kg-build.ts when translating cwd
|
|
17130
|
+
// → container-side path. Closes Samuel's multi-submodule cp-r bug
|
|
17131
|
+
// by construction: copy runs INSIDE the container as root, not on
|
|
17132
|
+
// the host with the operator's UID hitting locked .git/objects/pack/*.
|
|
17133
|
+
"--volume",
|
|
17134
|
+
`${process.env.HOME ?? "/root"}:/host-home:ro`,
|
|
17079
17135
|
this.imageTag
|
|
17080
17136
|
],
|
|
17081
17137
|
{ stdio: "pipe" }
|
|
@@ -17138,7 +17194,7 @@ var KgServiceContainerController = class {
|
|
|
17138
17194
|
}
|
|
17139
17195
|
};
|
|
17140
17196
|
function sleep4(ms) {
|
|
17141
|
-
return new Promise((
|
|
17197
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
17142
17198
|
}
|
|
17143
17199
|
|
|
17144
17200
|
// src/commands/services.ts
|
|
@@ -17226,7 +17282,7 @@ var McpAuthContainerController = class {
|
|
|
17226
17282
|
}
|
|
17227
17283
|
};
|
|
17228
17284
|
function sleep5(ms) {
|
|
17229
|
-
return new Promise((
|
|
17285
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
17230
17286
|
}
|
|
17231
17287
|
function dumpContainerLogs(container, tail = 40) {
|
|
17232
17288
|
try {
|
|
@@ -17922,10 +17978,10 @@ var HOST_CP_URL = "http://127.0.0.1:19000";
|
|
|
17922
17978
|
async function readHostCpTokenForCreate() {
|
|
17923
17979
|
try {
|
|
17924
17980
|
const { default: fs56 } = await import("node:fs");
|
|
17925
|
-
const { default:
|
|
17981
|
+
const { default: os32 } = await import("node:os");
|
|
17926
17982
|
const { default: path60 } = await import("node:path");
|
|
17927
17983
|
const tp = path60.join(
|
|
17928
|
-
process.env.OLAM_HOME ?? path60.join(
|
|
17984
|
+
process.env.OLAM_HOME ?? path60.join(os32.homedir(), ".olam"),
|
|
17929
17985
|
"host-cp.token"
|
|
17930
17986
|
);
|
|
17931
17987
|
if (!fs56.existsSync(tp)) return null;
|
|
@@ -18338,9 +18394,9 @@ function defaultNameFromPrompt(prompt) {
|
|
|
18338
18394
|
async function readHostCpToken3() {
|
|
18339
18395
|
try {
|
|
18340
18396
|
const { default: fs56 } = await import("node:fs");
|
|
18341
|
-
const { default:
|
|
18397
|
+
const { default: os32 } = await import("node:os");
|
|
18342
18398
|
const { default: path60 } = await import("node:path");
|
|
18343
|
-
const tp = path60.join(
|
|
18399
|
+
const tp = path60.join(os32.homedir(), ".olam", "host-cp.token");
|
|
18344
18400
|
if (!fs56.existsSync(tp)) return null;
|
|
18345
18401
|
const raw = fs56.readFileSync(tp, "utf-8").trim();
|
|
18346
18402
|
return raw.length > 0 ? raw : null;
|
|
@@ -19010,14 +19066,14 @@ function printTable(entries) {
|
|
|
19010
19066
|
async function confirmInteractive() {
|
|
19011
19067
|
process.stdout.write(" Type `yes` to proceed: ");
|
|
19012
19068
|
const buf = [];
|
|
19013
|
-
return new Promise((
|
|
19069
|
+
return new Promise((resolve15) => {
|
|
19014
19070
|
const onData = (chunk) => {
|
|
19015
19071
|
buf.push(chunk);
|
|
19016
19072
|
if (Buffer.concat(buf).toString("utf-8").includes("\n")) {
|
|
19017
19073
|
process.stdin.removeListener("data", onData);
|
|
19018
19074
|
process.stdin.pause();
|
|
19019
19075
|
const answer = Buffer.concat(buf).toString("utf-8").trim();
|
|
19020
|
-
|
|
19076
|
+
resolve15(answer.toLowerCase() === "yes");
|
|
19021
19077
|
}
|
|
19022
19078
|
};
|
|
19023
19079
|
process.stdin.resume();
|
|
@@ -24732,10 +24788,10 @@ async function confirm2(message) {
|
|
|
24732
24788
|
if (!process.stdin.isTTY) return true;
|
|
24733
24789
|
const { createInterface: createInterface7 } = await import("node:readline");
|
|
24734
24790
|
const rl = createInterface7({ input: process.stdin, output: process.stdout });
|
|
24735
|
-
return new Promise((
|
|
24791
|
+
return new Promise((resolve15) => {
|
|
24736
24792
|
rl.question(`${message} [y/N] `, (answer) => {
|
|
24737
24793
|
rl.close();
|
|
24738
|
-
|
|
24794
|
+
resolve15(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
24739
24795
|
});
|
|
24740
24796
|
});
|
|
24741
24797
|
}
|
|
@@ -27238,9 +27294,9 @@ function appendIdempotent(opts) {
|
|
|
27238
27294
|
}
|
|
27239
27295
|
function resolveShellRc(home, shellEnv) {
|
|
27240
27296
|
if (!shellEnv) return null;
|
|
27241
|
-
const
|
|
27242
|
-
if (
|
|
27243
|
-
if (
|
|
27297
|
+
const basename7 = path45.basename(shellEnv);
|
|
27298
|
+
if (basename7 === "zsh") return path45.join(home, ".zshrc");
|
|
27299
|
+
if (basename7 === "bash") return path45.join(home, ".bashrc");
|
|
27244
27300
|
return null;
|
|
27245
27301
|
}
|
|
27246
27302
|
|
|
@@ -27252,10 +27308,10 @@ var NEXT_STEPS_DOCS = [
|
|
|
27252
27308
|
"docs/architecture/manifest-spec.md \u2014 per-repo .adb.yaml schema",
|
|
27253
27309
|
"docs/architecture/config-spec.md \u2014 workspace .olam/config.yaml schema"
|
|
27254
27310
|
];
|
|
27255
|
-
var defaultSpawn = (cmd, args) => new Promise((
|
|
27311
|
+
var defaultSpawn = (cmd, args) => new Promise((resolve15) => {
|
|
27256
27312
|
const child = spawn5(cmd, [...args], { stdio: "inherit" });
|
|
27257
|
-
child.on("exit", (code) =>
|
|
27258
|
-
child.on("error", () =>
|
|
27313
|
+
child.on("exit", (code) => resolve15({ status: code }));
|
|
27314
|
+
child.on("error", () => resolve15({ status: 1 }));
|
|
27259
27315
|
});
|
|
27260
27316
|
var defaultPrompt = (question, defaultYes) => {
|
|
27261
27317
|
if (!process.stdin.isTTY) {
|
|
@@ -27265,18 +27321,18 @@ var defaultPrompt = (question, defaultYes) => {
|
|
|
27265
27321
|
);
|
|
27266
27322
|
return Promise.resolve(defaultYes);
|
|
27267
27323
|
}
|
|
27268
|
-
return new Promise((
|
|
27324
|
+
return new Promise((resolve15) => {
|
|
27269
27325
|
const rl = createInterface3({ input: process.stdin, output: process.stdout });
|
|
27270
27326
|
const suffix = defaultYes ? " [Y/n]: " : " [y/N]: ";
|
|
27271
27327
|
rl.question(`${question}${suffix}`, (answer) => {
|
|
27272
27328
|
rl.close();
|
|
27273
27329
|
const t = answer.trim().toLowerCase();
|
|
27274
|
-
if (t === "")
|
|
27275
|
-
else if (t === "y" || t === "yes")
|
|
27276
|
-
else if (t === "n" || t === "no")
|
|
27277
|
-
else
|
|
27330
|
+
if (t === "") resolve15(defaultYes);
|
|
27331
|
+
else if (t === "y" || t === "yes") resolve15(true);
|
|
27332
|
+
else if (t === "n" || t === "no") resolve15(false);
|
|
27333
|
+
else resolve15(defaultYes);
|
|
27278
27334
|
});
|
|
27279
|
-
rl.on("close", () =>
|
|
27335
|
+
rl.on("close", () => resolve15(defaultYes));
|
|
27280
27336
|
});
|
|
27281
27337
|
};
|
|
27282
27338
|
async function phase1SystemCheck(deps) {
|
|
@@ -28500,7 +28556,7 @@ function registerMcpLogin(cmd) {
|
|
|
28500
28556
|
init_output();
|
|
28501
28557
|
import * as readline2 from "node:readline";
|
|
28502
28558
|
async function readTokenSilent(prompt) {
|
|
28503
|
-
return new Promise((
|
|
28559
|
+
return new Promise((resolve15, reject) => {
|
|
28504
28560
|
const rl = readline2.createInterface({
|
|
28505
28561
|
input: process.stdin,
|
|
28506
28562
|
output: process.stdout,
|
|
@@ -28518,7 +28574,7 @@ async function readTokenSilent(prompt) {
|
|
|
28518
28574
|
process.stdin.removeListener("data", onData);
|
|
28519
28575
|
process.stdout.write("\n");
|
|
28520
28576
|
rl.close();
|
|
28521
|
-
|
|
28577
|
+
resolve15(token);
|
|
28522
28578
|
} else if (char === "") {
|
|
28523
28579
|
if (process.stdin.isTTY) process.stdin.setRawMode(false);
|
|
28524
28580
|
process.stdin.removeListener("data", onData);
|
|
@@ -28793,7 +28849,7 @@ async function discoverMcpSources(repoPaths) {
|
|
|
28793
28849
|
import { spawn as spawn7 } from "node:child_process";
|
|
28794
28850
|
var VALIDATION_TIMEOUT_MS = 5e3;
|
|
28795
28851
|
async function validateMcpEntry(entry) {
|
|
28796
|
-
return new Promise((
|
|
28852
|
+
return new Promise((resolve15) => {
|
|
28797
28853
|
let stdout = "";
|
|
28798
28854
|
let timedOut = false;
|
|
28799
28855
|
let child;
|
|
@@ -28803,7 +28859,7 @@ async function validateMcpEntry(entry) {
|
|
|
28803
28859
|
env: { ...process.env, ...entry.env ?? {} }
|
|
28804
28860
|
});
|
|
28805
28861
|
} catch (err) {
|
|
28806
|
-
|
|
28862
|
+
resolve15({
|
|
28807
28863
|
name: entry.name,
|
|
28808
28864
|
validated: false,
|
|
28809
28865
|
reason: err instanceof Error ? err.message : "spawn failed"
|
|
@@ -28820,11 +28876,11 @@ async function validateMcpEntry(entry) {
|
|
|
28820
28876
|
child.on("close", (code) => {
|
|
28821
28877
|
clearTimeout(timer);
|
|
28822
28878
|
if (timedOut) {
|
|
28823
|
-
|
|
28879
|
+
resolve15({ name: entry.name, validated: false, reason: "timeout (5s)" });
|
|
28824
28880
|
return;
|
|
28825
28881
|
}
|
|
28826
28882
|
const validated = code === 0 && stdout.trim().length > 0;
|
|
28827
|
-
|
|
28883
|
+
resolve15({
|
|
28828
28884
|
name: entry.name,
|
|
28829
28885
|
validated,
|
|
28830
28886
|
reason: validated ? "ok" : `exit code ${code ?? "null"}`
|
|
@@ -28832,7 +28888,7 @@ async function validateMcpEntry(entry) {
|
|
|
28832
28888
|
});
|
|
28833
28889
|
child.on("error", (err) => {
|
|
28834
28890
|
clearTimeout(timer);
|
|
28835
|
-
|
|
28891
|
+
resolve15({ name: entry.name, validated: false, reason: err.message });
|
|
28836
28892
|
});
|
|
28837
28893
|
});
|
|
28838
28894
|
}
|
|
@@ -28847,11 +28903,11 @@ async function multiSelectPicker(entries) {
|
|
|
28847
28903
|
);
|
|
28848
28904
|
});
|
|
28849
28905
|
console.log("\n" + pc29.dim('Enter numbers to import (e.g. 1,2,3 or "all" or Enter to skip):'));
|
|
28850
|
-
const answer = await new Promise((
|
|
28906
|
+
const answer = await new Promise((resolve15) => {
|
|
28851
28907
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
28852
28908
|
rl.question("> ", (ans) => {
|
|
28853
28909
|
rl.close();
|
|
28854
|
-
|
|
28910
|
+
resolve15(ans.trim());
|
|
28855
28911
|
});
|
|
28856
28912
|
});
|
|
28857
28913
|
if (!answer || answer === "") return [];
|
|
@@ -29136,6 +29192,12 @@ async function runMemoryStart() {
|
|
|
29136
29192
|
env: {
|
|
29137
29193
|
...process.env,
|
|
29138
29194
|
AGENTMEMORY_SECRET: secret,
|
|
29195
|
+
// Bind 0.0.0.0 so worlds inside Docker can reach the host service
|
|
29196
|
+
// via `host.docker.internal:3111`. Defaults to 127.0.0.1 in the
|
|
29197
|
+
// upstream iii-config, which would make the service host-only.
|
|
29198
|
+
// The bearer-secret gate above prevents non-authed access from
|
|
29199
|
+
// any other LAN host that can route to this machine.
|
|
29200
|
+
AGENTMEMORY_HOST: "0.0.0.0",
|
|
29139
29201
|
PATH: `${OLAM_BIN_DIR}:${process.env.PATH ?? ""}`
|
|
29140
29202
|
},
|
|
29141
29203
|
stdio: ["ignore", logFd, logFd],
|
|
@@ -29329,8 +29391,8 @@ async function runMemoryLogs(opts) {
|
|
|
29329
29391
|
args.push(MEMORY_LOG_PATH);
|
|
29330
29392
|
printHeader(`olam memory logs (${opts.follow ? "follow" : `tail -n ${tailN}`})`);
|
|
29331
29393
|
const child = spawn9("tail", args, { stdio: "inherit" });
|
|
29332
|
-
return new Promise((
|
|
29333
|
-
child.on("exit", (code) =>
|
|
29394
|
+
return new Promise((resolve15) => {
|
|
29395
|
+
child.on("exit", (code) => resolve15(code ?? 0));
|
|
29334
29396
|
});
|
|
29335
29397
|
}
|
|
29336
29398
|
function registerMemoryLogs(cmd) {
|
|
@@ -29696,10 +29758,88 @@ function registerMemory(program2) {
|
|
|
29696
29758
|
// src/commands/kg-build.ts
|
|
29697
29759
|
init_storage_paths();
|
|
29698
29760
|
init_workspace_name();
|
|
29761
|
+
import * as fs53 from "node:fs";
|
|
29762
|
+
import * as os30 from "node:os";
|
|
29763
|
+
import * as path57 from "node:path";
|
|
29764
|
+
|
|
29765
|
+
// ../core/dist/kg/kg-service-client.js
|
|
29766
|
+
var KG_SERVICE_PORT_DEFAULT = 9997;
|
|
29767
|
+
function port() {
|
|
29768
|
+
const env = process.env.OLAM_KG_SERVICE_PORT;
|
|
29769
|
+
if (!env)
|
|
29770
|
+
return KG_SERVICE_PORT_DEFAULT;
|
|
29771
|
+
const n = Number.parseInt(env, 10);
|
|
29772
|
+
return Number.isFinite(n) && n > 0 ? n : KG_SERVICE_PORT_DEFAULT;
|
|
29773
|
+
}
|
|
29774
|
+
function url(path60) {
|
|
29775
|
+
return `http://127.0.0.1:${port()}${path60}`;
|
|
29776
|
+
}
|
|
29777
|
+
function kgServiceHealthUrl() {
|
|
29778
|
+
return url("/health");
|
|
29779
|
+
}
|
|
29780
|
+
function kgServiceClassifyUrl() {
|
|
29781
|
+
return url("/classify");
|
|
29782
|
+
}
|
|
29783
|
+
function kgServiceStatusUrl() {
|
|
29784
|
+
return url("/status");
|
|
29785
|
+
}
|
|
29786
|
+
function kgServiceBuildUrl() {
|
|
29787
|
+
return url("/build");
|
|
29788
|
+
}
|
|
29789
|
+
var KgServiceUnreachableError = class extends Error {
|
|
29790
|
+
cause;
|
|
29791
|
+
constructor(message, cause) {
|
|
29792
|
+
super(message);
|
|
29793
|
+
this.cause = cause;
|
|
29794
|
+
this.name = "KgServiceUnreachableError";
|
|
29795
|
+
}
|
|
29796
|
+
};
|
|
29797
|
+
var DEFAULT_TIMEOUT_MS3 = 5e3;
|
|
29798
|
+
async function postJson(endpointUrl, body, timeoutMs = DEFAULT_TIMEOUT_MS3) {
|
|
29799
|
+
let res;
|
|
29800
|
+
try {
|
|
29801
|
+
res = await fetch(endpointUrl, {
|
|
29802
|
+
method: "POST",
|
|
29803
|
+
headers: { "Content-Type": "application/json" },
|
|
29804
|
+
body: JSON.stringify(body),
|
|
29805
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
29806
|
+
});
|
|
29807
|
+
} catch (err) {
|
|
29808
|
+
throw new KgServiceUnreachableError(`kg-service not reachable at ${endpointUrl} \u2014 run \`olam services up\` to start it.`, err);
|
|
29809
|
+
}
|
|
29810
|
+
if (!res.ok) {
|
|
29811
|
+
const errBody = await res.text().catch(() => "");
|
|
29812
|
+
throw new Error(`${endpointUrl} returned ${res.status}: ${errBody.slice(0, 500)}`);
|
|
29813
|
+
}
|
|
29814
|
+
return await res.json();
|
|
29815
|
+
}
|
|
29816
|
+
async function getJson(endpointUrl, timeoutMs = DEFAULT_TIMEOUT_MS3) {
|
|
29817
|
+
let res;
|
|
29818
|
+
try {
|
|
29819
|
+
res = await fetch(endpointUrl, { signal: AbortSignal.timeout(timeoutMs) });
|
|
29820
|
+
} catch (err) {
|
|
29821
|
+
throw new KgServiceUnreachableError(`kg-service not reachable at ${endpointUrl} \u2014 run \`olam services up\` to start it.`, err);
|
|
29822
|
+
}
|
|
29823
|
+
if (!res.ok) {
|
|
29824
|
+
throw new Error(`${endpointUrl} returned ${res.status}`);
|
|
29825
|
+
}
|
|
29826
|
+
return await res.json();
|
|
29827
|
+
}
|
|
29828
|
+
async function classify(req, opts = {}) {
|
|
29829
|
+
return postJson(kgServiceClassifyUrl(), req, opts.timeoutMs);
|
|
29830
|
+
}
|
|
29831
|
+
async function health(opts = {}) {
|
|
29832
|
+
return getJson(kgServiceHealthUrl(), opts.timeoutMs ?? 2e3);
|
|
29833
|
+
}
|
|
29834
|
+
async function status(opts = {}) {
|
|
29835
|
+
return getJson(kgServiceStatusUrl(), opts.timeoutMs);
|
|
29836
|
+
}
|
|
29837
|
+
async function build(req, opts = {}) {
|
|
29838
|
+
return postJson(kgServiceBuildUrl(), req, opts.timeoutMs ?? 9e5);
|
|
29839
|
+
}
|
|
29840
|
+
|
|
29841
|
+
// src/commands/kg-build.ts
|
|
29699
29842
|
init_output();
|
|
29700
|
-
import { spawnSync as spawnSync20 } from "node:child_process";
|
|
29701
|
-
import fs53 from "node:fs";
|
|
29702
|
-
import path57 from "node:path";
|
|
29703
29843
|
|
|
29704
29844
|
// src/commands/kg-status.ts
|
|
29705
29845
|
init_storage_paths();
|
|
@@ -30063,16 +30203,16 @@ async function runKgWatch(workspaceArg, opts, deps = {}) {
|
|
|
30063
30203
|
process.on("SIGINT", () => forward("SIGINT"));
|
|
30064
30204
|
process.on("SIGTERM", () => forward("SIGTERM"));
|
|
30065
30205
|
}
|
|
30066
|
-
return new Promise((
|
|
30206
|
+
return new Promise((resolve15) => {
|
|
30067
30207
|
child.on("exit", (code, signal) => {
|
|
30068
30208
|
removePidFile(name);
|
|
30069
30209
|
const exitCode = typeof code === "number" ? code : signal === "SIGINT" || signal === "SIGTERM" ? 0 : 1;
|
|
30070
|
-
|
|
30210
|
+
resolve15({ exitCode, pidWritten: true });
|
|
30071
30211
|
});
|
|
30072
30212
|
child.on("error", (err) => {
|
|
30073
30213
|
removePidFile(name);
|
|
30074
30214
|
printError(`graphify subprocess error: ${err.message}`);
|
|
30075
|
-
|
|
30215
|
+
resolve15({ exitCode: 1, pidWritten: true });
|
|
30076
30216
|
});
|
|
30077
30217
|
});
|
|
30078
30218
|
}
|
|
@@ -30087,78 +30227,6 @@ function registerKgWatchCommand(kg) {
|
|
|
30087
30227
|
|
|
30088
30228
|
// src/commands/kg-classify.ts
|
|
30089
30229
|
import pc31 from "picocolors";
|
|
30090
|
-
|
|
30091
|
-
// ../core/dist/kg/kg-service-client.js
|
|
30092
|
-
var KG_SERVICE_PORT_DEFAULT = 9997;
|
|
30093
|
-
function port() {
|
|
30094
|
-
const env = process.env.OLAM_KG_SERVICE_PORT;
|
|
30095
|
-
if (!env)
|
|
30096
|
-
return KG_SERVICE_PORT_DEFAULT;
|
|
30097
|
-
const n = Number.parseInt(env, 10);
|
|
30098
|
-
return Number.isFinite(n) && n > 0 ? n : KG_SERVICE_PORT_DEFAULT;
|
|
30099
|
-
}
|
|
30100
|
-
function url(path60) {
|
|
30101
|
-
return `http://127.0.0.1:${port()}${path60}`;
|
|
30102
|
-
}
|
|
30103
|
-
function kgServiceHealthUrl() {
|
|
30104
|
-
return url("/health");
|
|
30105
|
-
}
|
|
30106
|
-
function kgServiceClassifyUrl() {
|
|
30107
|
-
return url("/classify");
|
|
30108
|
-
}
|
|
30109
|
-
function kgServiceStatusUrl() {
|
|
30110
|
-
return url("/status");
|
|
30111
|
-
}
|
|
30112
|
-
var KgServiceUnreachableError = class extends Error {
|
|
30113
|
-
cause;
|
|
30114
|
-
constructor(message, cause) {
|
|
30115
|
-
super(message);
|
|
30116
|
-
this.cause = cause;
|
|
30117
|
-
this.name = "KgServiceUnreachableError";
|
|
30118
|
-
}
|
|
30119
|
-
};
|
|
30120
|
-
var DEFAULT_TIMEOUT_MS3 = 5e3;
|
|
30121
|
-
async function postJson(endpointUrl, body, timeoutMs = DEFAULT_TIMEOUT_MS3) {
|
|
30122
|
-
let res;
|
|
30123
|
-
try {
|
|
30124
|
-
res = await fetch(endpointUrl, {
|
|
30125
|
-
method: "POST",
|
|
30126
|
-
headers: { "Content-Type": "application/json" },
|
|
30127
|
-
body: JSON.stringify(body),
|
|
30128
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
30129
|
-
});
|
|
30130
|
-
} catch (err) {
|
|
30131
|
-
throw new KgServiceUnreachableError(`kg-service not reachable at ${endpointUrl} \u2014 run \`olam services up\` to start it.`, err);
|
|
30132
|
-
}
|
|
30133
|
-
if (!res.ok) {
|
|
30134
|
-
const errBody = await res.text().catch(() => "");
|
|
30135
|
-
throw new Error(`${endpointUrl} returned ${res.status}: ${errBody.slice(0, 500)}`);
|
|
30136
|
-
}
|
|
30137
|
-
return await res.json();
|
|
30138
|
-
}
|
|
30139
|
-
async function getJson(endpointUrl, timeoutMs = DEFAULT_TIMEOUT_MS3) {
|
|
30140
|
-
let res;
|
|
30141
|
-
try {
|
|
30142
|
-
res = await fetch(endpointUrl, { signal: AbortSignal.timeout(timeoutMs) });
|
|
30143
|
-
} catch (err) {
|
|
30144
|
-
throw new KgServiceUnreachableError(`kg-service not reachable at ${endpointUrl} \u2014 run \`olam services up\` to start it.`, err);
|
|
30145
|
-
}
|
|
30146
|
-
if (!res.ok) {
|
|
30147
|
-
throw new Error(`${endpointUrl} returned ${res.status}`);
|
|
30148
|
-
}
|
|
30149
|
-
return await res.json();
|
|
30150
|
-
}
|
|
30151
|
-
async function classify(req, opts = {}) {
|
|
30152
|
-
return postJson(kgServiceClassifyUrl(), req, opts.timeoutMs);
|
|
30153
|
-
}
|
|
30154
|
-
async function health(opts = {}) {
|
|
30155
|
-
return getJson(kgServiceHealthUrl(), opts.timeoutMs ?? 2e3);
|
|
30156
|
-
}
|
|
30157
|
-
async function status(opts = {}) {
|
|
30158
|
-
return getJson(kgServiceStatusUrl(), opts.timeoutMs);
|
|
30159
|
-
}
|
|
30160
|
-
|
|
30161
|
-
// src/commands/kg-classify.ts
|
|
30162
30230
|
init_output();
|
|
30163
30231
|
function registerKgClassifyCommand(kg) {
|
|
30164
30232
|
kg.command("classify <question>").description("Route a question to kg | grep | both via the 4-layer classifier (kg-service required)").option("--workspace <name>", "Scope the L2 probe gate to a specific workspace graph").option("--json", "Emit raw JSON instead of the formatted summary").action(async (question, opts) => {
|
|
@@ -30627,60 +30695,24 @@ function registerKgUninstallHookCommand(kg) {
|
|
|
30627
30695
|
}
|
|
30628
30696
|
|
|
30629
30697
|
// src/commands/kg-build.ts
|
|
30630
|
-
var DEFAULT_DEVBOX_IMAGE2 = "olam-devbox:latest";
|
|
30631
30698
|
function resolveWorkspace(arg) {
|
|
30632
30699
|
const cwd = process.cwd();
|
|
30633
30700
|
const name = arg ?? path57.basename(cwd).toLowerCase();
|
|
30634
30701
|
validateWorkspaceName(name);
|
|
30635
30702
|
return { name, sourcePath: cwd };
|
|
30636
30703
|
}
|
|
30637
|
-
function
|
|
30638
|
-
|
|
30639
|
-
|
|
30640
|
-
|
|
30641
|
-
|
|
30642
|
-
|
|
30643
|
-
|
|
30644
|
-
}
|
|
30645
|
-
const r = spawnSync20("cp", ["-r", source + "/.", scratch], {
|
|
30646
|
-
stdio: ["ignore", "ignore", "pipe"],
|
|
30647
|
-
encoding: "utf-8"
|
|
30648
|
-
});
|
|
30649
|
-
if (r.status !== 0) {
|
|
30650
|
-
throw new Error(`cp -r failed: ${(r.stderr ?? "").trim() || r.error?.message}`);
|
|
30651
|
-
}
|
|
30652
|
-
return "cp-r";
|
|
30653
|
-
}
|
|
30654
|
-
function parseNodeCount(graphifyOutDir) {
|
|
30655
|
-
const graphPath = path57.join(graphifyOutDir, "graph.json");
|
|
30656
|
-
if (!fs53.existsSync(graphPath)) return null;
|
|
30657
|
-
try {
|
|
30658
|
-
const content = fs53.readFileSync(graphPath, "utf-8");
|
|
30659
|
-
const data = JSON.parse(content);
|
|
30660
|
-
return Array.isArray(data.nodes) ? data.nodes.length : null;
|
|
30661
|
-
} catch {
|
|
30662
|
-
return null;
|
|
30704
|
+
function toContainerPath(hostPath) {
|
|
30705
|
+
const home = os30.homedir();
|
|
30706
|
+
const resolved = path57.resolve(hostPath);
|
|
30707
|
+
if (!resolved.startsWith(home + path57.sep) && resolved !== home) {
|
|
30708
|
+
throw new Error(
|
|
30709
|
+
`source path "${resolved}" is not under $HOME (${home}). kg-service can only build repos that live under your home dir (it bind-mounts $HOME:/host-home:ro at start). Move the repo or set OLAM_HOME if you need a different root.`
|
|
30710
|
+
);
|
|
30663
30711
|
}
|
|
30664
|
-
|
|
30665
|
-
|
|
30666
|
-
const r = spawnSync20(
|
|
30667
|
-
"docker",
|
|
30668
|
-
[
|
|
30669
|
-
"run",
|
|
30670
|
-
"--rm",
|
|
30671
|
-
"--entrypoint=/opt/graphify-venv/bin/pip",
|
|
30672
|
-
image,
|
|
30673
|
-
"show",
|
|
30674
|
-
"graphifyy"
|
|
30675
|
-
],
|
|
30676
|
-
{ encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }
|
|
30677
|
-
);
|
|
30678
|
-
if (r.status !== 0) return "unknown";
|
|
30679
|
-
const m = (r.stdout ?? "").match(/^Version:\s*(\S+)/m);
|
|
30680
|
-
return m?.[1] ?? "unknown";
|
|
30712
|
+
const rel = path57.relative(home, resolved);
|
|
30713
|
+
return rel === "" ? "/host-home" : path57.posix.join("/host-home", rel.split(path57.sep).join("/"));
|
|
30681
30714
|
}
|
|
30682
30715
|
async function runKgBuild(workspaceArg, options = {}) {
|
|
30683
|
-
const image = options.image ?? DEFAULT_DEVBOX_IMAGE2;
|
|
30684
30716
|
let workspace;
|
|
30685
30717
|
try {
|
|
30686
30718
|
workspace = resolveWorkspace(workspaceArg);
|
|
@@ -30688,82 +30720,68 @@ async function runKgBuild(workspaceArg, options = {}) {
|
|
|
30688
30720
|
printError(err instanceof Error ? err.message : String(err));
|
|
30689
30721
|
return { exitCode: 2 };
|
|
30690
30722
|
}
|
|
30723
|
+
let containerRepoPath;
|
|
30724
|
+
try {
|
|
30725
|
+
containerRepoPath = toContainerPath(workspace.sourcePath);
|
|
30726
|
+
} catch (err) {
|
|
30727
|
+
printError(err instanceof Error ? err.message : String(err));
|
|
30728
|
+
return { exitCode: 2 };
|
|
30729
|
+
}
|
|
30691
30730
|
const outDir = kgPristinePath(workspace.name);
|
|
30692
|
-
const scratchDir = path57.join(outDir, "scratch");
|
|
30693
30731
|
fs53.mkdirSync(outDir, { recursive: true });
|
|
30694
|
-
if (fs53.existsSync(scratchDir)) fs53.rmSync(scratchDir, { recursive: true, force: true });
|
|
30695
|
-
fs53.mkdirSync(scratchDir);
|
|
30696
30732
|
const human = !options.json;
|
|
30697
30733
|
if (human) {
|
|
30698
30734
|
printInfo("kg build", `workspace=${workspace.name} source=${workspace.sourcePath}`);
|
|
30699
|
-
printInfo("kg build",
|
|
30735
|
+
printInfo("kg build", `\u2192 kg-service /build (container path ${containerRepoPath}) \u2192 ${outDir}/graphify-out/`);
|
|
30700
30736
|
}
|
|
30701
|
-
|
|
30702
|
-
let scratchStrategy;
|
|
30737
|
+
let resp;
|
|
30703
30738
|
try {
|
|
30704
|
-
|
|
30705
|
-
if (human) printInfo("kg build", `copied via ${scratchStrategy}`);
|
|
30706
|
-
const dockerArgs = [
|
|
30707
|
-
"run",
|
|
30708
|
-
"--rm",
|
|
30709
|
-
"-v",
|
|
30710
|
-
`${scratchDir}:/work`,
|
|
30711
|
-
"-w",
|
|
30712
|
-
"/work",
|
|
30713
|
-
"--entrypoint=graphify",
|
|
30714
|
-
image,
|
|
30715
|
-
"update",
|
|
30716
|
-
"."
|
|
30717
|
-
];
|
|
30718
|
-
const r = human ? spawnSync20("docker", dockerArgs, { stdio: "inherit" }) : spawnSync20("docker", dockerArgs, { stdio: ["ignore", "ignore", "pipe"] });
|
|
30719
|
-
if (r.status !== 0) {
|
|
30720
|
-
printError(`graphify update failed (exit ${r.status})`);
|
|
30721
|
-
return { exitCode: r.status ?? 1 };
|
|
30722
|
-
}
|
|
30723
|
-
const scratchOut = path57.join(scratchDir, "graphify-out");
|
|
30724
|
-
const finalOut = path57.join(outDir, "graphify-out");
|
|
30725
|
-
if (!fs53.existsSync(scratchOut)) {
|
|
30726
|
-
printError(`graphify produced no graphify-out/ in scratch (${scratchOut})`);
|
|
30727
|
-
return { exitCode: 1 };
|
|
30728
|
-
}
|
|
30729
|
-
if (fs53.existsSync(finalOut)) fs53.rmSync(finalOut, { recursive: true, force: true });
|
|
30730
|
-
fs53.renameSync(scratchOut, finalOut);
|
|
30731
|
-
const durationMs = Date.now() - started;
|
|
30732
|
-
const nodeCount = parseNodeCount(finalOut);
|
|
30733
|
-
const version = readGraphifyVersion(image);
|
|
30734
|
-
const freshness = {
|
|
30735
|
-
built_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
30736
|
-
duration_ms: durationMs,
|
|
30737
|
-
node_count: nodeCount,
|
|
30738
|
-
graphify_version: version,
|
|
30739
|
+
resp = await build({
|
|
30739
30740
|
workspace: workspace.name,
|
|
30740
|
-
|
|
30741
|
-
};
|
|
30742
|
-
|
|
30743
|
-
|
|
30744
|
-
|
|
30745
|
-
"
|
|
30741
|
+
repo_path: containerRepoPath
|
|
30742
|
+
});
|
|
30743
|
+
} catch (err) {
|
|
30744
|
+
if (err instanceof KgServiceUnreachableError) {
|
|
30745
|
+
printError(err.message);
|
|
30746
|
+
printInfo("remedy", "run `olam services up` to start kg-service, then re-run `olam kg build`.");
|
|
30747
|
+
return { exitCode: 3 };
|
|
30748
|
+
}
|
|
30749
|
+
printError(`kg-service /build failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
30750
|
+
return { exitCode: 1 };
|
|
30751
|
+
}
|
|
30752
|
+
if (!resp.ok) {
|
|
30753
|
+
printError(`kg-service /build returned error: ${resp.error ?? "unknown"}`);
|
|
30754
|
+
return { exitCode: 1 };
|
|
30755
|
+
}
|
|
30756
|
+
const freshness = {
|
|
30757
|
+
built_at: resp.built_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
30758
|
+
duration_ms: resp.duration_ms ?? 0,
|
|
30759
|
+
node_count: resp.nodes ?? null,
|
|
30760
|
+
edge_count: resp.edges ?? null,
|
|
30761
|
+
workspace: workspace.name,
|
|
30762
|
+
graphify_path: "container"
|
|
30763
|
+
};
|
|
30764
|
+
fs53.writeFileSync(
|
|
30765
|
+
path57.join(outDir, "freshness.json"),
|
|
30766
|
+
JSON.stringify(freshness, null, 2) + "\n",
|
|
30767
|
+
"utf-8"
|
|
30768
|
+
);
|
|
30769
|
+
const finalOut = path57.join(outDir, "graphify-out");
|
|
30770
|
+
if (options.json) {
|
|
30771
|
+
process.stdout.write(JSON.stringify(freshness) + "\n");
|
|
30772
|
+
} else {
|
|
30773
|
+
printSuccess(
|
|
30774
|
+
`kg build ${workspace.name} \u2014 ${resp.nodes ?? "?"} nodes / ${resp.edges ?? "?"} edges in ${((resp.duration_ms ?? 0) / 1e3).toFixed(1)}s (via kg-service container)`
|
|
30746
30775
|
);
|
|
30747
|
-
|
|
30748
|
-
process.stdout.write(JSON.stringify(freshness) + "\n");
|
|
30749
|
-
} else {
|
|
30750
|
-
printSuccess(
|
|
30751
|
-
`kg build ${workspace.name} \u2014 ${nodeCount ?? "?"} nodes in ${(durationMs / 1e3).toFixed(1)}s (graphify ${version})`
|
|
30752
|
-
);
|
|
30753
|
-
printInfo("output", `${finalOut}/graph.json`);
|
|
30754
|
-
}
|
|
30755
|
-
return { exitCode: 0, freshness, outputDir: finalOut };
|
|
30756
|
-
} finally {
|
|
30757
|
-
if (fs53.existsSync(scratchDir)) {
|
|
30758
|
-
fs53.rmSync(scratchDir, { recursive: true, force: true });
|
|
30759
|
-
}
|
|
30776
|
+
printInfo("output", `${finalOut}/graph.json`);
|
|
30760
30777
|
}
|
|
30778
|
+
return { exitCode: 0, freshness, outputDir: finalOut };
|
|
30761
30779
|
}
|
|
30762
30780
|
function registerKg(program2) {
|
|
30763
|
-
const kg = program2.command("kg").description("Knowledge-graph operations (
|
|
30781
|
+
const kg = program2.command("kg").description("Knowledge-graph operations (kg-service container)");
|
|
30764
30782
|
kg.command("build").description(
|
|
30765
|
-
"Build pristine KG for a workspace (default: current dir).
|
|
30766
|
-
).argument("[workspace]", "workspace name (lowercase alphanumeric + hyphens/underscores)").option("--
|
|
30783
|
+
"Build pristine KG for a workspace (default: current dir). Routes through olam-kg-service /build endpoint."
|
|
30784
|
+
).argument("[workspace]", "workspace name (lowercase alphanumeric + hyphens/underscores)").option("--json", "emit freshness record as JSON instead of human-readable status").action(async (workspaceArg, opts) => {
|
|
30767
30785
|
const r = await runKgBuild(workspaceArg, opts);
|
|
30768
30786
|
if (r.exitCode !== 0) process.exitCode = r.exitCode;
|
|
30769
30787
|
});
|
|
@@ -30777,7 +30795,7 @@ function registerKg(program2) {
|
|
|
30777
30795
|
|
|
30778
30796
|
// src/commands/seed.ts
|
|
30779
30797
|
init_output();
|
|
30780
|
-
import { spawnSync as
|
|
30798
|
+
import { spawnSync as spawnSync20, spawn as spawnAsync2 } from "node:child_process";
|
|
30781
30799
|
var DEFAULT_SINGLETON_CONTAINER = "olam-postgres";
|
|
30782
30800
|
var DEFAULT_SINGLETON_USER = "development";
|
|
30783
30801
|
function assertValidSeedName(name) {
|
|
@@ -30788,7 +30806,7 @@ function assertValidSeedName(name) {
|
|
|
30788
30806
|
}
|
|
30789
30807
|
}
|
|
30790
30808
|
function singletonDocker(container, user, args, stdin) {
|
|
30791
|
-
return
|
|
30809
|
+
return spawnSync20(
|
|
30792
30810
|
"docker",
|
|
30793
30811
|
["exec", "-i", container, "psql", "-U", user, ...args],
|
|
30794
30812
|
{ encoding: "utf-8", input: stdin }
|
|
@@ -30843,7 +30861,7 @@ async function handleBake(opts) {
|
|
|
30843
30861
|
if (sources.length > 1) {
|
|
30844
30862
|
throw new Error("multiple sources specified \u2014 pass exactly one of --source-container, --source-url, --source-local");
|
|
30845
30863
|
}
|
|
30846
|
-
const ping =
|
|
30864
|
+
const ping = spawnSync20("docker", ["inspect", "--format", "{{.State.Status}}", singleton], { encoding: "utf-8" });
|
|
30847
30865
|
if (ping.status !== 0 || (ping.stdout || "").trim() !== "running") {
|
|
30848
30866
|
throw new Error(`singleton container "${singleton}" not running \u2014 run \`olam bootstrap\` first`);
|
|
30849
30867
|
}
|
|
@@ -31025,13 +31043,13 @@ init_context();
|
|
|
31025
31043
|
init_output();
|
|
31026
31044
|
import { spawnSync as defaultSpawnSync } from "node:child_process";
|
|
31027
31045
|
import * as fs54 from "node:fs";
|
|
31028
|
-
import * as
|
|
31046
|
+
import * as os31 from "node:os";
|
|
31029
31047
|
import * as path58 from "node:path";
|
|
31030
31048
|
function devboxContainerName(worldId) {
|
|
31031
31049
|
return `olam-${worldId}-devbox`;
|
|
31032
31050
|
}
|
|
31033
31051
|
function olamHomeDir() {
|
|
31034
|
-
return process.env["OLAM_HOME"] ?? path58.join(
|
|
31052
|
+
return process.env["OLAM_HOME"] ?? path58.join(os31.homedir(), ".olam");
|
|
31035
31053
|
}
|
|
31036
31054
|
function defaultRestartContainer(name, spawn11 = defaultSpawnSync) {
|
|
31037
31055
|
const r = spawn11("docker", ["restart", "--time", "30", name], {
|