@pleri/olam-cli 0.1.205 → 0.1.206

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.
@@ -1,12 +1,12 @@
1
1
  {
2
- "auth": "sha256:06c9cd39405e650141a78927f1701bf7b06a86cd98eeaef9b22eb53d46f6f523",
3
- "devbox": "sha256:467e0da5ce48ce281c9799f52b2efabc2eba2228e4ab807412523bdb00a52917",
4
- "devbox-base": "sha256:4fd8d2797b6126778c034e442a8429cbbc2e90f772ff11061bcb317d735d9293",
5
- "host-cp": "sha256:501037587e33d0a1c13df88d72ad9b855508e4c0163cb65673211cd3ddd9227b",
6
- "kg-service": "sha256:a739f0fdf60aef0d26b51314698a07bba423c3d43571616cffd7b1195abb205d",
7
- "memory-service": "sha256:b10649ba9b56bb11b99e5142559d4b8a37a2b8ae2ad8ce38fb8b535449d26f85",
8
- "mcp-auth": "sha256:cdeb8813619f0198dbbcc80b2c98dbeb3a842e8d1ec38796d459ad254c5e1d98",
2
+ "auth": "sha256:10879610c8930d06e2201171ca98249da756461fbbca7540face7593de3f2516",
3
+ "devbox": "sha256:df30833b7192a3c49f842f66556a6c59f1e125931b3eb6555d0747df9025a955",
4
+ "devbox-base": "sha256:bffb02ffa2abe8781753abc28f985eda029ed7660bc225c8bbb71c5aab94fde9",
5
+ "host-cp": "sha256:f11d34247171fba77439e3877ba8b781b857d1eb3f1c983bac2621dd7a254fef",
6
+ "kg-service": "sha256:4fc5f7257d2fa8e11c07e5436a68edd0353c0d503739b9e90f7736e5b336a8fa",
7
+ "memory-service": "sha256:4b2742280eb0437e3865e603d1d148e28408a1ec8aa4a7dd2c726cd3d31ee8dd",
8
+ "mcp-auth": "sha256:0780d597d7eb7d124eb998cf8e56649e375a594e4181ddb181f8b1cb2d443701",
9
9
  "$schema_version": 1,
10
- "$published_version": "0.1.205",
10
+ "$published_version": "0.1.206",
11
11
  "$registry": "ghcr.io/pleri"
12
12
  }
package/dist/index.js CHANGED
@@ -18059,11 +18059,12 @@ function mergeHomeSettingsJson(filePath, options) {
18059
18059
  return { status: "already-present", message: `hook already present at ${filePath}` };
18060
18060
  }
