@inetafrica/open-claudia 3.5.74-usage.2 → 3.5.75
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/CHANGELOG.md +17 -9
- package/Dockerfile +0 -2
- package/bin/cli.js +41 -0
- package/bin/owner-setup.js +56 -0
- package/bot.js +42 -0
- package/channels/kazee/call/camera.js +2 -1
- package/channels/kazee/call/session.js +5 -6
- package/channels/spaces/adapter.js +25 -1
- package/channels/spaces/client.js +6 -2
- package/channels/telegram/adapter.js +1 -2
- package/channels/web/adapter.js +27 -11
- package/core/access.js +25 -0
- package/core/app-pass.js +145 -0
- package/core/bot-profile.js +228 -0
- package/core/config.js +7 -0
- package/core/connected-apps.js +19 -4
- package/core/handlers.js +3 -1
- package/core/identity.js +14 -0
- package/core/lessons.js +1 -2
- package/core/loopback.js +21 -0
- package/core/owner-setup.js +216 -0
- package/core/pack-review.js +10 -77
- package/core/recall/index.js +2 -3
- package/core/recall/warm-walker.js +1 -31
- package/core/runner.js +1 -4
- package/core/system-prompt.js +20 -0
- package/core/usage-log.js +0 -1
- package/core/web-otp.js +17 -8
- package/core/web-sessions.js +11 -2
- package/docker-entrypoint.sh +0 -10
- package/package.json +2 -2
- package/test-provider-language.js +4 -3
- package/web.js +19 -8
package/core/pack-review.js
CHANGED
|
@@ -682,49 +682,6 @@ function listDeferredDecisions() {
|
|
|
682
682
|
} catch (_) { return []; }
|
|
683
683
|
}
|
|
684
684
|
|
|
685
|
-
// In-process FIFO in front of the review model: a busy bot runs reviews one at a
|
|
686
|
-
// time instead of stacking model processes (OC_REVIEW_CONCURRENCY, default 1).
|
|
687
|
-
// Utility calls over their cap are rejected, not queued, so lowering the cap
|
|
688
|
-
// would lose reviews. acquire() hands back a release function, at once when a
|
|
689
|
-
// slot is free and otherwise as a promise; a waiter pushed out by the bound
|
|
690
|
-
// (OC_REVIEW_QUEUE_MAX, default 20, oldest first) gets "dropped", and one still
|
|
691
|
-
// waiting at shutdown gets "closed".
|
|
692
|
-
function reviewSetting(key, fallback) {
|
|
693
|
-
const value = Number(require("./config").settingValue(key));
|
|
694
|
-
return Number.isSafeInteger(value) && value > 0 ? value : fallback;
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
function createReviewGate({ limit, maxWaiting }) {
|
|
698
|
-
let active = 0;
|
|
699
|
-
let closed = false;
|
|
700
|
-
const waiting = [];
|
|
701
|
-
function grant() {
|
|
702
|
-
active += 1;
|
|
703
|
-
let released = false;
|
|
704
|
-
return () => {
|
|
705
|
-
if (released) return;
|
|
706
|
-
released = true;
|
|
707
|
-
active -= 1;
|
|
708
|
-
if (waiting.length) waiting.shift()(grant());
|
|
709
|
-
};
|
|
710
|
-
}
|
|
711
|
-
return {
|
|
712
|
-
acquire() {
|
|
713
|
-
if (closed) return "closed";
|
|
714
|
-
if (active < limit) return grant();
|
|
715
|
-
if (waiting.length >= maxWaiting) {
|
|
716
|
-
waiting.shift()("dropped");
|
|
717
|
-
console.warn(`[pack-review] review queue full (${maxWaiting} waiting): dropped the oldest waiting review`);
|
|
718
|
-
}
|
|
719
|
-
return new Promise((resolve) => waiting.push(resolve));
|
|
720
|
-
},
|
|
721
|
-
close() {
|
|
722
|
-
closed = true;
|
|
723
|
-
for (const resolve of waiting.splice(0)) resolve("closed");
|
|
724
|
-
},
|
|
725
|
-
};
|
|
726
|
-
}
|
|
727
|
-
|
|
728
685
|
function createPackReviewer(dependencies = {}) {
|
|
729
686
|
const runUtility = dependencies.spawnUtilityAgent || spawnUtilityAgent;
|
|
730
687
|
const queue = dependencies.mutationQueue || memoryMutationQueue;
|
|
@@ -732,10 +689,6 @@ function createPackReviewer(dependencies = {}) {
|
|
|
732
689
|
const lockRetryDelayMs = dependencies.lockRetryDelayMs ?? LOCK_RETRY_DELAY_MS;
|
|
733
690
|
const adjudicator = dependencies.dedupAdjudicator
|
|
734
691
|
|| dedupAdjudicator.createDedupAdjudicator({ spawnUtilityAgent: dependencies.spawnUtilityAgent });
|
|
735
|
-
const gate = createReviewGate({
|
|
736
|
-
limit: reviewSetting("OC_REVIEW_CONCURRENCY", 1),
|
|
737
|
-
maxWaiting: reviewSetting("OC_REVIEW_QUEUE_MAX", 20),
|
|
738
|
-
});
|
|
739
692
|
const handles = new Map();
|
|
740
693
|
let accepting = true;
|
|
741
694
|
|
|
@@ -759,34 +712,19 @@ function createPackReviewer(dependencies = {}) {
|
|
|
759
712
|
}
|
|
760
713
|
|
|
761
714
|
const capturedProvider = provider || null;
|
|
715
|
+
const versions = snapshotMemoryVersions();
|
|
716
|
+
// Denies are the OWNER's refusals — mine them only when reviewing an
|
|
717
|
+
// owner turn, so deny content never surfaces via external speakers' turns.
|
|
718
|
+
const denies = (!source || source.isOwner) ? collectDeniedApprovals() : { block: "", ids: [] };
|
|
719
|
+
const prompt = buildReviewPrompt(
|
|
720
|
+
redactSensitive(String(userText || "")),
|
|
721
|
+
redactSensitive(String(assistantText || "")),
|
|
722
|
+
activePacks,
|
|
723
|
+
denies.block,
|
|
724
|
+
);
|
|
762
725
|
const work = (async () => {
|
|
763
726
|
let utilityResult = null;
|
|
764
|
-
let releaseSlot = () => {};
|
|
765
727
|
try {
|
|
766
|
-
// The review's own timeout starts at the model call, after this wait.
|
|
767
|
-
let slot = gate.acquire();
|
|
768
|
-
if (slot instanceof Promise) slot = await slot;
|
|
769
|
-
if (slot === "dropped") {
|
|
770
|
-
reviewerMetric({ provider: capturedProvider || "", status: "dropped", code: "REVIEW_QUEUE_FULL" });
|
|
771
|
-
return { status: "dropped", reason: "review queue full" };
|
|
772
|
-
}
|
|
773
|
-
if (slot === "closed") {
|
|
774
|
-
queue.record({ id: null, label: "review", status: "pending_intent_rejected", provider: capturedProvider, runId: runId || null });
|
|
775
|
-
return { status: "not_admitted", reason: "review shutdown in progress" };
|
|
776
|
-
}
|
|
777
|
-
releaseSlot = slot;
|
|
778
|
-
// Read memory after the wait: a snapshot from before it would make this
|
|
779
|
-
// review's rewrites stale whenever the review ahead touched the same pack.
|
|
780
|
-
const versions = snapshotMemoryVersions();
|
|
781
|
-
// Denies are the OWNER's refusals — mine them only when reviewing an
|
|
782
|
-
// owner turn, so deny content never surfaces via external speakers' turns.
|
|
783
|
-
const denies = (!source || source.isOwner) ? collectDeniedApprovals() : { block: "", ids: [] };
|
|
784
|
-
const prompt = buildReviewPrompt(
|
|
785
|
-
redactSensitive(String(userText || "")),
|
|
786
|
-
redactSensitive(String(assistantText || "")),
|
|
787
|
-
activePacks,
|
|
788
|
-
denies.block,
|
|
789
|
-
);
|
|
790
728
|
utilityResult = await runUtility(prompt, {
|
|
791
729
|
purpose: "review",
|
|
792
730
|
activeProvider: capturedProvider,
|
|
@@ -816,8 +754,6 @@ function createPackReviewer(dependencies = {}) {
|
|
|
816
754
|
try {
|
|
817
755
|
dedup = await adjudicator.adjudicateDecision(decision, { provider: capturedProvider, cwd: process.cwd() });
|
|
818
756
|
} catch (_) {}
|
|
819
|
-
// Model runs are done; the wait for the write lock does not hold the slot.
|
|
820
|
-
releaseSlot();
|
|
821
757
|
const finalDecision = dedup ? dedup.decision : decision;
|
|
822
758
|
const enqueueApply = () => queue.enqueue("review", () => applyDecisionBatch({
|
|
823
759
|
decision: finalDecision,
|
|
@@ -886,8 +822,6 @@ function createPackReviewer(dependencies = {}) {
|
|
|
886
822
|
announcementFailed,
|
|
887
823
|
error: { code: error.code || "REVIEW_FAILED", message: redactSensitive(error.message) },
|
|
888
824
|
};
|
|
889
|
-
} finally {
|
|
890
|
-
releaseSlot();
|
|
891
825
|
}
|
|
892
826
|
})();
|
|
893
827
|
return track(work, { provider: capturedProvider, channelId: channelId || null, runId: runId || null });
|
|
@@ -895,7 +829,6 @@ function createPackReviewer(dependencies = {}) {
|
|
|
895
829
|
|
|
896
830
|
function stopAdmission(reason = "shutdown") {
|
|
897
831
|
accepting = false;
|
|
898
|
-
gate.close();
|
|
899
832
|
queue.record({ id: null, label: "review", status: "review_admission_stopped", reason: String(reason).slice(0, 160) });
|
|
900
833
|
}
|
|
901
834
|
|
package/core/recall/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// Each engine implements: async run(ctx) -> { packBlock, entityBlock,
|
|
5
5
|
// packMatches, entityMatches }. The active engine is chosen per channel via
|
|
6
6
|
// the `recallEngine` setting (set by the /engine slash command), falling back
|
|
7
|
-
// to RECALL_ENGINE
|
|
7
|
+
// to the RECALL_ENGINE env var, then to DEFAULT_ENGINE. Unknown names fall
|
|
8
8
|
// back to the default so a bad value can never break recall. The discoverer is
|
|
9
9
|
// the default: it's fail-open (falls back to the classic keyword baseline on
|
|
10
10
|
// any error), so it never recalls worse than classic, only better. `ask`
|
|
@@ -37,8 +37,7 @@ function listEngines() {
|
|
|
37
37
|
|
|
38
38
|
function activeEngineName(settings) {
|
|
39
39
|
const fromSettings = settings && settings.recallEngine;
|
|
40
|
-
|
|
41
|
-
try { fromEnv = require("../config").settingValue("RECALL_ENGINE"); } catch (e) { fromEnv = process.env.RECALL_ENGINE; }
|
|
40
|
+
const fromEnv = process.env.RECALL_ENGINE;
|
|
42
41
|
const name = String(fromSettings || fromEnv || DEFAULT_ENGINE).toLowerCase();
|
|
43
42
|
return ENGINES[name] ? name : DEFAULT_ENGINE;
|
|
44
43
|
}
|
|
@@ -16,9 +16,6 @@ const MAX_CHARS = Number(process.env.RECALL_WARM_WALKER_MAX_CHARS || 24000);
|
|
|
16
16
|
const DEFAULT_TIMEOUT_MS = 25000;
|
|
17
17
|
const KILL_GRACE_MS = Number(process.env.RECALL_WARM_WALKER_KILL_GRACE_MS || 250);
|
|
18
18
|
const MAX_BUFFER_BYTES = Number(process.env.RECALL_WARM_WALKER_MAX_BUFFER_BYTES || 1024 * 1024);
|
|
19
|
-
// The child holds about 160 MB doing nothing; stop it this long after the last
|
|
20
|
-
// walk ends (0 = never). The next walk respawns it.
|
|
21
|
-
const IDLE_MS = Number(process.env.RECALL_WARM_WALKER_IDLE_MS || 10 * 60 * 1000);
|
|
22
19
|
|
|
23
20
|
let child = null;
|
|
24
21
|
let childProviderId = null;
|
|
@@ -29,8 +26,6 @@ let charCount = 0;
|
|
|
29
26
|
let costTotal = 0;
|
|
30
27
|
let childModel = null;
|
|
31
28
|
let stopPromise = null;
|
|
32
|
-
let idleTimer = null;
|
|
33
|
-
let walksInHand = 0;
|
|
34
29
|
|
|
35
30
|
function isEnabled(provider) {
|
|
36
31
|
if (String(process.env.RECALL_WARM_WALKER || "on").toLowerCase() === "off") return false;
|
|
@@ -75,22 +70,6 @@ function stopChild(reason = "warm walker stopped") {
|
|
|
75
70
|
return stopPromise;
|
|
76
71
|
}
|
|
77
72
|
|
|
78
|
-
function clearIdleTimer() {
|
|
79
|
-
if (idleTimer) clearTimeout(idleTimer);
|
|
80
|
-
idleTimer = null;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function armIdleTimer() {
|
|
84
|
-
clearIdleTimer();
|
|
85
|
-
if (!(IDLE_MS > 0) || !child) return;
|
|
86
|
-
idleTimer = setTimeout(() => {
|
|
87
|
-
idleTimer = null;
|
|
88
|
-
if (pending || walksInHand) return;
|
|
89
|
-
stopChild("warm walker idle").catch(() => {});
|
|
90
|
-
}, IDLE_MS);
|
|
91
|
-
idleTimer.unref();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
73
|
function persistentInvocation(cfg) {
|
|
95
74
|
const provider = cfg.provider;
|
|
96
75
|
if (!isEnabled(provider)) throw new Error(`${provider?.id || "provider"} has no enabled persistent utility stream`);
|
|
@@ -186,8 +165,6 @@ function spawnChild(cfg) {
|
|
|
186
165
|
|
|
187
166
|
async function doWalk(promptText, opts) {
|
|
188
167
|
if (!isEnabled(opts.provider)) throw new Error(`${opts.provider?.id || "provider"} persistent recall is unavailable`);
|
|
189
|
-
// An idle stop still closing: its close must not land on this walk.
|
|
190
|
-
if (stopPromise) await stopPromise;
|
|
191
168
|
if (child && (childProviderId !== opts.provider.id || msgCount >= MAX_MSGS || charCount >= MAX_CHARS)) {
|
|
192
169
|
await stopChild("warm walker recycled");
|
|
193
170
|
}
|
|
@@ -216,20 +193,13 @@ async function doWalk(promptText, opts) {
|
|
|
216
193
|
}
|
|
217
194
|
|
|
218
195
|
function walkWarm(promptText, opts = {}) {
|
|
219
|
-
clearIdleTimer();
|
|
220
|
-
walksInHand += 1;
|
|
221
196
|
const run = () => doWalk(promptText, opts);
|
|
222
197
|
const result = chain.then(run, run);
|
|
223
|
-
|
|
224
|
-
walksInHand -= 1;
|
|
225
|
-
if (!walksInHand) armIdleTimer();
|
|
226
|
-
};
|
|
227
|
-
chain = result.then(walkEnded, walkEnded);
|
|
198
|
+
chain = result.then(() => {}, () => {});
|
|
228
199
|
return result;
|
|
229
200
|
}
|
|
230
201
|
|
|
231
202
|
async function shutdown() {
|
|
232
|
-
clearIdleTimer();
|
|
233
203
|
await stopChild("warm walker shutdown");
|
|
234
204
|
}
|
|
235
205
|
|
package/core/runner.js
CHANGED
|
@@ -49,7 +49,6 @@ const packReview = require("./pack-review");
|
|
|
49
49
|
const {
|
|
50
50
|
appendUsageRecord,
|
|
51
51
|
loadUsageHistory,
|
|
52
|
-
usageAlertsOn,
|
|
53
52
|
usageAlertPolicy,
|
|
54
53
|
evaluateUsageAlert,
|
|
55
54
|
} = require("./usage-log");
|
|
@@ -235,9 +234,7 @@ function logTurnUsage(state, usage, costUsd, announce, opts = {}) {
|
|
|
235
234
|
record.rawCacheReadTokens = raw.cacheRead;
|
|
236
235
|
record.rawContextTokens = raw.context;
|
|
237
236
|
}
|
|
238
|
-
|
|
239
|
-
// not free.
|
|
240
|
-
const previousRecords = usageAlertsOn(config) ? loadUsageHistory() : [];
|
|
237
|
+
const previousRecords = loadUsageHistory();
|
|
241
238
|
appendUsageRecord(record, { strict: !!opts.strict });
|
|
242
239
|
|
|
243
240
|
const policy = usageAlertPolicy(config);
|
package/core/system-prompt.js
CHANGED
|
@@ -261,6 +261,24 @@ function buildBrowserAppBlock() {
|
|
|
261
261
|
Kazee Chat Browser app: people in a direct chat with you can watch this browser live, take it over, and teach you a task (Teach me). When you need a person in the browser (a login, a captcha, a one-time code, a judgement call), send a card in their direct chat with an Open Browser button, say what you need, then wait: you are woken in that chat when they hand it back. For example \`open-claudia card send '{"v":1,"kind":"report","title":"I need you in the browser","body":"<what you need and why>","open":{"app":"browser","label":"Open Browser"}}'\`. While someone drives, your agent-browser commands other than get, snapshot and screenshot are refused. Never ask for passwords in chat.`;
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
+
// A personal bot's own instructions (core/bot-profile.js): it works for one
|
|
265
|
+
// person, acts as her in apps, and asks her first for approvals, money and
|
|
266
|
+
// deletes. Stable for the bot, so it lives in the cached core. Autonomous
|
|
267
|
+
// bots keep their current instructions ("").
|
|
268
|
+
// A personal bot also learns how its owner switches it on: one tap on a card,
|
|
269
|
+
// never a page to find (core/owner-setup.js).
|
|
270
|
+
function buildBotKindBlock() {
|
|
271
|
+
try {
|
|
272
|
+
const block = require("./bot-profile").instructionsBlock();
|
|
273
|
+
if (!block) return "";
|
|
274
|
+
return [
|
|
275
|
+
block,
|
|
276
|
+
"- When your owner asks how to let you work for them, or an app refuses you because you're not switched on there, run `open-claudia owner-setup` (add `--apps <app>` when one app is needed; `--renew` to renew) so they get a one-tap card in Kazee Chat.",
|
|
277
|
+
"- Never ask them to find the page by hand. You can never switch yourself on: only they can confirm it.",
|
|
278
|
+
].join("\n");
|
|
279
|
+
} catch (e) { return ""; }
|
|
280
|
+
}
|
|
281
|
+
|
|
264
282
|
function buildCoreInstructionsUncached() {
|
|
265
283
|
const soul = loadSoul();
|
|
266
284
|
// Gate on actual TTS capability, not local Whisper: hosted pods hear and
|
|
@@ -271,6 +289,7 @@ function buildCoreInstructionsUncached() {
|
|
|
271
289
|
${soul}
|
|
272
290
|
${buildPersonaBlock()}
|
|
273
291
|
${buildLessonsBlock()}
|
|
292
|
+
${buildBotKindBlock()}
|
|
274
293
|
## Open Claudia runtime
|
|
275
294
|
- Interface: chat through Open Claudia using the selected coding-agent provider.
|
|
276
295
|
- Voice notes: ${hasVoice ? "enabled" : "disabled"}
|
|
@@ -1569,6 +1588,7 @@ const buildSystemPrompt = buildCoreInstructions;
|
|
|
1569
1588
|
|
|
1570
1589
|
module.exports = {
|
|
1571
1590
|
browserRuntimeNote,
|
|
1591
|
+
buildBotKindBlock,
|
|
1572
1592
|
liveCallCameraNote,
|
|
1573
1593
|
voiceReplyGuidance,
|
|
1574
1594
|
PromptConstructionError,
|
package/core/usage-log.js
CHANGED
package/core/web-otp.js
CHANGED
|
@@ -19,26 +19,35 @@ function _save(list) {
|
|
|
19
19
|
try { fs.writeFileSync(OTP_FILE, JSON.stringify(list), { mode: 0o600 }); } catch (e) {}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
// `userId` names the person the link is for (the /dashboard command passes
|
|
23
|
+
// the sender). Agent Space's SSO mint names nobody. A personal bot counts a
|
|
24
|
+
// dashboard session as its owner only when it names her (core/access.js).
|
|
25
|
+
function mint(opts = {}) {
|
|
26
|
+
const { ttlMs = TTL_MS, userId = "" } = typeof opts === "number" ? { ttlMs: opts } : (opts || {});
|
|
23
27
|
const token = crypto.randomBytes(32).toString("hex");
|
|
24
28
|
const expiresAt = Date.now() + ttlMs;
|
|
25
29
|
const now = Date.now();
|
|
26
30
|
const list = _load().filter((e) => e && e.expiresAt > now);
|
|
27
|
-
list.push({ token, expiresAt });
|
|
31
|
+
list.push(userId ? { token, expiresAt, userId: String(userId) } : { token, expiresAt });
|
|
28
32
|
_save(list);
|
|
29
33
|
return { token, expiresAt };
|
|
30
34
|
}
|
|
31
35
|
|
|
32
|
-
// Validate and burn (single use). Returns
|
|
33
|
-
// present and unexpired; prunes expired entries
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
// Validate and burn (single use). Returns the entry ({ userId? }) only if
|
|
37
|
+
// the token was present and unexpired, else null; prunes expired entries
|
|
38
|
+
// either way.
|
|
39
|
+
function take(token) {
|
|
40
|
+
if (!token || typeof token !== "string") return null;
|
|
36
41
|
const now = Date.now();
|
|
37
42
|
const list = _load();
|
|
38
43
|
const idx = list.findIndex((e) => e && e.token === token && e.expiresAt > now);
|
|
39
44
|
const remaining = list.filter((e, i) => e && e.expiresAt > now && i !== idx);
|
|
40
45
|
if (remaining.length !== list.length) _save(remaining);
|
|
41
|
-
return idx !== -1;
|
|
46
|
+
return idx !== -1 ? list[idx] : null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function consume(token) {
|
|
50
|
+
return !!take(token);
|
|
42
51
|
}
|
|
43
52
|
|
|
44
|
-
module.exports = { mint, consume, OTP_FILE, TTL_MS };
|
|
53
|
+
module.exports = { mint, take, consume, OTP_FILE, TTL_MS };
|
package/core/web-sessions.js
CHANGED
|
@@ -40,12 +40,15 @@ function sweep(sessions, now = Date.now()) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
// Mint and persist a fresh session token, returning it for the Set-Cookie.
|
|
43
|
-
|
|
43
|
+
// `userId` is the person the session was opened for (an owner's /dashboard
|
|
44
|
+
// link); a password login names nobody.
|
|
45
|
+
function issue({ userId = "" } = {}) {
|
|
44
46
|
const token = crypto.randomBytes(32).toString("hex");
|
|
45
47
|
const sessions = load();
|
|
46
48
|
sweep(sessions);
|
|
47
49
|
const now = Date.now();
|
|
48
50
|
sessions[token] = { created: now, expires: now + TTL_MS };
|
|
51
|
+
if (userId) sessions[token].userId = String(userId);
|
|
49
52
|
persist(sessions);
|
|
50
53
|
return token;
|
|
51
54
|
}
|
|
@@ -61,6 +64,12 @@ function valid(token) {
|
|
|
61
64
|
return true;
|
|
62
65
|
}
|
|
63
66
|
|
|
67
|
+
// The person a live session was opened for, or "".
|
|
68
|
+
function userIdOf(token) {
|
|
69
|
+
if (!valid(token)) return "";
|
|
70
|
+
return String(load()[token].userId || "");
|
|
71
|
+
}
|
|
72
|
+
|
|
64
73
|
function revoke(token) {
|
|
65
74
|
if (!token) return;
|
|
66
75
|
const sessions = load();
|
|
@@ -75,4 +84,4 @@ function revokeAll() {
|
|
|
75
84
|
persist({});
|
|
76
85
|
}
|
|
77
86
|
|
|
78
|
-
module.exports = { issue, valid, revoke, revokeAll, sweep, TTL_MS, SESSIONS_FILE };
|
|
87
|
+
module.exports = { issue, valid, userIdOf, revoke, revokeAll, sweep, TTL_MS, SESSIONS_FILE };
|
package/docker-entrypoint.sh
CHANGED
|
@@ -83,15 +83,5 @@ if [ -f "$ENV_FILE" ]; then
|
|
|
83
83
|
sync_env_key KAZEE_OWNER_USER_ID "$KAZEE_OWNER_USER_ID"
|
|
84
84
|
fi
|
|
85
85
|
|
|
86
|
-
# OC_NODE_FLAGS: Node flags for the main process only, on its command line.
|
|
87
|
-
# NODE_OPTIONS would hand them to every node child (agents, hooks, CLI runs).
|
|
88
|
-
if [ -n "$OC_NODE_FLAGS" ] && [ "${1##*/}" = "node" ]; then
|
|
89
|
-
node_bin="$1"; shift
|
|
90
|
-
flags="$OC_NODE_FLAGS"; unset OC_NODE_FLAGS
|
|
91
|
-
set -f # split on spaces, no file-name expansion
|
|
92
|
-
# shellcheck disable=SC2086
|
|
93
|
-
exec "$node_bin" $flags "$@"
|
|
94
|
-
fi
|
|
95
|
-
|
|
96
86
|
# Execute the main command
|
|
97
87
|
exec "$@"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inetafrica/open-claudia",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.75",
|
|
4
4
|
"description": "An always-on, provider-agnostic coding-agent harness for Claude Code and OpenAI Codex via chat",
|
|
5
5
|
"main": "bot.js",
|
|
6
6
|
"bin": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"setup": "node setup.js",
|
|
12
12
|
"start": "node bot.js",
|
|
13
13
|
"pretest": "node test-provider-fixture.js && node test-provider-core-prompt.js && node test-turn-observer.js && node test-provider-prompt-parity.js && node test-provider-env-isolation.js && node test-provider-resume-parity.js && node test-provider-bootstrap.js && node test-provider-registry.js && node test-provider-stream-decoder.js && node test-provider-events.js && node test-provider-claude.js && node test-provider-codex.js && node test-codex-output-schema.js && node test-codex-device-login.js && node test-provider-runner.js && node test-provider-refusal-recovery.js && node test-provider-run-lifecycle.js && node test-provider-gateway.js && node test-provider-side-chat.js && node test-single-runtime.js && node test-provider-migration-backup.js && node test-provider-state-migration.js && node test-provider-session-history.js && node test-provider-session-commands.js && node test-provider-compaction.js && node test-provider-scheduler.js && node test-credential-capture.js && node test-effort-reset.js && node test-cursor-removal.js && node test-utility-provider-policy.js && node test-provider-subagent.js && node test-provider-recall.js && node test-provider-pack-review.js && node test-memory-mutation-queue.js && node test-provider-dream.js && node test-provider-enforcer.js && node test-provider-tool-hooks.js && node test-provider-boot-matrix.js && node test-provider-capabilities.js && node test-provider-language.js && node test-upgrade-path.js && node test-provider-coupling-audit.js && node test-provider-parity-e2e.js && node test-kazee-channel-health.js && node test-kazee-media-caption.js && node test-kazee-context-media.js && node test-kazee-typing-join.js && node test-kazee-inbound-dedup.js && node test-typing-phase-push.js && node test-socket-reconnect.js && node test-speech-loopback.js && node test-prompt-budget.js && node test-agency-ledger.js && node test-agency-deliberate.js && node test-guardrail.js && node test-group-status-notes.js && node test-spaces-comment-content.js && node test-boot-health.js && node test-lexical-floor.js && node test-safe-mode.js && node test-logout.js && node test-kazee-call-audio.js && node test-kazee-call-janus.js && node test-kazee-call-webrtc.js && node test-kazee-call-speech.js && node test-kazee-call-manager.js && node test-call-speech.js && node test-kazee-call-session.js",
|
|
14
|
-
"test": "OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node -e \"require('./vault'); console.log('OK')\" && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-runner-watchdog-static.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-usage-accounting.js && node test-codex-rollout.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-engine.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-graph.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-discoverer.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-query.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-walker-score.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-score-gate.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-cokept-warming.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-project-transcripts-smoke.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-transcript-room-scope.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-abilities.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-extraction.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-couse.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-transfer.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-tiers.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-merge-guard.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-learning-e2e.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-pack-nesting.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-pack-search.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-extractive-injection.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-journal-dedupe.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-read-signal.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tools.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tool-graph.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tool-guard.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-test-run-guard.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-read-guard.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tooling-mode.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tool-manifest.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-evolution.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-approval-async.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-unified-identity.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-persona-packs.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-speaker-persona.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-persona-pipeline.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-relationship-gate.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-relationship.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-enforcer.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-mandate-hygiene.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-external-rule-scopes.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-owner-cards-dm.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-approval-cards.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-identity-prune.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-kazee-message-id.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-kazee-group-gate.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-kazee-group-context.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-kazee-threads.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-people-owner-seed.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-delivery-contract.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-run-lock.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-thread-lanes.js && node test-thread-titles.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-thread-stop.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-stop-queue.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-typing-heartbeat.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-web-sessions.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-telegram-poll-recovery.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-telegram-409-grace.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-telegram-conflict-heal-guard.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-single-instance.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-streaming-split.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-stream-preview-purpose.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-quiet-defaults.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-spaces-autoenable.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-say-loopback.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-loopback-threads.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-thread-handoff.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-transcript-threads.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-journal-union.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-subst-score.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-section-budgets.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-dedup-adjudicator.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-prospective.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-regressions.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-cost-report.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-cost-by-part.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-speaker-context.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-approval-mining.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tool-certification.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-apprenticeship.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-speaker-attest.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-run-attest.js && node test-sandbox-probe.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-bot-endpoint.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tool-gate.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-cli-owner-gates.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-verify-contact.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-loopback-owner-gate.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-watch-check-env.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-intro-adoption.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-grants.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-room-provider-settings.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-store-durability.js && node test-kazee-cards.js && node test-card-blocks.js && node test-decision-upkeep.js && node test-passive-replies.js && node test-kazee-bot-loops.js && node test-kazee-bot-handoffs.js && node test-placeholder-reply.js && node test-media-speech.js && node test-speech-voices.js && node test-tts-voice.js && node test-passive-replies-router.js && node test-loopback-cards.js && node test-task-injection.js && node test-speaker-extras.js && node test-token-diet.js && node test-dream-tasks.js && node test-task-archive.js && node test-cron-tolerance.js && node test-dream-schedule.js && node test-job-failures.js && node test-scheduled-placeholder.js && node test-lessons-since.js && node test-pack-reinject.js && node test-turn-journal.js && node test-kazee-catchup.js && node test-usage-limits.js && node test-limit-waits.js && node test-signin-race-retry.js && node test-limit-pickup.js && node test-browser-view.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test node test-web-browser-view.js && node test-browser-address.js && node test-browser-control.js && node test-browser-drive.js && node test-browser-teach.js && node test-kazee-bot-apps.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test node test-web-browser-app.js && node test-safe-filename.js && node test-media-filename-paths.js && node test-router-document-guard.js && OPEN_CLAUDIA_TEST=1 node test-web-dashboard-escape.js && OPEN_CLAUDIA_TEST=1 node test-web-bad-requests.js && OPEN_CLAUDIA_TEST=1 node test-kazee-download-limit.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test node test-web-auth-routes.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test node test-web-otp-link-preview.js && node test-call-quick-voice.js && node test-call-run-stop.js && node test-call-stopped-transcript.js && node test-call-greeting-context.js && node test-call-camera.js && node test-switchboard-calls.js && node test-switchboard-supervisor.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-topic-lessons.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-env-pins.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-session-core.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-transcript-related.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-pack-decisions.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-external.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-introspection-retry.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-watch-every-cron.js && node test-rust-cli-parity.js && node test-lazy-heavy-libs.js && node test-lessons-meta-keep.js && node test-walker-idle-stop.js && node test-usage-history-lazy.js && node test-node-flags-entrypoint.js && node test-recall-engine-env.js && node test-review-queue.js"
|
|
14
|
+
"test": "OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node -e \"require('./vault'); console.log('OK')\" && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-runner-watchdog-static.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-usage-accounting.js && node test-codex-rollout.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-engine.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-graph.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-discoverer.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-query.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-walker-score.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-score-gate.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-cokept-warming.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-project-transcripts-smoke.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-transcript-room-scope.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-abilities.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-extraction.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-couse.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-transfer.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-tiers.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-merge-guard.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-learning-e2e.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-pack-nesting.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-pack-search.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-extractive-injection.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-journal-dedupe.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-read-signal.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tools.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tool-graph.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tool-guard.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-test-run-guard.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-read-guard.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tooling-mode.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tool-manifest.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-evolution.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-approval-async.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-unified-identity.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-persona-packs.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-speaker-persona.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-persona-pipeline.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-relationship-gate.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-relationship.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-enforcer.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-mandate-hygiene.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-external-rule-scopes.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-owner-cards-dm.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-approval-cards.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-identity-prune.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-kazee-message-id.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-kazee-group-gate.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-kazee-group-context.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-kazee-threads.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-people-owner-seed.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-delivery-contract.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-run-lock.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-thread-lanes.js && node test-thread-titles.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-thread-stop.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-stop-queue.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-typing-heartbeat.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-web-sessions.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-telegram-poll-recovery.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-telegram-409-grace.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-telegram-conflict-heal-guard.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-single-instance.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-streaming-split.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-stream-preview-purpose.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-quiet-defaults.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-spaces-autoenable.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-say-loopback.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-loopback-threads.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-thread-handoff.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-transcript-threads.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-journal-union.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-subst-score.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-section-budgets.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-dedup-adjudicator.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-prospective.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-regressions.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-cost-report.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-cost-by-part.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-speaker-context.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-approval-mining.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tool-certification.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-apprenticeship.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-speaker-attest.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-run-attest.js && node test-sandbox-probe.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-bot-endpoint.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tool-gate.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-cli-owner-gates.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-verify-contact.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-loopback-owner-gate.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-watch-check-env.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-intro-adoption.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-grants.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-room-provider-settings.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-store-durability.js && node test-kazee-cards.js && node test-card-blocks.js && node test-decision-upkeep.js && node test-passive-replies.js && node test-kazee-bot-loops.js && node test-kazee-bot-handoffs.js && node test-placeholder-reply.js && node test-media-speech.js && node test-speech-voices.js && node test-tts-voice.js && node test-passive-replies-router.js && node test-loopback-cards.js && node test-task-injection.js && node test-speaker-extras.js && node test-token-diet.js && node test-dream-tasks.js && node test-task-archive.js && node test-cron-tolerance.js && node test-dream-schedule.js && node test-job-failures.js && node test-scheduled-placeholder.js && node test-lessons-since.js && node test-pack-reinject.js && node test-turn-journal.js && node test-kazee-catchup.js && node test-usage-limits.js && node test-limit-waits.js && node test-signin-race-retry.js && node test-limit-pickup.js && node test-browser-view.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test node test-web-browser-view.js && node test-browser-address.js && node test-browser-control.js && node test-browser-drive.js && node test-browser-teach.js && node test-kazee-bot-apps.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test node test-web-browser-app.js && node test-safe-filename.js && node test-media-filename-paths.js && node test-router-document-guard.js && OPEN_CLAUDIA_TEST=1 node test-web-dashboard-escape.js && OPEN_CLAUDIA_TEST=1 node test-web-bad-requests.js && OPEN_CLAUDIA_TEST=1 node test-kazee-download-limit.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test node test-web-auth-routes.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test node test-web-otp-link-preview.js && node test-call-quick-voice.js && node test-call-run-stop.js && node test-call-stopped-transcript.js && node test-call-greeting-context.js && node test-call-camera.js && node test-switchboard-calls.js && node test-switchboard-supervisor.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-topic-lessons.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-env-pins.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-session-core.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-transcript-related.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-pack-decisions.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-external.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-introspection-retry.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-watch-every-cron.js && node test-rust-cli-parity.js && OPEN_CLAUDIA_TEST=1 node test-bot-acts-for-owner.js"
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
17
|
"bot.js",
|
|
@@ -664,13 +664,14 @@ assert.match(pkg.description, /provider-agnostic coding-agent harness/i);
|
|
|
664
664
|
// reset file up and the bot saved the old max/xhigh back. Same approved
|
|
665
665
|
// rollout (Sumeet, 20 Oct: "set high on all the bots"), now working.
|
|
666
666
|
// Sumeet, 31 Oct 08:02 EAT card 6ae574c5: "Release to all bots now, without
|
|
667
|
-
// the Maia rename". 3.5.74
|
|
668
|
-
// 3.5.
|
|
667
|
+
// the Maia rename". 3.5.74 = 3.5.73 + the Rust command helper (Sumeet 8 Nov, card 6af067bc: "Yes, Maya Cloud first, then one bot at a time").
|
|
668
|
+
// 3.5.75 = 3.5.74 + personal bots act for their owner through a pass, and the
|
|
669
|
+
// one-tap switch-on card (from the Maia build: plan v2 of 25 Oct, SEC-28 of 30 Oct).
|
|
669
670
|
// 3.5.73 = 3.5.72 + a smaller image (Sumeet 31 Oct 15:06, bot resource plan: "proceed ... roll out the others").
|
|
670
671
|
// 3.5.72 = 3.5.71 + the Mac memory fixes of 22-28 Oct:
|
|
671
672
|
// topic lessons ride with their pack, .env recall pins, prompt fixes, past
|
|
672
673
|
// chats reach recall, settled decisions, /engine x|mem0, nightly retry.
|
|
673
|
-
assert.strictEqual(pkg.version, "3.5.
|
|
674
|
+
assert.strictEqual(pkg.version, "3.5.75", "release version must remain unchanged without explicit approval");
|
|
674
675
|
for (const keyword of ["claude", "codex", "coding-agent", "provider-agnostic"]) {
|
|
675
676
|
assert.ok(pkg.keywords.includes(keyword), `package keyword missing: ${keyword}`);
|
|
676
677
|
}
|
package/web.js
CHANGED
|
@@ -143,6 +143,15 @@ function checkAuth(req) {
|
|
|
143
143
|
return webSessions.valid(token);
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
// The person the request's dashboard session was opened for (an owner's
|
|
147
|
+
// /dashboard link), or "" for a password login, Agent Space's link or the
|
|
148
|
+
// control token.
|
|
149
|
+
function sessionUserId(req) {
|
|
150
|
+
const cookie = (req.headers.cookie || "").split(";").find((c) => c.trim().startsWith("oc_session="));
|
|
151
|
+
if (!cookie) return "";
|
|
152
|
+
return webSessions.userIdOf(cookie.split("=")[1]?.trim());
|
|
153
|
+
}
|
|
154
|
+
|
|
146
155
|
// Hash both sides so timingSafeEqual gets equal-length buffers and the
|
|
147
156
|
// comparison leaks neither content nor password length.
|
|
148
157
|
function safeEqual(a, b) {
|
|
@@ -190,10 +199,10 @@ function clearLoginFailures(req) {
|
|
|
190
199
|
|
|
191
200
|
// Secure flag only when the client actually arrived over HTTPS (ingress
|
|
192
201
|
// sets X-Forwarded-Proto) — keeps plain-HTTP port-forward logins working.
|
|
193
|
-
function sessionCookie(req) {
|
|
202
|
+
function sessionCookie(req, userId = "") {
|
|
194
203
|
const proto = String(req.headers["x-forwarded-proto"] || "").split(",")[0].trim();
|
|
195
204
|
const secure = proto === "https" ? "; Secure" : "";
|
|
196
|
-
return `oc_session=${webSessions.issue()}; Path=/; HttpOnly; SameSite=Strict; Max-Age=86400${secure}`;
|
|
205
|
+
return `oc_session=${webSessions.issue({ userId })}; Path=/; HttpOnly; SameSite=Strict; Max-Age=86400${secure}`;
|
|
197
206
|
}
|
|
198
207
|
|
|
199
208
|
// ── Config helpers ─────────────────────────────────────────────────
|
|
@@ -796,7 +805,7 @@ async function handleAPI(req, res, body, dependencies = {}) {
|
|
|
796
805
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
797
806
|
return res.end(JSON.stringify({ error: "Empty message" }));
|
|
798
807
|
}
|
|
799
|
-
const messageId = webChat.postText(String(text));
|
|
808
|
+
const messageId = webChat.postText(String(text), { userId: sessionUserId(req) });
|
|
800
809
|
res.writeHead(202, { "Content-Type": "application/json" });
|
|
801
810
|
return res.end(JSON.stringify({ ok: true, messageId }));
|
|
802
811
|
}
|
|
@@ -804,7 +813,7 @@ async function handleAPI(req, res, body, dependencies = {}) {
|
|
|
804
813
|
if (url === "/api/chat/action" && req.method === "POST") {
|
|
805
814
|
let parsed = {};
|
|
806
815
|
try { parsed = JSON.parse(body || "{}"); } catch (e) {}
|
|
807
|
-
const callbackId = webChat.postAction(parsed);
|
|
816
|
+
const callbackId = webChat.postAction(parsed, { userId: sessionUserId(req) });
|
|
808
817
|
if (!callbackId) {
|
|
809
818
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
810
819
|
return res.end(JSON.stringify({ error: "Missing action payload" }));
|
|
@@ -862,10 +871,11 @@ async function handleAPI(req, res, body, dependencies = {}) {
|
|
|
862
871
|
setPassword(newPassword);
|
|
863
872
|
// Changing the password invalidates every outstanding session, then we
|
|
864
873
|
// re-issue one so the caller who just changed it stays logged in.
|
|
874
|
+
const keptUserId = sessionUserId(req);
|
|
865
875
|
webSessions.revokeAll();
|
|
866
876
|
res.writeHead(200, {
|
|
867
877
|
"Content-Type": "application/json",
|
|
868
|
-
"Set-Cookie": sessionCookie(req),
|
|
878
|
+
"Set-Cookie": sessionCookie(req, keptUserId),
|
|
869
879
|
});
|
|
870
880
|
return res.end(JSON.stringify({ ok: true }));
|
|
871
881
|
}
|
|
@@ -1689,11 +1699,12 @@ function startWebServer(options = {}) {
|
|
|
1689
1699
|
return page(200, `<form method="post" action="/otp/${token}"><h2>Opening your dashboard…</h2><button type="submit">Open dashboard</button></form>`, "<script>document.forms[0].submit()</script>");
|
|
1690
1700
|
}
|
|
1691
1701
|
req.resume();
|
|
1692
|
-
const {
|
|
1693
|
-
|
|
1702
|
+
const { take } = require("./core/web-otp");
|
|
1703
|
+
const entry = take(token);
|
|
1704
|
+
if (entry) {
|
|
1694
1705
|
res.writeHead(302, {
|
|
1695
1706
|
"Location": "/",
|
|
1696
|
-
"Set-Cookie": sessionCookie(req),
|
|
1707
|
+
"Set-Cookie": sessionCookie(req, entry.userId || ""),
|
|
1697
1708
|
});
|
|
1698
1709
|
return res.end();
|
|
1699
1710
|
}
|