@inetafrica/open-claudia 3.4.20 → 3.4.22
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 +13 -1
- package/core/handlers.js +98 -26
- package/core/providers/claude.js +8 -3
- package/package.json +2 -2
- package/test-provider-claude.js +18 -2
- package/test-provider-language.js +8 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.4.22
|
|
4
|
+
|
|
5
|
+
Supersedes 3.4.21, which was tagged but never published: its build failed because `test-upgrade-path.js` was wired into the test chain without being committed. Nothing shipped from that tag.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
- Fix `/upgrade` reporting success while upgrading a copy of the bot that nothing runs. It ran `npm install -g`, then read the resulting version back from `npm root -g` — the one directory guaranteed to agree with itself. Found on a host where the bot executes from `/usr/local/lib/node_modules` while `npm config get prefix` is `~/.local`: three releases (3.4.18, 3.4.19, 3.4.20) were each announced as installed while the running process stayed on 3.4.17.
|
|
9
|
+
- The layout check no longer string-matches the docker `/app` path. It compares the directory the running process executes from against the directory npm would write to, so any prefix drift routes to the in-place overlay, not just the container case. An unqueryable `npm root -g` is not treated as a mismatch — the post-install check is the backstop there.
|
|
10
|
+
- `/upgrade` and `/downgrade` now read the resulting version back from the directory the process actually executes from. A mismatch reports "Upgrade did NOT take", names both directories, and restarts nothing; the previous behaviour was to restart and claim success.
|
|
11
|
+
- Drop the superseded `claude-opus-4-8`, `claude-opus-4-7` and `claude-opus-4-6` buttons from the Claude model picker, which had grown long enough to bury the current models.
|
|
12
|
+
- Removal is cosmetic by design. `/model` takes a typed name verbatim without consulting the list, so `/model claude-opus-4-8` still works as a rollback; only the buttons go. The list is still checked on tapped callbacks, whose job is to reject a stale button from an old message.
|
|
13
|
+
- `claude-sonnet-4-6` and `claude-haiku-4-5-20251001` deliberately stay: they are the tier models for medium and low utility work, not picker garnish, and dropping them would push recall, pack review and the enforcer onto opus.
|
|
14
|
+
|
|
3
15
|
## 3.4.20
|
|
4
16
|
|
|
5
17
|
- Make `claude-opus-5-5` the default Claude model. 3.4.19 only added it to the picker; the default stayed on `claude-opus-4-8`, so a room that had never run `/model` kept the old model.
|
|
@@ -261,7 +273,7 @@ Three approved plans land together — memory adoption A1-A4 (from the TencentDB
|
|
|
261
273
|
## v3.1.21 — Kazee public participation: owner seeding, group tag-gating, guarded external turns
|
|
262
274
|
|
|
263
275
|
- **Owner seeding for kazee-only pods.** A pod whose only owner signal is `KAZEE_OWNER_USER_ID` (empty `auth.json`) never got a people-store owner record, so every unknown inbound — group or DM — was refused with a false "no owner configured" (observed on network-mon, 2026-07-23). `seedOwnerFromLegacy` now falls back to the kazee env owner; legacy `auth.json` owners keep precedence and seeding stays idempotent.
|
|
264
|
-
- **Group chats engage only when addressed.** The kazee adapter fetches chat meta (5-min cache) and, in group chats, engages only on an @-mention of the bot or a reply to the bot's own message — matching chat-central's own `assistantAction` default `assistant_tagged_reply`. Chats set to `assistant_free_reply` engage on everything. Untagged group chatter is dropped silently (no roster prompts, no refusals — owner included). 1:1 chats are unchanged;
|
|
276
|
+
- **Group chats engage only when addressed.** The kazee adapter fetches chat meta (5-min cache) and, in group chats, engages only on an @-mention of the bot or a reply to the bot's own message — matching chat-central's own `assistantAction` default `assistant_tagged_reply`. Chats set to `assistant_free_reply` engage on everything. Untagged group chatter is dropped silently (no roster prompts, no refusals — owner included). 1:1 chats are unchanged; an unresolved metadata fetch is not cached and fails closed because the room cannot safely be classified as a DM.
|
|
265
277
|
- **Tagged externals get the guarded turn.** An engaged group message authorizes the turn via adapter-attested `envelope.engaged` (never derived from message content), but the speaker still classifies external: replies are vetted by the enforcer and escalate to the owner's approve-once / deny / make-a-rule card — the same pattern as Spaces. Slash commands stay closed to externals.
|
|
266
278
|
- **Escalation cards reach the kazee owner.** `ownerTarget` used to return env-seeded kazee owner handles as the raw user id, but kazee sends need a chat-document id, so approval cards would 404. User-id handles now resolve through `openDirectChat`, falling back to the configured owner target.
|
|
267
279
|
- New release-chain tests: `test-people-owner-seed.js` (env seed, legacy precedence, no-signal refusal) and `test-kazee-group-gate.js` (mention/reply engagement, free-reply, 1:1, meta failure, meta cache, engaged access pass-through).
|
package/core/handlers.js
CHANGED
|
@@ -643,21 +643,70 @@ async function requestAgentSpaceUpgrade() {
|
|
|
643
643
|
});
|
|
644
644
|
}
|
|
645
645
|
|
|
646
|
-
//
|
|
647
|
-
//
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
646
|
+
// The directory the RUNNING bot's source actually lives in. Everything about
|
|
647
|
+
// upgrading has to be judged against this, never against `npm root -g`.
|
|
648
|
+
function runningInstallRoot() {
|
|
649
|
+
return path.resolve(path.join(__dirname, ".."));
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
// Where `npm install -g` would place our package, or null when npm cannot be
|
|
653
|
+
// asked. Null means "cannot tell" and callers fall back to the npm path.
|
|
654
|
+
function globalInstallRoot() {
|
|
652
655
|
try {
|
|
653
|
-
const
|
|
654
|
-
|
|
656
|
+
const root = execSync("npm root -g", {
|
|
657
|
+
encoding: "utf-8", timeout: 15000,
|
|
658
|
+
cwd: process.env.HOME || require("os").homedir(),
|
|
659
|
+
env: { ...process.env, PATH: FULL_PATH },
|
|
660
|
+
}).trim();
|
|
661
|
+
if (!root) return null;
|
|
662
|
+
return path.resolve(path.join(root, "@inetafrica", "open-claudia"));
|
|
663
|
+
} catch (e) {
|
|
664
|
+
return null;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// True when `npm install -g` cannot upgrade THIS process, because the code it
|
|
669
|
+
// executes does not live where npm would write. Two shapes seen in the wild:
|
|
670
|
+
//
|
|
671
|
+
// 1. the docker /app layout from our Dockerfile - the process reads code
|
|
672
|
+
// from /app and uid 1001 cannot write the global root anyway;
|
|
673
|
+
// 2. a host whose npm prefix has moved away from where the bot was
|
|
674
|
+
// installed. Observed 2026-09-23 on Sumeet's Mac: launchd runs
|
|
675
|
+
// /usr/local/lib/node_modules/@inetafrica/open-claudia/bot.js while
|
|
676
|
+
// `npm config get prefix` is ~/.local, so `npm install -g` faithfully
|
|
677
|
+
// installed a copy nothing executes. Three releases (3.4.18, 3.4.19,
|
|
678
|
+
// 3.4.20) landed in that copy and /upgrade reported success each time
|
|
679
|
+
// while the running bot stayed on 3.4.17 from 7 Sep.
|
|
680
|
+
//
|
|
681
|
+
// Case 2 is why this is a directory comparison and not a string match on
|
|
682
|
+
// "/app": the failure is general, and it is silent, which is the worst part.
|
|
683
|
+
// Version recorded in a given install directory, or null if unreadable. The
|
|
684
|
+
// ONLY honest way to answer "did the upgrade take": read it back from the
|
|
685
|
+
// directory the process executes from.
|
|
686
|
+
function installedVersionAt(dir) {
|
|
687
|
+
try {
|
|
688
|
+
return JSON.parse(fs.readFileSync(path.join(dir, "package.json"), "utf-8")).version || null;
|
|
689
|
+
} catch (e) {
|
|
690
|
+
return null;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
function npmGlobalUpgradeWouldMiss(probe = {}) {
|
|
695
|
+
try {
|
|
696
|
+
const running = probe.running !== undefined ? probe.running : runningInstallRoot();
|
|
697
|
+
if (running === "/app") return true;
|
|
698
|
+
const global = probe.global !== undefined ? probe.global : globalInstallRoot();
|
|
699
|
+
// Cannot tell where npm would write - keep the historical behaviour and
|
|
700
|
+
// let `npm install -g` run. The post-install version check below is what
|
|
701
|
+
// catches it if that guess was wrong.
|
|
702
|
+
if (!global) return false;
|
|
703
|
+
return global !== running;
|
|
655
704
|
} catch (e) {
|
|
656
705
|
return false;
|
|
657
706
|
}
|
|
658
707
|
}
|
|
659
708
|
|
|
660
|
-
function inPlaceTarballUpgrade(targetVersion) {
|
|
709
|
+
function inPlaceTarballUpgrade(targetVersion, targetDir = "/app") {
|
|
661
710
|
const tmpDir = `/tmp/oc-upgrade-${process.pid}-${Date.now()}`;
|
|
662
711
|
fs.mkdirSync(tmpDir, { recursive: true });
|
|
663
712
|
const env = { ...process.env, PATH: FULL_PATH, HOME: process.env.HOME || require("os").homedir() };
|
|
@@ -670,10 +719,10 @@ function inPlaceTarballUpgrade(targetVersion) {
|
|
|
670
719
|
execSync(`tar -xzf "${tgzPath}" -C "${tmpDir}"`, { encoding: "utf-8", timeout: 60000 });
|
|
671
720
|
// npm pack tarballs always extract into a top-level "package/" directory.
|
|
672
721
|
// cp -a preserves perms and symlinks; the trailing /. copies contents only.
|
|
673
|
-
execSync(`cp -a "${tmpDir}/package/." /
|
|
674
|
-
try { fs.chmodSync("
|
|
722
|
+
execSync(`cp -a "${tmpDir}/package/." "${targetDir}/"`, { encoding: "utf-8", timeout: 60000 });
|
|
723
|
+
try { fs.chmodSync(path.join(targetDir, "bin", "cli.js"), 0o755); } catch (e) {}
|
|
675
724
|
execSync(`npm install --omit=dev --no-audit --no-fund`, {
|
|
676
|
-
encoding: "utf-8", cwd:
|
|
725
|
+
encoding: "utf-8", cwd: targetDir, timeout: 240000, env,
|
|
677
726
|
});
|
|
678
727
|
try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch (e) {}
|
|
679
728
|
}
|
|
@@ -731,11 +780,12 @@ register({
|
|
|
731
780
|
return;
|
|
732
781
|
}
|
|
733
782
|
}
|
|
734
|
-
//
|
|
735
|
-
//
|
|
736
|
-
//
|
|
737
|
-
// brings us back on the new source.
|
|
738
|
-
if (
|
|
783
|
+
// The running source does not live where `npm install -g` writes - docker
|
|
784
|
+
// /app, or a host whose npm prefix has drifted. Overlay the tarball onto
|
|
785
|
+
// the directory we actually execute from and exit; whatever supervises us
|
|
786
|
+
// (k8s, docker restart=always, launchd) brings us back on the new source.
|
|
787
|
+
if (npmGlobalUpgradeWouldMiss()) {
|
|
788
|
+
const overlayDir = runningInstallRoot();
|
|
739
789
|
try { process.chdir("/tmp"); } catch (e) {}
|
|
740
790
|
let latest = null;
|
|
741
791
|
try {
|
|
@@ -751,19 +801,27 @@ register({
|
|
|
751
801
|
await send(`Already on the latest version (v${CURRENT_VERSION}).`);
|
|
752
802
|
return;
|
|
753
803
|
}
|
|
754
|
-
await send(`Upgrading v${CURRENT_VERSION} → v${latest} (in-place
|
|
804
|
+
await send(`Upgrading v${CURRENT_VERSION} → v${latest} (in-place overlay into ${overlayDir})...`);
|
|
755
805
|
try {
|
|
756
|
-
inPlaceTarballUpgrade(latest);
|
|
806
|
+
inPlaceTarballUpgrade(latest, overlayDir);
|
|
757
807
|
} catch (e) {
|
|
758
808
|
const errOutput = (e.stdout || e.stderr || e.message || String(e)).slice(-700);
|
|
759
809
|
await send(`Upgrade failed:\n${errOutput}`);
|
|
760
810
|
return;
|
|
761
811
|
}
|
|
812
|
+
// Verify against the directory we RUN from. Reporting a version read
|
|
813
|
+
// from anywhere else is how three releases were announced as installed
|
|
814
|
+
// while the running bot never moved.
|
|
815
|
+
const landed = installedVersionAt(overlayDir);
|
|
816
|
+
if (landed !== latest) {
|
|
817
|
+
await send(`Upgrade did NOT take: ${overlayDir} still reports v${landed || "unknown"}, expected v${latest}. Nothing was restarted.`);
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
762
820
|
let newVersion = latest;
|
|
763
821
|
let whatsNew = "";
|
|
764
822
|
try {
|
|
765
|
-
newVersion = JSON.parse(fs.readFileSync("
|
|
766
|
-
const changelog = fs.readFileSync("
|
|
823
|
+
newVersion = JSON.parse(fs.readFileSync(path.join(overlayDir, "package.json"), "utf-8")).version;
|
|
824
|
+
const changelog = fs.readFileSync(path.join(overlayDir, "CHANGELOG.md"), "utf-8");
|
|
767
825
|
let versionHeader = `## v${newVersion}`;
|
|
768
826
|
let start = changelog.indexOf(versionHeader);
|
|
769
827
|
if (start < 0) { versionHeader = `## ${newVersion}`; start = changelog.indexOf(versionHeader); }
|
|
@@ -809,11 +867,20 @@ register({
|
|
|
809
867
|
const { ensureSetup: postUpgradeSetup } = require("../health");
|
|
810
868
|
postUpgradeSetup();
|
|
811
869
|
} catch (e) {}
|
|
812
|
-
|
|
813
|
-
|
|
870
|
+
// Read the result back from the directory we EXECUTE from. Reading it
|
|
871
|
+
// from `npm root -g` only proves npm wrote somewhere, which is exactly
|
|
872
|
+
// the bug that let 3.4.18/19/20 be announced as installed on a host
|
|
873
|
+
// whose prefix had drifted while the running bot stayed on 3.4.17.
|
|
874
|
+
const runRoot = runningInstallRoot();
|
|
875
|
+
const landed = installedVersionAt(runRoot);
|
|
876
|
+
if (installTarget !== "latest" && landed !== installTarget) {
|
|
877
|
+
await send(`Upgrade did NOT take: ${runRoot} still reports v${landed || "unknown"}, expected v${installTarget}. npm installed elsewhere (prefix ${globalInstallRoot() || "unknown"}). Nothing was restarted.`);
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
const newPkg = { version: landed || installTarget };
|
|
814
881
|
let whatsNew = "";
|
|
815
882
|
try {
|
|
816
|
-
const changelog = fs.readFileSync(path.join(
|
|
883
|
+
const changelog = fs.readFileSync(path.join(runRoot, "CHANGELOG.md"), "utf-8");
|
|
817
884
|
let versionHeader = `## v${newPkg.version}`;
|
|
818
885
|
let start = changelog.indexOf(versionHeader);
|
|
819
886
|
if (start < 0) { versionHeader = `## ${newPkg.version}`; start = changelog.indexOf(versionHeader); }
|
|
@@ -882,14 +949,14 @@ register({
|
|
|
882
949
|
return;
|
|
883
950
|
}
|
|
884
951
|
const direction = isNewerVersion(resolved, CURRENT_VERSION) ? "Moving" : "Rolling back";
|
|
885
|
-
if (
|
|
952
|
+
if (npmGlobalUpgradeWouldMiss()) {
|
|
886
953
|
try { process.chdir("/tmp"); } catch (e) {}
|
|
887
954
|
const podNote = process.env.AGENTSPACE_POD_TOKEN
|
|
888
955
|
? "\nNote: this is an in-place overlay — a pod recreate returns to the deployment image version. Roll the image for a permanent downgrade."
|
|
889
956
|
: "";
|
|
890
957
|
await send(`${direction} v${CURRENT_VERSION} → v${resolved} (in-place tarball overlay into /app)...${podNote}`);
|
|
891
958
|
try {
|
|
892
|
-
inPlaceTarballUpgrade(resolved);
|
|
959
|
+
inPlaceTarballUpgrade(resolved, runningInstallRoot());
|
|
893
960
|
} catch (e) {
|
|
894
961
|
const errOutput = (e.stdout || e.stderr || e.message || String(e)).slice(-700);
|
|
895
962
|
await send(`Downgrade failed:\n${errOutput}`);
|
|
@@ -2687,3 +2754,8 @@ register({
|
|
|
2687
2754
|
send("Usage: /intros | /intros approve <id> | /intros reject <id> [reason]");
|
|
2688
2755
|
},
|
|
2689
2756
|
});
|
|
2757
|
+
|
|
2758
|
+
module.exports.runningInstallRoot = runningInstallRoot;
|
|
2759
|
+
module.exports.globalInstallRoot = globalInstallRoot;
|
|
2760
|
+
module.exports.npmGlobalUpgradeWouldMiss = npmGlobalUpgradeWouldMiss;
|
|
2761
|
+
module.exports.installedVersionAt = installedVersionAt;
|
package/core/providers/claude.js
CHANGED
|
@@ -12,14 +12,19 @@ const { createClaudeHookTransport } = require("./claude-hook");
|
|
|
12
12
|
// them. Verified 2026-09-23 on 2.1.280: the API reported claude-opus-5-5 as the
|
|
13
13
|
// serving model (canonicalModel claude-opus-5-5, 1M context), while 2.1.258
|
|
14
14
|
// returned "does not support this model; version 2.1.280 or newer is required".
|
|
15
|
+
// The opus 4.x entries (4-8, 4-7, 4-6) were dropped from the picker in 3.4.21 —
|
|
16
|
+
// superseded, and the menu had grown long enough to bury the current models.
|
|
17
|
+
// This removes the BUTTONS only: /model takes a typed name verbatim without
|
|
18
|
+
// consulting this list, so `/model claude-opus-4-8` still works as a rollback.
|
|
19
|
+
// The list is consulted on tapped mb: callbacks (core/actions.js), whose job is
|
|
20
|
+
// to reject a stale button from an old message — that is the intended effect.
|
|
21
|
+
// claude-sonnet-4-6 and claude-haiku-4-5 STAY: they are the tier models for
|
|
22
|
+
// utility work (see tierModel below), not just picker entries.
|
|
15
23
|
const CLAUDE_MODELS = Object.freeze([
|
|
16
24
|
"claude-fable-5-1",
|
|
17
25
|
"claude-fable-5",
|
|
18
26
|
"claude-opus-5-5",
|
|
19
27
|
"claude-opus-5",
|
|
20
|
-
"claude-opus-4-8",
|
|
21
|
-
"claude-opus-4-7",
|
|
22
|
-
"claude-opus-4-6",
|
|
23
28
|
"claude-sonnet-4-6",
|
|
24
29
|
"claude-haiku-4-5-20251001",
|
|
25
30
|
]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inetafrica/open-claudia",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.22",
|
|
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,7 +10,7 @@
|
|
|
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-call-speech.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-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-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",
|
|
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-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-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
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-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": [
|
package/test-provider-claude.js
CHANGED
|
@@ -49,6 +49,15 @@ 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
51
|
assert.ok(provider.modelChoices().includes("claude-sonnet-4-6"));
|
|
52
|
+
// 3.4.21: the superseded opus 4.x entries are gone from the picker. They are
|
|
53
|
+
// BUTTONS only - /model takes a typed name verbatim (core/handlers.js reads
|
|
54
|
+
// tail without consulting this list), so the rollback path survives removal.
|
|
55
|
+
for (const retired of ["claude-opus-4-8", "claude-opus-4-7", "claude-opus-4-6"]) {
|
|
56
|
+
assert.ok(!provider.modelChoices().includes(retired), `retired model still offered: ${retired}`);
|
|
57
|
+
}
|
|
58
|
+
// These two are NOT picker garnish - they are what tierModel returns for
|
|
59
|
+
// utility work, so they must survive any picker trim.
|
|
60
|
+
assert.ok(provider.modelChoices().includes("claude-haiku-4-5-20251001"), "haiku stays: it is the low tier");
|
|
52
61
|
|
|
53
62
|
// The SHIPPED default, asserted on the real module rather than the fixture above,
|
|
54
63
|
// so changing the constant cannot pass unnoticed. Read from source because the
|
|
@@ -65,8 +74,15 @@ assert.match(
|
|
|
65
74
|
// stop a default bump from silently repricing recall, pack review and the enforcer.
|
|
66
75
|
assert.strictEqual(claudeProvider.tierModel("low"), "claude-haiku-4-5-20251001", "low-tier utility work stays on haiku");
|
|
67
76
|
assert.strictEqual(claudeProvider.tierModel("medium"), "claude-sonnet-4-6", "medium-tier utility work stays on sonnet");
|
|
68
|
-
|
|
69
|
-
|
|
77
|
+
// Guard on the RESOLVED config, not process.env: loadEnv folds ~/.open-claudia/.env
|
|
78
|
+
// over process.env, so an operator pin lives in config.config and never appears in
|
|
79
|
+
// process.env. The 3.4.20 version of this check tested the wrong one and passed
|
|
80
|
+
// locally on a machine that was in fact pinned - fixed in 3.4.21.
|
|
81
|
+
if (!require("./core/config").config.CLAUDE_MODEL) {
|
|
82
|
+
assert.ok(
|
|
83
|
+
CLAUDE_MODELS.includes(claudeProvider.defaultModel()),
|
|
84
|
+
"with no operator override, the resolved default must be a model the picker offers",
|
|
85
|
+
);
|
|
70
86
|
}
|
|
71
87
|
assert.deepStrictEqual(provider.compatibilityStatus(), {
|
|
72
88
|
state: "compatible",
|
|
@@ -487,7 +487,14 @@ assert.match(pkg.description, /provider-agnostic coding-agent harness/i);
|
|
|
487
487
|
// entrypoint never writes one, so the constant is what pods resolve; the pod
|
|
488
488
|
// image installs Claude Code unpinned, which must be >= 2.1.280 or the model is
|
|
489
489
|
// refused with an API 400 rather than degrading.
|
|
490
|
-
|
|
490
|
+
// 3.4.21 approved by Sumeet 2026-09-23 ("I think we can get rid of the 4th gen",
|
|
491
|
+
// then "Your call" when asked to confirm the scope): drop claude-opus-4-8, 4-7
|
|
492
|
+
// and 4-6 from the Claude picker. Deliberately NOT dropped: claude-sonnet-4-6
|
|
493
|
+
// and claude-haiku-4-5, which tierModel returns for medium/low utility work -
|
|
494
|
+
// removing those would push recall, pack review and the enforcer onto opus.
|
|
495
|
+
// Removal is cosmetic by design: /model accepts a typed name without checking
|
|
496
|
+
// the list, so `/model claude-opus-4-8` remains a working rollback.
|
|
497
|
+
assert.strictEqual(pkg.version, "3.4.22", "release version must remain unchanged without explicit approval");
|
|
491
498
|
for (const keyword of ["claude", "codex", "coding-agent", "provider-agnostic"]) {
|
|
492
499
|
assert.ok(pkg.keywords.includes(keyword), `package keyword missing: ${keyword}`);
|
|
493
500
|
}
|