18061
18061
  } else {
18062
+ const filteredArr = options.ensureHook.staleSentinelPrefix ? dropStaleHooks(stageArr, options.ensureHook.staleSentinelPrefix, sentinel) : stageArr;
18062
18063
  settings = {
18063
18064
  ...settings,
18064
18065
  hooks: {
18065
18066
  ...settings.hooks,
18066
- [stage]: [...stageArr, entry]
18067
+ [stage]: [...filteredArr, entry]
18067
18068
  }
18068
18069
  };
18069
18070
  changed = true;
@@ -18097,6 +18098,24 @@ function readSettings(filePath) {
18097
18098
  return {};
18098
18099
  return JSON.parse(raw);
18099
18100
  }
18101
+ function dropStaleHooks(matchers, stalePrefix, currentSentinel) {
18102
+ const out = [];
18103
+ for (const matcher of matchers) {
18104
+ const allCmds = [];
18105
+ if (typeof matcher.command === "string")
18106
+ allCmds.push(matcher.command);
18107
+ if (Array.isArray(matcher.hooks)) {
18108
+ for (const h of matcher.hooks) {
18109
+ if (typeof h.command === "string")
18110
+ allCmds.push(h.command);
18111
+ }
18112
+ }
18113
+ const isStale = allCmds.some((c) => c.includes(stalePrefix)) && !allCmds.some((c) => c.includes(currentSentinel));
18114
+ if (!isStale)
18115
+ out.push(matcher);
18116
+ }
18117
+ return out;
18118
+ }
18100
18119
  function isHookSentinelPresent(matchers, sentinel) {
18101
18120
  for (const matcher of matchers) {
18102
18121
  if (typeof matcher?.command === "string" && matcher.command.includes(sentinel)) {
@@ -22350,6 +22369,7 @@ var init_kg_eager = __esm({
22350
22369
  var hook_template_exports = {};
22351
22370
  __export(hook_template_exports, {
22352
22371
  KG_HOOK_SENTINEL: () => KG_HOOK_SENTINEL,
22372
+ KG_HOOK_SENTINEL_PREFIX: () => KG_HOOK_SENTINEL_PREFIX,
22353
22373
  buildHookCommand: () => buildHookCommand,
22354
22374
  buildHookMatcherEntry: () => buildHookMatcherEntry
22355
22375
  });
@@ -22366,10 +22386,20 @@ function buildHookCommand(opts) {
22366
22386
  const emitContext = `python3 -c 'import json,sys,os
22367
22387
  try:
22368
22388
  d=json.loads(sys.stdin.read())
22369
- if d.get("route") and d["route"] != "grep":
22389
+ route=d.get("route","")
22390
+ if route:
22391
+ if route in ("kg","both"):
22392
+ label=d.get("top_match") or d.get("reason","")
22393
+ layer=d.get("layer","?")
22394
+ nodes=d.get("nodes_matched",0)
22395
+ saved=(d.get("savings") or {}).get("saved_tokens_est",0)
22396
+ saved_k=round(saved/1000)
22397
+ sys.stderr.write(f"\\x1b[32m\\u29bf\\u29bf\\x1b[0m KG hit \\u2713 {label} \\u2192 L{layer}/{route} \\u00b7 {nodes} nodes \\u00b7 \\x1b[32m~{saved_k}k tokens saved\\x1b[0m\\n")
22398
+ else:
22399
+ sys.stderr.write("\\U0001f50d Grep used\\n")
22400
+ if route and route != "grep":
22370
22401
  label=d.get("top_match") or d.get("reason","")
22371
22402
  layer=d.get("layer","?")
22372
- route=d["route"]
22373
22403
  nodes=d.get("nodes_matched",0)
22374
22404
  saved=(d.get("savings") or {}).get("saved_tokens_est",0)
22375
22405
  saved_k=round(saved/1000)
@@ -22380,7 +22410,6 @@ try:
22380
22410
  rel=any(k in ql for k in ("call","caller","import","uses","used","reference","who "))
22381
22411
  g="olam kg mirror graph \\"" + sym + "\\" --workspace <ws>"
22382
22412
  hint=g + (" --relates" if rel else "") + " (where X is defined; add --relates for what calls/imports it; --repo <name> to browse a repo)"
22383
- sys.stderr.write(f"\\x1b[32m\\u2713 KG hit\\x1b[0m \\"{q}\\" \\u2192 L{layer}/{route} \\u00b7 {nodes} nodes \\u00b7 ~{saved_k}k tokens saved\\n")
22384
22413
  print(json.dumps({"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":f"[kg-classifier L{layer}|{route}] {label[:140]}\\n\\u21b3 graph: {hint}"}}))
22385
22414
  except Exception: pass' 2>/dev/null`;
22386
22415
  const isCloud = opts.flavor === "cloud-sandbox";
@@ -22389,7 +22418,7 @@ except Exception: pass' 2>/dev/null`;
22389
22418
  const cloudGuard = isCloud ? `if [ -z "\${OLAM_KG_PROXY_URL:-}" ] || [ -z "\${OLAM_KG_PROXY_BEARER:-}" ]; then exit 0; fi; ` : "";
22390
22419
  const wsField = isCloud ? `,\\"workspace\\":\\"\${OLAM_KG_PROXY_WORKSPACE:-}\\"` : "";
22391
22420
  const curlPost = `RESP=$(curl -s --max-time 1 -X POST -H 'Content-Type: application/json' ${authHeader} -d "{\\"q\\":\\"$(echo \\"$CMD\\" | head -c 200 | tr '\\"' ' ')\\"${wsField}}" ${resolvedUrl} 2>/dev/null)`;
22392
- const hostRemoteFallback = opts.flavor === "host" ? `; if [ -z "$RESP" ] && [ -r "$HOME/.olam/kg-proxy-url" ] && [ -r "$HOME/.olam/kg-proxy-bearer" ]; then RESP=$(curl -s --max-time 2 -X POST -H 'Content-Type: application/json' -H "Authorization: Bearer $(cat "$HOME/.olam/kg-proxy-bearer")" -d "{\\"q\\":\\"$(echo \\"$CMD\\" | head -c 200 | tr '\\"' ' ')\\"}" "$(cat "$HOME/.olam/kg-proxy-url")/v1/classify" 2>/dev/null); fi` : "";
22421
+ const hostRemoteFallback = opts.flavor === "host" ? `; if [ -z "$RESP" ] && [ -r "$HOME/.olam/kg-proxy-url" ] && [ -r "$HOME/.olam/kg-proxy-bearer" ]; then KG_ORIGIN=$(sed 's|\\(https*://[^/]*\\).*|\\1|' "$HOME/.olam/kg-proxy-url" 2>/dev/null); RESP=$(curl -s --max-time 3 -X POST -H 'Content-Type: application/json' -H "Authorization: Bearer $(cat "$HOME/.olam/kg-proxy-bearer")" -d "{\\"q\\":\\"$(echo \\"$CMD\\" | head -c 200 | tr '\\"' ' ')\\"}" "$KG_ORIGIN/v1/classify" 2>/dev/null); fi` : "";
22393
22422
  return [
22394
22423
  `KG_SENTINEL=${KG_HOOK_SENTINEL}`,
22395
22424
  `CMD=$(${extractCmd})`,
@@ -22409,11 +22438,12 @@ function buildHookMatcherEntry(opts) {
22409
22438
  ]
22410
22439
  };
22411
22440
  }
22412
- var KG_HOOK_SENTINEL;
22441
+ var KG_HOOK_SENTINEL, KG_HOOK_SENTINEL_PREFIX;
22413
22442
  var init_hook_template2 = __esm({
22414
22443
  "../core/dist/kg/hook-template.js"() {
22415
22444
  "use strict";
22416
- KG_HOOK_SENTINEL = "kg-service-v2-classifier-hook";
22445
+ KG_HOOK_SENTINEL = "kg-service-v3-classifier-hook";
22446
+ KG_HOOK_SENTINEL_PREFIX = "kg-service-v";
22417
22447
  }
22418
22448
  });
22419
22449
 
@@ -54926,15 +54956,21 @@ var HOOK_BASENAMES = [
54926
54956
  "agentmemory-reflect-cite.mjs",
54927
54957
  "recall-log.mjs"
54928
54958
  ];
54959
+ var SOURCE_ANCHOR = "agentmemory-session-recall.js";
54960
+ function resolveSourceDir(here3) {
54961
+ let dir = here3;
54962
+ for (; ; ) {
54963
+ for (const cand of [join122(dir, "memory-hooks"), join122(dir, "memory-service", "hooks")]) {
54964
+ if (existsSync120(join122(cand, SOURCE_ANCHOR))) return cand;
54965
+ }
54966
+ const parent = dirname66(dir);
54967
+ if (parent === dir) break;
54968
+ dir = parent;
54969
+ }
54970
+ return resolve28(here3, "..", "memory-hooks");
54971
+ }
54929
54972
  function defaultSourceDir() {
54930
- const here3 = dirname66(fileURLToPath11(import.meta.url));
54931
- const bundled = resolve28(here3, "..", "..", "..", "memory-hooks");
54932
- if (existsSync120(bundled)) return bundled;
54933
- const sibling = resolve28(here3, "..", "..", "..", "..", "memory-service", "hooks");
54934
- if (existsSync120(sibling)) return sibling;
54935
- const srcSibling = resolve28(here3, "..", "..", "..", "..", "..", "memory-service", "hooks");
54936
- if (existsSync120(srcSibling)) return srcSibling;
54937
- return bundled;
54973
+ return resolveSourceDir(dirname66(fileURLToPath11(import.meta.url)));
54938
54974
  }
54939
54975
  function installOne2(basename17, sourceDir, targetDir, opts) {
54940
54976
  const sourcePath = join122(sourceDir, basename17);
@@ -56318,6 +56354,7 @@ function registerKgInstallHookCommand(kg) {
56318
56354
  ensureHook: {
56319
56355
  stage: "PreToolUse",
56320
56356
  sentinel: KG_HOOK_SENTINEL,
56357
+ staleSentinelPrefix: KG_HOOK_SENTINEL_PREFIX,
56321
56358
  entry: buildHookMatcherEntry({ flavor: "host" })
56322
56359
  }
56323
56360
  });
@@ -56367,7 +56404,7 @@ function dropSentinel(matchers) {
56367
56404
  for (const matcher of matchers) {
56368
56405
  const innerHooks = matcher.hooks ?? [];
56369
56406
  const keptInner = innerHooks.filter((h) => {
56370
- if (typeof h.command === "string" && h.command.includes(KG_HOOK_SENTINEL)) {
56407
+ if (typeof h.command === "string" && h.command.includes(KG_HOOK_SENTINEL_PREFIX)) {
56371
56408
  changed = true;
56372
56409
  return false;
56373
56410
  }
@@ -15051,11 +15051,12 @@ function mergeHomeSettingsJson(filePath, options) {
15051
15051
  return { status: "already-present", message: `hook already present at ${filePath}` };
15052
15052
  }
15053
15053
  } else {
15054
+ const filteredArr = options.ensureHook.staleSentinelPrefix ? dropStaleHooks(stageArr, options.ensureHook.staleSentinelPrefix, sentinel) : stageArr;
15054
15055
  settings = {
15055
15056
  ...settings,
15056
15057
  hooks: {
15057
15058
  ...settings.hooks,
15058
- [stage]: [...stageArr, entry]
15059
+ [stage]: [...filteredArr, entry]
15059
15060
  }
15060
15061
  };
15061
15062
  changed = true;
@@ -15089,6 +15090,24 @@ function readSettings(filePath) {
15089
15090
  return {};
15090
15091
  return JSON.parse(raw);
15091
15092
  }
15093
+ function dropStaleHooks(matchers, stalePrefix, currentSentinel) {
15094
+ const out = [];
15095
+ for (const matcher of matchers) {
15096
+ const allCmds = [];
15097
+ if (typeof matcher.command === "string")
15098
+ allCmds.push(matcher.command);
15099
+ if (Array.isArray(matcher.hooks)) {
15100
+ for (const h of matcher.hooks) {
15101
+ if (typeof h.command === "string")
15102
+ allCmds.push(h.command);
15103
+ }
15104
+ }
15105
+ const isStale = allCmds.some((c) => c.includes(stalePrefix)) && !allCmds.some((c) => c.includes(currentSentinel));
15106
+ if (!isStale)
15107
+ out.push(matcher);
15108
+ }
15109
+ return out;
15110
+ }
15092
15111
  function isHookSentinelPresent(matchers, sentinel) {
15093
15112
  for (const matcher of matchers) {
15094
15113
  if (typeof matcher?.command === "string" && matcher.command.includes(sentinel)) {
@@ -48697,7 +48716,7 @@ import * as path44 from "node:path";
48697
48716
  import * as os27 from "node:os";
48698
48717
 
48699
48718
  // ../core/dist/kg/hook-template.js
48700
- var KG_HOOK_SENTINEL = "kg-service-v2-classifier-hook";
48719
+ var KG_HOOK_SENTINEL = "kg-service-v3-classifier-hook";
48701
48720
  function defaultUrl(flavor) {
48702
48721
  if (flavor === "host")
48703
48722
  return "http://127.0.0.1:9997/classify";
@@ -48711,10 +48730,20 @@ function buildHookCommand(opts) {
48711
48730
  const emitContext = `python3 -c 'import json,sys,os
48712
48731
  try:
48713
48732
  d=json.loads(sys.stdin.read())
48714
- if d.get("route") and d["route"] != "grep":
48733
+ route=d.get("route","")
48734
+ if route:
48735
+ if route in ("kg","both"):
48736
+ label=d.get("top_match") or d.get("reason","")
48737
+ layer=d.get("layer","?")
48738
+ nodes=d.get("nodes_matched",0)
48739
+ saved=(d.get("savings") or {}).get("saved_tokens_est",0)
48740
+ saved_k=round(saved/1000)
48741
+ sys.stderr.write(f"\\x1b[32m\\u29bf\\u29bf\\x1b[0m KG hit \\u2713 {label} \\u2192 L{layer}/{route} \\u00b7 {nodes} nodes \\u00b7 \\x1b[32m~{saved_k}k tokens saved\\x1b[0m\\n")
48742
+ else:
48743
+ sys.stderr.write("\\U0001f50d Grep used\\n")
48744
+ if route and route != "grep":
48715
48745
  label=d.get("top_match") or d.get("reason","")
48716
48746
  layer=d.get("layer","?")
48717
- route=d["route"]
48718
48747
  nodes=d.get("nodes_matched",0)
48719
48748
  saved=(d.get("savings") or {}).get("saved_tokens_est",0)
48720
48749
  saved_k=round(saved/1000)
@@ -48725,7 +48754,6 @@ try:
48725
48754
  rel=any(k in ql for k in ("call","caller","import","uses","used","reference","who "))
48726
48755
  g="olam kg mirror graph \\"" + sym + "\\" --workspace <ws>"
48727
48756
  hint=g + (" --relates" if rel else "") + " (where X is defined; add --relates for what calls/imports it; --repo <name> to browse a repo)"
48728
- sys.stderr.write(f"\\x1b[32m\\u2713 KG hit\\x1b[0m \\"{q}\\" \\u2192 L{layer}/{route} \\u00b7 {nodes} nodes \\u00b7 ~{saved_k}k tokens saved\\n")
48729
48757
  print(json.dumps({"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":f"[kg-classifier L{layer}|{route}] {label[:140]}\\n\\u21b3 graph: {hint}"}}))
48730
48758
  except Exception: pass' 2>/dev/null`;
48731
48759
  const isCloud = opts.flavor === "cloud-sandbox";
@@ -48734,7 +48762,7 @@ except Exception: pass' 2>/dev/null`;
48734
48762
  const cloudGuard = isCloud ? `if [ -z "\${OLAM_KG_PROXY_URL:-}" ] || [ -z "\${OLAM_KG_PROXY_BEARER:-}" ]; then exit 0; fi; ` : "";
48735
48763
  const wsField = isCloud ? `,\\"workspace\\":\\"\${OLAM_KG_PROXY_WORKSPACE:-}\\"` : "";
48736
48764
  const curlPost = `RESP=$(curl -s --max-time 1 -X POST -H 'Content-Type: application/json' ${authHeader2} -d "{\\"q\\":\\"$(echo \\"$CMD\\" | head -c 200 | tr '\\"' ' ')\\"${wsField}}" ${resolvedUrl} 2>/dev/null)`;
48737
- const hostRemoteFallback = opts.flavor === "host" ? `; if [ -z "$RESP" ] && [ -r "$HOME/.olam/kg-proxy-url" ] && [ -r "$HOME/.olam/kg-proxy-bearer" ]; then RESP=$(curl -s --max-time 2 -X POST -H 'Content-Type: application/json' -H "Authorization: Bearer $(cat "$HOME/.olam/kg-proxy-bearer")" -d "{\\"q\\":\\"$(echo \\"$CMD\\" | head -c 200 | tr '\\"' ' ')\\"}" "$(cat "$HOME/.olam/kg-proxy-url")/v1/classify" 2>/dev/null); fi` : "";
48765
+ const hostRemoteFallback = opts.flavor === "host" ? `; if [ -z "$RESP" ] && [ -r "$HOME/.olam/kg-proxy-url" ] && [ -r "$HOME/.olam/kg-proxy-bearer" ]; then KG_ORIGIN=$(sed 's|\\(https*://[^/]*\\).*|\\1|' "$HOME/.olam/kg-proxy-url" 2>/dev/null); RESP=$(curl -s --max-time 3 -X POST -H 'Content-Type: application/json' -H "Authorization: Bearer $(cat "$HOME/.olam/kg-proxy-bearer")" -d "{\\"q\\":\\"$(echo \\"$CMD\\" | head -c 200 | tr '\\"' ' ')\\"}" "$KG_ORIGIN/v1/classify" 2>/dev/null); fi` : "";
48738
48766
  return [
48739
48767
  `KG_SENTINEL=${KG_HOOK_SENTINEL}`,
48740
48768
  `CMD=$(${extractCmd})`,
@@ -1,4 +1,4 @@
1
1
  {
2
- "bundledAt": "2026-06-02T08:06:35.843Z",
2
+ "bundledAt": "2026-06-02T12:45:34.001Z",
3
3
  "kgFirstSha": "29a9ccce1b115d049e375c4a90eb5cf7c123e610e2d0590270a4db2cdbc64a28"
4
4
  }
@@ -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:501037587e33d0a1c13df88d72ad9b855508e4c0163cb65673211cd3ddd9227b
121
+ image: ghcr.io/pleri/olam-host-cp@sha256:f11d34247171fba77439e3877ba8b781b857d1eb3f1c983bac2621dd7a254fef
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:06c9cd39405e650141a78927f1701bf7b06a86cd98eeaef9b22eb53d46f6f523
73
+ image: ghcr.io/pleri/olam-auth@sha256:10879610c8930d06e2201171ca98249da756461fbbca7540face7593de3f2516
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:a739f0fdf60aef0d26b51314698a07bba423c3d43571616cffd7b1195abb205d
64
+ image: ghcr.io/pleri/olam-kg-service@sha256:4fc5f7257d2fa8e11c07e5436a68edd0353c0d503739b9e90f7736e5b336a8fa
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:cdeb8813619f0198dbbcc80b2c98dbeb3a842e8d1ec38796d459ad254c5e1d98
71
+ image: ghcr.io/pleri/olam-mcp-auth@sha256:0780d597d7eb7d124eb998cf8e56649e375a594e4181ddb181f8b1cb2d443701
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:b10649ba9b56bb11b99e5142559d4b8a37a2b8ae2ad8ce38fb8b535449d26f85
73
+ image: ghcr.io/pleri/olam-memory-service@sha256:4b2742280eb0437e3865e603d1d148e28408a1ec8aa4a7dd2c726cd3d31ee8dd
74
74
  imagePullPolicy: IfNotPresent
75
75
  securityContext:
76
76
  runAsNonRoot: true
@@ -2241,6 +2241,35 @@ const server = http.createServer(instrumentHandler('host-cp', async (req, res) =
2241
2241
  ...(burstKgWorkspace ? { kgWorkspace: burstKgWorkspace } : {}),
2242
2242
  ...(burstHostCpUrl ? { hostCpUrl: burstHostCpUrl } : {}),
2243
2243
  ...(burstChunksSinkUrl ? { chunksSinkUrl: burstChunksSinkUrl } : {}),
2244
+ // attachments → runner materializes operator-pasted file/image bytes
2245
+ // from R2 into /workspace/<sid>/.attachments (plan-chat-spa-attachments
2246
+ // Phase A, #1614). The runner reads body.attachments; sandbox-dispatch-client
2247
+ // forwards it on the plan-DO path, so cloud-burst must too — else a
2248
+ // sandbox dispatch carrying attachments silently runs without the files
2249
+ // (drift parity with sandbox-dispatch-client — same class as #1605/#1622).
2250
+ ...(Array.isArray(parsedBody.attachments) && parsedBody.attachments.length > 0 ? { attachments: parsedBody.attachments } : {}),
2251
+ // Agent-capability fields the runner /spawn handler reads and
2252
+ // sandbox-dispatch-client (cell #4) already forwards. The cloud-burst
2253
+ // path (cell #2) builds an explicit spawnBody, so it must forward them
2254
+ // too or a local-mode→sandbox dispatch carrying any of these silently
2255
+ // loses the capability (same drift class as submodules/attachments).
2256
+ // Body-supplied (the cell #2 SPA send is the only source on this path);
2257
+ // absent → spread to nothing, so today's bare {prompt,session_id,world_id}
2258
+ // burst is byte-for-byte unchanged.
2259
+ // skillSources → runner lays the operator's /100x chain into ~/.claude.
2260
+ // mcpServers → runner writes ~/.claude.json so the agent has MCP tools.
2261
+ // interactive → runner launches a tmux REPL instead of headless -p.
2262
+ // operatorSub → in-container poster stamps chunks with the owner sub
2263
+ // (runner reads body.operatorSub ?? body.operator_sub;
2264
+ // forwarding the camelCase alias satisfies both reads —
2265
+ // operator_sub is a documented EXCLUSIONS alias).
2266
+ // chunksSinkBearer → per-dispatch chunk-sink auth (NEVER logged); runner
2267
+ // prefers it over its deploy-time env.CHUNKS_INGEST_BEARER.
2268
+ ...(Array.isArray(parsedBody.skillSources) && parsedBody.skillSources.length > 0 ? { skillSources: parsedBody.skillSources } : {}),
2269
+ ...(parsedBody.mcpServers && typeof parsedBody.mcpServers === 'object' && Object.keys(parsedBody.mcpServers).length > 0 ? { mcpServers: parsedBody.mcpServers } : {}),
2270
+ ...(parsedBody.interactive ? { interactive: true } : {}),
2271
+ ...(parsedBody.operatorSub ? { operatorSub: parsedBody.operatorSub } : {}),
2272
+ ...(parsedBody.chunksSinkBearer ? { chunksSinkBearer: parsedBody.chunksSinkBearer } : {}),
2244
2273
  idempotencyKey,
2245
2274
  ...safeOptions,
2246
2275
  };
@@ -4064,7 +4093,7 @@ const _spaCacheByKey = new Map();
4064
4093
  // audit FAIL. Keep it as the canonical HN/WP-array parity source until
4065
4094
  // that audit is repointed at worldFetch.ts directly (follow-up).
4066
4095
  // eslint-disable-next-line no-unused-vars -- retained as HN/WP parity-audit source
4067
- const BOOTSTRAP_SCRIPT = `<script>(function(){function ck(){var m=document.cookie.match(/olam_host_cp_token=([^;]+)/);return m?m[1]:'';}function sw(t){document.cookie='olam_host_cp_token='+t+'; path=/; samesite=strict';}try{var x=new XMLHttpRequest();x.open('GET','/api/bootstrap',false);x.send();if(x.status===200){var d=JSON.parse(x.responseText);sw(d.token);}}catch(e){console.error('[host-cp bootstrap]',e);}var reloading=false;function recover(){if(reloading)return;try{var x=new XMLHttpRequest();x.open('GET','/api/bootstrap',false);x.send();if(x.status===200){var d=JSON.parse(x.responseText);if(d.token&&ck()!==d.token){reloading=true;sw(d.token);console.warn('[host-cp auth recover] token rotated; reloading');location.reload();}}}catch(e){console.error('[host-cp auth recover]',e);}}var HN=['/api/bootstrap','/api/worlds','/api/projects','/api/workspaces','/api/workspaces/match','/api/repos','/api/runbooks','/api/auth','/api/host-stream','/api/plan-chat','/api/plan/agent-runtime','/health'];var WP=['/api/','/session/','/hooks/','/dispatch','/lanes','/codex/','/review/'];function sr(p){if(typeof p!=='string')return false;if(p.startsWith('/api/world/'))return false;for(var i=0;i<HN.length;i++){var n=HN[i];if(p===n||p.startsWith(n+'?')||p.startsWith(n+'/'))return false;}for(var j=0;j<WP.length;j++){var w=WP[j];if(p===w||p===w.replace(/\\/$/,'')||p.startsWith(w)||p.startsWith(w.replace(/\\/$/,'')+'?')||p.startsWith(w.replace(/\\/$/,'')+'/'))return true;}return false;}function wid(){var p=location.pathname;var m=p.match(/^\\/(world|inbox|session)\\/([^/?#]+)/);if(m)return m[2];if(/^\\/(?:worlds?|workspaces?|world|sandbox|session|inbox|plan|design|repos|runbooks|assets|api|health|favicon)($|\\/|\\?)/.test(p))return null;var r=p.match(/^\\/([a-z][a-z0-9-]+)(?:\\/|$|\\?)/);return r?r[1]:null;}function rw(p){var w=wid();return w?'/api/world/'+w+p:p;}var of=window.fetch.bind(window);window.fetch=function(input,init){var pr;if(typeof input==='string'&&sr(input))pr=of(rw(input),init);else if(input&&typeof input.url==='string'&&sr(input.url))pr=of(new Request(rw(input.url),input),init);else pr=of(input,init);return pr.then(function(res){if(res&&res.status===401)recover();return res;});};var OE=window.EventSource;if(OE){window.EventSource=function(u,i){var s=u;if(typeof s==='string'&&sr(s))s=rw(s);var es=new OE(s,i);es.addEventListener('error',function(){if(es.readyState===OE.CLOSED)recover();});return es;};window.EventSource.prototype=OE.prototype;window.EventSource.CONNECTING=OE.CONNECTING;window.EventSource.OPEN=OE.OPEN;window.EventSource.CLOSED=OE.CLOSED;}})();</script>`;
4096
+ const BOOTSTRAP_SCRIPT = `<script>(function(){function ck(){var m=document.cookie.match(/olam_host_cp_token=([^;]+)/);return m?m[1]:'';}function sw(t){document.cookie='olam_host_cp_token='+t+'; path=/; samesite=strict';}try{var x=new XMLHttpRequest();x.open('GET','/api/bootstrap',false);x.send();if(x.status===200){var d=JSON.parse(x.responseText);sw(d.token);}}catch(e){console.error('[host-cp bootstrap]',e);}var reloading=false;function recover(){if(reloading)return;try{var x=new XMLHttpRequest();x.open('GET','/api/bootstrap',false);x.send();if(x.status===200){var d=JSON.parse(x.responseText);if(d.token&&ck()!==d.token){reloading=true;sw(d.token);console.warn('[host-cp auth recover] token rotated; reloading');location.reload();}}}catch(e){console.error('[host-cp auth recover]',e);}}var HN=['/api/bootstrap','/api/whoami','/api/worlds','/api/projects','/api/chats','/api/workspaces','/api/workspaces/match','/api/repos','/api/runbooks','/api/auth','/api/host-stream','/api/plan-chat','/api/plan/agent-runtime','/health'];var WP=['/api/','/session/','/hooks/','/dispatch','/lanes','/codex/','/review/'];function sr(p){if(typeof p!=='string')return false;if(p.startsWith('/api/world/'))return false;for(var i=0;i<HN.length;i++){var n=HN[i];if(p===n||p.startsWith(n+'?')||p.startsWith(n+'/'))return false;}for(var j=0;j<WP.length;j++){var w=WP[j];if(p===w||p===w.replace(/\\/$/,'')||p.startsWith(w)||p.startsWith(w.replace(/\\/$/,'')+'?')||p.startsWith(w.replace(/\\/$/,'')+'/'))return true;}return false;}function wid(){var p=location.pathname;var m=p.match(/^\\/(world|inbox|session)\\/([^/?#]+)/);if(m)return m[2];if(/^\\/(?:worlds?|workspaces?|world|sandbox|session|inbox|plan|design|repos|runbooks|assets|api|health|favicon)($|\\/|\\?)/.test(p))return null;var r=p.match(/^\\/([a-z][a-z0-9-]+)(?:\\/|$|\\?)/);return r?r[1]:null;}function rw(p){var w=wid();return w?'/api/world/'+w+p:p;}var of=window.fetch.bind(window);window.fetch=function(input,init){var pr;if(typeof input==='string'&&sr(input))pr=of(rw(input),init);else if(input&&typeof input.url==='string'&&sr(input.url))pr=of(new Request(rw(input.url),input),init);else pr=of(input,init);return pr.then(function(res){if(res&&res.status===401)recover();return res;});};var OE=window.EventSource;if(OE){window.EventSource=function(u,i){var s=u;if(typeof s==='string'&&sr(s))s=rw(s);var es=new OE(s,i);es.addEventListener('error',function(){if(es.readyState===OE.CLOSED)recover();});return es;};window.EventSource.prototype=OE.prototype;window.EventSource.CONNECTING=OE.CONNECTING;window.EventSource.OPEN=OE.OPEN;window.EventSource.CLOSED=OE.CLOSED;}})();</script>`;
4068
4097
 
4069
4098
  /**
4070
4099
  * Build the plan-chat bearer injection script. Reads
@@ -204,6 +204,11 @@ async function main() {
204
204
  const additionalContext = formatAdditionalContext(response, prompt);
205
205
  if (!additionalContext) return;
206
206
 
207
+ const count = response?.results?.length ?? 0;
208
+ process.stderr.write(
209
+ `\x1b[34m[🧠⇣ Memory recalled]\x1b[0m (${count} memories · "${prompt.slice(0, 60)}${prompt.length > 60 ? '…' : ''}")\n`
210
+ );
211
+
207
212
  process.stdout.write(JSON.stringify({
208
213
  hookSpecificOutput: {
209
214
  hookEventName: 'PreToolUse',
@@ -321,6 +321,10 @@ async function main() {
321
321
  const additionalContext =
322
322
  `## Recalled from agent memory (query: "${query}")\n\n${lines}\n\n${nudge}`;
323
323
 
324
+ process.stderr.write(
325
+ `\x1b[34m[🧠⇣ Memory recalled]\x1b[0m (${result.results.length} memories · "${query}")\n`
326
+ );
327
+
324
328
  process.stdout.write(JSON.stringify({
325
329
  hookSpecificOutput: {
326
330
  hookEventName: 'SessionStart',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pleri/olam-cli",
3
- "version": "0.1.205",
3
+ "version": "0.1.206",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "olam": "./bin/olam.cjs"