@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.
- package/dist/image-digests.json +8 -8
- package/dist/index.js +53 -16
- package/dist/mcp-server.js +34 -6
- 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 +30 -1
- package/memory-hooks/agentmemory-recall-trigger.mjs +5 -0
- package/memory-hooks/agentmemory-session-recall.js +4 -0
- package/package.json +1 -1
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: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.
|
|
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]: [...
|
|
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
|
-
|
|
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
|
|
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-
|
|
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
|
-
|
|
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(
|
|
56407
|
+
if (typeof h.command === "string" && h.command.includes(KG_HOOK_SENTINEL_PREFIX)) {
|
|
56371
56408
|
changed = true;
|
|
56372
56409
|
return false;
|
|
56373
56410
|
}
|
package/dist/mcp-server.js
CHANGED
|
@@ -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]: [...
|
|
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-
|
|
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
|
-
|
|
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
|
|
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})`,
|
|
@@ -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: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:
|
|
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:
|
|
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:
|
|
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:
|
|
73
|
+
image: ghcr.io/pleri/olam-memory-service@sha256:4b2742280eb0437e3865e603d1d148e28408a1ec8aa4a7dd2c726cd3d31ee8dd
|
|
74
74
|
imagePullPolicy: IfNotPresent
|
|
75
75
|
securityContext:
|
|
76
76
|
runAsNonRoot: true
|
package/host-cp/src/server.mjs
CHANGED
|
@@ -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',
|