@pleri/olam-cli 0.1.210 → 0.1.212
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/README.md +9 -3
- package/dist/image-digests.json +8 -8
- package/dist/index.js +90 -23
- package/dist/mcp-server.js +224 -139
- package/hermes-bundle/version.json +1 -1
- package/host-cp/k8s/manifests/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +1 -1
- package/host-cp/src/server.mjs +7 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,11 +53,17 @@ olam setup \
|
|
|
53
53
|
--remote-memory-url=<memory-url> \
|
|
54
54
|
--remote-kg-url=<kg-url> \
|
|
55
55
|
--remote-dispatch-url=<dispatch-url> \
|
|
56
|
-
--credentials=gcp
|
|
56
|
+
--credentials=gcp \
|
|
57
|
+
--gcp-bucket=<gs://your-bucket[/prefix]> # explicit — no implicit default
|
|
57
58
|
```
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
The credentials bucket has no implicit default: pass `--gcp-bucket`, set
|
|
61
|
+
`OLAM_CREDENTIALS_BUCKET`, or persist it with
|
|
62
|
+
`olam config set credentials.bucket <gs://bucket[/prefix]>`.
|
|
63
|
+
|
|
64
|
+
- **Admin (once):** `olam credentials push --gcp-bucket <name>` uploads the
|
|
65
|
+
team's bearers to the bucket (auto-created, uniform bucket-level access).
|
|
66
|
+
Grant teammates
|
|
61
67
|
`roles/storage.objectViewer`.
|
|
62
68
|
- **Teammate:** `--credentials=gcp` runs `olam credentials pull` — `gcloud`
|
|
63
69
|
downloads the bearers with the teammate's own ADC and writes them `0600`.
|
package/dist/image-digests.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"auth": "sha256:
|
|
3
|
-
"devbox": "sha256:
|
|
4
|
-
"devbox-base": "sha256:
|
|
5
|
-
"host-cp": "sha256:
|
|
6
|
-
"kg-service": "sha256:
|
|
7
|
-
"memory-service": "sha256:
|
|
8
|
-
"mcp-auth": "sha256:
|
|
2
|
+
"auth": "sha256:7a206b619cd92d39b2550a09e270e9999a6c0b1a70e391e72b46c2cfbbf0be9c",
|
|
3
|
+
"devbox": "sha256:d9d1635ba112c00f3f722f2f19c272263f3187b7667751839c33307ee79fef6b",
|
|
4
|
+
"devbox-base": "sha256:e09f5646a9434fb7b19dcaa70f7efca92e5e884b1a3395146856e7087046fa3a",
|
|
5
|
+
"host-cp": "sha256:1818b62ee1475cf42f8d55c3ba3cbda9c27b799dc99abcff6c63f02d54574893",
|
|
6
|
+
"kg-service": "sha256:b74d2099752a0299317c95feab19893764a291db375c4ce0fd96d06691defb9f",
|
|
7
|
+
"memory-service": "sha256:847d97e6970158f5037821c5664836a1781949750ce69caab08128e1c9c6a157",
|
|
8
|
+
"mcp-auth": "sha256:9e1b11d9a67005a1a3c65f63b5c4c94d311a35f6b424e576d63bba82290f86cf",
|
|
9
9
|
"$schema_version": 1,
|
|
10
|
-
"$published_version": "0.1.
|
|
10
|
+
"$published_version": "0.1.212",
|
|
11
11
|
"$registry": "ghcr.io/pleri"
|
|
12
12
|
}
|
package/dist/index.js
CHANGED
|
@@ -5742,7 +5742,11 @@ function writeConfig(updates, opts = {}) {
|
|
|
5742
5742
|
...current,
|
|
5743
5743
|
"config.schema": 1,
|
|
5744
5744
|
host: { ...current.host, ...updates.host ?? {} },
|
|
5745
|
-
install_id: current.install_id
|
|
5745
|
+
install_id: current.install_id,
|
|
5746
|
+
// Only materialise `credentials` when the update sets it or it already
|
|
5747
|
+
// exists — avoids writing an empty `credentials: {}` on every host-only
|
|
5748
|
+
// write.
|
|
5749
|
+
...updates.credentials || current.credentials ? { credentials: { ...current.credentials, ...updates.credentials ?? {} } } : {}
|
|
5746
5750
|
};
|
|
5747
5751
|
atomicWrite(configPath, next, stderr);
|
|
5748
5752
|
return next;
|
|
@@ -23497,6 +23501,41 @@ import { existsSync as existsSync97, mkdtempSync as mkdtempSync5, readFileSync a
|
|
|
23497
23501
|
import { spawnSync as spawnSync29 } from "node:child_process";
|
|
23498
23502
|
import { homedir as homedir56, tmpdir as tmpdir7 } from "node:os";
|
|
23499
23503
|
import { join as join104 } from "node:path";
|
|
23504
|
+
function parseBucketSpec(spec) {
|
|
23505
|
+
const trimmed = spec.trim().replace(/^gs:\/\//i, "").replace(/\/+$/, "");
|
|
23506
|
+
if (!trimmed) return null;
|
|
23507
|
+
const slash = trimmed.indexOf("/");
|
|
23508
|
+
if (slash === -1) return { bucket: trimmed };
|
|
23509
|
+
const bucket = trimmed.slice(0, slash);
|
|
23510
|
+
const prefix = trimmed.slice(slash + 1).replace(/^\/+/, "");
|
|
23511
|
+
if (!bucket) return null;
|
|
23512
|
+
return prefix ? { bucket, prefix } : { bucket };
|
|
23513
|
+
}
|
|
23514
|
+
function readConfiguredBucketDefault() {
|
|
23515
|
+
try {
|
|
23516
|
+
const cfg = readConfig();
|
|
23517
|
+
return cfg.credentials?.bucket;
|
|
23518
|
+
} catch {
|
|
23519
|
+
return void 0;
|
|
23520
|
+
}
|
|
23521
|
+
}
|
|
23522
|
+
function resolveCredentialsBucket(explicit, deps = {}) {
|
|
23523
|
+
const env = deps.env ?? process.env;
|
|
23524
|
+
const readConfigured = deps.readConfiguredBucket ?? readConfiguredBucketDefault;
|
|
23525
|
+
const candidates2 = [
|
|
23526
|
+
{ value: explicit, source: "flag" },
|
|
23527
|
+
{ value: env[CREDENTIALS_BUCKET_ENV], source: "env" },
|
|
23528
|
+
{ value: readConfigured(), source: "config" }
|
|
23529
|
+
];
|
|
23530
|
+
for (const { value, source } of candidates2) {
|
|
23531
|
+
if (value && value.trim()) {
|
|
23532
|
+
const spec = parseBucketSpec(value);
|
|
23533
|
+
if (!spec) return { ok: false, error: `invalid credentials bucket spec: "${value}"`, remedy: NO_BUCKET_REMEDY };
|
|
23534
|
+
return { ok: true, bucket: spec.bucket, prefix: spec.prefix, source };
|
|
23535
|
+
}
|
|
23536
|
+
}
|
|
23537
|
+
return { ok: false, error: "no credentials bucket configured", remedy: NO_BUCKET_REMEDY };
|
|
23538
|
+
}
|
|
23500
23539
|
function preflightGcp(project, deps = {}) {
|
|
23501
23540
|
const run = deps.run ?? defaultRun;
|
|
23502
23541
|
const version = run("gcloud", ["--version"]);
|
|
@@ -23531,8 +23570,9 @@ function preflightGcp(project, deps = {}) {
|
|
|
23531
23570
|
}
|
|
23532
23571
|
return { ok: true, project: resolvedProject, account };
|
|
23533
23572
|
}
|
|
23534
|
-
function bucketUri(bucket, object) {
|
|
23535
|
-
|
|
23573
|
+
function bucketUri(bucket, object, prefix) {
|
|
23574
|
+
const parts = [prefix, object].filter((p) => !!p && p.length > 0);
|
|
23575
|
+
return parts.length > 0 ? `gs://${bucket}/${parts.join("/")}` : `gs://${bucket}`;
|
|
23536
23576
|
}
|
|
23537
23577
|
function olamDir(deps) {
|
|
23538
23578
|
return join104(deps.home ?? homedir56(), ".olam");
|
|
@@ -23550,7 +23590,9 @@ function resolveLocalSecretValue(obj, deps = {}) {
|
|
|
23550
23590
|
}
|
|
23551
23591
|
function pushCredentials(opts, deps = {}) {
|
|
23552
23592
|
const run = deps.run ?? defaultRun;
|
|
23553
|
-
const bucket = opts.bucket
|
|
23593
|
+
const bucket = opts.bucket;
|
|
23594
|
+
if (!bucket) return { ok: false, error: "no credentials bucket specified" };
|
|
23595
|
+
const prefix = opts.prefix;
|
|
23554
23596
|
const project = opts.project;
|
|
23555
23597
|
const describe2 = run("gcloud", ["storage", "buckets", "describe", bucketUri(bucket), "--format=value(name)"]);
|
|
23556
23598
|
if (describe2.status !== 0) {
|
|
@@ -23573,7 +23615,7 @@ function pushCredentials(opts, deps = {}) {
|
|
|
23573
23615
|
}
|
|
23574
23616
|
const tmp = join104(staging, obj.object);
|
|
23575
23617
|
writeSecretAtPath(tmp, value);
|
|
23576
|
-
const cp = run("gcloud", ["storage", "cp", tmp, bucketUri(bucket, obj.object)]);
|
|
23618
|
+
const cp = run("gcloud", ["storage", "cp", tmp, bucketUri(bucket, obj.object, prefix)]);
|
|
23577
23619
|
if (cp.status !== 0) {
|
|
23578
23620
|
return { ok: false, pushed, error: `upload ${obj.object} failed: ${cp.stderr.trim()}` };
|
|
23579
23621
|
}
|
|
@@ -23586,14 +23628,16 @@ function pushCredentials(opts, deps = {}) {
|
|
|
23586
23628
|
}
|
|
23587
23629
|
function pullCredentials(opts, deps = {}) {
|
|
23588
23630
|
const run = deps.run ?? defaultRun;
|
|
23589
|
-
const bucket = opts.bucket
|
|
23631
|
+
const bucket = opts.bucket;
|
|
23632
|
+
if (!bucket) return { ok: false, error: "no credentials bucket specified" };
|
|
23633
|
+
const prefix = opts.prefix;
|
|
23590
23634
|
const pulled = [];
|
|
23591
23635
|
const skipped = [];
|
|
23592
23636
|
const staging = mkdtempSync5(join104(tmpdir7(), "olam-cred-pull-"));
|
|
23593
23637
|
try {
|
|
23594
23638
|
for (const obj of CREDENTIAL_OBJECTS) {
|
|
23595
23639
|
const tmp = join104(staging, obj.object);
|
|
23596
|
-
const cp = run("gcloud", ["storage", "cp", bucketUri(bucket, obj.object), tmp]);
|
|
23640
|
+
const cp = run("gcloud", ["storage", "cp", bucketUri(bucket, obj.object, prefix), tmp]);
|
|
23597
23641
|
if (cp.status !== 0 || !existsSync97(tmp)) {
|
|
23598
23642
|
skipped.push(obj.object);
|
|
23599
23643
|
continue;
|
|
@@ -23607,17 +23651,19 @@ function pullCredentials(opts, deps = {}) {
|
|
|
23607
23651
|
rmSync12(staging, { recursive: true, force: true });
|
|
23608
23652
|
}
|
|
23609
23653
|
if (pulled.length === 0) {
|
|
23610
|
-
return { ok: false, pulled, skipped, error: `no credential objects found in ${bucketUri(bucket)} (check bucket name + IAM access)` };
|
|
23654
|
+
return { ok: false, pulled, skipped, error: `no credential objects found in ${bucketUri(bucket, void 0, prefix)} (check bucket name + IAM access)` };
|
|
23611
23655
|
}
|
|
23612
23656
|
return { ok: true, pulled, skipped };
|
|
23613
23657
|
}
|
|
23614
|
-
var
|
|
23658
|
+
var CREDENTIALS_BUCKET_ENV, NO_BUCKET_REMEDY, CREDENTIAL_OBJECTS, defaultRun;
|
|
23615
23659
|
var init_gcp_credentials = __esm({
|
|
23616
23660
|
"src/lib/gcp-credentials.ts"() {
|
|
23617
23661
|
"use strict";
|
|
23618
23662
|
init_memory_secret();
|
|
23619
23663
|
init_remote_connection();
|
|
23620
|
-
|
|
23664
|
+
init_config();
|
|
23665
|
+
CREDENTIALS_BUCKET_ENV = "OLAM_CREDENTIALS_BUCKET";
|
|
23666
|
+
NO_BUCKET_REMEDY = `set one: olam config set credentials.bucket <gs://bucket[/prefix]> \xB7 or pass --gcp-bucket <name> \xB7 or export ${CREDENTIALS_BUCKET_ENV}=<name>`;
|
|
23621
23667
|
CREDENTIAL_OBJECTS = [
|
|
23622
23668
|
{ local: "secrets/cloud-memory-secret", object: "cloud-memory-secret" },
|
|
23623
23669
|
{ local: "kg-proxy-bearer", object: "kg-proxy-bearer" },
|
|
@@ -23734,14 +23780,20 @@ async function runCloudFirstSetup(opts, deps = {}) {
|
|
|
23734
23780
|
}
|
|
23735
23781
|
if (usingGcp) {
|
|
23736
23782
|
printInfo("5. Credentials", "pull team bearers from GCS (IAM-gated)");
|
|
23783
|
+
const resolvedBucket = resolveCredentialsBucket(opts.gcpBucket);
|
|
23737
23784
|
const preflight2 = (deps.gcpPreflightFn ?? preflightGcp)(opts.gcpProject);
|
|
23738
|
-
if (!
|
|
23785
|
+
if (!resolvedBucket.ok) {
|
|
23786
|
+
printError(` ${resolvedBucket.error}`);
|
|
23787
|
+
printWarning(` remedy: ${resolvedBucket.remedy}`);
|
|
23788
|
+
steps.push({ name: "credentials", status: "error" });
|
|
23789
|
+
} else if (!preflight2.ok) {
|
|
23739
23790
|
printError(` GCP preflight failed: ${preflight2.error}`);
|
|
23740
23791
|
if (preflight2.remedy) printWarning(` remedy: ${preflight2.remedy}`);
|
|
23741
23792
|
steps.push({ name: "credentials", status: "error" });
|
|
23742
23793
|
} else {
|
|
23743
23794
|
const pull = (deps.gcpPullFn ?? ((o) => pullCredentials(o)))({
|
|
23744
|
-
bucket:
|
|
23795
|
+
bucket: resolvedBucket.bucket,
|
|
23796
|
+
prefix: resolvedBucket.prefix,
|
|
23745
23797
|
project: preflight2.project
|
|
23746
23798
|
});
|
|
23747
23799
|
if (pull.ok) {
|
|
@@ -47669,7 +47721,7 @@ function registerSetup(program2) {
|
|
|
47669
47721
|
).option(
|
|
47670
47722
|
"--skip-inbox-hook",
|
|
47671
47723
|
"Skip Phase 10 (do not install question-inbox hook; run `olam inbox install-hook` later)"
|
|
47672
|
-
).option("--verbose", "[k3s] stream all bootstrap phase output sequentially instead of collapsing to live spinner lines").option("--skip-prepull", "[k3s] skip pre-pulling olam-* images into the k3d node (pods cold-pull on demand)").option("--cloud-first", "Run the guided cloud-first onboarding (skills/memory/kg/remote); skips docker/k3s").option("--local-mode", "Run the legacy local (docker/k3s) bootstrap pipeline and reveal local commands").option("--skills-source <git-url>", "Cloud-first: register + sync this skill source (trusted)").option("--memory-url <url>", "Cloud-first: non-interactive memory service URL").option("--remote-memory-url <url>", "Cloud-first: alias of --memory-url").option("--memory-secret <bearer>", "Cloud-first: memory bearer secret (stored 0600; prefer --credentials=gcp)").option("--kg-url <url>", "Cloud-first: non-interactive KG mirror URL").option("--remote-kg-url <url>", "Cloud-first: alias of --kg-url").option("--kg-bearer <token>", "Cloud-first: KG mirror bearer (stored 0600; prefer --credentials=gcp)").option("--remote-url <url>", "Cloud-first: non-interactive plan-agent backend URL").option("--remote-dispatch-url <url>", "Cloud-first: alias of --remote-url (cloud dispatch backend)").option("--remote-password <pw>", "Cloud-first: plan-DO showcase password (stored 0600; prefer --credentials=gcp)").option("--credentials <source>", 'Cloud-first: secret source \u2014 "gcp" pulls bearers from the shared GCS bucket (no secrets on the CLI)').option("--gcp-bucket <name>", "Cloud-first: GCS bucket for --credentials=gcp (default
|
|
47724
|
+
).option("--verbose", "[k3s] stream all bootstrap phase output sequentially instead of collapsing to live spinner lines").option("--skip-prepull", "[k3s] skip pre-pulling olam-* images into the k3d node (pods cold-pull on demand)").option("--cloud-first", "Run the guided cloud-first onboarding (skills/memory/kg/remote); skips docker/k3s").option("--local-mode", "Run the legacy local (docker/k3s) bootstrap pipeline and reveal local commands").option("--skills-source <git-url>", "Cloud-first: register + sync this skill source (trusted)").option("--memory-url <url>", "Cloud-first: non-interactive memory service URL").option("--remote-memory-url <url>", "Cloud-first: alias of --memory-url").option("--memory-secret <bearer>", "Cloud-first: memory bearer secret (stored 0600; prefer --credentials=gcp)").option("--kg-url <url>", "Cloud-first: non-interactive KG mirror URL").option("--remote-kg-url <url>", "Cloud-first: alias of --kg-url").option("--kg-bearer <token>", "Cloud-first: KG mirror bearer (stored 0600; prefer --credentials=gcp)").option("--remote-url <url>", "Cloud-first: non-interactive plan-agent backend URL").option("--remote-dispatch-url <url>", "Cloud-first: alias of --remote-url (cloud dispatch backend)").option("--remote-password <pw>", "Cloud-first: plan-DO showcase password (stored 0600; prefer --credentials=gcp)").option("--credentials <source>", 'Cloud-first: secret source \u2014 "gcp" pulls bearers from the shared GCS bucket (no secrets on the CLI)').option("--gcp-bucket <name>", "Cloud-first: GCS bucket or gs://bucket/prefix for --credentials=gcp (overrides OLAM_CREDENTIALS_BUCKET / config; required \u2014 no implicit default)").option("--gcp-project <id>", "Cloud-first: GCP project for --credentials=gcp (default: gcloud active project)").option("--allow-local-dev", "Cloud-first: allow http:// / private-IP connect endpoints").action(async (rawOpts) => {
|
|
47673
47725
|
const { resolveSetupPath: resolveSetupPath2, runCloudFirstSetup: runCloudFirstSetup2 } = await Promise.resolve().then(() => (init_setup_cloud_first(), setup_cloud_first_exports));
|
|
47674
47726
|
const isTty = Boolean(process.stdin.isTTY);
|
|
47675
47727
|
const hasCloudArg = Boolean(
|
|
@@ -48281,7 +48333,8 @@ var SETTABLE_KEYS = [
|
|
|
48281
48333
|
"host.substrate",
|
|
48282
48334
|
"host.mode",
|
|
48283
48335
|
"host.kubectl_context_pinned",
|
|
48284
|
-
"host.gh_token"
|
|
48336
|
+
"host.gh_token",
|
|
48337
|
+
"credentials.bucket"
|
|
48285
48338
|
];
|
|
48286
48339
|
var SECRET_KEYS = /* @__PURE__ */ new Set(["host.gh_token"]);
|
|
48287
48340
|
function hostConfigPath() {
|
|
@@ -48396,6 +48449,14 @@ function registerConfig(program2) {
|
|
|
48396
48449
|
process.exit(1);
|
|
48397
48450
|
}
|
|
48398
48451
|
writeConfig({ host: { gh_token: value } }, { configPath });
|
|
48452
|
+
} else if (key === "credentials.bucket") {
|
|
48453
|
+
if (value.length === 0) {
|
|
48454
|
+
process.stderr.write(
|
|
48455
|
+
"credentials.bucket must be a non-empty bucket name or gs://bucket[/prefix] path\n"
|
|
48456
|
+
);
|
|
48457
|
+
process.exit(1);
|
|
48458
|
+
}
|
|
48459
|
+
writeConfig({ credentials: { bucket: value } }, { configPath });
|
|
48399
48460
|
} else {
|
|
48400
48461
|
process.stderr.write(
|
|
48401
48462
|
`unknown config key: "${key}"
|
|
@@ -56410,28 +56471,34 @@ function fail(message, remedy) {
|
|
|
56410
56471
|
}
|
|
56411
56472
|
function registerCredentials(program2) {
|
|
56412
56473
|
const credentials = program2.command("credentials").description("Distribute team secret bearers through a GCS bucket (IAM-gated)");
|
|
56413
|
-
credentials.command("push").description("Upload local secret bearers to the shared GCS bucket (admin)").option("--gcp-bucket <name>",
|
|
56474
|
+
credentials.command("push").description("Upload local secret bearers to the shared GCS bucket (admin)").option("--gcp-bucket <name>", "GCS bucket or gs://bucket/prefix path (overrides OLAM_CREDENTIALS_BUCKET / config)").option("--gcp-project <id>", "GCP project (default: gcloud active project)").action((opts) => {
|
|
56475
|
+
const resolved = resolveCredentialsBucket(opts.gcpBucket);
|
|
56476
|
+
if (!resolved.ok) fail(resolved.error, resolved.remedy);
|
|
56477
|
+
const { bucket, prefix } = resolved;
|
|
56414
56478
|
const pre = preflightGcp(opts.gcpProject);
|
|
56415
56479
|
if (!pre.ok) fail(pre.error ?? "gcloud preflight failed", pre.remedy);
|
|
56416
|
-
const
|
|
56480
|
+
const uri = prefix ? `gs://${bucket}/${prefix}` : `gs://${bucket}`;
|
|
56417
56481
|
printInfo("account", pre.account ?? "?");
|
|
56418
56482
|
printInfo("project", pre.project ?? "?");
|
|
56419
|
-
printInfo("bucket",
|
|
56420
|
-
const result = pushCredentials({ bucket, project: pre.project });
|
|
56483
|
+
printInfo("bucket", `${uri} (${resolved.source})`);
|
|
56484
|
+
const result = pushCredentials({ bucket, prefix, project: pre.project });
|
|
56421
56485
|
if (!result.ok) fail(result.error ?? "push failed");
|
|
56422
|
-
printSuccess(`pushed ${result.pushed?.length ?? 0} secret(s) to
|
|
56486
|
+
printSuccess(`pushed ${result.pushed?.length ?? 0} secret(s) to ${uri}`);
|
|
56423
56487
|
for (const o of result.pushed ?? []) printInfo("\u2191", o);
|
|
56424
56488
|
if (result.skipped && result.skipped.length > 0) {
|
|
56425
56489
|
printWarning(`skipped (not present locally): ${result.skipped.join(", ")}`);
|
|
56426
56490
|
}
|
|
56427
56491
|
});
|
|
56428
|
-
credentials.command("pull").description("Download secret bearers from the shared GCS bucket into ~/.olam/ (0600)").option("--gcp-bucket <name>",
|
|
56492
|
+
credentials.command("pull").description("Download secret bearers from the shared GCS bucket into ~/.olam/ (0600)").option("--gcp-bucket <name>", "GCS bucket or gs://bucket/prefix path (overrides OLAM_CREDENTIALS_BUCKET / config)").option("--gcp-project <id>", "GCP project (default: gcloud active project)").action((opts) => {
|
|
56493
|
+
const resolved = resolveCredentialsBucket(opts.gcpBucket);
|
|
56494
|
+
if (!resolved.ok) fail(resolved.error, resolved.remedy);
|
|
56495
|
+
const { bucket, prefix } = resolved;
|
|
56429
56496
|
const pre = preflightGcp(opts.gcpProject);
|
|
56430
56497
|
if (!pre.ok) fail(pre.error ?? "gcloud preflight failed", pre.remedy);
|
|
56431
|
-
const
|
|
56498
|
+
const uri = prefix ? `gs://${bucket}/${prefix}` : `gs://${bucket}`;
|
|
56432
56499
|
printInfo("account", pre.account ?? "?");
|
|
56433
|
-
printInfo("bucket",
|
|
56434
|
-
const result = pullCredentials({ bucket, project: pre.project });
|
|
56500
|
+
printInfo("bucket", `${uri} (${resolved.source})`);
|
|
56501
|
+
const result = pullCredentials({ bucket, prefix, project: pre.project });
|
|
56435
56502
|
if (!result.ok) fail(result.error ?? "pull failed", "verify the bucket name and your IAM access (roles/storage.objectViewer)");
|
|
56436
56503
|
printSuccess(`pulled ${result.pulled?.length ?? 0} secret(s) into ~/.olam/ (0600)`);
|
|
56437
56504
|
for (const o of result.pulled ?? []) printInfo("\u2193", o);
|
package/dist/mcp-server.js
CHANGED
|
@@ -10909,37 +10909,37 @@ var require_dist = __commonJS({
|
|
|
10909
10909
|
});
|
|
10910
10910
|
|
|
10911
10911
|
// ../core/dist/paths/olam-paths.js
|
|
10912
|
-
import { homedir } from "node:os";
|
|
10913
|
-
import { join as
|
|
10912
|
+
import { homedir as homedir2 } from "node:os";
|
|
10913
|
+
import { join as join3 } from "node:path";
|
|
10914
10914
|
function olamHome() {
|
|
10915
10915
|
const fromEnv = process.env["OLAM_HOME"];
|
|
10916
10916
|
if (fromEnv && fromEnv.length > 0)
|
|
10917
10917
|
return fromEnv;
|
|
10918
|
-
return
|
|
10918
|
+
return join3(homedir2(), ".olam");
|
|
10919
10919
|
}
|
|
10920
10920
|
function claudeDir() {
|
|
10921
10921
|
const fromEnv = process.env["OLAM_CLAUDE_DIR"];
|
|
10922
10922
|
if (fromEnv && fromEnv.length > 0)
|
|
10923
10923
|
return fromEnv;
|
|
10924
|
-
return
|
|
10924
|
+
return join3(homedir2(), ".claude");
|
|
10925
10925
|
}
|
|
10926
10926
|
function globalConfigPath() {
|
|
10927
10927
|
const override = process.env["OLAM_GLOBAL_CONFIG_PATH"];
|
|
10928
10928
|
if (override && override.length > 0)
|
|
10929
10929
|
return override;
|
|
10930
|
-
return
|
|
10930
|
+
return join3(olamHome(), "config.json");
|
|
10931
10931
|
}
|
|
10932
10932
|
function stateDir() {
|
|
10933
10933
|
const override = process.env["OLAM_STATE_DIR"];
|
|
10934
10934
|
if (override && override.length > 0)
|
|
10935
10935
|
return override;
|
|
10936
|
-
return
|
|
10936
|
+
return join3(olamHome(), "state");
|
|
10937
10937
|
}
|
|
10938
10938
|
function skillSourcesDir() {
|
|
10939
10939
|
const override = process.env["OLAM_SKILL_SOURCES_DIR"];
|
|
10940
10940
|
if (override && override.length > 0)
|
|
10941
10941
|
return override;
|
|
10942
|
-
return
|
|
10942
|
+
return join3(stateDir(), "skill-sources");
|
|
10943
10943
|
}
|
|
10944
10944
|
var init_olam_paths = __esm({
|
|
10945
10945
|
"../core/dist/paths/olam-paths.js"() {
|
|
@@ -11086,8 +11086,8 @@ var init_version2 = __esm({
|
|
|
11086
11086
|
});
|
|
11087
11087
|
|
|
11088
11088
|
// ../core/dist/world/repo-manifest.js
|
|
11089
|
-
import { existsSync as
|
|
11090
|
-
import { join as
|
|
11089
|
+
import { existsSync as existsSync6, lstatSync, readFileSync as readFileSync4 } from "node:fs";
|
|
11090
|
+
import { join as join7, resolve as resolve3, sep } from "node:path";
|
|
11091
11091
|
import YAML from "yaml";
|
|
11092
11092
|
function bootstrapStepCmd(entry) {
|
|
11093
11093
|
return typeof entry === "string" ? entry : entry.cmd;
|
|
@@ -11151,14 +11151,14 @@ function isPlainObject3(value) {
|
|
|
11151
11151
|
return value !== null && typeof value === "object" && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
11152
11152
|
}
|
|
11153
11153
|
function loadRepoManifest(repoDir) {
|
|
11154
|
-
const olamPath =
|
|
11155
|
-
const adbPath =
|
|
11154
|
+
const olamPath = join7(repoDir, ".olam.yaml");
|
|
11155
|
+
const adbPath = join7(repoDir, ".adb.yaml");
|
|
11156
11156
|
let manifestPath2;
|
|
11157
11157
|
let source;
|
|
11158
|
-
if (
|
|
11158
|
+
if (existsSync6(olamPath)) {
|
|
11159
11159
|
manifestPath2 = olamPath;
|
|
11160
11160
|
source = "olam";
|
|
11161
|
-
} else if (
|
|
11161
|
+
} else if (existsSync6(adbPath)) {
|
|
11162
11162
|
manifestPath2 = adbPath;
|
|
11163
11163
|
source = "adb";
|
|
11164
11164
|
} else {
|
|
@@ -11168,10 +11168,10 @@ function loadRepoManifest(repoDir) {
|
|
|
11168
11168
|
if (stat2.isSymbolicLink()) {
|
|
11169
11169
|
throw new Error(`[manifest] ${manifestPath2}: symbolic links are not permitted`);
|
|
11170
11170
|
}
|
|
11171
|
-
const raw =
|
|
11171
|
+
const raw = readFileSync4(manifestPath2, "utf-8");
|
|
11172
11172
|
const parsed = YAML.parse(raw, { maxAliasCount: 100 });
|
|
11173
11173
|
if (parsed === null || parsed === void 0) {
|
|
11174
|
-
if (source === "olam" &&
|
|
11174
|
+
if (source === "olam" && existsSync6(adbPath)) {
|
|
11175
11175
|
console.warn(`[manifest] ${manifestPath2}: file is empty; .adb.yaml is NOT consulted (delete .olam.yaml to fall back)`);
|
|
11176
11176
|
}
|
|
11177
11177
|
return null;
|
|
@@ -11191,14 +11191,14 @@ function loadRepoManifest(repoDir) {
|
|
|
11191
11191
|
if (!inheritedAbs.startsWith(repoDirAbs + sep) && inheritedAbs !== repoDirAbs) {
|
|
11192
11192
|
throw new Error(`[manifest] ${manifestPath2}: inherits target "${inheritsRaw}" escapes repo dir`);
|
|
11193
11193
|
}
|
|
11194
|
-
if (!
|
|
11194
|
+
if (!existsSync6(inheritedAbs)) {
|
|
11195
11195
|
throw new Error(`[manifest] ${manifestPath2}: inherits target "${inheritsRaw}" not found`);
|
|
11196
11196
|
}
|
|
11197
11197
|
const inheritedStat = lstatSync(inheritedAbs);
|
|
11198
11198
|
if (inheritedStat.isSymbolicLink()) {
|
|
11199
11199
|
throw new Error(`[manifest] ${manifestPath2}: inherits target "${inheritsRaw}" is a symlink (not permitted)`);
|
|
11200
11200
|
}
|
|
11201
|
-
const inheritedRaw =
|
|
11201
|
+
const inheritedRaw = readFileSync4(inheritedAbs, "utf-8");
|
|
11202
11202
|
const inheritedParsed = YAML.parse(inheritedRaw, { maxAliasCount: 100 });
|
|
11203
11203
|
if (inheritedParsed !== null && inheritedParsed !== void 0) {
|
|
11204
11204
|
if (typeof inheritedParsed !== "object" || Array.isArray(inheritedParsed)) {
|
|
@@ -11417,7 +11417,7 @@ var init_path = __esm({
|
|
|
11417
11417
|
import * as fs5 from "node:fs";
|
|
11418
11418
|
import * as os4 from "node:os";
|
|
11419
11419
|
import * as path7 from "node:path";
|
|
11420
|
-
import { parse as
|
|
11420
|
+
import { parse as parseYaml2, stringify as stringifyYaml } from "yaml";
|
|
11421
11421
|
function workspacesDir() {
|
|
11422
11422
|
const override = process.env["OLAM_WORKSPACES_DIR"];
|
|
11423
11423
|
if (override && override.length > 0)
|
|
@@ -11441,7 +11441,7 @@ function listWorkspaces() {
|
|
|
11441
11441
|
for (const entry of entries) {
|
|
11442
11442
|
try {
|
|
11443
11443
|
const raw = fs5.readFileSync(path7.join(dir, entry), "utf-8");
|
|
11444
|
-
const parsed =
|
|
11444
|
+
const parsed = parseYaml2(raw);
|
|
11445
11445
|
const ws = WorkspaceSchema.parse(parsed);
|
|
11446
11446
|
result.push(ws);
|
|
11447
11447
|
} catch (err) {
|
|
@@ -11466,7 +11466,7 @@ function readWorkspace(name) {
|
|
|
11466
11466
|
if (!fs5.existsSync(file2))
|
|
11467
11467
|
return null;
|
|
11468
11468
|
const raw = fs5.readFileSync(file2, "utf-8");
|
|
11469
|
-
return WorkspaceSchema.parse(
|
|
11469
|
+
return WorkspaceSchema.parse(parseYaml2(raw));
|
|
11470
11470
|
}
|
|
11471
11471
|
function writeWorkspace(ws, options = {}) {
|
|
11472
11472
|
validateName(ws.name);
|
|
@@ -12392,7 +12392,7 @@ __export(loader_exports, {
|
|
|
12392
12392
|
});
|
|
12393
12393
|
import * as fs8 from "node:fs";
|
|
12394
12394
|
import * as path9 from "node:path";
|
|
12395
|
-
import { parse as
|
|
12395
|
+
import { parse as parseYaml3 } from "yaml";
|
|
12396
12396
|
function findConfigFile(startDir) {
|
|
12397
12397
|
const searched = [];
|
|
12398
12398
|
let current = path9.resolve(startDir);
|
|
@@ -12432,7 +12432,7 @@ function loadConfig(startDir) {
|
|
|
12432
12432
|
}
|
|
12433
12433
|
let parsed;
|
|
12434
12434
|
try {
|
|
12435
|
-
parsed =
|
|
12435
|
+
parsed = parseYaml3(rawContent);
|
|
12436
12436
|
} catch (err) {
|
|
12437
12437
|
const message = err instanceof Error ? err.message : String(err);
|
|
12438
12438
|
throw new Error(`Invalid YAML in ${found.path}: ${message}`);
|
|
@@ -13387,7 +13387,7 @@ var init_cleanup = __esm({
|
|
|
13387
13387
|
|
|
13388
13388
|
// ../adapters/dist/ssh/connection.js
|
|
13389
13389
|
import { Client as SSHClient } from "ssh2";
|
|
13390
|
-
import { readFileSync as
|
|
13390
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
13391
13391
|
var SSHConnectionPool;
|
|
13392
13392
|
var init_connection = __esm({
|
|
13393
13393
|
"../adapters/dist/ssh/connection.js"() {
|
|
@@ -13482,7 +13482,7 @@ var init_connection = __esm({
|
|
|
13482
13482
|
host: config2.host,
|
|
13483
13483
|
port: config2.port ?? 22,
|
|
13484
13484
|
username: config2.user,
|
|
13485
|
-
...config2.key ? { privateKey:
|
|
13485
|
+
...config2.key ? { privateKey: readFileSync11(config2.key) } : {},
|
|
13486
13486
|
...config2.password ? { password: config2.password } : {}
|
|
13487
13487
|
});
|
|
13488
13488
|
});
|
|
@@ -16305,9 +16305,9 @@ var init_model_router = __esm({
|
|
|
16305
16305
|
});
|
|
16306
16306
|
|
|
16307
16307
|
// ../core/dist/meta-hooks/model-router-deploy.js
|
|
16308
|
-
import { existsSync as
|
|
16309
|
-
import { homedir as
|
|
16310
|
-
import { dirname as dirname13, join as
|
|
16308
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync16, readFileSync as readFileSync24, writeFileSync as writeFileSync15 } from "node:fs";
|
|
16309
|
+
import { homedir as homedir15 } from "node:os";
|
|
16310
|
+
import { dirname as dirname13, join as join31, resolve as resolve7 } from "node:path";
|
|
16311
16311
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
16312
16312
|
function resolveModelRouterSourcePath() {
|
|
16313
16313
|
const here = dirname13(fileURLToPath3(import.meta.url));
|
|
@@ -16321,21 +16321,21 @@ function resolveModelRouterSourcePath() {
|
|
|
16321
16321
|
resolve7(here, "..", "..", "hooks", MODEL_ROUTER_SCRIPT_BASENAME)
|
|
16322
16322
|
];
|
|
16323
16323
|
for (const candidate of candidates) {
|
|
16324
|
-
if (
|
|
16324
|
+
if (existsSync33(candidate))
|
|
16325
16325
|
return candidate;
|
|
16326
16326
|
}
|
|
16327
16327
|
return candidates[0];
|
|
16328
16328
|
}
|
|
16329
16329
|
function deployModelRouterScript(opts = {}) {
|
|
16330
|
-
const targetDir = opts.targetDir ??
|
|
16331
|
-
const targetPath =
|
|
16330
|
+
const targetDir = opts.targetDir ?? join31(homedir15(), ".claude", "hooks");
|
|
16331
|
+
const targetPath = join31(targetDir, MODEL_ROUTER_SCRIPT_BASENAME);
|
|
16332
16332
|
const sourcePath = opts.sourcePath ?? resolveModelRouterSourcePath();
|
|
16333
|
-
if (!
|
|
16333
|
+
if (!existsSync33(sourcePath)) {
|
|
16334
16334
|
return { basename: MODEL_ROUTER_SCRIPT_BASENAME, action: "source-missing", targetPath };
|
|
16335
16335
|
}
|
|
16336
|
-
const newContent =
|
|
16337
|
-
if (
|
|
16338
|
-
const existing =
|
|
16336
|
+
const newContent = readFileSync24(sourcePath, "utf8");
|
|
16337
|
+
if (existsSync33(targetPath)) {
|
|
16338
|
+
const existing = readFileSync24(targetPath, "utf8");
|
|
16339
16339
|
if (existing === newContent) {
|
|
16340
16340
|
return { basename: MODEL_ROUTER_SCRIPT_BASENAME, action: "unchanged", targetPath };
|
|
16341
16341
|
}
|
|
@@ -16613,7 +16613,7 @@ var init_schema5 = __esm({
|
|
|
16613
16613
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
16614
16614
|
import * as fs30 from "node:fs";
|
|
16615
16615
|
import * as path28 from "node:path";
|
|
16616
|
-
import { parse as
|
|
16616
|
+
import { parse as parseYaml4 } from "yaml";
|
|
16617
16617
|
function findProjectOverride(startDir) {
|
|
16618
16618
|
let dir = path28.resolve(startDir);
|
|
16619
16619
|
const root = path28.parse(dir).root;
|
|
@@ -16623,7 +16623,7 @@ function findProjectOverride(startDir) {
|
|
|
16623
16623
|
const raw = fs30.readFileSync(candidate, "utf-8");
|
|
16624
16624
|
let parsed;
|
|
16625
16625
|
try {
|
|
16626
|
-
parsed =
|
|
16626
|
+
parsed = parseYaml4(raw);
|
|
16627
16627
|
} catch (err) {
|
|
16628
16628
|
const msg = err instanceof Error ? err.message : String(err);
|
|
16629
16629
|
throw new Error(`failed to parse "${candidate}" as YAML: ${msg}`);
|
|
@@ -16854,13 +16854,13 @@ var init_file_lock = __esm({
|
|
|
16854
16854
|
});
|
|
16855
16855
|
|
|
16856
16856
|
// ../core/dist/lib/min-version-filter.js
|
|
16857
|
-
import { existsSync as
|
|
16857
|
+
import { existsSync as existsSync36, readFileSync as readFileSync28 } from "node:fs";
|
|
16858
16858
|
function readOlamMinVersion(filepath) {
|
|
16859
|
-
if (!
|
|
16859
|
+
if (!existsSync36(filepath))
|
|
16860
16860
|
return void 0;
|
|
16861
16861
|
let text;
|
|
16862
16862
|
try {
|
|
16863
|
-
text =
|
|
16863
|
+
text = readFileSync28(filepath, "utf8");
|
|
16864
16864
|
} catch {
|
|
16865
16865
|
return void 0;
|
|
16866
16866
|
}
|
|
@@ -17536,7 +17536,7 @@ var init_meta_hook_injector = __esm({
|
|
|
17536
17536
|
|
|
17537
17537
|
// ../core/dist/lib/markdown-merger.js
|
|
17538
17538
|
import { createHash as createHash5 } from "node:crypto";
|
|
17539
|
-
import { readFileSync as
|
|
17539
|
+
import { readFileSync as readFileSync32, existsSync as existsSync39, statSync as statSync10 } from "node:fs";
|
|
17540
17540
|
function parseFrontmatter(text) {
|
|
17541
17541
|
const match = FM_RE2.exec(text);
|
|
17542
17542
|
if (match === null)
|
|
@@ -17665,9 +17665,9 @@ function mergeMarkdown(upstreamText, overlayText, labelForError, upstreamPath, o
|
|
|
17665
17665
|
return { merged: fmBlock !== "" ? fmBlock + mergedBody : mergedBody };
|
|
17666
17666
|
}
|
|
17667
17667
|
function sha256OfPath(p) {
|
|
17668
|
-
if (!
|
|
17668
|
+
if (!existsSync39(p) || !statSync10(p).isFile())
|
|
17669
17669
|
return "MISSING";
|
|
17670
|
-
return createHash5("sha256").update(
|
|
17670
|
+
return createHash5("sha256").update(readFileSync32(p)).digest("hex");
|
|
17671
17671
|
}
|
|
17672
17672
|
var FM_RE2, H2_RE;
|
|
17673
17673
|
var init_markdown_merger = __esm({
|
|
@@ -17935,26 +17935,26 @@ var init_prefix_deploy = __esm({
|
|
|
17935
17935
|
});
|
|
17936
17936
|
|
|
17937
17937
|
// ../core/dist/skill-sync/resolve-source-config.js
|
|
17938
|
-
import { readFileSync as
|
|
17939
|
-
import { join as
|
|
17940
|
-
import { parse as
|
|
17938
|
+
import { readFileSync as readFileSync34, existsSync as existsSync40 } from "node:fs";
|
|
17939
|
+
import { join as join40 } from "node:path";
|
|
17940
|
+
import { parse as parseYaml5 } from "yaml";
|
|
17941
17941
|
function sourceConfigPath(clonePath) {
|
|
17942
|
-
return
|
|
17942
|
+
return join40(clonePath, "shared", "source-config.yaml");
|
|
17943
17943
|
}
|
|
17944
17944
|
function readSourceConfig(clonePath, sourceId) {
|
|
17945
17945
|
const path62 = sourceConfigPath(clonePath);
|
|
17946
|
-
if (!
|
|
17946
|
+
if (!existsSync40(path62))
|
|
17947
17947
|
return void 0;
|
|
17948
17948
|
let raw;
|
|
17949
17949
|
try {
|
|
17950
|
-
raw =
|
|
17950
|
+
raw = readFileSync34(path62, "utf-8");
|
|
17951
17951
|
} catch (err) {
|
|
17952
17952
|
emitMalformedWarning(sourceId, `read failed: ${errToMsg(err)}`);
|
|
17953
17953
|
return void 0;
|
|
17954
17954
|
}
|
|
17955
17955
|
let parsed;
|
|
17956
17956
|
try {
|
|
17957
|
-
parsed =
|
|
17957
|
+
parsed = parseYaml5(raw);
|
|
17958
17958
|
} catch (err) {
|
|
17959
17959
|
emitMalformedWarning(sourceId, `YAML parse failed: ${errToMsg(err)}`);
|
|
17960
17960
|
return void 0;
|
|
@@ -39602,6 +39602,68 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
39602
39602
|
}
|
|
39603
39603
|
};
|
|
39604
39604
|
|
|
39605
|
+
// ../mcp-server/src/cloud-visibility.ts
|
|
39606
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
39607
|
+
import { homedir } from "node:os";
|
|
39608
|
+
import { join } from "node:path";
|
|
39609
|
+
import { parse as parseYaml } from "yaml";
|
|
39610
|
+
var DEFAULT_MCP_MODE = "cloud";
|
|
39611
|
+
var SHOW_ALL_TOOLS_ENV = "OLAM_MCP_SHOW_ALL_TOOLS";
|
|
39612
|
+
var MCP_LOCAL_ONLY_TOOLS = /* @__PURE__ */ new Set([
|
|
39613
|
+
"olam_enter",
|
|
39614
|
+
// world-enter — literal `docker exec -it … tmux attach`
|
|
39615
|
+
"olam_observe",
|
|
39616
|
+
// world-observe — local better-sqlite3 world DB read
|
|
39617
|
+
"olam_web_task",
|
|
39618
|
+
// web-task — host venv `spawn(python -m webwright)`
|
|
39619
|
+
"olam_create_lane",
|
|
39620
|
+
// lane-create — in-container .exec curl (CF exec unsupported)
|
|
39621
|
+
"olam_list_lanes",
|
|
39622
|
+
// lane-list — in-container .exec curl
|
|
39623
|
+
"olam_dispatch_lane",
|
|
39624
|
+
// lane-dispatch — in-container .exec curl
|
|
39625
|
+
"olam_destroy_lane",
|
|
39626
|
+
// lane-destroy — in-container .exec curl
|
|
39627
|
+
"olam_merge_lane"
|
|
39628
|
+
// lane-merge — in-container .exec curl
|
|
39629
|
+
]);
|
|
39630
|
+
function resolveConfigPath() {
|
|
39631
|
+
const override = process.env["OLAM_CONFIG_PATH"];
|
|
39632
|
+
if (override && override.trim() !== "") return override;
|
|
39633
|
+
const home = join(homedir(), ".olam");
|
|
39634
|
+
const jsonPath = join(home, "config.json");
|
|
39635
|
+
const yamlPath = join(home, "config.yaml");
|
|
39636
|
+
if (existsSync(jsonPath)) return jsonPath;
|
|
39637
|
+
if (existsSync(yamlPath)) return yamlPath;
|
|
39638
|
+
return jsonPath;
|
|
39639
|
+
}
|
|
39640
|
+
function isYamlPath(p) {
|
|
39641
|
+
return p.endsWith(".yaml") || p.endsWith(".yml");
|
|
39642
|
+
}
|
|
39643
|
+
function readMcpMode(opts = {}) {
|
|
39644
|
+
try {
|
|
39645
|
+
const configPath = opts.configPath ?? resolveConfigPath();
|
|
39646
|
+
if (!existsSync(configPath)) return DEFAULT_MCP_MODE;
|
|
39647
|
+
const raw = readFileSync(configPath, "utf8");
|
|
39648
|
+
const parsed = isYamlPath(configPath) ? parseYaml(raw) : JSON.parse(raw);
|
|
39649
|
+
const mode = parsed?.host?.mode;
|
|
39650
|
+
return mode === "local" ? "local" : DEFAULT_MCP_MODE;
|
|
39651
|
+
} catch {
|
|
39652
|
+
return DEFAULT_MCP_MODE;
|
|
39653
|
+
}
|
|
39654
|
+
}
|
|
39655
|
+
function isCloudMode(opts = {}) {
|
|
39656
|
+
return readMcpMode(opts) === "cloud";
|
|
39657
|
+
}
|
|
39658
|
+
function showAllToolsForced() {
|
|
39659
|
+
return process.env[SHOW_ALL_TOOLS_ENV] === "1";
|
|
39660
|
+
}
|
|
39661
|
+
function resolveDeniedTools(opts = {}) {
|
|
39662
|
+
if (opts.showAll || showAllToolsForced()) return /* @__PURE__ */ new Set();
|
|
39663
|
+
if (!isCloudMode({ configPath: opts.configPath })) return /* @__PURE__ */ new Set();
|
|
39664
|
+
return MCP_LOCAL_ONLY_TOOLS;
|
|
39665
|
+
}
|
|
39666
|
+
|
|
39605
39667
|
// ../mcp-server/src/tool-filter.ts
|
|
39606
39668
|
function getToolFilterContextFromEnv() {
|
|
39607
39669
|
const raw = process.env.OLAM_ALLOWED_TOOLS;
|
|
@@ -39616,20 +39678,29 @@ function getToolFilterContextFromEnv() {
|
|
|
39616
39678
|
context.allowedTools = allowedTools;
|
|
39617
39679
|
}
|
|
39618
39680
|
}
|
|
39681
|
+
const denied = resolveDeniedTools();
|
|
39682
|
+
if (denied.size > 0) {
|
|
39683
|
+
context.deniedTools = denied;
|
|
39684
|
+
}
|
|
39619
39685
|
return context;
|
|
39620
39686
|
}
|
|
39621
39687
|
function withFilteredTools(server, context) {
|
|
39622
39688
|
const allowed = context.allowedTools;
|
|
39623
|
-
|
|
39689
|
+
const denied = context.deniedTools;
|
|
39690
|
+
const hasAllow = !!allowed && allowed.length > 0;
|
|
39691
|
+
const hasDeny = !!denied && denied.size > 0;
|
|
39692
|
+
if (!hasAllow && !hasDeny) {
|
|
39624
39693
|
return { server, finalize: () => {
|
|
39625
39694
|
} };
|
|
39626
39695
|
}
|
|
39627
|
-
const allowedSet = new Set(allowed);
|
|
39696
|
+
const allowedSet = hasAllow ? new Set(allowed) : null;
|
|
39628
39697
|
const registered = /* @__PURE__ */ new Set();
|
|
39629
39698
|
const host = server;
|
|
39630
39699
|
const original = host.tool;
|
|
39631
39700
|
const filtered = function(name, ...rest) {
|
|
39632
|
-
|
|
39701
|
+
const passesAllow = typeof name === "string" && (!allowedSet || allowedSet.has(name));
|
|
39702
|
+
const passesDeny = !hasDeny || !denied.has(name);
|
|
39703
|
+
if (passesAllow && passesDeny) {
|
|
39633
39704
|
registered.add(name);
|
|
39634
39705
|
return original.apply(
|
|
39635
39706
|
server,
|
|
@@ -39643,12 +39714,14 @@ function withFilteredTools(server, context) {
|
|
|
39643
39714
|
server,
|
|
39644
39715
|
finalize: () => {
|
|
39645
39716
|
host.tool = original;
|
|
39646
|
-
|
|
39647
|
-
|
|
39648
|
-
|
|
39649
|
-
|
|
39717
|
+
if (allowedSet) {
|
|
39718
|
+
for (const name of allowedSet) {
|
|
39719
|
+
if (!registered.has(name) && !(hasDeny && denied.has(name))) {
|
|
39720
|
+
process.stderr.write(
|
|
39721
|
+
`[tool-filter] warning: unknown tool name in OLAM_ALLOWED_TOOLS: "${name}"
|
|
39650
39722
|
`
|
|
39651
|
-
|
|
39723
|
+
);
|
|
39724
|
+
}
|
|
39652
39725
|
}
|
|
39653
39726
|
}
|
|
39654
39727
|
}
|
|
@@ -40171,7 +40244,7 @@ function sleep(ms) {
|
|
|
40171
40244
|
|
|
40172
40245
|
// ../core/dist/auth/container.js
|
|
40173
40246
|
import { execFileSync, spawnSync } from "node:child_process";
|
|
40174
|
-
import { chmodSync as chmodSync3, existsSync as
|
|
40247
|
+
import { chmodSync as chmodSync3, existsSync as existsSync5, mkdtempSync, rmSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
40175
40248
|
import { tmpdir } from "node:os";
|
|
40176
40249
|
import * as path4 from "node:path";
|
|
40177
40250
|
import { fileURLToPath } from "node:url";
|
|
@@ -40240,7 +40313,7 @@ var AuthContainerController = class {
|
|
|
40240
40313
|
*/
|
|
40241
40314
|
buildImage() {
|
|
40242
40315
|
const dockerfileDir = resolveAuthServicePath();
|
|
40243
|
-
if (!
|
|
40316
|
+
if (!existsSync5(path4.join(dockerfileDir, "Dockerfile"))) {
|
|
40244
40317
|
throw new Error(`auth image '${this.imageTag}' is not present locally and no Dockerfile is available at ${dockerfileDir} to build from. Run \`olam bootstrap\` to pull the published image, or check out the olam source tree.`);
|
|
40245
40318
|
}
|
|
40246
40319
|
execFileSync("docker", ["build", "--tag", this.imageTag, dockerfileDir], { stdio: "inherit" });
|
|
@@ -41390,12 +41463,12 @@ var logger = {
|
|
|
41390
41463
|
// ../mcp-server/src/utils/profile-sync.ts
|
|
41391
41464
|
import { execFile } from "node:child_process";
|
|
41392
41465
|
import { promisify } from "node:util";
|
|
41393
|
-
import { readFileSync as
|
|
41394
|
-
import { homedir as
|
|
41395
|
-
import { join as
|
|
41466
|
+
import { readFileSync as readFileSync6, existsSync as existsSync8, statSync } from "node:fs";
|
|
41467
|
+
import { homedir as homedir6 } from "node:os";
|
|
41468
|
+
import { join as join10 } from "node:path";
|
|
41396
41469
|
var execFileP = promisify(execFile);
|
|
41397
41470
|
async function tarSkillsDir(skillsDir) {
|
|
41398
|
-
if (!
|
|
41471
|
+
if (!existsSync8(skillsDir) || !statSync(skillsDir).isDirectory()) {
|
|
41399
41472
|
return null;
|
|
41400
41473
|
}
|
|
41401
41474
|
const { stdout } = await execFileP(
|
|
@@ -41406,12 +41479,12 @@ async function tarSkillsDir(skillsDir) {
|
|
|
41406
41479
|
return stdout;
|
|
41407
41480
|
}
|
|
41408
41481
|
function extractMcpConfig(claudeJsonPath) {
|
|
41409
|
-
if (!
|
|
41482
|
+
if (!existsSync8(claudeJsonPath)) {
|
|
41410
41483
|
return { mcpServers: {}, secrets: {} };
|
|
41411
41484
|
}
|
|
41412
41485
|
let parsed;
|
|
41413
41486
|
try {
|
|
41414
|
-
const raw =
|
|
41487
|
+
const raw = readFileSync6(claudeJsonPath, "utf8");
|
|
41415
41488
|
parsed = JSON.parse(raw);
|
|
41416
41489
|
} catch (err) {
|
|
41417
41490
|
logger.warn("Failed to parse ~/.claude.json", {
|
|
@@ -41449,19 +41522,19 @@ function extractMcpConfig(claudeJsonPath) {
|
|
|
41449
41522
|
return { mcpServers, secrets };
|
|
41450
41523
|
}
|
|
41451
41524
|
function readOptional(path62) {
|
|
41452
|
-
if (!
|
|
41525
|
+
if (!existsSync8(path62)) return null;
|
|
41453
41526
|
try {
|
|
41454
|
-
return
|
|
41527
|
+
return readFileSync6(path62, "utf8");
|
|
41455
41528
|
} catch {
|
|
41456
41529
|
return null;
|
|
41457
41530
|
}
|
|
41458
41531
|
}
|
|
41459
41532
|
async function syncProfileToCloudflare(opts) {
|
|
41460
|
-
const home = opts.homeDir ??
|
|
41461
|
-
const skillsDir =
|
|
41462
|
-
const claudeJsonPath =
|
|
41463
|
-
const claudeMdPath =
|
|
41464
|
-
const agentsMdPath =
|
|
41533
|
+
const home = opts.homeDir ?? homedir6();
|
|
41534
|
+
const skillsDir = join10(home, ".claude", "skills");
|
|
41535
|
+
const claudeJsonPath = join10(home, ".claude.json");
|
|
41536
|
+
const claudeMdPath = join10(home, ".claude", "CLAUDE.md");
|
|
41537
|
+
const agentsMdPath = join10(home, ".claude", "AGENTS.md");
|
|
41465
41538
|
const form = new FormData();
|
|
41466
41539
|
const skillsBuf = await tarSkillsDir(skillsDir);
|
|
41467
41540
|
if (skillsBuf) {
|
|
@@ -43618,7 +43691,7 @@ __export(world_observe_exports, {
|
|
|
43618
43691
|
register: () => register9
|
|
43619
43692
|
});
|
|
43620
43693
|
import { createRequire as createRequire3 } from "node:module";
|
|
43621
|
-
import { existsSync as
|
|
43694
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
43622
43695
|
|
|
43623
43696
|
// ../skill-runtime/dist/skills/world-observe.js
|
|
43624
43697
|
init_v3();
|
|
@@ -43669,7 +43742,7 @@ function readWorldChunks(dbPath, params) {
|
|
|
43669
43742
|
limit
|
|
43670
43743
|
}
|
|
43671
43744
|
});
|
|
43672
|
-
if (!
|
|
43745
|
+
if (!existsSync13(dbPath)) return empty();
|
|
43673
43746
|
const Sqlite = require2("better-sqlite3");
|
|
43674
43747
|
const db = new Sqlite(dbPath, { readonly: true, fileMustExist: true });
|
|
43675
43748
|
try {
|
|
@@ -44582,12 +44655,12 @@ __export(capture_view_exports, {
|
|
|
44582
44655
|
});
|
|
44583
44656
|
init_v3();
|
|
44584
44657
|
import { mkdir } from "node:fs/promises";
|
|
44585
|
-
import { join as
|
|
44658
|
+
import { join as join17, resolve as resolvePath } from "node:path";
|
|
44586
44659
|
|
|
44587
44660
|
// ../mcp-server/src/tools/_capture/manifest.ts
|
|
44588
44661
|
import { createHash as createHash3 } from "node:crypto";
|
|
44589
44662
|
import { readFile, writeFile } from "node:fs/promises";
|
|
44590
|
-
import { basename as basename2, join as
|
|
44663
|
+
import { basename as basename2, join as join16 } from "node:path";
|
|
44591
44664
|
function redactUrl(url3) {
|
|
44592
44665
|
if (url3.startsWith("world://")) return url3;
|
|
44593
44666
|
let parsed;
|
|
@@ -44630,7 +44703,7 @@ async function writeManifest(args) {
|
|
|
44630
44703
|
capturedAt: args.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
44631
44704
|
shots: entries
|
|
44632
44705
|
};
|
|
44633
|
-
const path62 =
|
|
44706
|
+
const path62 = join16(args.outDir, "manifest.json");
|
|
44634
44707
|
await writeFile(path62, `${JSON.stringify(manifest, null, 2)}
|
|
44635
44708
|
`, "utf8");
|
|
44636
44709
|
return { path: path62, manifest };
|
|
@@ -45428,7 +45501,7 @@ function releaseLaunchSlot() {
|
|
|
45428
45501
|
function resolveShootsRoot() {
|
|
45429
45502
|
const fromEnv = process.env.OLAM_SHOOTS_ROOT;
|
|
45430
45503
|
if (fromEnv && fromEnv.length > 0) return resolvePath(fromEnv);
|
|
45431
|
-
return resolvePath(
|
|
45504
|
+
return resolvePath(join17(process.cwd(), ".olam", "shoots"));
|
|
45432
45505
|
}
|
|
45433
45506
|
function isUnderRoot(absPath, root) {
|
|
45434
45507
|
if (absPath === root) return true;
|
|
@@ -45729,7 +45802,7 @@ async function runShot(browser, shot, outDir, format, jpegQuality, allowEval, as
|
|
|
45729
45802
|
await page.waitForTimeout(shot.afterLoadMs);
|
|
45730
45803
|
}
|
|
45731
45804
|
const ext = format === "jpeg" ? "jpg" : "png";
|
|
45732
|
-
const path62 =
|
|
45805
|
+
const path62 = join17(outDir, `${shot.name}.${ext}`);
|
|
45733
45806
|
await page.screenshot({
|
|
45734
45807
|
path: path62,
|
|
45735
45808
|
type: format,
|
|
@@ -46041,20 +46114,20 @@ var webTaskShape = external_exports2.object(webTaskInput);
|
|
|
46041
46114
|
|
|
46042
46115
|
// ../mcp-server/src/tools/_web_task/provision.ts
|
|
46043
46116
|
import { spawn as spawn3 } from "node:child_process";
|
|
46044
|
-
import { existsSync as
|
|
46045
|
-
import { homedir as
|
|
46046
|
-
import { join as
|
|
46117
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
46118
|
+
import { homedir as homedir10 } from "node:os";
|
|
46119
|
+
import { join as join18 } from "node:path";
|
|
46047
46120
|
var WEBWRIGHT_SETUP_COMMAND = "olam webwright setup";
|
|
46048
46121
|
function resolveVenvPath(cfg) {
|
|
46049
46122
|
if (cfg?.venvPath && cfg.venvPath.length > 0) return cfg.venvPath;
|
|
46050
|
-
return
|
|
46123
|
+
return join18(homedir10(), ".olam", "venvs", "webwright");
|
|
46051
46124
|
}
|
|
46052
46125
|
function resolveConfigDir(cfg) {
|
|
46053
46126
|
if (cfg?.configDir && cfg.configDir.length > 0) {
|
|
46054
|
-
return
|
|
46127
|
+
return existsSync15(cfg.configDir) ? cfg.configDir : null;
|
|
46055
46128
|
}
|
|
46056
|
-
const candidate =
|
|
46057
|
-
|
|
46129
|
+
const candidate = join18(
|
|
46130
|
+
homedir10(),
|
|
46058
46131
|
".claude",
|
|
46059
46132
|
"plugins",
|
|
46060
46133
|
"marketplaces",
|
|
@@ -46063,7 +46136,7 @@ function resolveConfigDir(cfg) {
|
|
|
46063
46136
|
"webwright",
|
|
46064
46137
|
"config"
|
|
46065
46138
|
);
|
|
46066
|
-
return
|
|
46139
|
+
return existsSync15(candidate) ? candidate : null;
|
|
46067
46140
|
}
|
|
46068
46141
|
function isWebwrightEnabled(cfg) {
|
|
46069
46142
|
const env = process.env.OLAM_WEBWRIGHT_ENABLED;
|
|
@@ -46071,10 +46144,10 @@ function isWebwrightEnabled(cfg) {
|
|
|
46071
46144
|
return cfg?.enabled === true;
|
|
46072
46145
|
}
|
|
46073
46146
|
function venvPython(venvPath) {
|
|
46074
|
-
const posix =
|
|
46075
|
-
if (
|
|
46076
|
-
const win =
|
|
46077
|
-
if (
|
|
46147
|
+
const posix = join18(venvPath, "bin", "python");
|
|
46148
|
+
if (existsSync15(posix)) return posix;
|
|
46149
|
+
const win = join18(venvPath, "Scripts", "python.exe");
|
|
46150
|
+
if (existsSync15(win)) return win;
|
|
46078
46151
|
return null;
|
|
46079
46152
|
}
|
|
46080
46153
|
async function probeWebwrightImportable(pythonPath, opts = {}) {
|
|
@@ -46120,7 +46193,7 @@ async function checkWebwrightProvisioned(cfg, probe = probeWebwrightImportable)
|
|
|
46120
46193
|
};
|
|
46121
46194
|
}
|
|
46122
46195
|
const venvPath = resolveVenvPath(cfg);
|
|
46123
|
-
if (!
|
|
46196
|
+
if (!existsSync15(venvPath)) {
|
|
46124
46197
|
return {
|
|
46125
46198
|
ok: false,
|
|
46126
46199
|
reason: "venv_missing",
|
|
@@ -46157,14 +46230,14 @@ async function checkWebwrightProvisioned(cfg, probe = probeWebwrightImportable)
|
|
|
46157
46230
|
// ../mcp-server/src/tools/_web_task/spawn-executor.ts
|
|
46158
46231
|
import { spawn as spawn4 } from "node:child_process";
|
|
46159
46232
|
import { mkdir as mkdir2, mkdtemp, readFile as readFile3, readdir, rm, writeFile as writeFile2 } from "node:fs/promises";
|
|
46160
|
-
import { existsSync as
|
|
46233
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
46161
46234
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
46162
|
-
import { join as
|
|
46235
|
+
import { join as join20, resolve as resolvePath2 } from "node:path";
|
|
46163
46236
|
|
|
46164
46237
|
// ../mcp-server/src/tools/_web_task/model-config.ts
|
|
46165
46238
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
46166
|
-
import { homedir as
|
|
46167
|
-
import { join as
|
|
46239
|
+
import { homedir as homedir11 } from "node:os";
|
|
46240
|
+
import { join as join19 } from "node:path";
|
|
46168
46241
|
var PLACEHOLDER_ANTHROPIC_API_KEY = "olam-vault-routed-placeholder-stripped-by-proxy";
|
|
46169
46242
|
var DEFAULT_WEB_TASK_MODEL = "claude-opus-4-7";
|
|
46170
46243
|
var AnthropicBaseUrlMissingError = class extends Error {
|
|
@@ -46179,7 +46252,7 @@ async function resolveVaultBaseUrl(opts = {}) {
|
|
|
46179
46252
|
const env = opts.env ?? process.env;
|
|
46180
46253
|
const fromEnv = env.OLAM_ANTHROPIC_BASE_URL;
|
|
46181
46254
|
if (fromEnv && fromEnv.trim().length > 0) return fromEnv.trim();
|
|
46182
|
-
const file2 = opts.baseUrlFile ??
|
|
46255
|
+
const file2 = opts.baseUrlFile ?? join19(homedir11(), ".olam", "anthropic-base-url");
|
|
46183
46256
|
let raw;
|
|
46184
46257
|
try {
|
|
46185
46258
|
raw = await readFile2(file2, "utf-8");
|
|
@@ -46229,7 +46302,7 @@ var WebTaskSpawnError = class extends Error {
|
|
|
46229
46302
|
function resolveWebTaskRoot() {
|
|
46230
46303
|
const fromEnv = process.env.OLAM_WEB_TASK_ROOT;
|
|
46231
46304
|
if (fromEnv && fromEnv.length > 0) return resolvePath2(fromEnv);
|
|
46232
|
-
return resolvePath2(
|
|
46305
|
+
return resolvePath2(join20(process.cwd(), ".olam", "web-tasks"));
|
|
46233
46306
|
}
|
|
46234
46307
|
function isUnderRoot2(absPath, root) {
|
|
46235
46308
|
if (absPath === root) return true;
|
|
@@ -46292,7 +46365,7 @@ async function runWebwright(pythonPath, args, spawnEnv, timeoutMs, deps) {
|
|
|
46292
46365
|
});
|
|
46293
46366
|
}
|
|
46294
46367
|
async function locateRunDir(outDir) {
|
|
46295
|
-
if (
|
|
46368
|
+
if (existsSync16(join20(outDir, "trajectory.json"))) return outDir;
|
|
46296
46369
|
let entries = [];
|
|
46297
46370
|
try {
|
|
46298
46371
|
entries = await readdir(outDir);
|
|
@@ -46301,8 +46374,8 @@ async function locateRunDir(outDir) {
|
|
|
46301
46374
|
}
|
|
46302
46375
|
const candidates = [];
|
|
46303
46376
|
for (const name of entries) {
|
|
46304
|
-
const sub =
|
|
46305
|
-
if (
|
|
46377
|
+
const sub = join20(outDir, name);
|
|
46378
|
+
if (existsSync16(join20(sub, "trajectory.json"))) candidates.push({ dir: sub });
|
|
46306
46379
|
}
|
|
46307
46380
|
if (candidates.length === 0) return outDir;
|
|
46308
46381
|
candidates.sort((a, b) => a.dir < b.dir ? 1 : -1);
|
|
@@ -46315,14 +46388,14 @@ async function collectScreenshots(runDir) {
|
|
|
46315
46388
|
} catch {
|
|
46316
46389
|
return [];
|
|
46317
46390
|
}
|
|
46318
|
-
const shots = entries.filter((n) => /\.(png|jpe?g)$/i.test(n)).sort().map((n, i) => ({ step: i, path:
|
|
46391
|
+
const shots = entries.filter((n) => /\.(png|jpe?g)$/i.test(n)).sort().map((n, i) => ({ step: i, path: join20(runDir, n) }));
|
|
46319
46392
|
return shots;
|
|
46320
46393
|
}
|
|
46321
46394
|
async function readTrajectoryFacts(runDir, stdoutTail) {
|
|
46322
46395
|
let answer = null;
|
|
46323
46396
|
let modelCalls = null;
|
|
46324
46397
|
try {
|
|
46325
|
-
const raw = await readFile3(
|
|
46398
|
+
const raw = await readFile3(join20(runDir, "trajectory.json"), "utf-8");
|
|
46326
46399
|
const parsed = JSON.parse(raw);
|
|
46327
46400
|
answer = extractFinalAnswer(parsed);
|
|
46328
46401
|
modelCalls = extractModelCalls(parsed);
|
|
@@ -46455,11 +46528,11 @@ async function runSpawnExecutor(spec, ctx, provision, deps = { spawn: spawn4 })
|
|
|
46455
46528
|
} catch (err) {
|
|
46456
46529
|
throw new WebTaskSpawnError("vault_base_url_missing", err.message);
|
|
46457
46530
|
}
|
|
46458
|
-
const tmpDirRoot = await mkdtemp(
|
|
46459
|
-
const modelYamlPath =
|
|
46531
|
+
const tmpDirRoot = await mkdtemp(join20(tmpdir2(), "olam-web-task-"));
|
|
46532
|
+
const modelYamlPath = join20(tmpDirRoot, "model_olam.yaml");
|
|
46460
46533
|
await writeFile2(modelYamlPath, modelYaml.yaml, "utf-8");
|
|
46461
46534
|
try {
|
|
46462
|
-
const baseYaml =
|
|
46535
|
+
const baseYaml = join20(provision.configDir, "base.yaml");
|
|
46463
46536
|
const args = [
|
|
46464
46537
|
"-m",
|
|
46465
46538
|
"webwright.run.cli",
|
|
@@ -46513,10 +46586,10 @@ ${tail}` : ""}`
|
|
|
46513
46586
|
);
|
|
46514
46587
|
}
|
|
46515
46588
|
const runDir = await locateRunDir(absOutDir);
|
|
46516
|
-
const trajectoryPath =
|
|
46589
|
+
const trajectoryPath = join20(runDir, "trajectory.json");
|
|
46517
46590
|
const screenshots = await collectScreenshots(runDir);
|
|
46518
46591
|
const facts = await readTrajectoryFacts(runDir, outcome.stdout);
|
|
46519
|
-
const scriptPath =
|
|
46592
|
+
const scriptPath = existsSync16(join20(runDir, "final_script.py")) ? join20(runDir, "final_script.py") : void 0;
|
|
46520
46593
|
return {
|
|
46521
46594
|
result: facts.answer,
|
|
46522
46595
|
trajectoryPath,
|
|
@@ -50238,8 +50311,14 @@ var toolModules = [
|
|
|
50238
50311
|
memory_reinforce_exports,
|
|
50239
50312
|
cloud_dispatch_exports
|
|
50240
50313
|
];
|
|
50241
|
-
function registerAllTools(server, ctx, initError) {
|
|
50314
|
+
function registerAllTools(server, ctx, initError, options = {}) {
|
|
50242
50315
|
const filterContext = getToolFilterContextFromEnv();
|
|
50316
|
+
if (options.showAll) {
|
|
50317
|
+
delete filterContext.deniedTools;
|
|
50318
|
+
} else {
|
|
50319
|
+
const denied = resolveDeniedTools();
|
|
50320
|
+
if (denied.size > 0) filterContext.deniedTools = denied;
|
|
50321
|
+
}
|
|
50243
50322
|
const { server: filtered, finalize: finalize2 } = withFilteredTools(server, filterContext);
|
|
50244
50323
|
try {
|
|
50245
50324
|
for (const mod of toolModules) {
|
|
@@ -50596,7 +50675,8 @@ function describeParam(schema) {
|
|
|
50596
50675
|
constrained: isConstrained(base)
|
|
50597
50676
|
};
|
|
50598
50677
|
}
|
|
50599
|
-
function extractToolCatalog() {
|
|
50678
|
+
function extractToolCatalog(opts = {}) {
|
|
50679
|
+
const showAll = opts.showAll ?? true;
|
|
50600
50680
|
const captured = [];
|
|
50601
50681
|
const recordingServer = {
|
|
50602
50682
|
tool(name, description, inputSchema, _handler) {
|
|
@@ -50609,7 +50689,12 @@ function extractToolCatalog() {
|
|
|
50609
50689
|
captured.push({ name, description: description ?? "", params });
|
|
50610
50690
|
}
|
|
50611
50691
|
};
|
|
50612
|
-
registerAllTools(
|
|
50692
|
+
registerAllTools(
|
|
50693
|
+
recordingServer,
|
|
50694
|
+
void 0,
|
|
50695
|
+
void 0,
|
|
50696
|
+
{ showAll }
|
|
50697
|
+
);
|
|
50613
50698
|
return [...captured].sort((a, b) => a.name.localeCompare(b.name));
|
|
50614
50699
|
}
|
|
50615
50700
|
|
|
@@ -50637,7 +50722,7 @@ function buildToolsCatalogPayload(catalog) {
|
|
|
50637
50722
|
};
|
|
50638
50723
|
}
|
|
50639
50724
|
function createToolsCatalogResource(deps = {}) {
|
|
50640
|
-
const extract = deps.extract ?? extractToolCatalog;
|
|
50725
|
+
const extract = deps.extract ?? (() => extractToolCatalog({ showAll: false }));
|
|
50641
50726
|
let cachedPayload = null;
|
|
50642
50727
|
return {
|
|
50643
50728
|
name: "olam-tools",
|
|
@@ -52269,8 +52354,8 @@ import * as fs51 from "node:fs";
|
|
|
52269
52354
|
import * as path50 from "node:path";
|
|
52270
52355
|
|
|
52271
52356
|
// ../core/dist/kg/storage-paths.js
|
|
52272
|
-
import { homedir as
|
|
52273
|
-
import { join as
|
|
52357
|
+
import { homedir as homedir27 } from "node:os";
|
|
52358
|
+
import { join as join54, resolve as resolve11 } from "node:path";
|
|
52274
52359
|
|
|
52275
52360
|
// ../core/dist/world/workspace-name.js
|
|
52276
52361
|
var InvalidWorkspaceNameError = class extends Error {
|
|
@@ -52291,13 +52376,13 @@ function validateWorkspaceName(name) {
|
|
|
52291
52376
|
|
|
52292
52377
|
// ../core/dist/kg/storage-paths.js
|
|
52293
52378
|
function olamHome3() {
|
|
52294
|
-
return process.env.OLAM_HOME ??
|
|
52379
|
+
return process.env.OLAM_HOME ?? join54(homedir27(), ".olam");
|
|
52295
52380
|
}
|
|
52296
52381
|
function kgRoot() {
|
|
52297
|
-
return
|
|
52382
|
+
return join54(olamHome3(), "kg");
|
|
52298
52383
|
}
|
|
52299
52384
|
function worldsRoot() {
|
|
52300
|
-
return
|
|
52385
|
+
return join54(olamHome3(), "worlds");
|
|
52301
52386
|
}
|
|
52302
52387
|
function assertWithinPrefix(path62, prefix, label) {
|
|
52303
52388
|
if (!path62.startsWith(prefix + "/")) {
|
|
@@ -52307,7 +52392,7 @@ function assertWithinPrefix(path62, prefix, label) {
|
|
|
52307
52392
|
function kgPristinePath(workspace) {
|
|
52308
52393
|
validateWorkspaceName(workspace);
|
|
52309
52394
|
const root = kgRoot();
|
|
52310
|
-
const path62 = resolve11(
|
|
52395
|
+
const path62 = resolve11(join54(root, workspace));
|
|
52311
52396
|
assertWithinPrefix(path62, root, "kgPristinePath");
|
|
52312
52397
|
return path62;
|
|
52313
52398
|
}
|
|
@@ -52408,8 +52493,8 @@ import * as fs52 from "node:fs";
|
|
|
52408
52493
|
import * as os26 from "node:os";
|
|
52409
52494
|
import * as path51 from "node:path";
|
|
52410
52495
|
var DEFAULT_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
|
|
52411
|
-
function expandHome2(p,
|
|
52412
|
-
return p.replace(/^~(?=$|\/|\\)/,
|
|
52496
|
+
function expandHome2(p, homedir34) {
|
|
52497
|
+
return p.replace(/^~(?=$|\/|\\)/, homedir34());
|
|
52413
52498
|
}
|
|
52414
52499
|
function sanitizeRepoFilename(name) {
|
|
52415
52500
|
const sanitized = name.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
@@ -52432,7 +52517,7 @@ ${stderr}`;
|
|
|
52432
52517
|
}
|
|
52433
52518
|
function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
52434
52519
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync7(cmd, args, opts));
|
|
52435
|
-
const
|
|
52520
|
+
const homedir34 = deps.homedir ?? (() => os26.homedir());
|
|
52436
52521
|
const baselineDir = path51.join(workspacePath, ".olam", "baseline");
|
|
52437
52522
|
try {
|
|
52438
52523
|
fs52.mkdirSync(baselineDir, { recursive: true });
|
|
@@ -52448,7 +52533,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
52448
52533
|
continue;
|
|
52449
52534
|
const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
|
|
52450
52535
|
const outPath = path51.join(baselineDir, filename);
|
|
52451
|
-
const repoPath = expandHome2(repo.path,
|
|
52536
|
+
const repoPath = expandHome2(repo.path, homedir34);
|
|
52452
52537
|
if (!fs52.existsSync(repoPath)) {
|
|
52453
52538
|
writeBaselineFile(outPath, `# repo: ${repo.name}
|
|
52454
52539
|
# (skipped: path ${repoPath} does not exist)
|
|
@@ -52584,8 +52669,8 @@ function extractStderr(err) {
|
|
|
52584
52669
|
}
|
|
52585
52670
|
function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
52586
52671
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync7(cmd, args, opts));
|
|
52587
|
-
const
|
|
52588
|
-
const
|
|
52672
|
+
const homedir34 = deps.homedir ?? (() => os26.homedir());
|
|
52673
|
+
const existsSync62 = deps.existsSync ?? ((p) => fs52.existsSync(p));
|
|
52589
52674
|
const copyFileSync10 = deps.copyFileSync ?? ((src, dest) => fs52.copyFileSync(src, dest));
|
|
52590
52675
|
const mkdirSync34 = deps.mkdirSync ?? ((dirPath, opts) => {
|
|
52591
52676
|
fs52.mkdirSync(dirPath, opts);
|
|
@@ -52594,11 +52679,11 @@ function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
|
52594
52679
|
for (const repo of repos) {
|
|
52595
52680
|
if (!repo.path)
|
|
52596
52681
|
continue;
|
|
52597
|
-
const repoPath = expandHome2(repo.path,
|
|
52682
|
+
const repoPath = expandHome2(repo.path, homedir34);
|
|
52598
52683
|
const worktreePath = path51.join(workspacePath, repo.name);
|
|
52599
|
-
if (!
|
|
52684
|
+
if (!existsSync62(repoPath))
|
|
52600
52685
|
continue;
|
|
52601
|
-
if (!
|
|
52686
|
+
if (!existsSync62(worktreePath)) {
|
|
52602
52687
|
console.warn(`[carry] ${repo.name}: world worktree ${worktreePath} missing; skipping carry for this repo`);
|
|
52603
52688
|
continue;
|
|
52604
52689
|
}
|
|
@@ -52658,7 +52743,7 @@ function carryUncommittedEdits(repos, workspacePath, deps = {}) {
|
|
|
52658
52743
|
for (const rel of plan.diff.untracked) {
|
|
52659
52744
|
const src = path51.join(plan.repoPath, rel);
|
|
52660
52745
|
const dest = path51.join(plan.worktreePath, rel);
|
|
52661
|
-
if (!
|
|
52746
|
+
if (!existsSync62(src))
|
|
52662
52747
|
continue;
|
|
52663
52748
|
try {
|
|
52664
52749
|
mkdirSync34(path51.dirname(dest), { recursive: true });
|
|
@@ -53917,14 +54002,14 @@ function enrichReposWithManifests(repos, workspacePath) {
|
|
|
53917
54002
|
// ../core/dist/policies/loader.js
|
|
53918
54003
|
import * as fs55 from "node:fs";
|
|
53919
54004
|
import * as path55 from "node:path";
|
|
53920
|
-
import { parse as
|
|
54005
|
+
import { parse as parseYaml6 } from "yaml";
|
|
53921
54006
|
function parseFrontmatter2(content) {
|
|
53922
54007
|
const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/m.exec(content);
|
|
53923
54008
|
if (!match)
|
|
53924
54009
|
return null;
|
|
53925
54010
|
const [, yamlText = "", body = ""] = match;
|
|
53926
54011
|
try {
|
|
53927
|
-
const frontmatter =
|
|
54012
|
+
const frontmatter = parseYaml6(yamlText);
|
|
53928
54013
|
return { frontmatter, body };
|
|
53929
54014
|
} catch {
|
|
53930
54015
|
return null;
|
|
@@ -57385,8 +57470,8 @@ var PleriClient = class {
|
|
|
57385
57470
|
};
|
|
57386
57471
|
|
|
57387
57472
|
// ../mcp-server/src/env-loader.ts
|
|
57388
|
-
import { readFileSync as
|
|
57389
|
-
import { join as
|
|
57473
|
+
import { readFileSync as readFileSync48, existsSync as existsSync61, statSync as statSync16 } from "node:fs";
|
|
57474
|
+
import { join as join66, dirname as dirname31, resolve as resolve15 } from "node:path";
|
|
57390
57475
|
var PROJECT_MARKERS = [
|
|
57391
57476
|
".olam/config.yaml",
|
|
57392
57477
|
".olam/config.yml",
|
|
@@ -57398,12 +57483,12 @@ function findProjectRoot2(startDir) {
|
|
|
57398
57483
|
const root = resolve15("/");
|
|
57399
57484
|
while (true) {
|
|
57400
57485
|
for (const marker of PROJECT_MARKERS) {
|
|
57401
|
-
if (
|
|
57486
|
+
if (existsSync61(join66(dir, marker))) return dir;
|
|
57402
57487
|
}
|
|
57403
|
-
const pkg =
|
|
57404
|
-
if (
|
|
57488
|
+
const pkg = join66(dir, "package.json");
|
|
57489
|
+
if (existsSync61(pkg)) {
|
|
57405
57490
|
try {
|
|
57406
|
-
const json2 = JSON.parse(
|
|
57491
|
+
const json2 = JSON.parse(readFileSync48(pkg, "utf8"));
|
|
57407
57492
|
const isOlamWorkspace = typeof json2.name === "string" && json2.name.startsWith("@olam/");
|
|
57408
57493
|
const hasOlamDep = json2.dependencies && Object.keys(json2.dependencies).some((k) => k.startsWith("@olam/")) || json2.devDependencies && Object.keys(json2.devDependencies).some((k) => k.startsWith("@olam/"));
|
|
57409
57494
|
if (isOlamWorkspace || hasOlamDep) return dir;
|
|
@@ -57417,7 +57502,7 @@ function findProjectRoot2(startDir) {
|
|
|
57417
57502
|
}
|
|
57418
57503
|
function parseEnvFile(path62) {
|
|
57419
57504
|
const out = {};
|
|
57420
|
-
const raw =
|
|
57505
|
+
const raw = readFileSync48(path62, "utf8");
|
|
57421
57506
|
for (const line of raw.split(/\r?\n/)) {
|
|
57422
57507
|
const trimmed = line.trim();
|
|
57423
57508
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -57440,8 +57525,8 @@ function loadProjectEnv(startDir = process.cwd()) {
|
|
|
57440
57525
|
const filesRead = [];
|
|
57441
57526
|
const merged = {};
|
|
57442
57527
|
for (const name of [".env", ".env.local"]) {
|
|
57443
|
-
const p =
|
|
57444
|
-
if (
|
|
57528
|
+
const p = join66(root, name);
|
|
57529
|
+
if (existsSync61(p) && statSync16(p).isFile()) {
|
|
57445
57530
|
Object.assign(merged, parseEnvFile(p));
|
|
57446
57531
|
filesRead.push(p);
|
|
57447
57532
|
}
|
|
@@ -118,7 +118,7 @@ spec:
|
|
|
118
118
|
# k3d), started by `olam upgrade` Step 0.7 — not inside this Pod.
|
|
119
119
|
containers:
|
|
120
120
|
- name: olam-host-cp
|
|
121
|
-
image: ghcr.io/pleri/olam-host-cp@sha256:
|
|
121
|
+
image: ghcr.io/pleri/olam-host-cp@sha256:1818b62ee1475cf42f8d55c3ba3cbda9c27b799dc99abcff6c63f02d54574893
|
|
122
122
|
imagePullPolicy: IfNotPresent
|
|
123
123
|
securityContext:
|
|
124
124
|
runAsNonRoot: true
|
|
@@ -70,7 +70,7 @@ spec:
|
|
|
70
70
|
mountPath: /data
|
|
71
71
|
containers:
|
|
72
72
|
- name: olam-auth-service
|
|
73
|
-
image: ghcr.io/pleri/olam-auth@sha256:
|
|
73
|
+
image: ghcr.io/pleri/olam-auth@sha256:7a206b619cd92d39b2550a09e270e9999a6c0b1a70e391e72b46c2cfbbf0be9c
|
|
74
74
|
imagePullPolicy: IfNotPresent
|
|
75
75
|
securityContext:
|
|
76
76
|
runAsNonRoot: true
|
|
@@ -61,7 +61,7 @@ spec:
|
|
|
61
61
|
mountPath: /data
|
|
62
62
|
containers:
|
|
63
63
|
- name: olam-kg-service
|
|
64
|
-
image: ghcr.io/pleri/olam-kg-service@sha256:
|
|
64
|
+
image: ghcr.io/pleri/olam-kg-service@sha256:b74d2099752a0299317c95feab19893764a291db375c4ce0fd96d06691defb9f
|
|
65
65
|
imagePullPolicy: IfNotPresent
|
|
66
66
|
securityContext:
|
|
67
67
|
runAsNonRoot: true
|
|
@@ -68,7 +68,7 @@ spec:
|
|
|
68
68
|
mountPath: /data
|
|
69
69
|
containers:
|
|
70
70
|
- name: olam-mcp-auth-service
|
|
71
|
-
image: ghcr.io/pleri/olam-mcp-auth@sha256:
|
|
71
|
+
image: ghcr.io/pleri/olam-mcp-auth@sha256:9e1b11d9a67005a1a3c65f63b5c4c94d311a35f6b424e576d63bba82290f86cf
|
|
72
72
|
imagePullPolicy: IfNotPresent
|
|
73
73
|
securityContext:
|
|
74
74
|
runAsNonRoot: true
|
|
@@ -70,7 +70,7 @@ spec:
|
|
|
70
70
|
# bootstrap-placeholder comment + run `npm run refresh:manifest-digests`
|
|
71
71
|
# once ghcr.io/pleri/olam-memory-service has a real published digest.
|
|
72
72
|
# bootstrap-placeholder: pre-publish; refresh after first release
|
|
73
|
-
image: ghcr.io/pleri/olam-memory-service@sha256:
|
|
73
|
+
image: ghcr.io/pleri/olam-memory-service@sha256:847d97e6970158f5037821c5664836a1781949750ce69caab08128e1c9c6a157
|
|
74
74
|
imagePullPolicy: IfNotPresent
|
|
75
75
|
securityContext:
|
|
76
76
|
runAsNonRoot: true
|
package/host-cp/src/server.mjs
CHANGED
|
@@ -3308,8 +3308,14 @@ const server = http.createServer(instrumentHandler('host-cp', async (req, res) =
|
|
|
3308
3308
|
// binding hops (plan-DO) because those bypass the CF Access edge; a CF
|
|
3309
3309
|
// Access app in front of plan-DO would still not receive service-binding
|
|
3310
3310
|
// traffic. See docs/runbooks/cf-access-service-token.md.
|
|
3311
|
+
// Phase B (cloud-plan-execute-split): a `mode: 'plan'` dispatch routes to
|
|
3312
|
+
// plan-DO's /v1/plan endpoint (the light Sandbox pool, no-push planning
|
|
3313
|
+
// role) instead of /v1/dispatch (the execute/world path). Any other value
|
|
3314
|
+
// (incl. absent) keeps the existing /v1/dispatch route — zero behaviour
|
|
3315
|
+
// change for execute dispatches. The SPA opts in by setting body.mode.
|
|
3316
|
+
const dispatchPath = parsed.mode === 'plan' ? '/v1/plan' : '/v1/dispatch';
|
|
3311
3317
|
const upstream = await fetch(
|
|
3312
|
-
`${cloudUrl.replace(/\/+$/, '')}
|
|
3318
|
+
`${cloudUrl.replace(/\/+$/, '')}${dispatchPath}?plan_id=${encodeURIComponent(planId)}`,
|
|
3313
3319
|
{
|
|
3314
3320
|
method: 'POST',
|
|
3315
3321
|
headers: {
|