@inetafrica/open-claudia 3.4.3 → 3.4.5
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 -0
- package/Dockerfile +1 -1
- package/README.md +1 -3
- package/channels/kazee/adapter.js +27 -0
- package/core/handlers.js +6 -27
- package/core/providers/codex.js +2 -1
- package/core/run-context.js +9 -1
- package/core/runner.js +2 -1
- package/core/state.js +37 -2
- package/package.json +3 -3
- package/test-provider-codex.js +1 -1
- package/test-provider-gateway.js +3 -0
- package/test-provider-language.js +24 -1
- package/test-provider-session-commands.js +5 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v3.4.5 — Astra on the picker, two shortcuts fewer
|
|
4
|
+
|
|
5
|
+
- **gpt-6-astra is offered by the codex provider.** OpenAI rolled GPT-6 (Astra) out to ChatGPT-plan Codex accounts on 2026-09-05 — the earlier 400 (`not supported when using Codex with a ChatGPT account`) was a staged rollout, not client staleness. It sits first in `CODEX_MODELS`, so it appears as a `/model` button; the typed form `/model gpt-6-astra` already worked because the typed path never validated against the list. The default model is unchanged (`gpt-5.6-sol` unless `CODEX_MODEL` is set).
|
|
6
|
+
- **`/claude` and `/codex` are gone.** They were one-line aliases of `/backend claude|codex`, and the `/model` picker switches the backend by itself, so three ways to do one thing became one. `/backend` stays.
|
|
7
|
+
- **Codex CLI: the Dockerfile installs `@openai/codex` unpinned, so every image build bakes the then-latest CLI; a running pod keeps whatever its image carried until the next build + roll.** This release's image picks up 0.153.4.
|
|
8
|
+
|
|
9
|
+
## v3.4.4 — The room's model was saved, shown, and never once used
|
|
10
|
+
|
|
11
|
+
- **A model pinned in a room was silently ignored by every turn in it.** `/model` wrote the choice to the room, `/status` read it back from the room, and the picker highlighted it — all three already room-aware. Only the code that actually launches the provider was not: `captureRunContext` read `state.providerSettings[provider]`, the *speaker's* own bucket, so the room's pinned model was never consulted. The setting looked applied everywhere a human could look while every turn ran the personal default.
|
|
12
|
+
- **This was a v3.4.0 regression, not a long-standing bug.** `run-context.js` dates from 10 Jul, when the speaker's bucket was the only scope that existed and reading it directly was correct. v3.4.0 introduced rooms and the room-aware resolver but never revisited that read. Channels without a room are unaffected — the resolver returns the same personal bucket there.
|
|
13
|
+
- **Three more call sites had the same shape.** `applyProviderSetting` wrote `/effort`, `/budget`, `/plan` and `/worktree` to the speaker instead of the room; the provider-switch payload reported the speaker's bucket; and usage records attributed the wrong model, so cost accounting named a model the turn never ran on.
|
|
14
|
+
- **`getProviderSettings` was not identity-stable.** It rebuilt the bucket (`{ ...defaults, ...bucket }`) and assigned it back on every call, so any caller holding the previous reference wrote into a detached copy that was then discarded. Nothing depended on the rebuild; it now backfills missing defaults in place.
|
|
15
|
+
- **Reads must not mutate.** Routing the run-context read through `getProviderSettings` made merely capturing a turn seed room buckets into `savedState` — side-chat execution began mutating main state. Reads now go through a new pure `resolveProviderSettings`, which creates nothing; the mutating accessor is reserved for the setter that genuinely needs the live object.
|
|
16
|
+
- `test-room-provider-settings.js` pins the behaviour and was verified to FAIL against unmodified code with exactly the reported symptom — `got "personal-default-model", expected "room-pinned-model"` — and also pins that an unpinned room does not inherit another room's choice.
|
|
17
|
+
|
|
18
|
+
- **Kazee replied to everything twice.** chat-central fans `message:new` out to both `chatId` and each participant's `user:<id>` room so delivery survives a failed join. The bot only ever sat in its own user room until v3.4.2 joined chat rooms for the typing indicator — which put it in both, so every inbound message was handled twice and `/model` answered with two identical pickers. The join is correct; the missing half was the id-dedupe every other client already does. Inbound ids are now remembered (bounded, oldest evicted); an id-less message is still let through rather than silently swallowed.
|
|
19
|
+
|
|
3
20
|
## v3.4.3 — The chip knew it had started typing; nobody asked it in time
|
|
4
21
|
|
|
5
22
|
- **v3.4.2 restored the indicator and immediately exposed a second bug underneath it.** With delivery fixed, the chip reached the client — and then sat on "thinking" for the whole turn and stopped, never showing "typing". Same symptom, different layer: 3.4.2 was DELIVERY, this is CONTENT.
|
package/Dockerfile
CHANGED
|
@@ -8,7 +8,7 @@ FROM ${BASE_IMAGE}
|
|
|
8
8
|
RUN curl -fsSL https://claude.ai/install.sh | sh || \
|
|
9
9
|
npm install -g @anthropic-ai/claude-code
|
|
10
10
|
|
|
11
|
-
# Install OpenAI Codex CLI for the
|
|
11
|
+
# Install OpenAI Codex CLI for the codex backend (unpinned: each image build bakes the then-latest CLI)
|
|
12
12
|
RUN npm install -g @openai/codex
|
|
13
13
|
|
|
14
14
|
# Browser automation for the agent: vercel-labs agent-browser (Rust CLI, token-efficient,
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Send text, voice notes, screenshots, and files from your phone. Open Claudia run
|
|
|
8
8
|
|
|
9
9
|
### Channels & providers
|
|
10
10
|
- **Multi-channel** — run the same bot on Telegram, Kazee Chat, or both at once (`CHANNELS=telegram,kazee`). Each channel renders keyboards, files, voice notes, and edits natively
|
|
11
|
-
- **Multi-provider** — switch between Claude Code and OpenAI Codex on the fly (`/claude`, `/
|
|
11
|
+
- **Multi-provider** — switch between Claude Code and OpenAI Codex on the fly (`/backend claude|codex`, or pick a model in `/model`); each keeps its own project-scoped session state
|
|
12
12
|
- **Multi-user / team mode** — one bot serves multiple authorized users in parallel, each with their own conversations, settings, model, provider, and usage counters
|
|
13
13
|
- **Multi-project sessions** — switch between workspace projects; per-project conversation history auto-resumes
|
|
14
14
|
|
|
@@ -137,8 +137,6 @@ If installed as a background service, the bot starts automatically on login and
|
|
|
137
137
|
|
|
138
138
|
| Command | Description |
|
|
139
139
|
|---------|-------------|
|
|
140
|
-
| `/claude` | Switch to the Claude Code provider |
|
|
141
|
-
| `/codex` | Switch to the OpenAI Codex provider |
|
|
142
140
|
| `/backend` | Show the current provider with picker |
|
|
143
141
|
|
|
144
142
|
Each provider keeps its own persistent project session. Switching doesn't lose your place — you can go back and forth freely.
|
|
@@ -24,6 +24,15 @@ const kazeeState = require("./state");
|
|
|
24
24
|
// late is worth less than the next heartbeat tick, which retries the join.
|
|
25
25
|
const KAZEE_JOIN_ACK_TIMEOUT_MS = 5000;
|
|
26
26
|
|
|
27
|
+
// chat-central deliberately fans message:new out TWICE to anyone in the chat
|
|
28
|
+
// room: once via to(chatId) and again via to(`user:<id>`) per participant, so
|
|
29
|
+
// delivery survives a failed room join (see broadcastBridge). Ordinary clients
|
|
30
|
+
// dedupe by message id; the bot never had to, because until it joined chat
|
|
31
|
+
// rooms for the typing indicator it only ever sat in its own user room. How
|
|
32
|
+
// many ids to remember: large enough to cover a burst, small enough to stay
|
|
33
|
+
// trivial to scan.
|
|
34
|
+
const INBOUND_DEDUP_MEMORY = 500;
|
|
35
|
+
|
|
27
36
|
const CONTEXT_MAX_MESSAGES = 40;
|
|
28
37
|
const CONTEXT_BODY_LIMIT = 280;
|
|
29
38
|
const COLD_START_WINDOW = 15;
|
|
@@ -71,6 +80,8 @@ class KazeeAdapter {
|
|
|
71
80
|
// on every (re)connect.
|
|
72
81
|
this._joinedRooms = new Set();
|
|
73
82
|
this._joinPending = new Map();
|
|
83
|
+
// Insertion-ordered, so the oldest id is always the first key.
|
|
84
|
+
this._seenMessageIds = new Set();
|
|
74
85
|
this._callManager = new KazeeCallManager({ adapter: this });
|
|
75
86
|
}
|
|
76
87
|
|
|
@@ -186,8 +197,24 @@ class KazeeAdapter {
|
|
|
186
197
|
});
|
|
187
198
|
}
|
|
188
199
|
|
|
200
|
+
// True the SECOND time a message id is seen. An id-less message is always
|
|
201
|
+
// let through: dropping every one of them would silently swallow real
|
|
202
|
+
// traffic, and the duplicate pair we are guarding against always carries an
|
|
203
|
+
// id (it is the same persisted document emitted down two paths).
|
|
204
|
+
_isDuplicateInbound(msg) {
|
|
205
|
+
const id = String(msg._id || msg.id || "");
|
|
206
|
+
if (!id) return false;
|
|
207
|
+
if (this._seenMessageIds.has(id)) return true;
|
|
208
|
+
this._seenMessageIds.add(id);
|
|
209
|
+
if (this._seenMessageIds.size > INBOUND_DEDUP_MEMORY) {
|
|
210
|
+
this._seenMessageIds.delete(this._seenMessageIds.values().next().value);
|
|
211
|
+
}
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
|
|
189
215
|
async _handleInboundMessage(msg) {
|
|
190
216
|
if (!msg) return;
|
|
217
|
+
if (this._isDuplicateInbound(msg)) return;
|
|
191
218
|
const senderId = String(msg.sender?._id || msg.sender?.id || msg.senderId || "");
|
|
192
219
|
if (this.botUserId && senderId === String(this.botUserId)) return; // ignore our own echoes
|
|
193
220
|
const chatField = msg.chat;
|
package/core/handlers.js
CHANGED
|
@@ -17,7 +17,7 @@ const { currentAdapter, currentChannelId } = require("./context");
|
|
|
17
17
|
const {
|
|
18
18
|
currentState, saveState, rootSession,
|
|
19
19
|
freshUsage, getActiveProvider, getProjectKey, getProviderSession, setProviderSession, clearProviderSession,
|
|
20
|
-
getProviderSettings,
|
|
20
|
+
getProviderSettings, resolveProviderSettings,
|
|
21
21
|
getProjectSessions, getLastProjectSession, userOwnsProviderSession,
|
|
22
22
|
createSessionCallbackToken, linkIdentity,
|
|
23
23
|
roomSettingsFor, setRoomSetting,
|
|
@@ -176,7 +176,10 @@ function applyProviderSetting(state, providerId, setting, value, options = {}) {
|
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
|
|
179
|
+
// Room-aware: a setting changed inside a room lands on the room, so every
|
|
180
|
+
// speaker there gets the same assistant. Preferring the raw personal bucket
|
|
181
|
+
// here wrote /effort, /budget and /plan to the speaker instead.
|
|
182
|
+
const settings = getProviderSettings(state, provider.id);
|
|
180
183
|
const previous = settings[setting];
|
|
181
184
|
settings[setting] = normalized;
|
|
182
185
|
if (options.persist) {
|
|
@@ -232,7 +235,7 @@ function switchProviderState(providerId, options = {}) {
|
|
|
232
235
|
state.isFirstMessage = previous.isFirstMessage;
|
|
233
236
|
});
|
|
234
237
|
return persisted.ok
|
|
235
|
-
? { ok: true, provider, sessionId: getProviderSession(state, provider, project), settings: state
|
|
238
|
+
? { ok: true, provider, sessionId: getProviderSession(state, provider, project), settings: resolveProviderSettings(state, provider) }
|
|
236
239
|
: persisted;
|
|
237
240
|
}
|
|
238
241
|
|
|
@@ -1534,30 +1537,6 @@ register({
|
|
|
1534
1537
|
},
|
|
1535
1538
|
});
|
|
1536
1539
|
|
|
1537
|
-
async function switchProviderCommand(env, providerId) {
|
|
1538
|
-
if (!authorized(env)) return;
|
|
1539
|
-
const provider = providerFromRegistry(providerId);
|
|
1540
|
-
if (!provider) return send(`Unknown provider: ${providerId}`);
|
|
1541
|
-
if (!providerAvailability(provider)) {
|
|
1542
|
-
return send(`${provider.label} is unavailable. Install its CLI or configure its path, then run /doctor.`);
|
|
1543
|
-
}
|
|
1544
|
-
const state = currentState();
|
|
1545
|
-
const switched = switchProviderState(provider.id, { state });
|
|
1546
|
-
if (!switched.ok) return send(`Could not switch provider: ${switched.error.message}`);
|
|
1547
|
-
const session = switched.sessionId ? `\nSession: ${switched.sessionId.slice(0, 8)}...` : "\nNew session.";
|
|
1548
|
-
return send(`Switched to ${provider.label}.${session}`);
|
|
1549
|
-
}
|
|
1550
|
-
|
|
1551
|
-
register({
|
|
1552
|
-
name: "claude", description: "Switch to Claude Code provider",
|
|
1553
|
-
handler: async (env) => switchProviderCommand(env, "claude"),
|
|
1554
|
-
});
|
|
1555
|
-
|
|
1556
|
-
register({
|
|
1557
|
-
name: "codex", description: "Switch to OpenAI Codex provider",
|
|
1558
|
-
handler: async (env) => switchProviderCommand(env, "codex"),
|
|
1559
|
-
});
|
|
1560
|
-
|
|
1561
1540
|
register({
|
|
1562
1541
|
name: "backend", description: "Show/switch active provider", args: "[claude|codex]",
|
|
1563
1542
|
handler: async (env, { tail }) => {
|
package/core/providers/codex.js
CHANGED
|
@@ -7,7 +7,8 @@ const { createCodexParserState, normalizeCodexEvent } = require("./codex-events"
|
|
|
7
7
|
const { createCodexHookTransport } = require("./codex-hook");
|
|
8
8
|
|
|
9
9
|
// gpt-5.6-sol-pro is rejected on ChatGPT-plan auth (400 from the API); it needs API-key billing.
|
|
10
|
-
|
|
10
|
+
// gpt-6-astra (GPT-6) reached ChatGPT-plan accounts on 2026-09-05; verified live with codex 0.153.
|
|
11
|
+
const CODEX_MODELS = Object.freeze(["gpt-6-astra", "gpt-5.6-sol", "gpt-5.6-sol-pro", "gpt-5.6-terra", "gpt-5.6-luna"]);
|
|
11
12
|
// max + ultra verified live against codex 0.144 (ultra = proactive multi-agent behavior).
|
|
12
13
|
const CODEX_EFFORT_VALUES = Object.freeze(["minimal", "low", "medium", "high", "xhigh", "max", "ultra"]);
|
|
13
14
|
const REQUIRED_EXEC_HELP_FLAGS = Object.freeze(["--config", "--json", "--sandbox", "--image", "--model", "--skip-git-repo-check"]);
|
package/core/run-context.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const crypto = require("crypto");
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const { currentConversationKey } = require("./context");
|
|
6
|
+
const { resolveProviderSettings } = require("./state");
|
|
6
7
|
|
|
7
8
|
function cloneSerializable(value, label = "run context value") {
|
|
8
9
|
if (value === undefined) return undefined;
|
|
@@ -109,8 +110,15 @@ function captureRunContext({
|
|
|
109
110
|
const resolvedChannelId = channelId != null
|
|
110
111
|
? String(channelId)
|
|
111
112
|
: (origin.channelId || (state.channelId != null ? String(state.channelId) : null));
|
|
113
|
+
// Inside a room the model/effort/budget belong to the room, not to whoever
|
|
114
|
+
// happens to be speaking, so this must go through the room-aware resolver.
|
|
115
|
+
// Reading `state.providerSettings[provider]` directly took the speaker's own
|
|
116
|
+
// bucket and silently ignored a room's pinned model: the picker saved it and
|
|
117
|
+
// /status reported it (both already room-aware) while every turn still ran
|
|
118
|
+
// the personal default. Outside a room the resolver returns that same
|
|
119
|
+
// personal bucket, so non-room channels are unaffected.
|
|
112
120
|
const providerSettings = cloneSerializable({
|
|
113
|
-
...(state
|
|
121
|
+
...(resolveProviderSettings(state, provider) || {}),
|
|
114
122
|
...(opts.providerSettings || {}),
|
|
115
123
|
}, "provider settings");
|
|
116
124
|
delete providerSettings.backend;
|
package/core/runner.js
CHANGED
|
@@ -15,6 +15,7 @@ const {
|
|
|
15
15
|
currentState, saveState, recordSession,
|
|
16
16
|
resetSessionUsage, acquireRunLock, getActiveProvider, getProjectKey,
|
|
17
17
|
getProviderSession, setProviderSession, clearProviderSession, quarantineProviderSession, getUsageForSession, commitProviderCompaction,
|
|
18
|
+
resolveProviderSettings,
|
|
18
19
|
} = require("./state");
|
|
19
20
|
const { chatContext, currentChannelId, currentAdapter } = require("./context");
|
|
20
21
|
const { buildTurnPrompt } = require("./system-prompt");
|
|
@@ -167,7 +168,7 @@ function logTurnUsage(state, usage, costUsd, announce, opts = {}) {
|
|
|
167
168
|
provider: backend,
|
|
168
169
|
model: Object.prototype.hasOwnProperty.call(opts, "model")
|
|
169
170
|
? (opts.model || null)
|
|
170
|
-
: (state
|
|
171
|
+
: (resolveProviderSettings(state, backend)?.model || getProvider(backend).defaultModel()),
|
|
171
172
|
userId: opts.userId || state.userId || null,
|
|
172
173
|
sessionId: Object.prototype.hasOwnProperty.call(opts, "sessionId")
|
|
173
174
|
? (opts.sessionId || null)
|
package/core/state.js
CHANGED
|
@@ -519,6 +519,40 @@ function isSessionQuarantined(state, sessionId) {
|
|
|
519
519
|
&& isRecord(state.quarantinedSessions[sessionId]));
|
|
520
520
|
}
|
|
521
521
|
|
|
522
|
+
// Add any missing defaults to an existing settings bucket IN PLACE. Rebuilding
|
|
523
|
+
// it (`{ ...defaults, ...bucket }`) returned a fresh object on every call, so a
|
|
524
|
+
// caller holding the previous reference silently wrote to a detached copy —
|
|
525
|
+
// the settings object has to keep its identity across calls.
|
|
526
|
+
function backfillDefaults(bucket) {
|
|
527
|
+
const defaults = providerDefaults();
|
|
528
|
+
for (const key of Object.keys(defaults)) {
|
|
529
|
+
if (!Object.prototype.hasOwnProperty.call(bucket, key)) bucket[key] = defaults[key];
|
|
530
|
+
}
|
|
531
|
+
return bucket;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// Read-only view of the effective provider settings for a turn: the room's
|
|
535
|
+
// bucket when the turn happens inside a room, otherwise the speaker's own,
|
|
536
|
+
// with defaults filled in. Unlike getProviderSettings this creates nothing and
|
|
537
|
+
// mutates nothing — capturing a run context and writing a usage record are
|
|
538
|
+
// reads, and must not seed buckets or write into savedState as a side effect.
|
|
539
|
+
function resolveProviderSettings(state, providerId) {
|
|
540
|
+
const provider = normalizeProviderId(providerId || getActiveProvider(state), null);
|
|
541
|
+
if (!provider) return providerDefaults();
|
|
542
|
+
const roomKey = state && state.roomKey ? String(state.roomKey) : "";
|
|
543
|
+
const room = roomKey && isRecord(savedState.rooms)
|
|
544
|
+
&& isRecord(savedState.rooms[roomKey])
|
|
545
|
+
&& isRecord(savedState.rooms[roomKey].providerSettings)
|
|
546
|
+
&& isRecord(savedState.rooms[roomKey].providerSettings[provider])
|
|
547
|
+
? savedState.rooms[roomKey].providerSettings[provider]
|
|
548
|
+
: null;
|
|
549
|
+
if (room) return { ...providerDefaults(), ...room };
|
|
550
|
+
const personal = isRecord(state && state.providerSettings) && isRecord(state.providerSettings[provider])
|
|
551
|
+
? state.providerSettings[provider]
|
|
552
|
+
: {};
|
|
553
|
+
return { ...providerDefaults(), ...personal };
|
|
554
|
+
}
|
|
555
|
+
|
|
522
556
|
function getProviderSettings(state, providerId) {
|
|
523
557
|
if (!state || typeof state !== "object") throw new TypeError("state is required");
|
|
524
558
|
const provider = normalizeProviderId(providerId || getActiveProvider(state), null);
|
|
@@ -529,7 +563,7 @@ function getProviderSettings(state, providerId) {
|
|
|
529
563
|
}
|
|
530
564
|
if (!isRecord(state.providerSettings)) state.providerSettings = {};
|
|
531
565
|
if (!isRecord(state.providerSettings[provider])) state.providerSettings[provider] = providerDefaults();
|
|
532
|
-
else state.providerSettings[provider]
|
|
566
|
+
else backfillDefaults(state.providerSettings[provider]);
|
|
533
567
|
// Inside a room, model/effort/budget belong to the room, so every speaker
|
|
534
568
|
// gets the same assistant. The room's bucket is seeded from the speaker who
|
|
535
569
|
// first pins it, then diverges — mutations by callers land on the room object
|
|
@@ -543,7 +577,7 @@ function getProviderSettings(state, providerId) {
|
|
|
543
577
|
if (!isRecord(room.providerSettings[provider])) {
|
|
544
578
|
room.providerSettings[provider] = { ...providerDefaults(), ...state.providerSettings[provider] };
|
|
545
579
|
} else {
|
|
546
|
-
room.providerSettings[provider]
|
|
580
|
+
backfillDefaults(room.providerSettings[provider]);
|
|
547
581
|
}
|
|
548
582
|
return room.providerSettings[provider];
|
|
549
583
|
}
|
|
@@ -1490,6 +1524,7 @@ module.exports = {
|
|
|
1490
1524
|
quarantineProviderSession,
|
|
1491
1525
|
isSessionQuarantined,
|
|
1492
1526
|
getProviderSettings,
|
|
1527
|
+
resolveProviderSettings,
|
|
1493
1528
|
getActiveUsage,
|
|
1494
1529
|
getUsageForSession,
|
|
1495
1530
|
usageSessionKey,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inetafrica/open-claudia",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.5",
|
|
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": {
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"test:kazee-call": "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-kazee-call-session.js",
|
|
11
11
|
"setup": "node setup.js",
|
|
12
12
|
"start": "node bot.js",
|
|
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-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-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-typing-join.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-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-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 && OPEN_CLAUDIA_TEST=1 WORKSPACE=/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-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-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-queue-routing.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/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-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-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-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-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-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-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-store-durability.js"
|
|
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-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-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-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-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-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 && OPEN_CLAUDIA_TEST=1 WORKSPACE=/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-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-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-queue-routing.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/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-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-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-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-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-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-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"
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
17
|
"bot.js",
|
package/test-provider-codex.js
CHANGED
|
@@ -46,7 +46,7 @@ assert.strictEqual(provider.label, "OpenAI Codex");
|
|
|
46
46
|
assert.strictEqual(provider.isAvailable(), true);
|
|
47
47
|
assert.strictEqual(provider.executable(), "/fixture/codex");
|
|
48
48
|
assert.strictEqual(provider.defaultModel(), "gpt-5-codex");
|
|
49
|
-
assert.deepStrictEqual(provider.modelChoices(), ["gpt-5.6-sol", "gpt-5.6-sol-pro", "gpt-5.6-terra", "gpt-5.6-luna"]);
|
|
49
|
+
assert.deepStrictEqual(provider.modelChoices(), ["gpt-6-astra", "gpt-5.6-sol", "gpt-5.6-sol-pro", "gpt-5.6-terra", "gpt-5.6-luna"]);
|
|
50
50
|
assert.ok(!provider.modelChoices().includes("o4-mini"));
|
|
51
51
|
assert.deepStrictEqual(provider.compatibilityStatus(), {
|
|
52
52
|
state: "compatible",
|
package/test-provider-gateway.js
CHANGED
|
@@ -51,6 +51,7 @@ async function routerProbe() {
|
|
|
51
51
|
|
|
52
52
|
installStub("./core/state", {
|
|
53
53
|
currentState: () => state,
|
|
54
|
+
resolveProviderSettings: (s, provider) => ({ ...((s || state).providerSettings?.[provider] || {}) }),
|
|
54
55
|
autoLinkOwnerChannel: () => null,
|
|
55
56
|
getActiveProvider: (s) => (s || state).settings?.backend || null,
|
|
56
57
|
getProjectKey: (s) => (s || state).currentSession?.name || "",
|
|
@@ -298,6 +299,7 @@ async function schedulerProbe() {
|
|
|
298
299
|
getUserState: () => state,
|
|
299
300
|
getActiveProvider: (s) => (s || state).settings?.backend || null,
|
|
300
301
|
getProviderSettings: (s, provider) => ({ ...((s || state).providerSettings?.[provider] || {}) }),
|
|
302
|
+
resolveProviderSettings: (s, provider) => ({ ...((s || state).providerSettings?.[provider] || {}) }),
|
|
301
303
|
getProviderSession: (_state, provider, project) => (
|
|
302
304
|
state.activeSessions?.[project]?.[provider] || null
|
|
303
305
|
),
|
|
@@ -410,6 +412,7 @@ function queueProbe() {
|
|
|
410
412
|
|
|
411
413
|
installStub("./core/state", {
|
|
412
414
|
currentState: () => state,
|
|
415
|
+
resolveProviderSettings: (s, provider) => ({ ...((s || state).providerSettings?.[provider] || {}) }),
|
|
413
416
|
saveState: () => {},
|
|
414
417
|
recordSession: () => {},
|
|
415
418
|
userOwnsProviderSession: () => false,
|
|
@@ -433,7 +433,30 @@ assert.match(pkg.description, /provider-agnostic coding-agent harness/i);
|
|
|
433
433
|
// changes now push through state.typingTick on the transition. Reproduced by a
|
|
434
434
|
// regression test that fails against unmodified code with exactly the reported
|
|
435
435
|
// symptom (["thinking"] where ["thinking","typing"] was expected).
|
|
436
|
-
|
|
436
|
+
// 3.4.4 approved by Sumeet 2026-09-04 ("yes" to cutting it together with the
|
|
437
|
+
// Kazee dedup fix) after he set this room to fable 5.1 and asked why it was
|
|
438
|
+
// still running opus. Real bug, v3.4.0 regression: /model wrote the choice to
|
|
439
|
+
// the ROOM and /status read it back from the room (both room-aware), but
|
|
440
|
+
// captureRunContext read state.providerSettings[provider] — the speaker's own
|
|
441
|
+
// bucket, correct in July when that was the only scope, never revisited when
|
|
442
|
+
// rooms arrived — so every turn ran the personal default while the setting
|
|
443
|
+
// looked applied everywhere a human could look. Same shape at three more
|
|
444
|
+
// sites (setter, switch payload, usage attribution). Along the way:
|
|
445
|
+
// getProviderSettings rebuilt the bucket on every call (callers holding a
|
|
446
|
+
// reference wrote to a detached copy) and routing a READ through it made
|
|
447
|
+
// capturing a run context mutate savedState — fixed with in-place backfill and
|
|
448
|
+
// a pure resolveProviderSettings. Regression test fails against unmodified
|
|
449
|
+
// code with exactly the reported symptom. Also ships the Kazee inbound
|
|
450
|
+
// dedupe: chat-central fans message:new to both the chat room and each user
|
|
451
|
+
// room, and v3.4.2's room join put the bot in both, so it replied twice.
|
|
452
|
+
// 3.4.5 approved by Sumeet 2026-09-05 ("Can you update open Claudia model
|
|
453
|
+
// picker /model ... /codex probably worth getting rid off. Then I think let's
|
|
454
|
+
// upgrade the CLI to the latest"): gpt-6-astra reached ChatGPT-plan accounts
|
|
455
|
+
// on 2026-09-05 (the 400 was a staged rollout, not client staleness), so it
|
|
456
|
+
// joins CODEX_MODELS first; the /claude and /codex shortcuts go — /backend and
|
|
457
|
+
// the /model picker already switch providers; Codex CLI bumped to 0.153.4 on
|
|
458
|
+
// the operator host and the image (unpinned install) picks it up at build.
|
|
459
|
+
assert.strictEqual(pkg.version, "3.4.5", "release version must remain unchanged without explicit approval");
|
|
437
460
|
for (const keyword of ["claude", "codex", "coding-agent", "provider-agnostic"]) {
|
|
438
461
|
assert.ok(pkg.keywords.includes(keyword), `package keyword missing: ${keyword}`);
|
|
439
462
|
}
|
|
@@ -139,10 +139,12 @@ function restartProbe() {
|
|
|
139
139
|
|
|
140
140
|
function commandRegistrationProbe() {
|
|
141
141
|
const names = new Set(commands.list().map((command) => command.name));
|
|
142
|
-
for (const name of ["new", "end", "continue", "backend"
|
|
142
|
+
for (const name of ["new", "end", "continue", "backend"]) assert.ok(names.has(name), `/${name} registered`);
|
|
143
|
+
// v3.4.5: the /claude and /codex aliases were removed — /backend and the /model picker switch providers.
|
|
144
|
+
for (const name of ["claude", "codex"]) assert.ok(!names.has(name), `/${name} must no longer be registered`);
|
|
143
145
|
const source = fs.readFileSync(path.join(root, "core", "handlers.js"), "utf8");
|
|
144
|
-
assert.
|
|
145
|
-
assert.match(source, /name: "
|
|
146
|
+
assert.doesNotMatch(source, /switchProviderCommand/, "the per-provider shortcut helper went with the aliases");
|
|
147
|
+
assert.match(source, /name: "backend"[\s\S]*switchProviderState\(descriptor\.id\)/);
|
|
146
148
|
assert.match(source, /name: "continue"[\s\S]*activeContinueOptions/);
|
|
147
149
|
const actions = fs.readFileSync(path.join(root, "core", "actions.js"), "utf8");
|
|
148
150
|
assert.match(actions, /switchProviderState/);
|