@inetafrica/open-claudia 3.5.20 → 3.5.23
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/.env.example +8 -3
- package/CHANGELOG.md +27 -0
- package/README.md +5 -4
- package/core/actions.js +4 -0
- package/core/auth-flow.js +7 -2
- package/core/dream.js +132 -10
- package/core/handlers.js +16 -2
- package/core/limit-pickup.js +24 -20
- package/core/providers/claude.js +15 -8
- package/core/providers/events.js +25 -1
- package/core/providers/utility-policy.js +31 -6
- package/core/runner.js +203 -10
- package/core/scheduler.js +57 -0
- package/core/state.js +14 -0
- package/core/system-prompt.js +1 -1
- package/core/turn-journal.js +55 -2
- package/core/usage-limits.js +110 -0
- package/core/utility-agent.js +109 -15
- package/package.json +2 -2
- package/test-fixtures/fake-agent-cli.js +46 -2
- package/test-provider-boot-matrix.js +6 -2
- package/test-provider-capabilities.js +1 -1
- package/test-provider-claude.js +7 -5
- package/test-provider-events.js +43 -1
- package/test-provider-language.js +11 -1
package/core/usage-limits.js
CHANGED
|
@@ -302,9 +302,119 @@ function limitHitDetails({ provider, error, rateLimit = null, windows = [], now
|
|
|
302
302
|
};
|
|
303
303
|
}
|
|
304
304
|
|
|
305
|
+
// ---------------------------------------------------------------------------
|
|
306
|
+
// Waiting for a reset: one rule and one record for every kind of work
|
|
307
|
+
// (Sumeet, 9 Oct 2026: a used-up limit is handled the same way everywhere,
|
|
308
|
+
// as a runtime concept, not a fix per feature).
|
|
309
|
+
//
|
|
310
|
+
// - limitRetryAt() is when work a limit stopped runs again: a chat message
|
|
311
|
+
// (core/limit-pickup), a scheduled run (core/scheduler), the dream's AI
|
|
312
|
+
// step (core/dream). Never another provider: the other one may not be
|
|
313
|
+
// signed in or may be used up too.
|
|
314
|
+
// - noteLimitHit() records that a provider is used up until its reset,
|
|
315
|
+
// from any run a limit stopped; a run that works clears it
|
|
316
|
+
// (clearLimitBlock). Background calls read it (limitBlock) and do not
|
|
317
|
+
// start a used-up provider again and again. Chat turns never read it:
|
|
318
|
+
// they always try, so the provider stays the judge.
|
|
319
|
+
|
|
320
|
+
function setting(name) {
|
|
321
|
+
if (process.env[name] !== undefined) return process.env[name];
|
|
322
|
+
return config[name];
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Wait this long after the reset, so the provider's window has turned over.
|
|
326
|
+
function limitRetryDelayMs() {
|
|
327
|
+
const n = Number(setting("LIMIT_PICKUP_DELAY_S"));
|
|
328
|
+
return (Number.isFinite(n) && n >= 0 ? n : 120) * 1000;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// A reset further out than this (a monthly spend cap) is not waited for.
|
|
332
|
+
function limitMaxWaitMs() {
|
|
333
|
+
const n = Number(setting("LIMIT_PICKUP_MAX_WAIT_H"));
|
|
334
|
+
return (Number.isFinite(n) && n > 0 ? n : 192) * 3600000;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/** When work a limit stopped should run again; null when the reset is not known. */
|
|
338
|
+
function limitRetryAt(resetsAt, { now = Date.now() } = {}) {
|
|
339
|
+
if (!Number.isFinite(resetsAt) || resetsAt <= now - 6 * 3600000) return null;
|
|
340
|
+
return Math.max(resetsAt, now) + limitRetryDelayMs();
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/** Whether a wait until `runAt` is short enough to wait for. */
|
|
344
|
+
function canWaitFor(runAt, { now = Date.now() } = {}) {
|
|
345
|
+
return Number.isFinite(runAt) && runAt - now <= limitMaxWaitMs();
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
function liveFile(file) {
|
|
349
|
+
// A test run that did not point the config dir somewhere else never touches
|
|
350
|
+
// the live bot's file.
|
|
351
|
+
return !(file === DEFAULT_FILE && process.env.OPEN_CLAUDIA_TEST === "1" && !process.env.OPEN_CLAUDIA_CONFIG_DIR);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// A model-family limit (Claude's weekly Opus or Sonnet limit) stops only that
|
|
355
|
+
// family; an unknown model counts as stopped.
|
|
356
|
+
function blocksModel(limitType, model) {
|
|
357
|
+
const family = /opus|sonnet|fable|haiku/i.exec(String(limitType || ""));
|
|
358
|
+
if (!family || !model) return true;
|
|
359
|
+
return String(model).toLowerCase().includes(family[0].toLowerCase());
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/** Record that `provider` is used up until `resetsAt` (a run hit its limit). */
|
|
363
|
+
function noteLimitHit({ provider, limitType = null, resetsAt, file = DEFAULT_FILE, now = Date.now() } = {}) {
|
|
364
|
+
if (!provider || !Number.isFinite(resetsAt) || resetsAt <= now || !liveFile(file)) return null;
|
|
365
|
+
return withFileLock(file, () => {
|
|
366
|
+
const state = readState(file);
|
|
367
|
+
if (!state.blocks || typeof state.blocks !== "object") state.blocks = {};
|
|
368
|
+
const previous = state.blocks[provider];
|
|
369
|
+
const block = {
|
|
370
|
+
limitType: limitType || null,
|
|
371
|
+
resetsAt,
|
|
372
|
+
since: previous && previous.resetsAt > now ? previous.since : new Date(now).toISOString(),
|
|
373
|
+
updatedAt: new Date(now).toISOString(),
|
|
374
|
+
};
|
|
375
|
+
state.blocks[provider] = block;
|
|
376
|
+
atomicWriteFileSync(file, JSON.stringify(state, null, 2) + "\n");
|
|
377
|
+
return { provider, ...block };
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/** The limit `provider` is used up on now, or null. `model` narrows a model-family limit. */
|
|
382
|
+
function limitBlock(provider, { model = null, file = DEFAULT_FILE, now = Date.now() } = {}) {
|
|
383
|
+
if (!provider || !liveFile(file)) return null;
|
|
384
|
+
const block = readState(file).blocks?.[provider];
|
|
385
|
+
if (!block || !Number.isFinite(block.resetsAt) || block.resetsAt <= now) return null;
|
|
386
|
+
if (!blocksModel(block.limitType, model)) return null;
|
|
387
|
+
return { provider, ...block };
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* A run on `provider` worked: it is not used up (any more). A run on a model
|
|
392
|
+
* a model-family limit does not cover proves nothing about that limit.
|
|
393
|
+
*/
|
|
394
|
+
function clearLimitBlock(provider, { model = null, file = DEFAULT_FILE } = {}) {
|
|
395
|
+
if (!provider || !liveFile(file)) return false;
|
|
396
|
+
// Read first: almost every run finds nothing to clear and writes nothing.
|
|
397
|
+
const found = readState(file).blocks?.[provider];
|
|
398
|
+
if (!found || !blocksModel(found.limitType, model)) return false;
|
|
399
|
+
return withFileLock(file, () => {
|
|
400
|
+
const state = readState(file);
|
|
401
|
+
if (!state.blocks?.[provider]) return false;
|
|
402
|
+
delete state.blocks[provider];
|
|
403
|
+
atomicWriteFileSync(file, JSON.stringify(state, null, 2) + "\n");
|
|
404
|
+
return true;
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
|
|
305
408
|
module.exports = {
|
|
306
409
|
DEFAULT_FILE,
|
|
307
410
|
DEFAULT_WARN_PERCENTS,
|
|
411
|
+
limitRetryDelayMs,
|
|
412
|
+
limitMaxWaitMs,
|
|
413
|
+
limitRetryAt,
|
|
414
|
+
canWaitFor,
|
|
415
|
+
noteLimitHit,
|
|
416
|
+
limitBlock,
|
|
417
|
+
clearLimitBlock,
|
|
308
418
|
warnPercents,
|
|
309
419
|
providerLabel,
|
|
310
420
|
windowLabel,
|
package/core/utility-agent.js
CHANGED
|
@@ -9,7 +9,7 @@ const { MAX_PROCESS_TIMEOUT } = require("./config");
|
|
|
9
9
|
const { killProcessTree } = require("./process-tree");
|
|
10
10
|
const { redactSensitive } = require("./redact");
|
|
11
11
|
const { validateInvocation } = require("./providers/contract");
|
|
12
|
-
const { selectTerminalText } = require("./providers/events");
|
|
12
|
+
const { providerFailureCode, selectTerminalText } = require("./providers/events");
|
|
13
13
|
const { createUtilityPolicy, normalizePurpose } = require("./providers/utility-policy");
|
|
14
14
|
|
|
15
15
|
const DEFAULT_TIMEOUT_MS = 10 * 60 * 1000;
|
|
@@ -20,6 +20,11 @@ const DEFAULT_KILL_GRACE_MS = 500;
|
|
|
20
20
|
const DEFAULT_GLOBAL_CONCURRENCY = 6;
|
|
21
21
|
const DEFAULT_PURPOSE_CONCURRENCY = 3;
|
|
22
22
|
const DEFAULT_RECURSION_DEPTH = 2;
|
|
23
|
+
// Claude Code's refresh-lock race passes in seconds: one more try after this,
|
|
24
|
+
// for work nobody waits on. A chat's own checks (recall, a passive reply, a
|
|
25
|
+
// title, the guard) go without instead of holding the reply up.
|
|
26
|
+
const DEFAULT_TRANSIENT_RETRY_MS = 20 * 1000;
|
|
27
|
+
const TRANSIENT_RETRY_PURPOSES = new Set(["dream", "introspection", "review", "dedup", "subagent"]);
|
|
23
28
|
const DEFAULT_SYSTEM_PROMPT = [
|
|
24
29
|
"You are a bounded Open Claudia utility agent.",
|
|
25
30
|
"Follow the supplied task and return only the requested result.",
|
|
@@ -62,8 +67,22 @@ function appendBounded(current, addition, maxBytes) {
|
|
|
62
67
|
return clipUtf8(joined, maxBytes);
|
|
63
68
|
}
|
|
64
69
|
|
|
65
|
-
function stableError(code, message) {
|
|
66
|
-
return {
|
|
70
|
+
function stableError(code, message, details = null) {
|
|
71
|
+
return {
|
|
72
|
+
code,
|
|
73
|
+
message: redactSensitive(String(message || "Utility agent failed")),
|
|
74
|
+
...(details ? { details } : {}),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// A limit's reset as the provider reported it (Claude: the rate_limit_event);
|
|
79
|
+
// usage-limits.limitHitDetails reads it, else the wording of the message.
|
|
80
|
+
function failureDetails(event, code) {
|
|
81
|
+
if (code !== "PROVIDER_USAGE_LIMIT") return null;
|
|
82
|
+
return {
|
|
83
|
+
limitResetsAt: Number.isFinite(event?.limitResetsAt) ? event.limitResetsAt : null,
|
|
84
|
+
limitType: event?.limitType || null,
|
|
85
|
+
};
|
|
67
86
|
}
|
|
68
87
|
|
|
69
88
|
function extractJson(text) {
|
|
@@ -298,10 +317,10 @@ function executeUtilityInvocation(options) {
|
|
|
298
317
|
else if (cancelled) failure = stableError("UTILITY_CANCELLED", "Utility agent was cancelled");
|
|
299
318
|
else if (timedOut) failure = stableError("UTILITY_TIMEOUT", "Utility agent timed out");
|
|
300
319
|
else if (outputLimit) failure = stableError("UTILITY_OUTPUT_LIMIT", "Utility provider stdout exceeded its hard limit");
|
|
301
|
-
else if (normalizedFailure)
|
|
302
|
-
|
|
303
|
-
normalizedFailure.message || "Utility provider failed",
|
|
304
|
-
|
|
320
|
+
else if (normalizedFailure) {
|
|
321
|
+
const code = providerFailureCode(normalizedFailure, "UTILITY_PROVIDER_ERROR");
|
|
322
|
+
failure = stableError(code, normalizedFailure.message || "Utility provider failed", failureDetails(normalizedFailure, code));
|
|
323
|
+
}
|
|
305
324
|
else if (closeInfo?.code !== 0) failure = stableError(
|
|
306
325
|
"UTILITY_PROCESS_FAILED",
|
|
307
326
|
safeStderr || `Utility provider exited with code ${closeInfo?.code == null ? "unknown" : closeInfo.code}`,
|
|
@@ -423,6 +442,21 @@ function executeUtilityInvocation(options) {
|
|
|
423
442
|
});
|
|
424
443
|
}
|
|
425
444
|
|
|
445
|
+
// Wait `ms`, or less when the call is cancelled meanwhile.
|
|
446
|
+
function pause(ms, signal) {
|
|
447
|
+
return new Promise((resolve) => {
|
|
448
|
+
if (signal?.aborted || !(ms > 0)) return resolve();
|
|
449
|
+
let timer = null;
|
|
450
|
+
const done = () => {
|
|
451
|
+
clearTimeout(timer);
|
|
452
|
+
signal?.removeEventListener?.("abort", done);
|
|
453
|
+
resolve();
|
|
454
|
+
};
|
|
455
|
+
timer = setTimeout(done, ms);
|
|
456
|
+
signal?.addEventListener?.("abort", done, { once: true });
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
|
|
426
460
|
function fallbackEligible(errorCode) {
|
|
427
461
|
return new Set([
|
|
428
462
|
"PROVIDER_UNAVAILABLE",
|
|
@@ -438,6 +472,12 @@ function createUtilityAgentService(options = {}) {
|
|
|
438
472
|
const registry = options.registry || require("./providers");
|
|
439
473
|
const env = options.env || require("./config").config;
|
|
440
474
|
const policy = options.policy || createUtilityPolicy({ registry, env, activeProvider: options.activeProvider });
|
|
475
|
+
// The limit record (core/usage-limits.js): a used-up provider is not
|
|
476
|
+
// started; a limit hit is recorded; a call that worked clears it.
|
|
477
|
+
const limitsLib = options.limits || require("./usage-limits");
|
|
478
|
+
const transientRetryMs = Number.isFinite(Number(options.transientRetryMs)) && Number(options.transientRetryMs) >= 0
|
|
479
|
+
? Number(options.transientRetryMs)
|
|
480
|
+
: DEFAULT_TRANSIENT_RETRY_MS;
|
|
441
481
|
const spawnProcess = options.spawnProcess || spawn;
|
|
442
482
|
const killTree = options.killTree || killProcessTree;
|
|
443
483
|
const killGraceMs = positiveInteger(options.killGraceMs, DEFAULT_KILL_GRACE_MS, "killGraceMs");
|
|
@@ -490,6 +530,20 @@ function createUtilityAgentService(options = {}) {
|
|
|
490
530
|
else activeByPurpose.set(purpose, activePurpose - 1);
|
|
491
531
|
}
|
|
492
532
|
|
|
533
|
+
function usedUpFor(selection) {
|
|
534
|
+
try { return limitsLib.limitBlock(selection.providerId, { model: selection.model }); }
|
|
535
|
+
catch (_) { return null; }
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
function noteLimits(providerId, result) {
|
|
539
|
+
try {
|
|
540
|
+
if (result.ok) { limitsLib.clearLimitBlock(providerId, { model: result.model || null }); return; }
|
|
541
|
+
if (result.error?.code !== "PROVIDER_USAGE_LIMIT" || result.notStarted) return;
|
|
542
|
+
const hit = limitsLib.limitHitDetails({ provider: providerId, error: result.error });
|
|
543
|
+
if (hit?.resetsAt) limitsLib.noteLimitHit({ provider: providerId, limitType: hit.limitType, resetsAt: hit.resetsAt });
|
|
544
|
+
} catch (_) { /* the record is best effort */ }
|
|
545
|
+
}
|
|
546
|
+
|
|
493
547
|
function stats() {
|
|
494
548
|
return {
|
|
495
549
|
activeGlobal,
|
|
@@ -567,18 +621,48 @@ function createUtilityAgentService(options = {}) {
|
|
|
567
621
|
...(effort ? { effort } : {}),
|
|
568
622
|
};
|
|
569
623
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
624
|
+
// A provider used up until its reset is not started: the caller waits
|
|
625
|
+
// for the reset (the dream) or goes without (recall, a title).
|
|
626
|
+
const block = usedUpFor(selection);
|
|
627
|
+
if (block) {
|
|
628
|
+
const result = {
|
|
629
|
+
ok: false,
|
|
630
|
+
status: "failed",
|
|
631
|
+
text: "",
|
|
632
|
+
provider: selection.providerId,
|
|
633
|
+
model: selection.model,
|
|
634
|
+
tier: selection.tier,
|
|
635
|
+
purpose,
|
|
636
|
+
preferredProvider: selection.preferredProviderId,
|
|
637
|
+
fallbackUsed: selection.fallbackUsed,
|
|
638
|
+
effort,
|
|
639
|
+
notStarted: "usage limit",
|
|
640
|
+
error: stableError(
|
|
641
|
+
"PROVIDER_USAGE_LIMIT",
|
|
642
|
+
`${limitsLib.providerLabel(selection.providerId)}'s ${limitsLib.windowLabel(block.limitType)} is used up until ${new Date(block.resetsAt).toISOString()}`,
|
|
643
|
+
{ limitResetsAt: block.resetsAt, limitType: block.limitType || null },
|
|
644
|
+
),
|
|
645
|
+
};
|
|
646
|
+
lastResult = result;
|
|
647
|
+
if (index + 1 < candidates.length && fallbackEligible(result.error.code)) continue;
|
|
648
|
+
throw new UtilityAgentError(result.error.code, result.error.message, result);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
const buildInvocation = () => {
|
|
652
|
+
const built = validateInvocation(provider.buildUtilityInvocation(invocationContext));
|
|
653
|
+
return validateInvocation({
|
|
654
|
+
...built,
|
|
575
655
|
env: {
|
|
576
|
-
...
|
|
656
|
+
...built.env,
|
|
577
657
|
OC_PROVIDER: selection.providerId,
|
|
578
658
|
OC_UTILITY_DEPTH: String(depth + 1),
|
|
579
659
|
OC_UTILITY_PURPOSE: purpose,
|
|
580
660
|
},
|
|
581
661
|
});
|
|
662
|
+
};
|
|
663
|
+
let invocation;
|
|
664
|
+
try {
|
|
665
|
+
invocation = buildInvocation();
|
|
582
666
|
} catch (error) {
|
|
583
667
|
const result = {
|
|
584
668
|
ok: false,
|
|
@@ -598,9 +682,9 @@ function createUtilityAgentService(options = {}) {
|
|
|
598
682
|
throw new UtilityAgentError(result.error.code, result.error.message, result);
|
|
599
683
|
}
|
|
600
684
|
|
|
601
|
-
const
|
|
685
|
+
const execute = (built) => context.run({ depth: depth + 1, purpose }, () => executeUtilityInvocation({
|
|
602
686
|
provider,
|
|
603
|
-
invocation,
|
|
687
|
+
invocation: built,
|
|
604
688
|
cwd: request.cwd || process.cwd(),
|
|
605
689
|
spawnProcess,
|
|
606
690
|
killTree,
|
|
@@ -612,6 +696,15 @@ function createUtilityAgentService(options = {}) {
|
|
|
612
696
|
maxStdoutBytes,
|
|
613
697
|
outputSchema: request.outputSchema || null,
|
|
614
698
|
}));
|
|
699
|
+
let result = await execute(invocation);
|
|
700
|
+
// Claude Code's refresh-lock race passes: one more try, a little later.
|
|
701
|
+
if (!result.ok && result.error?.code === "PROVIDER_TRANSIENT" && TRANSIENT_RETRY_PURPOSES.has(purpose) && !request.signal?.aborted) {
|
|
702
|
+
await pause(transientRetryMs, request.signal);
|
|
703
|
+
if (!request.signal?.aborted) {
|
|
704
|
+
try { result = await execute(buildInvocation()); }
|
|
705
|
+
catch (_) { /* keep the first failure */ }
|
|
706
|
+
}
|
|
707
|
+
}
|
|
615
708
|
Object.assign(result, {
|
|
616
709
|
provider: selection.providerId,
|
|
617
710
|
model: selection.model,
|
|
@@ -624,6 +717,7 @@ function createUtilityAgentService(options = {}) {
|
|
|
624
717
|
noProductSideEffects: readOnlyMetadata(provider, request.readOnly !== false),
|
|
625
718
|
});
|
|
626
719
|
lastResult = result;
|
|
720
|
+
noteLimits(selection.providerId, result);
|
|
627
721
|
if (result.ok) return result;
|
|
628
722
|
if (index + 1 < candidates.length && fallbackEligible(result.error?.code)) continue;
|
|
629
723
|
throw new UtilityAgentError(result.error?.code || "UTILITY_AGENT_FAILED", result.error?.message || "Utility agent failed", result);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inetafrica/open-claudia",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.23",
|
|
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-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-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-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-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-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-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-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-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-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-usage-limits.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-control.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"
|
|
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-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-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-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-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-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-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-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-usage-limits.js && node test-limit-waits.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-control.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"
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
17
|
"bot.js",
|
|
@@ -13,7 +13,19 @@ const { spawn, spawnSync } = require("child_process");
|
|
|
13
13
|
|
|
14
14
|
const argv = process.argv.slice(2);
|
|
15
15
|
const kind = process.env.FAKE_AGENT_KIND;
|
|
16
|
-
|
|
16
|
+
// "provider-error": the run fails with FAKE_AGENT_ERROR_TEXT (a dead sign-in,
|
|
17
|
+
// Claude Code's refresh-lock race). With FAKE_AGENT_ERROR_ONCE_FILE set, only
|
|
18
|
+
// the first run fails (the file marks it) and later runs work.
|
|
19
|
+
function effectiveScenario() {
|
|
20
|
+
const named = process.env.FAKE_AGENT_SCENARIO || "success";
|
|
21
|
+
const once = process.env.FAKE_AGENT_ERROR_ONCE_FILE;
|
|
22
|
+
if (named === "provider-error" && once) {
|
|
23
|
+
if (fs.existsSync(once)) return "success";
|
|
24
|
+
fs.writeFileSync(once, "failed once\n");
|
|
25
|
+
}
|
|
26
|
+
return named;
|
|
27
|
+
}
|
|
28
|
+
const scenario = effectiveScenario();
|
|
17
29
|
let text = process.env.FAKE_AGENT_TEXT || "fixture says café 👋";
|
|
18
30
|
let invocationCapturePath = null;
|
|
19
31
|
let invocationCapture = null;
|
|
@@ -290,6 +302,19 @@ function claudeEvents(sessionId) {
|
|
|
290
302
|
];
|
|
291
303
|
}
|
|
292
304
|
|
|
305
|
+
if (scenario === "provider-error") {
|
|
306
|
+
return [
|
|
307
|
+
init,
|
|
308
|
+
{
|
|
309
|
+
type: "result",
|
|
310
|
+
subtype: "error_during_execution",
|
|
311
|
+
is_error: true,
|
|
312
|
+
session_id: sessionId,
|
|
313
|
+
result: process.env.FAKE_AGENT_ERROR_TEXT || "provider error fixture",
|
|
314
|
+
},
|
|
315
|
+
];
|
|
316
|
+
}
|
|
317
|
+
|
|
293
318
|
if (scenario === "usage-limit") {
|
|
294
319
|
// Claude Code 2.1.280 at a plan limit: the rejected rate_limit_event, the
|
|
295
320
|
// synthetic notice (error "rate_limit") and an error result.
|
|
@@ -390,6 +415,9 @@ function codexEvents(sessionId) {
|
|
|
390
415
|
{ type: "turn.failed", error: { message: "Authentication failed" } },
|
|
391
416
|
];
|
|
392
417
|
}
|
|
418
|
+
if (scenario === "provider-error") {
|
|
419
|
+
return [started, { type: "turn.failed", error: { message: process.env.FAKE_AGENT_ERROR_TEXT || "provider error fixture" } }];
|
|
420
|
+
}
|
|
393
421
|
|
|
394
422
|
const events = [started, { type: "turn.started" }];
|
|
395
423
|
if (process.env.FAKE_AGENT_THINKING) {
|
|
@@ -526,6 +554,19 @@ async function holdUntilReleased(stdin) {
|
|
|
526
554
|
while (!fs.existsSync(file) && Date.now() < deadline) await sleep(20);
|
|
527
555
|
}
|
|
528
556
|
|
|
557
|
+
// FAKE_AGENT_PROMPT_PROBES: {"name": "<regex source>", ...}; the run log says
|
|
558
|
+
// which of them matched the prompt (never the prompt itself).
|
|
559
|
+
function promptProbes(text) {
|
|
560
|
+
let spec = null;
|
|
561
|
+
try { spec = JSON.parse(process.env.FAKE_AGENT_PROMPT_PROBES || "null"); } catch (_) { return null; }
|
|
562
|
+
if (!spec || typeof spec !== "object") return null;
|
|
563
|
+
const out = {};
|
|
564
|
+
for (const [name, source] of Object.entries(spec)) {
|
|
565
|
+
try { out[name] = new RegExp(source).test(String(text || "")); } catch (_) { out[name] = false; }
|
|
566
|
+
}
|
|
567
|
+
return out;
|
|
568
|
+
}
|
|
569
|
+
|
|
529
570
|
function logRun(event, stdin) {
|
|
530
571
|
const logPath = process.env.FAKE_AGENT_RUN_LOG;
|
|
531
572
|
if (!logPath) return;
|
|
@@ -538,6 +579,9 @@ function logRun(event, stdin) {
|
|
|
538
579
|
threadId: process.env.OC_THREAD_ID || null,
|
|
539
580
|
runId: process.env.OC_RUN_ID || null,
|
|
540
581
|
tag: tag ? tag[1] : null,
|
|
582
|
+
// Every [[tag:…]] in the prompt, in order (a turn can carry several).
|
|
583
|
+
tags: [...String(stdin || "").matchAll(/\[\[tag:([\w-]{1,40})\]\]/g)].map((m) => m[1]),
|
|
584
|
+
probes: promptProbes(stdin),
|
|
541
585
|
fork: argv.includes("--fork-session"),
|
|
542
586
|
resume: argv.indexOf("--resume") >= 0 ? argv[argv.indexOf("--resume") + 1] || null : null,
|
|
543
587
|
sessionEnv: process.env.OC_SESSION_ID || null,
|
|
@@ -610,7 +654,7 @@ async function main() {
|
|
|
610
654
|
setInterval(() => {}, 1000);
|
|
611
655
|
return;
|
|
612
656
|
}
|
|
613
|
-
if (scenario === "auth-failure" || scenario === "refusal" || scenario === "usage-limit") {
|
|
657
|
+
if (scenario === "auth-failure" || scenario === "refusal" || scenario === "usage-limit" || scenario === "provider-error") {
|
|
614
658
|
process.exitCode = 1;
|
|
615
659
|
return;
|
|
616
660
|
}
|
|
@@ -297,7 +297,9 @@ if (process.argv[2] === "--probe") {
|
|
|
297
297
|
DISAPPEAR_PROVIDER: scenario.disappear || "",
|
|
298
298
|
},
|
|
299
299
|
encoding: "utf8",
|
|
300
|
-
|
|
300
|
+
// A boot takes about 1 s; loaded CI runners pushed one past 30 s (4 and 5 Oct,
|
|
301
|
+
// 9 Oct twice), so allow 2 min: this checks what boots, not how fast.
|
|
302
|
+
timeout: 120000,
|
|
301
303
|
});
|
|
302
304
|
|
|
303
305
|
try {
|
|
@@ -374,7 +376,9 @@ if (process.argv[2] === "--probe") {
|
|
|
374
376
|
WEB_FIXTURE_WORKSPACE: workspace,
|
|
375
377
|
},
|
|
376
378
|
encoding: "utf8",
|
|
377
|
-
|
|
379
|
+
// A boot takes about 1 s; loaded CI runners pushed one past 30 s (4 and 5 Oct,
|
|
380
|
+
// 9 Oct twice), so allow 2 min: this checks what boots, not how fast.
|
|
381
|
+
timeout: 120000,
|
|
378
382
|
});
|
|
379
383
|
assert.ifError(webChild.error);
|
|
380
384
|
assert.strictEqual(webChild.status, 0, webChild.stderr || webChild.stdout);
|
|
@@ -162,7 +162,7 @@ async function commandProbe() {
|
|
|
162
162
|
assert.ok(modelControls.includes("mb:codex:gpt-5.6-sol"));
|
|
163
163
|
assert.ok(modelControls.includes("mb:codex:gpt-5.6-luna"));
|
|
164
164
|
assert.ok(!modelControls.includes("mb:codex:o4-mini"));
|
|
165
|
-
assert.ok(modelControls.includes("mb:claude:claude-sonnet-
|
|
165
|
+
assert.ok(modelControls.includes("mb:claude:claude-sonnet-5-5"));
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
async function callbackProbe() {
|
package/test-provider-claude.js
CHANGED
|
@@ -48,7 +48,7 @@ assert.strictEqual(provider.defaultModel(), "claude-default-fixture");
|
|
|
48
48
|
assert.ok(provider.modelChoices().includes("claude-fable-5-1"));
|
|
49
49
|
assert.ok(provider.modelChoices().includes("claude-opus-5-5"), "opus 5.5 is offered in the model picker");
|
|
50
50
|
assert.ok(provider.modelChoices().includes("claude-fable-5"));
|
|
51
|
-
assert.ok(provider.modelChoices().includes("claude-sonnet-
|
|
51
|
+
assert.ok(provider.modelChoices().includes("claude-sonnet-5-5"));
|
|
52
52
|
// 3.4.21: the superseded opus 4.x entries are gone from the picker. They are
|
|
53
53
|
// BUTTONS only - /model takes a typed name verbatim (core/handlers.js reads
|
|
54
54
|
// tail without consulting this list), so the rollback path survives removal.
|
|
@@ -57,7 +57,9 @@ for (const retired of ["claude-opus-4-8", "claude-opus-4-7", "claude-opus-4-6"])
|
|
|
57
57
|
}
|
|
58
58
|
// These two are NOT picker garnish - they are what tierModel returns for
|
|
59
59
|
// utility work, so they must survive any picker trim.
|
|
60
|
-
assert.ok(provider.modelChoices().includes("claude-haiku-
|
|
60
|
+
assert.ok(provider.modelChoices().includes("claude-haiku-5-5"), "haiku stays: it is the low tier");
|
|
61
|
+
assert.ok(!provider.modelChoices().includes("claude-haiku-4-5-20251001"), "Haiku 4.5 left the picker for Haiku 5.5 (typed /model still works)");
|
|
62
|
+
assert.ok(!provider.modelChoices().includes("claude-sonnet-4-6"), "Sonnet 4.6 left the picker for Sonnet 5.5 (typed /model still works)");
|
|
61
63
|
|
|
62
64
|
// The SHIPPED default, asserted on the real module rather than the fixture above,
|
|
63
65
|
// so changing the constant cannot pass unnoticed. Read from source because the
|
|
@@ -72,8 +74,8 @@ assert.match(
|
|
|
72
74
|
);
|
|
73
75
|
// The default governs main turns only: utility tiers stay cheap. These are what
|
|
74
76
|
// stop a default bump from silently repricing recall, pack review and the enforcer.
|
|
75
|
-
assert.strictEqual(claudeProvider.tierModel("low"), "claude-haiku-
|
|
76
|
-
assert.strictEqual(claudeProvider.tierModel("medium"), "claude-sonnet-
|
|
77
|
+
assert.strictEqual(claudeProvider.tierModel("low"), "claude-haiku-5-5", "low-tier utility work stays on haiku (Haiku 5.5 since 9 Oct 2026)");
|
|
78
|
+
assert.strictEqual(claudeProvider.tierModel("medium"), "claude-sonnet-5-5", "medium-tier utility work stays on sonnet (Sonnet 5.5 since 9 Oct 2026)");
|
|
77
79
|
// Guard on the RESOLVED config, not process.env: loadEnv folds ~/.open-claudia/.env
|
|
78
80
|
// over process.env, so an operator pin lives in config.config and never appears in
|
|
79
81
|
// process.env. The 3.4.20 version of this check tested the wrong one and passed
|
|
@@ -205,7 +207,7 @@ assert.deepStrictEqual(utility.args.slice(utility.args.indexOf("--allowedTools")
|
|
|
205
207
|
assert.deepStrictEqual(utility.args.slice(utility.args.indexOf("--permission-mode"), utility.args.indexOf("--permission-mode") + 2), ["--permission-mode", "plan"]);
|
|
206
208
|
assert.strictEqual(utility.args.filter((arg) => arg === "/fixture/memory").length, 1, "read-only utility directories are deduplicated");
|
|
207
209
|
assert.deepStrictEqual(utility.args.slice(utility.args.indexOf("/fixture/memory") - 1, utility.args.indexOf("/fixture/memory") + 1), ["--add-dir", "/fixture/memory"]);
|
|
208
|
-
assert.strictEqual(utility.args[utility.args.indexOf("--model") + 1], "claude-haiku-
|
|
210
|
+
assert.strictEqual(utility.args[utility.args.indexOf("--model") + 1], "claude-haiku-5-5");
|
|
209
211
|
assert.strictEqual(utility.args[utility.args.indexOf("--json-schema") + 1], JSON.stringify({ type: "object", required: ["ok"] }));
|
|
210
212
|
assert.strictEqual(utility.stdin, "UTILITY PROMPT", "utility prompt uses protected stdin transport");
|
|
211
213
|
assert.ok(!utility.args.includes("UTILITY PROMPT"), "utility prompt is absent from argv");
|