@textcortex/zenocode 0.1.13 → 0.1.14
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/README.md
CHANGED
|
@@ -4,6 +4,12 @@ Zenocode is the secure coding agent for TextCortex customers. It runs in your te
|
|
|
4
4
|
|
|
5
5
|
Built for teams that need speed, control, and trust, Zenocode combines a terminal-native coding workflow with workspace routing and enterprise security from day one.
|
|
6
6
|
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
Zenocode is available on the **pay-as-you-go (PAYG)** plan. Your TextCortex account — or the organization seat assigned to you — must be on PAYG. On any other plan (Free, subscription, Business, Unlimited), `zenocode login` and model discovery return **"Zenocode is only available on the pay-as-you-go plan."** Switch your account (or ask your workspace admin to assign you a PAYG seat) before installing.
|
|
10
|
+
|
|
11
|
+
If you already use pay-as-you-go and just ran out of wallet credits, top up under **Settings → Billing** (`/user/dashboard/settings/billing`). If you are not on pay-as-you-go yet, pick a plan on the **plan selection** page (`/billing/plans`). The in-app Zenocode dialog (sidebar → Zenocode) links you to the right one automatically based on your account.
|
|
12
|
+
|
|
7
13
|
## What This Package Does
|
|
8
14
|
|
|
9
15
|
- Launches Zenocode from your terminal with the `zenocode` or `codecortex` command
|
|
@@ -31,13 +37,17 @@ The first `zenocode login` launches Zenocode automatically after browser authent
|
|
|
31
37
|
|
|
32
38
|
If you already have an API key, you can also start Zenocode by setting `TEXTCORTEX_API_KEY` or `TEXTCORTEX_API_TOKEN`.
|
|
33
39
|
|
|
40
|
+
## Models
|
|
41
|
+
|
|
42
|
+
Zenocode uses **GPT-5.6 Luna** by default. You can switch to any other model available to your TextCortex workspace from the model picker inside the agent. Available models are discovered automatically from your account, so the default falls back to the next best coding model (for example Kimi K2.7 Code) when Luna is not available to you.
|
|
43
|
+
|
|
34
44
|
## Built For Security And Compliance
|
|
35
45
|
|
|
36
|
-
Zenocode is built for organizations that treat security, compliance, and data
|
|
46
|
+
Zenocode is built for organizations that treat security, compliance, and data governance as non-negotiable.
|
|
37
47
|
|
|
38
|
-
-
|
|
48
|
+
- TextCortex-managed routing with workspace-aware model availability
|
|
39
49
|
- SOC 2 and ISO 27001 certified
|
|
40
|
-
-
|
|
50
|
+
- Model region metadata is surfaced for routing and governance decisions
|
|
41
51
|
- Zero data training: your data is not used for model training or fine-tuning
|
|
42
52
|
- Optional services or LLMs hosted outside the EU are covered by the EU-US Data Privacy Framework or GDPR Standard Contractual Clauses
|
|
43
53
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@textcortex/zenocode",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Secure,
|
|
3
|
+
"version": "0.1.14",
|
|
4
|
+
"description": "Secure, TextCortex-managed coding agent for customers that runs in your terminal, edits files, runs scripts, and more.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
7
7
|
"agent",
|
|
@@ -11,12 +11,17 @@
|
|
|
11
11
|
"developer-tools",
|
|
12
12
|
"textcortex",
|
|
13
13
|
"secure",
|
|
14
|
-
"
|
|
14
|
+
"enterprise",
|
|
15
15
|
"gdpr"
|
|
16
16
|
],
|
|
17
17
|
"private": false,
|
|
18
18
|
"license": "UNLICENSED",
|
|
19
19
|
"type": "module",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/textcortex/platform.git",
|
|
23
|
+
"directory": "apps/zenocode"
|
|
24
|
+
},
|
|
20
25
|
"publishConfig": {
|
|
21
26
|
"access": "public"
|
|
22
27
|
},
|
|
@@ -17,6 +17,10 @@ export const defaultOpenCodeForkUrl = "https://github.com/sst/opencode";
|
|
|
17
17
|
export const defaultOpenCodeRef = openCodeRef;
|
|
18
18
|
export const defaultOpenCodeVersion = openCodeVersion;
|
|
19
19
|
export const defaultOpenCodeBuildArgs = ["--skip-install"];
|
|
20
|
+
export const trustedPublishingRepository = {
|
|
21
|
+
type: "git",
|
|
22
|
+
url: "git+https://github.com/textcortex/platform.git",
|
|
23
|
+
};
|
|
20
24
|
const displayNameOnlyBrandingRefs = new Set([defaultOpenCodeRef]);
|
|
21
25
|
|
|
22
26
|
const forkUrl =
|
|
@@ -46,6 +50,8 @@ const publishTag =
|
|
|
46
50
|
process.env.ZENOCODE_PUBLISH_TAG ||
|
|
47
51
|
process.env.CODECORTEX_PUBLISH_TAG ||
|
|
48
52
|
"latest";
|
|
53
|
+
const publishProvenance =
|
|
54
|
+
(process.env.ZENOCODE_NPM_PROVENANCE || process.env.CODECORTEX_NPM_PROVENANCE) === "1";
|
|
49
55
|
const configuredBuildArgs = (
|
|
50
56
|
process.env.ZENOCODE_OPENCODE_BUILD_ARGS ||
|
|
51
57
|
process.env.CODECORTEX_OPENCODE_BUILD_ARGS ||
|
|
@@ -226,6 +232,20 @@ async function writeJson(filePath, payload) {
|
|
|
226
232
|
await fs.writeFile(filePath, `${JSON.stringify(payload, null, 2)}\n`, "utf-8");
|
|
227
233
|
}
|
|
228
234
|
|
|
235
|
+
export function selectLatestTarball(entries) {
|
|
236
|
+
const tarballs = entries.filter((entry) => entry.endsWith(".tgz")).sort((left, right) => {
|
|
237
|
+
const leftVersion = left.match(/-(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)(?:\+.*)?\.tgz$/)?.[1];
|
|
238
|
+
const rightVersion = right.match(/-(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)(?:\+.*)?\.tgz$/)?.[1];
|
|
239
|
+
if (leftVersion && rightVersion) {
|
|
240
|
+
return compareSemver(leftVersion, rightVersion);
|
|
241
|
+
}
|
|
242
|
+
if (leftVersion) return 1;
|
|
243
|
+
if (rightVersion) return -1;
|
|
244
|
+
return left.localeCompare(right);
|
|
245
|
+
});
|
|
246
|
+
return tarballs[tarballs.length - 1] || null;
|
|
247
|
+
}
|
|
248
|
+
|
|
229
249
|
async function maybePublishedVersion(packageName) {
|
|
230
250
|
const npmCommand = _command("npm");
|
|
231
251
|
try {
|
|
@@ -249,15 +269,18 @@ async function maybePublishedVersion(packageName) {
|
|
|
249
269
|
async function packPackage(packageDir) {
|
|
250
270
|
const npmCommand = _command("npm");
|
|
251
271
|
await run(npmCommand, ["pack"], { cwd: packageDir });
|
|
252
|
-
const
|
|
253
|
-
if (!
|
|
272
|
+
const tarball = selectLatestTarball(await fs.readdir(packageDir));
|
|
273
|
+
if (!tarball) {
|
|
254
274
|
throw new Error(`npm pack did not produce a tarball in ${packageDir}`);
|
|
255
275
|
}
|
|
256
|
-
return path.join(packageDir,
|
|
276
|
+
return path.join(packageDir, tarball);
|
|
257
277
|
}
|
|
258
278
|
|
|
259
|
-
export function buildPublishCommandArgs(tarballPath, { tag } = {}) {
|
|
279
|
+
export function buildPublishCommandArgs(tarballPath, { tag, provenance = false } = {}) {
|
|
260
280
|
const args = ["publish", tarballPath, "--access", "public"];
|
|
281
|
+
if (provenance) {
|
|
282
|
+
args.push("--provenance");
|
|
283
|
+
}
|
|
261
284
|
if (tag) {
|
|
262
285
|
args.push("--tag", tag);
|
|
263
286
|
}
|
|
@@ -281,10 +304,68 @@ async function publishTarballIfNeeded(packageName, version, tarballPath, cwd) {
|
|
|
281
304
|
}
|
|
282
305
|
|
|
283
306
|
const npmCommand = _command("npm");
|
|
284
|
-
await run(npmCommand, buildPublishCommandArgs(tarballPath, { tag: publishTag }), { cwd });
|
|
307
|
+
await run(npmCommand, buildPublishCommandArgs(tarballPath, { tag: publishTag, provenance: publishProvenance }), { cwd });
|
|
285
308
|
return { published: true, skipped: false };
|
|
286
309
|
}
|
|
287
310
|
|
|
311
|
+
async function readPublishTarget(packageDir) {
|
|
312
|
+
const pkg = await readJson(path.join(packageDir, "package.json"));
|
|
313
|
+
if (typeof pkg?.name !== "string" || typeof pkg?.version !== "string") {
|
|
314
|
+
throw new Error(`Invalid package metadata in ${packageDir}`);
|
|
315
|
+
}
|
|
316
|
+
const tarball = selectLatestTarball(await fs.readdir(packageDir));
|
|
317
|
+
if (!tarball) {
|
|
318
|
+
throw new Error(`Missing npm tarball in ${packageDir}`);
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
packageName: pkg.name,
|
|
322
|
+
version: pkg.version,
|
|
323
|
+
tarballPath: path.join(packageDir, tarball),
|
|
324
|
+
cwd: packageDir,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async function publishExistingPackages(artifactDir) {
|
|
329
|
+
const packageRoot = path.join(artifactDir, "npm-binaries");
|
|
330
|
+
const entries = await fs.readdir(packageRoot, { withFileTypes: true });
|
|
331
|
+
const binaryPackageDirs = entries
|
|
332
|
+
.filter((entry) => entry.isDirectory())
|
|
333
|
+
.map((entry) => path.join(packageRoot, entry.name))
|
|
334
|
+
.sort();
|
|
335
|
+
if (!binaryPackageDirs.length) {
|
|
336
|
+
throw new Error(`No existing binary packages found under ${packageRoot}`);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const targets = [];
|
|
340
|
+
for (const packageDir of binaryPackageDirs) {
|
|
341
|
+
targets.push(await readPublishTarget(packageDir));
|
|
342
|
+
}
|
|
343
|
+
targets.push(await readPublishTarget(path.join(artifactDir, "npm-package")));
|
|
344
|
+
|
|
345
|
+
const published = [];
|
|
346
|
+
const skipped = [];
|
|
347
|
+
for (const target of targets) {
|
|
348
|
+
const result = await publishTarballIfNeeded(
|
|
349
|
+
target.packageName,
|
|
350
|
+
target.version,
|
|
351
|
+
target.tarballPath,
|
|
352
|
+
target.cwd,
|
|
353
|
+
);
|
|
354
|
+
if (result.published) {
|
|
355
|
+
published.push(target.packageName);
|
|
356
|
+
} else if (result.skipped) {
|
|
357
|
+
skipped.push(target.packageName);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (published.length) {
|
|
362
|
+
console.log(`Published packages: ${published.join(", ")}`);
|
|
363
|
+
}
|
|
364
|
+
if (skipped.length) {
|
|
365
|
+
console.log(`Skipped already-published packages: ${skipped.join(", ")}`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
288
369
|
function _binaryFilename() {
|
|
289
370
|
return process.platform === "win32" ? "opencode.exe" : "opencode";
|
|
290
371
|
}
|
|
@@ -534,6 +615,7 @@ async function buildWrapperPackage({
|
|
|
534
615
|
version,
|
|
535
616
|
license: "MIT",
|
|
536
617
|
type: "commonjs",
|
|
618
|
+
repository: trustedPublishingRepository,
|
|
537
619
|
bin: buildWrapperBinMap(packageName, binName),
|
|
538
620
|
optionalDependencies: Object.fromEntries(
|
|
539
621
|
binaryPackages.map((pkg) => [pkg.brandedName, pkg.version]),
|
|
@@ -588,6 +670,7 @@ async function prepareBinaryPackages({ distDir, artifactDir, runtimePackageName
|
|
|
588
670
|
const targetDir = path.join(packageRoot, brandedName.replace("/", "__"));
|
|
589
671
|
await fs.cp(sourceDir, targetDir, { recursive: true });
|
|
590
672
|
pkg.name = brandedName;
|
|
673
|
+
pkg.repository = trustedPublishingRepository;
|
|
591
674
|
await writeJson(path.join(targetDir, "package.json"), pkg);
|
|
592
675
|
await patchBinaryAtPath(path.join(targetDir, "bin", _binaryFilename()));
|
|
593
676
|
|
|
@@ -641,21 +724,29 @@ async function main() {
|
|
|
641
724
|
console.log(" ZENOCODE_OPENCODE_BUILD_ARGS Additional args for upstream build script");
|
|
642
725
|
console.log(" ZENOCODE_PUBLISH=1 Publish packages to npm");
|
|
643
726
|
console.log(` ZENOCODE_PUBLISH_TAG npm tag (default: ${publishTag})`);
|
|
727
|
+
console.log(" --publish-existing Publish tarballs from the output directory without rebuilding");
|
|
644
728
|
console.log(" Legacy CODECORTEX_* env names are still accepted for compatibility.");
|
|
645
729
|
return;
|
|
646
730
|
}
|
|
647
731
|
|
|
732
|
+
const npmCommand = _command("npm");
|
|
733
|
+
await requireCommand(npmCommand);
|
|
734
|
+
|
|
735
|
+
const artifactDir = path.resolve(outputDir);
|
|
736
|
+
|
|
737
|
+
if (cliArgs.includes("--publish-existing")) {
|
|
738
|
+
await publishExistingPackages(artifactDir);
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
|
|
648
742
|
const gitCommand = _command("git");
|
|
649
743
|
const bunCommand = _command("bun");
|
|
650
|
-
const npmCommand = _command("npm");
|
|
651
744
|
await requireCommand(gitCommand);
|
|
652
745
|
await requireCommand(bunCommand);
|
|
653
|
-
await requireCommand(npmCommand);
|
|
654
746
|
|
|
655
747
|
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "zenocode-opencode-"));
|
|
656
748
|
const checkoutDir = path.join(tempRoot, "opencode");
|
|
657
749
|
const distDir = path.join(checkoutDir, "packages", "opencode", "dist");
|
|
658
|
-
const artifactDir = path.resolve(outputDir);
|
|
659
750
|
|
|
660
751
|
try {
|
|
661
752
|
const cloneArgs = ["clone", "--depth=1"];
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
defaultOpenCodeVersion,
|
|
11
11
|
deriveOpenCodeVersionFromRef,
|
|
12
12
|
mapBrandedBinaryPackageName,
|
|
13
|
+
selectLatestTarball,
|
|
14
|
+
trustedPublishingRepository,
|
|
13
15
|
} from "./build-branded-opencode.mjs";
|
|
14
16
|
|
|
15
17
|
test("branded OpenCode build defaults to the latest stable upstream release", () => {
|
|
@@ -49,7 +51,26 @@ test("buildWrapperBinMap includes package, opencode, and zenocode entrypoints",
|
|
|
49
51
|
});
|
|
50
52
|
});
|
|
51
53
|
|
|
52
|
-
test("
|
|
54
|
+
test("generated runtime packages point trusted publishing at this repository", () => {
|
|
55
|
+
assert.deepEqual(trustedPublishingRepository, {
|
|
56
|
+
type: "git",
|
|
57
|
+
url: "git+https://github.com/textcortex/platform.git",
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("buildPublishCommandArgs enables npm provenance for trusted publishing", () => {
|
|
62
|
+
assert.deepEqual(buildPublishCommandArgs("package.tgz", { tag: "latest", provenance: true }), [
|
|
63
|
+
"publish",
|
|
64
|
+
"package.tgz",
|
|
65
|
+
"--access",
|
|
66
|
+
"public",
|
|
67
|
+
"--provenance",
|
|
68
|
+
"--tag",
|
|
69
|
+
"latest",
|
|
70
|
+
]);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("buildPublishCommandArgs omits npm provenance unless requested", () => {
|
|
53
74
|
assert.deepEqual(buildPublishCommandArgs("package.tgz", { tag: "latest" }), [
|
|
54
75
|
"publish",
|
|
55
76
|
"package.tgz",
|
|
@@ -68,3 +89,15 @@ test("buildPublishCommandArgs omits tag arguments when no tag is provided", () =
|
|
|
68
89
|
"public",
|
|
69
90
|
]);
|
|
70
91
|
});
|
|
92
|
+
|
|
93
|
+
test("selectLatestTarball returns the sorted newest tarball", () => {
|
|
94
|
+
assert.equal(
|
|
95
|
+
selectLatestTarball([
|
|
96
|
+
"README.md",
|
|
97
|
+
"textcortex-zenocode-linux-x64-1.9.0.tgz",
|
|
98
|
+
"textcortex-zenocode-linux-x64-1.10.0.tgz",
|
|
99
|
+
]),
|
|
100
|
+
"textcortex-zenocode-linux-x64-1.10.0.tgz",
|
|
101
|
+
);
|
|
102
|
+
assert.equal(selectLatestTarball(["README.md"]), null);
|
|
103
|
+
});
|
package/scripts/run-zenocode.mjs
CHANGED
|
@@ -55,10 +55,18 @@ const opencodeBinaryPath =
|
|
|
55
55
|
const oauthInitiatePath = "/internal/v2/fastapi/zenocode/oauth2/initiate";
|
|
56
56
|
const oauthTokenPath = "/internal/v2/fastapi/zenocode/oauth2/token";
|
|
57
57
|
const defaultOrder = [
|
|
58
|
+
"gpt-5-6-luna",
|
|
59
|
+
"kimi-k2p7-code-non-thinking",
|
|
60
|
+
"kimi-k2p7-code-thinking",
|
|
58
61
|
"minimax-m3-thinking",
|
|
59
|
-
"kimi-k2-6",
|
|
62
|
+
"kimi-k2-6-non-thinking",
|
|
63
|
+
"kimi-k2-6-thinking",
|
|
64
|
+
"kimi-k2-5",
|
|
60
65
|
"kimi-k2-5-thinking",
|
|
61
|
-
"glm-5-
|
|
66
|
+
"glm-5-2-non-thinking",
|
|
67
|
+
"glm-5-2-thinking",
|
|
68
|
+
"glm-5-1-non-thinking",
|
|
69
|
+
"glm-5-1-thinking",
|
|
62
70
|
"gpt-5-2",
|
|
63
71
|
"gpt-5-1",
|
|
64
72
|
"gpt-5",
|
|
@@ -393,7 +401,8 @@ export function chooseDefaults(models) {
|
|
|
393
401
|
const ids = Object.keys(models);
|
|
394
402
|
if (!ids.length) throw new Error("No models were returned by the backend.");
|
|
395
403
|
const model = defaultOrder.find((id) => ids.includes(id)) || ids[0];
|
|
396
|
-
const smallModel =
|
|
404
|
+
const smallModel =
|
|
405
|
+
ids.find((id) => id.includes("-mini") || id.includes("haiku")) || model;
|
|
397
406
|
return { model, smallModel };
|
|
398
407
|
}
|
|
399
408
|
|
|
@@ -27,17 +27,60 @@ import {
|
|
|
27
27
|
writePrivateJsonFile,
|
|
28
28
|
} from "./run-zenocode.mjs";
|
|
29
29
|
|
|
30
|
-
test("chooseDefaults prefers
|
|
30
|
+
test("chooseDefaults prefers GPT-5.6 Luna as the Zenocode default", () => {
|
|
31
31
|
const defaults = chooseDefaults({
|
|
32
|
-
"
|
|
33
|
-
"
|
|
32
|
+
"kimi-k2p7-code-non-thinking": {},
|
|
33
|
+
"gpt-5-6-luna": {},
|
|
34
|
+
"glm-5-2-non-thinking": {},
|
|
34
35
|
"minimax-m3-thinking": {},
|
|
35
36
|
"gpt-5-2": {},
|
|
36
37
|
});
|
|
37
38
|
|
|
38
39
|
assert.deepEqual(defaults, {
|
|
39
|
-
model: "
|
|
40
|
-
smallModel: "
|
|
40
|
+
model: "gpt-5-6-luna",
|
|
41
|
+
smallModel: "gpt-5-6-luna",
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("chooseDefaults falls back to Kimi K2.7 Code when GPT-5.6 Luna is unavailable", () => {
|
|
46
|
+
const defaults = chooseDefaults({
|
|
47
|
+
"kimi-k2p7-code-non-thinking": {},
|
|
48
|
+
"glm-5-2-non-thinking": {},
|
|
49
|
+
"glm-5-1-non-thinking": {},
|
|
50
|
+
"kimi-k2-6-non-thinking": {},
|
|
51
|
+
"minimax-m3-thinking": {},
|
|
52
|
+
"gpt-5-2": {},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
assert.deepEqual(defaults, {
|
|
56
|
+
model: "kimi-k2p7-code-non-thinking",
|
|
57
|
+
smallModel: "kimi-k2p7-code-non-thinking",
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("chooseDefaults prefers GLM 5.2 over GLM 5.1 for Zenocode fallback", () => {
|
|
62
|
+
const defaults = chooseDefaults({
|
|
63
|
+
"glm-5-1-non-thinking": {},
|
|
64
|
+
"glm-5-2-non-thinking": {},
|
|
65
|
+
"gpt-5-mini": {},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
assert.deepEqual(defaults, {
|
|
69
|
+
model: "glm-5-2-non-thinking",
|
|
70
|
+
smallModel: "gpt-5-mini",
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("chooseDefaults falls back to explicit thinking variants when base models are absent", () => {
|
|
75
|
+
const defaults = chooseDefaults({
|
|
76
|
+
"kimi-k2p7-code-thinking": {},
|
|
77
|
+
"glm-5-2-non-thinking": {},
|
|
78
|
+
"kimi-k2-6-thinking": {},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
assert.deepEqual(defaults, {
|
|
82
|
+
model: "kimi-k2p7-code-thinking",
|
|
83
|
+
smallModel: "kimi-k2p7-code-thinking",
|
|
41
84
|
});
|
|
42
85
|
});
|
|
43
86
|
|
|
@@ -584,9 +627,14 @@ test("prepare-only refreshes stored Zenocode credentials when the access token h
|
|
|
584
627
|
textcortex: {
|
|
585
628
|
models: {
|
|
586
629
|
"minimax-m3-thinking": {},
|
|
587
|
-
"kimi-k2-6": {},
|
|
630
|
+
"kimi-k2-6-non-thinking": {},
|
|
631
|
+
"kimi-k2-6-thinking": {},
|
|
632
|
+
"kimi-k2-5": {},
|
|
588
633
|
"kimi-k2-5-thinking": {},
|
|
589
|
-
"glm-5-
|
|
634
|
+
"glm-5-2-non-thinking": {},
|
|
635
|
+
"glm-5-2-thinking": {},
|
|
636
|
+
"glm-5-1-non-thinking": {},
|
|
637
|
+
"glm-5-1-thinking": {},
|
|
590
638
|
},
|
|
591
639
|
},
|
|
592
640
|
}),
|
|
@@ -646,6 +694,11 @@ test("prepare-only refreshes stored Zenocode credentials when the access token h
|
|
|
646
694
|
await fs.readFile(path.join(zenocodeHome, "opencode.jsonc"), "utf-8"),
|
|
647
695
|
);
|
|
648
696
|
assert.equal(savedConfig.model, "textcortex/minimax-m3-thinking");
|
|
697
|
+
|
|
698
|
+
const savedModels = JSON.parse(
|
|
699
|
+
await fs.readFile(path.join(zenocodeHome, "models.json"), "utf-8"),
|
|
700
|
+
);
|
|
701
|
+
assert.ok(savedModels.textcortex.models["glm-5-2-non-thinking"]);
|
|
649
702
|
});
|
|
650
703
|
|
|
651
704
|
test("login launches the runtime immediately with system TUI theming", async (t) => {
|
|
@@ -733,9 +786,14 @@ main().catch((error) => {
|
|
|
733
786
|
textcortex: {
|
|
734
787
|
models: {
|
|
735
788
|
"minimax-m3-thinking": {},
|
|
736
|
-
"kimi-k2-6": {},
|
|
789
|
+
"kimi-k2-6-non-thinking": {},
|
|
790
|
+
"kimi-k2-6-thinking": {},
|
|
791
|
+
"kimi-k2-5": {},
|
|
737
792
|
"kimi-k2-5-thinking": {},
|
|
738
|
-
"glm-5-
|
|
793
|
+
"glm-5-2-non-thinking": {},
|
|
794
|
+
"glm-5-2-thinking": {},
|
|
795
|
+
"glm-5-1-non-thinking": {},
|
|
796
|
+
"glm-5-1-thinking": {},
|
|
739
797
|
},
|
|
740
798
|
},
|
|
741
799
|
}),
|
|
@@ -806,6 +864,11 @@ main().catch((error) => {
|
|
|
806
864
|
assert.equal(opencodeConfig.theme, "system");
|
|
807
865
|
assert.equal(opencodeConfig.model, "textcortex/minimax-m3-thinking");
|
|
808
866
|
|
|
867
|
+
const modelsConfig = JSON.parse(
|
|
868
|
+
await fs.readFile(path.join(zenocodeHome, "models.json"), "utf-8"),
|
|
869
|
+
);
|
|
870
|
+
assert.ok(modelsConfig.textcortex.models["glm-5-2-non-thinking"]);
|
|
871
|
+
|
|
809
872
|
const tuiConfig = JSON.parse(
|
|
810
873
|
await fs.readFile(runtimeInvocation.env.OPENCODE_TUI_CONFIG, "utf-8"),
|
|
811
874
|
);
|