@codexhost/cli-darwin-x64 0.12.1 → 0.13.0

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.
Files changed (54) hide show
  1. package/README.md +1 -1
  2. package/THIRD_PARTY_NOTICES.txt +8 -0
  3. package/app/codexhost-distribution.json +1 -1
  4. package/app/console-server.mjs +232 -21
  5. package/app/console-web.js +5434 -1092
  6. package/app/desktop-controller.mjs +252 -41
  7. package/app/host-runtime.mjs +5318 -1448
  8. package/app/plugins/antigravity/manifest.json +18 -1
  9. package/app/plugins/antigravity/plugin.mjs +276 -42
  10. package/app/plugins/claude-code/manifest.json +28 -0
  11. package/app/plugins/claude-code/plugin.mjs +1049 -359
  12. package/app/plugins/codebuddy/manifest.json +17 -0
  13. package/app/plugins/codebuddy/plugin.mjs +5931 -5358
  14. package/app/plugins/codex-usage/manifest.json +9 -0
  15. package/app/plugins/codex-usage/plugin.mjs +16703 -0
  16. package/app/plugins/cursor-cli/manifest.json +17 -0
  17. package/app/plugins/cursor-cli/plugin.mjs +351 -77
  18. package/app/plugins/deepseek-harness/assets/icon.svg +1 -0
  19. package/app/plugins/deepseek-harness/manifest.json +35 -2
  20. package/app/plugins/deepseek-harness/plugin.mjs +798 -242
  21. package/app/plugins/enabled.json +2 -1
  22. package/app/plugins/grok/manifest.json +21 -1
  23. package/app/plugins/grok/plugin.mjs +884 -259
  24. package/app/plugins/hermes/assets/icon.png +0 -0
  25. package/app/plugins/hermes/manifest.json +30 -2
  26. package/app/plugins/hermes/plugin.mjs +278 -33
  27. package/app/plugins/kimi-code/assets/icon.svg +5 -0
  28. package/app/plugins/kimi-code/manifest.json +25 -2
  29. package/app/plugins/kimi-code/plugin.mjs +555 -36
  30. package/app/plugins/kiro-cli/assets/kiro-agent.svg +11 -0
  31. package/app/plugins/kiro-cli/manifest.json +18 -1
  32. package/app/plugins/kiro-cli/plugin.mjs +284 -22
  33. package/app/plugins/omp/manifest.json +21 -1
  34. package/app/plugins/omp/plugin.mjs +2737 -1956
  35. package/app/plugins/opencode/manifest.json +18 -1
  36. package/app/plugins/opencode/plugin.mjs +694 -147
  37. package/app/plugins/pi/manifest.json +32 -0
  38. package/app/plugins/pi/plugin.mjs +2809 -2254
  39. package/app/plugins/qoder/manifest.json +18 -1
  40. package/app/plugins/qoder/plugin.mjs +585 -81
  41. package/app/plugins/qoder-cn/manifest.json +18 -1
  42. package/app/plugins/qoder-cn/plugin.mjs +585 -81
  43. package/app/plugins/workbuddy/manifest.json +18 -0
  44. package/app/plugins/workbuddy/plugin.mjs +6317 -5746
  45. package/app/plugins/zcode/manifest.json +19 -1
  46. package/app/plugins/zcode/plugin.mjs +1066 -260
  47. package/app/renderer-extension.js +1999 -1686
  48. package/bin/codexhost +0 -0
  49. package/libexec/codexhost-shim +0 -0
  50. package/libexec/codexhost-updater +0 -0
  51. package/licenses/Cordis-LICENSE.txt +21 -0
  52. package/licenses/Cosmokit-LICENSE.txt +21 -0
  53. package/package.json +1 -1
  54. package/app/plugins/kiro-cli/assets/icon.svg +0 -5
@@ -5,9 +5,50 @@ var __export = (target, all) => {
5
5
  __defProp(target, name, { get: all[name], enumerable: true });
6
6
  };
7
7
 
8
- // dist/adapter.js
9
- import path3 from "node:path";
10
- import { stat as stat2 } from "node:fs/promises";
8
+ // dist/usage-statistics.js
9
+ import os from "node:os";
10
+ import path from "node:path";
11
+ import { lstat } from "node:fs/promises";
12
+
13
+ // ../../harness-adapter/dist/usage-statistics.js
14
+ var MAX_SESSION_ID_LENGTH = 512;
15
+ var MAX_CWD_LENGTH = 4096;
16
+ function sessionIdOk(value) {
17
+ return typeof value === "string" && value.length > 0 && value.length <= MAX_SESSION_ID_LENGTH;
18
+ }
19
+ function cwdOk(value) {
20
+ return typeof value === "string" && value.length > 0 && value.length <= MAX_CWD_LENGTH && !value.includes("\0") && (value.startsWith("/") || /^[A-Za-z]:[\\/]/u.test(value) || value.startsWith("\\\\"));
21
+ }
22
+ function withUsageSession(entry, session) {
23
+ const sessionId = sessionIdOk(session.sessionId) ? session.sessionId : void 0;
24
+ const cwd = cwdOk(session.cwd) ? session.cwd : void 0;
25
+ if (sessionId === void 0 && cwd === void 0)
26
+ return entry;
27
+ return {
28
+ ...entry,
29
+ ...sessionId !== void 0 ? { sessionId } : {},
30
+ ...cwd !== void 0 ? { cwd } : {}
31
+ };
32
+ }
33
+ function usageEntryFromRequest(request, occurredAtMs) {
34
+ if (!Number.isSafeInteger(occurredAtMs) || occurredAtMs <= 0)
35
+ return null;
36
+ return {
37
+ id: request.requestId,
38
+ occurredAtMs,
39
+ ...request.model !== void 0 ? { model: request.model } : {},
40
+ inputTokens: request.inputTokens,
41
+ ...request.cachedInputTokens !== void 0 ? { cachedInputTokens: request.cachedInputTokens } : {},
42
+ ...request.cacheWriteInputTokens !== void 0 ? { cacheWriteInputTokens: request.cacheWriteInputTokens } : {},
43
+ ...request.cacheWrite1hInputTokens !== void 0 ? { cacheWrite1hInputTokens: request.cacheWrite1hInputTokens } : {},
44
+ outputTokens: request.outputTokens,
45
+ ...request.reasoningOutputTokens !== void 0 ? { reasoningOutputTokens: request.reasoningOutputTokens } : {}
46
+ };
47
+ }
48
+ function nativeTimeMs(value) {
49
+ const time3 = typeof value === "number" ? value : typeof value === "string" ? Date.parse(value) : Number.NaN;
50
+ return Number.isFinite(time3) && time3 > 0 ? Math.floor(time3) : null;
51
+ }
11
52
 
12
53
  // ../../../node_modules/zod/v4/classic/external.js
13
54
  var external_exports = {};
@@ -775,10 +816,10 @@ function mergeDefs(...defs) {
775
816
  function cloneDef(schema) {
776
817
  return mergeDefs(schema._zod.def);
777
818
  }
778
- function getElementAtPath(obj, path4) {
779
- if (!path4)
819
+ function getElementAtPath(obj, path7) {
820
+ if (!path7)
780
821
  return obj;
781
- return path4.reduce((acc, key) => acc?.[key], obj);
822
+ return path7.reduce((acc, key) => acc?.[key], obj);
782
823
  }
783
824
  function promiseAllObject(promisesObj) {
784
825
  const keys = Object.keys(promisesObj);
@@ -1187,11 +1228,11 @@ function explicitlyAborted(x, startIndex = 0) {
1187
1228
  }
1188
1229
  return false;
1189
1230
  }
1190
- function prefixIssues(path4, issues) {
1231
+ function prefixIssues(path7, issues) {
1191
1232
  return issues.map((iss) => {
1192
1233
  var _a3;
1193
1234
  (_a3 = iss).path ?? (_a3.path = []);
1194
- iss.path.unshift(path4);
1235
+ iss.path.unshift(path7);
1195
1236
  return iss;
1196
1237
  });
1197
1238
  }
@@ -1338,16 +1379,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
1338
1379
  }
1339
1380
  function formatError(error51, mapper = (issue2) => issue2.message) {
1340
1381
  const fieldErrors = { _errors: [] };
1341
- const processError = (error52, path4 = []) => {
1382
+ const processError = (error52, path7 = []) => {
1342
1383
  for (const issue2 of error52.issues) {
1343
1384
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1344
- issue2.errors.map((issues) => processError({ issues }, [...path4, ...issue2.path]));
1385
+ issue2.errors.map((issues) => processError({ issues }, [...path7, ...issue2.path]));
1345
1386
  } else if (issue2.code === "invalid_key") {
1346
- processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
1387
+ processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
1347
1388
  } else if (issue2.code === "invalid_element") {
1348
- processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
1389
+ processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
1349
1390
  } else {
1350
- const fullpath = [...path4, ...issue2.path];
1391
+ const fullpath = [...path7, ...issue2.path];
1351
1392
  if (fullpath.length === 0) {
1352
1393
  fieldErrors._errors.push(mapper(issue2));
1353
1394
  } else {
@@ -1374,17 +1415,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
1374
1415
  }
1375
1416
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
1376
1417
  const result = { errors: [] };
1377
- const processError = (error52, path4 = []) => {
1418
+ const processError = (error52, path7 = []) => {
1378
1419
  var _a3, _b;
1379
1420
  for (const issue2 of error52.issues) {
1380
1421
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1381
- issue2.errors.map((issues) => processError({ issues }, [...path4, ...issue2.path]));
1422
+ issue2.errors.map((issues) => processError({ issues }, [...path7, ...issue2.path]));
1382
1423
  } else if (issue2.code === "invalid_key") {
1383
- processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
1424
+ processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
1384
1425
  } else if (issue2.code === "invalid_element") {
1385
- processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
1426
+ processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
1386
1427
  } else {
1387
- const fullpath = [...path4, ...issue2.path];
1428
+ const fullpath = [...path7, ...issue2.path];
1388
1429
  if (fullpath.length === 0) {
1389
1430
  result.errors.push(mapper(issue2));
1390
1431
  continue;
@@ -1416,8 +1457,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
1416
1457
  }
1417
1458
  function toDotPath(_path) {
1418
1459
  const segs = [];
1419
- const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1420
- for (const seg of path4) {
1460
+ const path7 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1461
+ for (const seg of path7) {
1421
1462
  if (typeof seg === "number")
1422
1463
  segs.push(`[${seg}]`);
1423
1464
  else if (typeof seg === "symbol")
@@ -4645,8 +4686,8 @@ function az_default() {
4645
4686
  }
4646
4687
 
4647
4688
  // ../../../node_modules/zod/v4/locales/be.js
4648
- function getBelarusianPlural(count, one, few, many) {
4649
- const absCount = Math.abs(count);
4689
+ function getBelarusianPlural(count2, one, few, many) {
4690
+ const absCount = Math.abs(count2);
4650
4691
  const lastDigit = absCount % 10;
4651
4692
  const lastTwoDigits = absCount % 100;
4652
4693
  if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
@@ -6724,8 +6765,8 @@ function hu_default() {
6724
6765
  }
6725
6766
 
6726
6767
  // ../../../node_modules/zod/v4/locales/hy.js
6727
- function getArmenianPlural(count, one, many) {
6728
- return Math.abs(count) === 1 ? one : many;
6768
+ function getArmenianPlural(count2, one, many) {
6769
+ return Math.abs(count2) === 1 ? one : many;
6729
6770
  }
6730
6771
  function withDefiniteArticle(word) {
6731
6772
  if (!word)
@@ -8853,8 +8894,8 @@ function ro_default() {
8853
8894
  }
8854
8895
 
8855
8896
  // ../../../node_modules/zod/v4/locales/ru.js
8856
- function getRussianPlural(count, one, few, many) {
8857
- const absCount = Math.abs(count);
8897
+ function getRussianPlural(count2, one, few, many) {
8898
+ const absCount = Math.abs(count2);
8858
8899
  const lastDigit = absCount % 10;
8859
8900
  const lastTwoDigits = absCount % 100;
8860
8901
  if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
@@ -14109,13 +14150,13 @@ function resolveRef(ref, ctx) {
14109
14150
  if (!ref.startsWith("#")) {
14110
14151
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14111
14152
  }
14112
- const path4 = ref.slice(1).split("/").filter(Boolean);
14113
- if (path4.length === 0) {
14153
+ const path7 = ref.slice(1).split("/").filter(Boolean);
14154
+ if (path7.length === 0) {
14114
14155
  return ctx.rootSchema;
14115
14156
  }
14116
14157
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14117
- if (path4[0] === defsKey) {
14118
- const key = path4[1];
14158
+ if (path7[0] === defsKey) {
14159
+ const key = path7[1];
14119
14160
  if (!key || !ctx.defs[key]) {
14120
14161
  throw new Error(`Reference not found: ${ref}`);
14121
14162
  }
@@ -14317,8 +14358,8 @@ function convertBaseSchema(schema, ctx) {
14317
14358
  break;
14318
14359
  }
14319
14360
  const objectSchema2 = z.object(shape).passthrough();
14320
- const recordSchema2 = z.looseRecord(keySchema, valueSchema);
14321
- zodSchema = z.intersection(objectSchema2, recordSchema2);
14361
+ const recordSchema3 = z.looseRecord(keySchema, valueSchema);
14362
+ zodSchema = z.intersection(objectSchema2, recordSchema3);
14322
14363
  break;
14323
14364
  }
14324
14365
  if (schema.patternProperties) {
@@ -14523,6 +14564,143 @@ function date4(params) {
14523
14564
  // ../../../node_modules/zod/v4/classic/external.js
14524
14565
  config(en_default());
14525
14566
 
14567
+ // dist/protocol.js
14568
+ var recordSchema = external_exports.record(external_exports.string(), external_exports.unknown());
14569
+ var nativeModelSchema = external_exports.object({
14570
+ providerId: external_exports.string().min(1),
14571
+ modelId: external_exports.string().min(1),
14572
+ variant: external_exports.string().optional(),
14573
+ options: external_exports.object({ reasoningLevel: external_exports.string().min(1).optional() }).optional()
14574
+ });
14575
+ var levelSchema = external_exports.object({ value: external_exports.string(), label: external_exports.string() });
14576
+ var modelSchema = external_exports.object({
14577
+ ref: nativeModelSchema,
14578
+ label: external_exports.string(),
14579
+ providerLabel: external_exports.string().optional(),
14580
+ disabledReason: external_exports.string().optional(),
14581
+ contextWindow: external_exports.number().int().positive().optional(),
14582
+ reasoning: external_exports.object({
14583
+ enabled: external_exports.boolean().optional(),
14584
+ levels: external_exports.array(levelSchema),
14585
+ defaultLevel: external_exports.string().optional()
14586
+ }).transform((reasoning) => ({
14587
+ ...reasoning,
14588
+ enabled: reasoning.enabled ?? reasoning.levels.length > 0
14589
+ })).optional()
14590
+ }).transform(({ providerLabel, ...model2 }) => {
14591
+ const provider = model2.ref.providerId === "account:bigmodel-individual-coding-plan" ? "BigModel" : model2.ref.providerId === "account:zai-individual-coding-plan" ? "Z.AI" : providerLabel;
14592
+ return { ...model2, label: provider ? `${provider} / ${model2.label}` : model2.label };
14593
+ });
14594
+ var settingsSchema = external_exports.object({
14595
+ model: external_exports.object({
14596
+ current: nativeModelSchema.optional(),
14597
+ available: external_exports.array(modelSchema),
14598
+ lastUsed: nativeModelSchema.optional()
14599
+ }),
14600
+ thoughtLevel: external_exports.object({
14601
+ enabled: external_exports.boolean(),
14602
+ current: external_exports.string().optional(),
14603
+ defaultLevel: external_exports.string().optional(),
14604
+ available: external_exports.array(levelSchema)
14605
+ }),
14606
+ mode: external_exports.object({ current: external_exports.enum(["build", "edit", "plan", "yolo", "auto"]) })
14607
+ });
14608
+ var workspaceSchema = external_exports.object({
14609
+ workspacePath: external_exports.string().min(1),
14610
+ workspaceKey: external_exports.string().min(1),
14611
+ workspaceIdentity: external_exports.string().optional()
14612
+ });
14613
+ var summarySchema = external_exports.object({
14614
+ sessionId: external_exports.string().min(1),
14615
+ workspace: workspaceSchema,
14616
+ title: external_exports.string(),
14617
+ status: external_exports.string(),
14618
+ mode: external_exports.string(),
14619
+ createdAt: external_exports.number(),
14620
+ updatedAt: external_exports.number(),
14621
+ parentSessionId: external_exports.string().optional(),
14622
+ sessionKind: external_exports.string()
14623
+ });
14624
+ var partSchema = external_exports.object({
14625
+ partId: external_exports.string().min(1),
14626
+ messageId: external_exports.string(),
14627
+ sessionId: external_exports.string(),
14628
+ type: external_exports.string()
14629
+ }).catchall(external_exports.unknown());
14630
+ var messageSchema = external_exports.object({
14631
+ info: external_exports.object({
14632
+ messageId: external_exports.string().min(1),
14633
+ sessionId: external_exports.string(),
14634
+ role: external_exports.enum(["user", "assistant"]),
14635
+ parentMessageId: external_exports.string().optional(),
14636
+ time: external_exports.object({ created: external_exports.number(), completed: external_exports.number().optional() }),
14637
+ model: nativeModelSchema.optional(),
14638
+ // Keep telemetry unvalidated here: bad usage must not break history or the Turn.
14639
+ tokens: external_exports.unknown().optional(),
14640
+ finish: external_exports.string().optional(),
14641
+ error: recordSchema.optional(),
14642
+ synthetic: external_exports.boolean().optional(),
14643
+ visibility: external_exports.string().optional(),
14644
+ semantics: recordSchema.optional()
14645
+ }),
14646
+ parts: external_exports.array(partSchema)
14647
+ });
14648
+ var snapshotSchema = external_exports.object({
14649
+ protocol: external_exports.object({ name: external_exports.literal("ZCode Protocol"), version: external_exports.literal(1) }),
14650
+ session: summarySchema,
14651
+ settings: settingsSchema,
14652
+ projection: external_exports.object({
14653
+ status: external_exports.string(),
14654
+ contextUsed: external_exports.number(),
14655
+ contextWindow: external_exports.number(),
14656
+ currentTurnId: external_exports.string().optional(),
14657
+ backgroundJobs: external_exports.array(external_exports.unknown()).optional(),
14658
+ target: recordSchema.nullable().optional()
14659
+ }),
14660
+ messages: external_exports.array(messageSchema),
14661
+ runtime: recordSchema,
14662
+ target: recordSchema.nullable().optional(),
14663
+ slashCommands: external_exports.array(external_exports.object({ name: external_exports.string(), description: external_exports.string(), source: external_exports.string().optional() })).optional()
14664
+ });
14665
+ var workspaceStateSchema = external_exports.object({
14666
+ workspace: workspaceSchema,
14667
+ settings: settingsSchema
14668
+ });
14669
+ var eventSchema = external_exports.object({
14670
+ eventId: external_exports.string(),
14671
+ sessionId: external_exports.string(),
14672
+ turnId: external_exports.string().optional(),
14673
+ seq: external_exports.number(),
14674
+ timestamp: external_exports.number(),
14675
+ type: external_exports.string(),
14676
+ payload: recordSchema.optional()
14677
+ });
14678
+ var runtimeUsageSchema = external_exports.object({
14679
+ contextUsage: external_exports.object({
14680
+ used: external_exports.number().int().nonnegative(),
14681
+ cache: external_exports.object({
14682
+ totalCacheReadTokens: external_exports.number().int().nonnegative(),
14683
+ totalCacheWriteTokens: external_exports.number().int().nonnegative(),
14684
+ latestHitRate: external_exports.number().min(0).max(1).nullish()
14685
+ }).nullish()
14686
+ })
14687
+ });
14688
+ function record2(value) {
14689
+ return recordSchema.safeParse(value).data ?? {};
14690
+ }
14691
+ function text(value) {
14692
+ return typeof value === "string" ? value : "";
14693
+ }
14694
+
14695
+ // ../../shared-contracts/dist/delegation-read.js
14696
+ var REMOTE_THREAD_REPLY_MAX_BYTES = 16 * 1024 * 1024;
14697
+ var delegationReadParamsSchema = external_exports.strictObject({
14698
+ threadId: external_exports.string().min(1).max(1024),
14699
+ view: external_exports.enum(["result", "messages"]),
14700
+ cursor: external_exports.string().min(1).max(8192).optional(),
14701
+ limit: external_exports.number().int().min(1).max(100).optional()
14702
+ });
14703
+
14526
14704
  // ../../shared-contracts/dist/credential-imports.js
14527
14705
  var credentialSourceSchema = external_exports.object({
14528
14706
  id: external_exports.string().min(1).max(256),
@@ -14593,6 +14771,153 @@ var harnessDisplaySetSchema = external_exports.strictObject({
14593
14771
  initializeOnly: external_exports.boolean().optional()
14594
14772
  });
14595
14773
 
14774
+ // ../../shared-contracts/dist/model-price-overrides.js
14775
+ var usdPerMillionTokens = external_exports.number().finite().nonnegative();
14776
+ var modelPriceOverrideSchema = external_exports.strictObject({
14777
+ input: usdPerMillionTokens,
14778
+ output: usdPerMillionTokens,
14779
+ cacheRead: usdPerMillionTokens.optional(),
14780
+ cacheWrite: usdPerMillionTokens.optional(),
14781
+ cacheWrite1h: usdPerMillionTokens.optional()
14782
+ });
14783
+ var modelPriceKeySchema = external_exports.string().max(512).refine((key) => key.trim() === key && key.length > 0, "Model ID is required");
14784
+ var modelPriceOverridesSchema = external_exports.strictObject({
14785
+ /** Absolute path of the Host's `pricing.json`. */
14786
+ path: external_exports.string(),
14787
+ entries: external_exports.array(external_exports.strictObject({ key: external_exports.string(), price: modelPriceOverrideSchema })),
14788
+ /** Why the existing file is unusable; the Host then ignores it and refuses to overwrite it. */
14789
+ error: external_exports.string().nullable()
14790
+ });
14791
+ var modelPriceOverridesGetSchema = external_exports.strictObject({});
14792
+ var modelPriceOverridesSetSchema = external_exports.strictObject({
14793
+ key: modelPriceKeySchema,
14794
+ price: modelPriceOverrideSchema.nullable(),
14795
+ previousKey: modelPriceKeySchema.optional()
14796
+ });
14797
+ var modelPriceDefaultParamsSchema = external_exports.strictObject({
14798
+ model: modelPriceKeySchema
14799
+ });
14800
+ var modelPriceSuggestionSchema = external_exports.strictObject({
14801
+ /** Verified from catalog canonical links, not inferred from names or equal prices. */
14802
+ official: external_exports.boolean().optional(),
14803
+ canonicalModelId: external_exports.string().min(1).optional(),
14804
+ provider: external_exports.string().min(1).max(512),
14805
+ model: external_exports.string().min(1).max(512),
14806
+ price: modelPriceOverrideSchema
14807
+ });
14808
+ var modelPriceDefaultResultSchema = external_exports.strictObject({
14809
+ price: modelPriceOverrideSchema.nullable(),
14810
+ /** Local catalog suggestions only; never used automatically for pricing. */
14811
+ suggestions: external_exports.array(modelPriceSuggestionSchema).max(6).optional()
14812
+ });
14813
+
14814
+ // ../../shared-contracts/dist/usage-statistics.js
14815
+ var USAGE_STATISTICS_RANGES = ["today", "7d", "30d", "90d", "all"];
14816
+ var count = external_exports.number().int().min(0).max(Number.MAX_SAFE_INTEGER);
14817
+ var localDate = external_exports.string().regex(/^\d{4}-\d{2}-\d{2}$/u);
14818
+ var harness = external_exports.string().min(1).max(128);
14819
+ var model = external_exports.string().min(1).max(512);
14820
+ var project = external_exports.string().min(1).max(4096);
14821
+ var usageStatisticsParamsSchema = external_exports.strictObject({
14822
+ range: external_exports.enum(USAGE_STATISTICS_RANGES),
14823
+ harness: harness.optional(),
14824
+ model: model.nullable().optional(),
14825
+ project: project.nullable().optional(),
14826
+ /** One local date inside the range. */
14827
+ date: localDate.optional()
14828
+ });
14829
+ var usageStatisticsTotalsSchema = external_exports.strictObject({
14830
+ requests: count,
14831
+ inputTokens: count,
14832
+ cachedInputTokens: count,
14833
+ cacheWriteInputTokens: count,
14834
+ cacheKnownInputTokens: count,
14835
+ outputTokens: count,
14836
+ reasoningOutputTokens: count,
14837
+ /** USD at the public price, summed over the priced requests only. */
14838
+ costUsd: external_exports.number().finite().min(0),
14839
+ /** Requests without a price (or the cache data the price needs); not in `costUsd`. */
14840
+ unpricedRequests: count,
14841
+ /**
14842
+ * Requests whose storage gave no token counts: counted as requests, with neither tokens nor
14843
+ * cost, and not as unpriced.
14844
+ */
14845
+ unmeteredRequests: count
14846
+ });
14847
+ var totals = usageStatisticsTotalsSchema.shape;
14848
+ var usageStatisticsSessionSchema = external_exports.strictObject({
14849
+ harness,
14850
+ sessionId: external_exports.string().min(1).max(512),
14851
+ project: project.nullable(),
14852
+ /** Models the session used, most requests first. */
14853
+ models: external_exports.array(model).max(16),
14854
+ firstAtMs: count,
14855
+ lastAtMs: count,
14856
+ ...totals
14857
+ });
14858
+ var usageStatisticsResultSchema = external_exports.strictObject({
14859
+ range: external_exports.enum(USAGE_STATISTICS_RANGES),
14860
+ /** First local date of the range; null for all time. */
14861
+ from: localDate.nullable(),
14862
+ to: localDate,
14863
+ /** The filters these figures apply, echoed so a late answer to older filters is recognised. */
14864
+ filters: external_exports.strictObject({
14865
+ harness: harness.nullable(),
14866
+ model: model.nullable(),
14867
+ unknownModel: external_exports.boolean(),
14868
+ project: project.nullable(),
14869
+ unknownProject: external_exports.boolean(),
14870
+ date: localDate.nullable()
14871
+ }),
14872
+ /** Reading of native storage: incomplete while the first read, or a refresh, is under way. */
14873
+ reading: external_exports.strictObject({ complete: external_exports.boolean(), sources: count, read: count }),
14874
+ /** Harnesses whose storage could not be read; their part is missing, the rest is complete. */
14875
+ failures: external_exports.array(external_exports.strictObject({ harness, message: external_exports.string().max(2048) })).max(256),
14876
+ /** Every value seen in the range, ignoring the filters, to choose filters from. */
14877
+ options: external_exports.strictObject({
14878
+ harnesses: external_exports.array(harness).max(256),
14879
+ models: external_exports.array(model.nullable()).max(4096),
14880
+ projects: external_exports.array(project.nullable()).max(4096)
14881
+ }),
14882
+ /** Current display metadata, scoped by Harness. Never a pricing or filter identity.
14883
+ * Optional for older Hosts; missing/conflicting labels fall back to the native model ID.
14884
+ */
14885
+ modelLabels: external_exports.array(external_exports.strictObject({ harness, model, label: model })).max(4096).optional(),
14886
+ /** Native credits, all filters applied, never combined across Harnesses or treated as USD.
14887
+ * Only groups with at least one reported value appear; reportedRequests exposes partial data.
14888
+ */
14889
+ credits: external_exports.array(external_exports.strictObject({
14890
+ harness,
14891
+ model: model.nullable(),
14892
+ credits: external_exports.number().finite().min(0),
14893
+ reportedRequests: count,
14894
+ requests: count
14895
+ })).max(4096).optional(),
14896
+ /** All filters applied. */
14897
+ totals: usageStatisticsTotalsSchema,
14898
+ /** Each date and Harness of the range: every filter except the day. */
14899
+ daily: external_exports.array(external_exports.strictObject({ date: localDate, harness, ...totals })).max(2e5),
14900
+ /** Local weekday (0 = Sunday) and hour, all filters applied. */
14901
+ hourly: external_exports.array(external_exports.strictObject({
14902
+ weekday: external_exports.number().int().min(0).max(6),
14903
+ hour: external_exports.number().int().min(0).max(23),
14904
+ ...totals
14905
+ })).max(168),
14906
+ byHarness: external_exports.array(external_exports.strictObject({ harness, ...totals })).max(256),
14907
+ byModel: external_exports.array(external_exports.strictObject({
14908
+ model: model.nullable(),
14909
+ ...totals,
14910
+ /** Requests priced by what the Harness recorded they cost, not by a price list. */
14911
+ harnessPricedRequests: count
14912
+ })).max(4096),
14913
+ byProject: external_exports.array(external_exports.strictObject({ project: project.nullable(), ...totals })).max(4096),
14914
+ /**
14915
+ * The sessions that spent the most, by cost and by tokens without cache, all filters applied;
14916
+ * requests without a native session are not listed here but count everywhere else.
14917
+ */
14918
+ sessions: external_exports.array(usageStatisticsSessionSchema).max(100)
14919
+ });
14920
+
14596
14921
  // ../../shared-contracts/dist/ids.js
14597
14922
  var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
14598
14923
  message: "Identifier must not be empty or whitespace"
@@ -14640,6 +14965,10 @@ var CONSOLE_HOST_METHODS = Object.freeze([
14640
14965
  "codexhost/account/list",
14641
14966
  "codexhost/account/refresh",
14642
14967
  "codexhost/account/usage/inspect",
14968
+ "codexhost/usage/model-prices/get",
14969
+ "codexhost/usage/model-prices/set",
14970
+ "codexhost/usage/model-prices/default",
14971
+ "codexhost/usage/statistics/get",
14643
14972
  "codexhost/update/check",
14644
14973
  "codexhost/update/start",
14645
14974
  "codexhost/update/status"
@@ -14704,6 +15033,7 @@ var threadUsageSnapshotSchema = external_exports.object({
14704
15033
  cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
14705
15034
  outputTokens: nonNegativeSafeIntegerSchema.optional(),
14706
15035
  outputTokensPerSecond: finiteNonNegativeNumberSchema.optional(),
15036
+ apiOutputTokensPerSecond: finiteNonNegativeNumberSchema.optional(),
14707
15037
  reasoningOutputTokens: nonNegativeSafeIntegerSchema.optional(),
14708
15038
  totalTokens: nonNegativeSafeIntegerSchema.optional(),
14709
15039
  totalCostUsd: finiteNonNegativeNumberSchema.optional(),
@@ -14715,7 +15045,11 @@ var threadUsageSnapshotSchema = external_exports.object({
14715
15045
  planFiveHourUsedPercent: cacheHitRatePercentSchema.optional(),
14716
15046
  planFiveHourResetsAtUnix: nonNegativeSafeIntegerSchema.optional(),
14717
15047
  planSevenDayUsedPercent: cacheHitRatePercentSchema.optional(),
14718
- planSevenDayResetsAtUnix: nonNegativeSafeIntegerSchema.optional()
15048
+ planSevenDayResetsAtUnix: nonNegativeSafeIntegerSchema.optional(),
15049
+ sessionCacheHitRatePercent: cacheHitRatePercentSchema.optional(),
15050
+ timeToFirstOutputMs: nonNegativeSafeIntegerSchema.optional(),
15051
+ costSource: external_exports.enum(["publicPrice", "native"]).optional(),
15052
+ unpricedModels: external_exports.array(external_exports.string().min(1)).min(1).optional()
14719
15053
  }).strict().superRefine((usage, context) => {
14720
15054
  if (Object.keys(usage).length === 0) {
14721
15055
  context.addIssue({ code: "custom", message: "Thread Usage must contain a reliable field" });
@@ -14736,6 +15070,20 @@ var threadUsageSnapshotSchema = external_exports.object({
14736
15070
  path: ["contextWindowTokens"]
14737
15071
  });
14738
15072
  }
15073
+ if (usage.costSource !== void 0 && usage.totalCostUsd === void 0) {
15074
+ context.addIssue({
15075
+ code: "custom",
15076
+ message: "Thread Usage costSource must be provided with totalCostUsd",
15077
+ path: ["costSource"]
15078
+ });
15079
+ }
15080
+ if (usage.unpricedModels !== void 0 && usage.costSource !== "publicPrice") {
15081
+ context.addIssue({
15082
+ code: "custom",
15083
+ message: "Thread Usage unpricedModels must be provided with a publicPrice cost",
15084
+ path: ["unpricedModels"]
15085
+ });
15086
+ }
14739
15087
  if (usage.planFiveHourResetsAtUnix !== void 0 && usage.planFiveHourUsedPercent === void 0) {
14740
15088
  context.addIssue({
14741
15089
  code: "custom",
@@ -14990,27 +15338,27 @@ var harnessModelCatalogSchema = external_exports.object({
14990
15338
  }).strict().superRefine((catalog, context) => {
14991
15339
  const refs = /* @__PURE__ */ new Set();
14992
15340
  const thinkingIds = new Set(catalog.thinkingOptions.map(({ id }) => id));
14993
- for (const [index, model] of catalog.models.entries()) {
14994
- if (refs.has(model.ref.id)) {
15341
+ for (const [index, model2] of catalog.models.entries()) {
15342
+ if (refs.has(model2.ref.id)) {
14995
15343
  context.addIssue({
14996
15344
  code: "custom",
14997
15345
  message: "Model Catalog refs must be unique",
14998
15346
  path: ["models", index, "ref", "id"]
14999
15347
  });
15000
15348
  }
15001
- refs.add(model.ref.id);
15002
- if (model.fastModel) {
15003
- if (refs.has(model.fastModel.id) || catalog.models.some((entry) => entry.ref.id === model.fastModel?.id)) {
15349
+ refs.add(model2.ref.id);
15350
+ if (model2.fastModel) {
15351
+ if (refs.has(model2.fastModel.id) || catalog.models.some((entry) => entry.ref.id === model2.fastModel?.id)) {
15004
15352
  context.addIssue({
15005
15353
  code: "custom",
15006
15354
  message: "Fast Model refs must be distinct and unique",
15007
15355
  path: ["models", index, "fastModel"]
15008
15356
  });
15009
15357
  }
15010
- refs.add(model.fastModel.id);
15358
+ refs.add(model2.fastModel.id);
15011
15359
  }
15012
15360
  const supportedThinkingIds = /* @__PURE__ */ new Set();
15013
- for (const [optionIndex, optionId] of (model.supportedThinkingOptionIds ?? []).entries()) {
15361
+ for (const [optionIndex, optionId] of (model2.supportedThinkingOptionIds ?? []).entries()) {
15014
15362
  if (supportedThinkingIds.has(optionId)) {
15015
15363
  context.addIssue({
15016
15364
  code: "custom",
@@ -15204,13 +15552,40 @@ var HARNESS_PLUGIN_LIMIT = 128;
15204
15552
  var harnessPluginIdSchema = external_exports.string().min(1).max(128).regex(/^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$/u).refine((id) => id !== "codex", "The official Codex identity is reserved").pipe(harnessIdSchema);
15205
15553
  var relativeResourceSchema = external_exports.string().min(1).max(512).refine((value) => !/[\\\u0000:#?]/u.test(value) && !value.startsWith("/") && !value.split("/").some((part) => part === ".." || part === ""), "Plugin resources must be relative paths inside the plugin");
15206
15554
  var documentationUrlSchema = external_exports.url().refine((value) => /^https:\/\/[^/?#@]+(?:[/?#]|$)/iu.test(value), "Plugin documentation links must be credential-free HTTPS URLs");
15555
+ var localizedTextSchema = external_exports.object({ en: external_exports.string().max(4096), "zh-CN": external_exports.string().max(4096).optional() }).strict();
15556
+ var harnessInstallationGuideSchema = external_exports.object({
15557
+ commands: external_exports.array(external_exports.object({ terminal: external_exports.string().max(256), command: external_exports.string().max(4096) }).strict()).max(8),
15558
+ before: localizedTextSchema.optional(),
15559
+ after: localizedTextSchema.optional(),
15560
+ downloads: external_exports.array(external_exports.object({ label: external_exports.string().max(128), url: documentationUrlSchema }).strict()).max(8).optional()
15561
+ }).strict();
15207
15562
  var pluginPresentationShape = {
15208
15563
  id: harnessPluginIdSchema,
15209
15564
  name: external_exports.string().trim().min(1).max(128),
15210
15565
  version: external_exports.string().min(1).max(128),
15566
+ /** Capability-only plugin; omitted for existing session-capable plugins. */
15567
+ kind: external_exports.literal("usage").optional(),
15568
+ /** Original image styling or bounded vector paths; never arbitrary CSS/SVG markup. */
15569
+ iconStyle: external_exports.object({
15570
+ vector: external_exports.object({
15571
+ viewBox: external_exports.string().max(128).regex(/^-?\d+(?:\.\d+)?(?: +-?\d+(?:\.\d+)?){3}$/u),
15572
+ color: external_exports.string().regex(/^(?:currentColor|#[a-f0-9]{6})$/iu),
15573
+ paths: external_exports.array(external_exports.object({
15574
+ d: external_exports.string().min(1).max(32768).regex(/^[MmLlHhVvCcSsQqTtAaZz\d.,+eE\s-]+$/u),
15575
+ fillRule: external_exports.enum(["evenodd", "nonzero"]).optional(),
15576
+ fill: external_exports.string().regex(/^(?:currentColor|#[a-f0-9]{6})$/iu).optional()
15577
+ }).strict()).min(1).max(32)
15578
+ }).strict().optional(),
15579
+ background: external_exports.string().regex(/^#[a-f0-9]{6}$/iu).optional(),
15580
+ borderRadius: external_exports.number().min(0).max(50).optional(),
15581
+ paddingRatio: external_exports.number().min(0).max(0.25).optional()
15582
+ }).strict().optional(),
15583
+ installation: harnessInstallationGuideSchema.optional(),
15584
+ notice: localizedTextSchema.optional(),
15211
15585
  /** The factory accepts a persisted local entrypoint through its construction context. */
15212
15586
  launchCommand: external_exports.literal(true).optional(),
15213
15587
  links: external_exports.object({
15588
+ website: documentationUrlSchema.optional(),
15214
15589
  documentation: documentationUrlSchema.optional(),
15215
15590
  installation: documentationUrlSchema.optional()
15216
15591
  }).strict().optional()
@@ -15629,6 +16004,11 @@ var codexSshDraftSchema = external_exports.strictObject({
15629
16004
  });
15630
16005
  var remoteConnectionsRequestSchema = external_exports.discriminatedUnion("action", [
15631
16006
  external_exports.strictObject({ action: external_exports.literal("list") }),
16007
+ external_exports.strictObject({
16008
+ action: external_exports.literal("read-thread"),
16009
+ hostId: hostId.refine((id) => id !== "local"),
16010
+ input: delegationReadParamsSchema
16011
+ }),
15632
16012
  external_exports.strictObject({
15633
16013
  action: external_exports.literal("save"),
15634
16014
  draft: codexSshDraftSchema,
@@ -15652,10 +16032,6 @@ var remoteConnectionsReplySchema = external_exports.union([
15652
16032
  // ../../shared-contracts/dist/index.js
15653
16033
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
15654
16034
 
15655
- // dist/transport.js
15656
- import { spawn } from "node:child_process";
15657
- import { randomUUID } from "node:crypto";
15658
-
15659
16035
  // ../../harness-adapter/dist/approval.js
15660
16036
  function invalidRequest(message) {
15661
16037
  return { code: "invalidRequest", message, retryable: false };
@@ -15764,7 +16140,6 @@ var tokenFields = [
15764
16140
  "cachedInputTokens",
15765
16141
  "cacheWriteInputTokens",
15766
16142
  "outputTokens",
15767
- "outputTokensPerSecond",
15768
16143
  "reasoningOutputTokens",
15769
16144
  "totalTokens",
15770
16145
  "contextWindowTokens",
@@ -15772,10 +16147,12 @@ var tokenFields = [
15772
16147
  ];
15773
16148
  var safeIntegerFields = [
15774
16149
  "planFiveHourResetsAtUnix",
15775
- "planSevenDayResetsAtUnix"
16150
+ "planSevenDayResetsAtUnix",
16151
+ "timeToFirstOutputMs"
15776
16152
  ];
15777
16153
  var percentFields = [
15778
16154
  "cacheHitRatePercent",
16155
+ "sessionCacheHitRatePercent",
15779
16156
  "planFiveHourUsedPercent",
15780
16157
  "planSevenDayUsedPercent"
15781
16158
  ];
@@ -15783,9 +16160,14 @@ var usageFields = /* @__PURE__ */ new Set([
15783
16160
  ...tokenFields,
15784
16161
  ...safeIntegerFields,
15785
16162
  ...percentFields,
16163
+ "sessionCacheUsage",
15786
16164
  "totalCostUsd",
15787
16165
  "totalCredits",
15788
- "contextUsagePercent"
16166
+ "contextUsagePercent",
16167
+ "outputTokensPerSecond",
16168
+ "apiOutputTokensPerSecond",
16169
+ "costSource",
16170
+ "unpricedModels"
15789
16171
  ]);
15790
16172
  function isRecord(value) {
15791
16173
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -15801,7 +16183,11 @@ function parseHostUsage(value) {
15801
16183
  throw new Error(`Harness Usage contains unknown field '${key}'`);
15802
16184
  }
15803
16185
  }
15804
- for (const field2 of ["totalCredits", "contextUsagePercent"]) {
16186
+ for (const field2 of [
16187
+ "totalCredits",
16188
+ "contextUsagePercent",
16189
+ "apiOutputTokensPerSecond"
16190
+ ]) {
15805
16191
  const candidate = value[field2];
15806
16192
  if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
15807
16193
  throw new Error(`Harness Usage '${field2}' must be a finite non-negative number`);
@@ -15831,6 +16217,12 @@ function parseHostUsage(value) {
15831
16217
  throw new Error(`Harness Usage '${field2}' must be between 0 and 100`);
15832
16218
  }
15833
16219
  }
16220
+ if (value.sessionCacheUsage !== void 0) {
16221
+ const totals2 = value.sessionCacheUsage;
16222
+ if (!isRecord(totals2) || Object.keys(totals2).some((key) => key !== "inputTokens" && key !== "cachedInputTokens") || typeof totals2.inputTokens !== "number" || !Number.isSafeInteger(totals2.inputTokens) || totals2.inputTokens < 0 || typeof totals2.cachedInputTokens !== "number" || !Number.isSafeInteger(totals2.cachedInputTokens) || totals2.cachedInputTokens < 0 || totals2.cachedInputTokens > totals2.inputTokens) {
16223
+ throw new Error("Harness Usage 'sessionCacheUsage' must contain complete bounded token totals");
16224
+ }
16225
+ }
15834
16226
  const hasContextUsed = value.contextUsedTokens !== void 0;
15835
16227
  const hasContextWindow = value.contextWindowTokens !== void 0;
15836
16228
  if (hasContextUsed !== hasContextWindow) {
@@ -15845,8 +16237,323 @@ function parseHostUsage(value) {
15845
16237
  if (value.planSevenDayResetsAtUnix !== void 0 && value.planSevenDayUsedPercent === void 0) {
15846
16238
  throw new Error("Harness Usage 'planSevenDayResetsAtUnix' must be provided with 'planSevenDayUsedPercent'");
15847
16239
  }
16240
+ if (value.costSource !== void 0) {
16241
+ if (value.costSource !== "publicPrice" && value.costSource !== "native") {
16242
+ throw new Error("Harness Usage 'costSource' must be 'publicPrice' or 'native'");
16243
+ }
16244
+ if (value.totalCostUsd === void 0) {
16245
+ throw new Error("Harness Usage 'costSource' must be provided with 'totalCostUsd'");
16246
+ }
16247
+ }
16248
+ if (value.unpricedModels !== void 0) {
16249
+ const models = value.unpricedModels;
16250
+ if (!Array.isArray(models) || models.length === 0 || !models.every((model2) => typeof model2 === "string" && model2.length > 0)) {
16251
+ throw new Error("Harness Usage 'unpricedModels' must be a non-empty list of Model IDs");
16252
+ }
16253
+ if (value.costSource !== "publicPrice") {
16254
+ throw new Error("Harness Usage 'unpricedModels' must be provided with a 'publicPrice' cost");
16255
+ }
16256
+ return { ...value, unpricedModels: [...models] };
16257
+ }
15848
16258
  return { ...value };
15849
16259
  }
16260
+ var requestTokenFields = [
16261
+ "inputTokens",
16262
+ "cachedInputTokens",
16263
+ "cacheWriteInputTokens",
16264
+ "cacheWrite1hInputTokens",
16265
+ "outputTokens",
16266
+ "reasoningOutputTokens",
16267
+ "startedAtMs",
16268
+ "completedAtMs"
16269
+ ];
16270
+ var requestFields = /* @__PURE__ */ new Set([
16271
+ ...requestTokenFields,
16272
+ "requestId",
16273
+ "historical",
16274
+ "model",
16275
+ "provider"
16276
+ ]);
16277
+ function parseHostUsageRequest(value) {
16278
+ if (!isRecord(value))
16279
+ throw new Error("Harness Usage request must be an object");
16280
+ for (const key of Object.keys(value)) {
16281
+ if (!requestFields.has(key)) {
16282
+ throw new Error(`Harness Usage request contains unknown field '${key}'`);
16283
+ }
16284
+ }
16285
+ if (typeof value.requestId !== "string" || value.requestId.length === 0) {
16286
+ throw new Error("Harness Usage request 'requestId' must be a non-empty string");
16287
+ }
16288
+ for (const field2 of ["model", "provider"]) {
16289
+ const candidate = value[field2];
16290
+ if (candidate !== void 0 && (typeof candidate !== "string" || candidate.length === 0)) {
16291
+ throw new Error(`Harness Usage request '${field2}' must be a non-empty string`);
16292
+ }
16293
+ }
16294
+ if (value.historical !== void 0 && typeof value.historical !== "boolean") {
16295
+ throw new Error("Harness Usage request 'historical' must be a boolean");
16296
+ }
16297
+ for (const field2 of requestTokenFields) {
16298
+ const candidate = value[field2];
16299
+ if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16300
+ throw new Error(`Harness Usage request '${field2}' must be a non-negative safe integer`);
16301
+ }
16302
+ }
16303
+ if (value.inputTokens === void 0 || value.outputTokens === void 0) {
16304
+ throw new Error("Harness Usage request must contain 'inputTokens' and 'outputTokens'");
16305
+ }
16306
+ const request = value;
16307
+ if ((request.cachedInputTokens ?? 0) + (request.cacheWriteInputTokens ?? 0) > request.inputTokens) {
16308
+ throw new Error("Harness Usage request cache Tokens must not exceed 'inputTokens'");
16309
+ }
16310
+ if ((request.reasoningOutputTokens ?? 0) > request.outputTokens) {
16311
+ throw new Error("Harness Usage request 'reasoningOutputTokens' must not exceed 'outputTokens'");
16312
+ }
16313
+ if (request.cacheWrite1hInputTokens !== void 0 && request.cacheWrite1hInputTokens > (request.cacheWriteInputTokens ?? -1)) {
16314
+ throw new Error("Harness Usage request 'cacheWrite1hInputTokens' must not exceed 'cacheWriteInputTokens'");
16315
+ }
16316
+ if (request.startedAtMs === void 0 !== (request.completedAtMs === void 0)) {
16317
+ throw new Error("Harness Usage request timing fields must be provided together");
16318
+ }
16319
+ if (request.startedAtMs !== void 0 && request.completedAtMs !== void 0 && request.completedAtMs < request.startedAtMs) {
16320
+ throw new Error("Harness Usage request 'completedAtMs' must not precede 'startedAtMs'");
16321
+ }
16322
+ return { ...request };
16323
+ }
16324
+
16325
+ // dist/usage.js
16326
+ function requestTokens(id, model2, value) {
16327
+ const tokens = record2(value), cache = record2(tokens.cache);
16328
+ const request = parseHostUsageRequest({
16329
+ requestId: id,
16330
+ ...model2 ? { model: model2 } : {},
16331
+ inputTokens: tokens.input,
16332
+ outputTokens: tokens.output,
16333
+ ...cache.read !== void 0 ? { cachedInputTokens: cache.read } : {},
16334
+ ...cache.write !== void 0 ? { cacheWriteInputTokens: cache.write } : {},
16335
+ ...tokens.reasoning !== void 0 ? { reasoningOutputTokens: tokens.reasoning } : {}
16336
+ });
16337
+ if (!Number.isSafeInteger(tokens.total) || tokens.total !== request.inputTokens + request.outputTokens)
16338
+ throw new Error("ZCode request token convention is unknown");
16339
+ return request;
16340
+ }
16341
+ function zcodeUsageRecord(message) {
16342
+ const info = message.info;
16343
+ if (info.role !== "assistant" || info.synthetic === true || info.semantics?.origin === "system")
16344
+ return { kind: "none" };
16345
+ if (info.time.completed === void 0)
16346
+ return { kind: "missing" };
16347
+ const tokens = record2(info.tokens), cache = record2(tokens.cache);
16348
+ if ((info.error || info.finish === "start_plan_admission_retry_discarded") && tokens.total === void 0 && tokens.input === 0 && tokens.output === 0 && tokens.reasoning === 0 && cache.read === 0 && cache.write === 0)
16349
+ return { kind: "none" };
16350
+ try {
16351
+ return {
16352
+ kind: "request",
16353
+ request: requestTokens(info.messageId, info.model?.modelId, info.tokens)
16354
+ };
16355
+ } catch {
16356
+ return { kind: "missing" };
16357
+ }
16358
+ }
16359
+ var ZcodeUsage = class {
16360
+ sessionId;
16361
+ emit;
16362
+ #seen = /* @__PURE__ */ new Map();
16363
+ #pending;
16364
+ #timings = /* @__PURE__ */ new Map();
16365
+ #complete = true;
16366
+ constructor(sessionId, emit) {
16367
+ this.sessionId = sessionId;
16368
+ this.emit = emit;
16369
+ }
16370
+ invalidate() {
16371
+ if (!this.#complete)
16372
+ return;
16373
+ this.#complete = false;
16374
+ this.emit({ type: "usage.history", complete: false });
16375
+ }
16376
+ replay(messages, historical) {
16377
+ for (const message of messages) {
16378
+ if (message.info.sessionId !== this.sessionId)
16379
+ continue;
16380
+ const result = zcodeUsageRecord(message);
16381
+ if (result.kind === "missing")
16382
+ this.invalidate();
16383
+ else if (result.kind === "request") {
16384
+ this.#publish({
16385
+ ...result.request,
16386
+ ...historical ? { historical: true } : this.#timings.get(result.request.requestId)
16387
+ });
16388
+ }
16389
+ }
16390
+ if (historical)
16391
+ this.emit({ type: "usage.history", complete: this.#complete });
16392
+ this.#pending = void 0;
16393
+ this.#timings.clear();
16394
+ }
16395
+ #publish(request) {
16396
+ if ((request.reasoningOutputTokens ?? 0) > 0) {
16397
+ request = { ...request };
16398
+ delete request.startedAtMs;
16399
+ delete request.completedAtMs;
16400
+ }
16401
+ const previous = this.#seen.get(request.requestId);
16402
+ if (previous) {
16403
+ if (previous.model !== request.model || previous.inputTokens !== request.inputTokens || previous.outputTokens !== request.outputTokens || previous.cachedInputTokens !== request.cachedInputTokens || previous.cacheWriteInputTokens !== request.cacheWriteInputTokens || (previous.reasoningOutputTokens ?? 0) !== (request.reasoningOutputTokens ?? 0))
16404
+ this.invalidate();
16405
+ return;
16406
+ }
16407
+ this.#seen.set(request.requestId, request);
16408
+ this.emit({ type: "usage.request", request });
16409
+ }
16410
+ observe(event) {
16411
+ if (event.sessionId !== this.sessionId)
16412
+ return;
16413
+ const p = event.payload ?? {};
16414
+ if (event.type === "turn.started") {
16415
+ this.#pending = void 0;
16416
+ this.#timings.clear();
16417
+ return;
16418
+ }
16419
+ if (event.type === "model.streaming") {
16420
+ const pending2 = this.#pending;
16421
+ if (!pending2 || pending2.turnId !== event.turnId || p.source === "subagent")
16422
+ return;
16423
+ const id = text(p.assistantMessageId);
16424
+ if (!id)
16425
+ return;
16426
+ if (pending2.messageId && pending2.messageId !== id)
16427
+ pending2.ambiguous = true;
16428
+ pending2.messageId = id;
16429
+ if (pending2.startedAtMs === void 0 && ((p.kind === "text_delta" || p.kind === "reasoning_delta") && text(p.delta) || p.kind === "tool_input_start" || p.kind === "tool_input_delta" && text(p.delta) || p.kind === "tool_call"))
16430
+ pending2.startedAtMs = event.timestamp;
16431
+ return;
16432
+ }
16433
+ if (event.type !== "session.updated" || p.querySource !== "main_turn")
16434
+ return;
16435
+ if (p.type === "model_request_started") {
16436
+ const id = text(p.requestId), model2 = text(p.modelId);
16437
+ if (!id || !model2)
16438
+ return;
16439
+ this.#pending = {
16440
+ id,
16441
+ model: model2,
16442
+ turnId: event.turnId,
16443
+ ambiguous: this.#pending !== void 0
16444
+ };
16445
+ return;
16446
+ }
16447
+ if (p.type !== "model_request_completed")
16448
+ return;
16449
+ const pending = this.#pending;
16450
+ if (!pending || pending.id !== p.requestId || pending.turnId !== event.turnId)
16451
+ return;
16452
+ this.#pending = void 0;
16453
+ if (pending.ambiguous || !pending.messageId || pending.model !== p.modelId)
16454
+ return;
16455
+ const start = pending.startedAtMs;
16456
+ if (start !== void 0 && Number.isSafeInteger(start) && Number.isSafeInteger(event.timestamp) && event.timestamp >= start)
16457
+ this.#timings.set(pending.messageId, {
16458
+ startedAtMs: start,
16459
+ completedAtMs: event.timestamp
16460
+ });
16461
+ const usage = record2(p.usage);
16462
+ if (usage.cacheReadTokens === void 0 || usage.cacheWriteTokens === void 0)
16463
+ return;
16464
+ try {
16465
+ const request = requestTokens(pending.messageId, pending.model, {
16466
+ input: usage.inputTokens,
16467
+ output: usage.outputTokens,
16468
+ total: usage.totalTokens,
16469
+ reasoning: usage.reasoningTokens,
16470
+ cache: { read: usage.cacheReadTokens, write: usage.cacheWriteTokens }
16471
+ });
16472
+ this.#publish({ ...request, ...this.#timings.get(pending.messageId) });
16473
+ } catch {
16474
+ this.invalidate();
16475
+ }
16476
+ }
16477
+ };
16478
+
16479
+ // dist/usage-statistics.js
16480
+ function zcodeDatabasePath(environment) {
16481
+ return path.join(environment.ZCODE_DATA_BASE_DIR?.trim() || environment.HOME || os.homedir(), ".zcode", "cli", "db", "db.sqlite");
16482
+ }
16483
+ async function readZcodeUsage(file2) {
16484
+ const { DatabaseSync } = await import("node:sqlite");
16485
+ const database = new DatabaseSync(file2, { readOnly: true });
16486
+ try {
16487
+ const entries = [];
16488
+ const directories = /* @__PURE__ */ new Map();
16489
+ const hasSessions = database.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'session'").get();
16490
+ if (hasSessions) {
16491
+ for (const row of database.prepare("SELECT id, directory FROM session").iterate()) {
16492
+ if (typeof row.directory === "string")
16493
+ directories.set(String(row.id), row.directory);
16494
+ }
16495
+ }
16496
+ for (const row of database.prepare("SELECT id, session_id, data FROM message").iterate()) {
16497
+ let data;
16498
+ try {
16499
+ data = record2(JSON.parse(String(row.data)));
16500
+ } catch {
16501
+ continue;
16502
+ }
16503
+ if (data.role !== "assistant")
16504
+ continue;
16505
+ const modelId = text(data.modelId) || text(data.modelID);
16506
+ const providerId = text(data.providerId) || text(data.providerID);
16507
+ const parsed = messageSchema.safeParse({
16508
+ info: {
16509
+ ...data,
16510
+ messageId: String(row.id),
16511
+ sessionId: String(row.session_id),
16512
+ ...modelId && providerId ? { model: { providerId, modelId } } : {}
16513
+ },
16514
+ parts: []
16515
+ });
16516
+ if (!parsed.success)
16517
+ continue;
16518
+ const usage = zcodeUsageRecord(parsed.data);
16519
+ const at = nativeTimeMs(parsed.data.info.time.created);
16520
+ const entry = usage.kind === "request" && at !== null && usageEntryFromRequest(usage.request, at);
16521
+ if (entry) {
16522
+ const sessionId = String(row.session_id);
16523
+ entries.push(withUsageSession(entry, { sessionId, cwd: directories.get(sessionId) }));
16524
+ }
16525
+ }
16526
+ return entries;
16527
+ } finally {
16528
+ database.close();
16529
+ }
16530
+ }
16531
+ function createZcodeUsageStatistics(environment) {
16532
+ return Object.freeze({
16533
+ async listSources() {
16534
+ const file2 = zcodeDatabasePath(environment);
16535
+ const info = await lstat(file2).catch(() => null);
16536
+ if (!info?.isFile())
16537
+ return [];
16538
+ const wal = await lstat(`${file2}-wal`).catch(() => null);
16539
+ return [
16540
+ {
16541
+ id: file2,
16542
+ fingerprint: `${info.ino}:${info.size}:${info.mtimeMs}:${wal ? `${wal.size}:${wal.mtimeMs}` : "-"}`
16543
+ }
16544
+ ];
16545
+ },
16546
+ readSource: (id) => readZcodeUsage(id)
16547
+ });
16548
+ }
16549
+
16550
+ // dist/adapter.js
16551
+ import path6 from "node:path";
16552
+ import { stat as stat2 } from "node:fs/promises";
16553
+
16554
+ // dist/transport.js
16555
+ import { spawn } from "node:child_process";
16556
+ import { randomUUID } from "node:crypto";
15850
16557
 
15851
16558
  // dist/errors.js
15852
16559
  var ZcodeError = class extends Error {
@@ -15873,136 +16580,10 @@ function nativeError(error51) {
15873
16580
  return { code: "nativeFailure", message: "ZCode operation failed", retryable: false };
15874
16581
  }
15875
16582
 
15876
- // dist/protocol.js
15877
- var recordSchema = external_exports.record(external_exports.string(), external_exports.unknown());
15878
- var nativeModelSchema = external_exports.object({
15879
- providerId: external_exports.string().min(1),
15880
- modelId: external_exports.string().min(1),
15881
- variant: external_exports.string().optional(),
15882
- options: external_exports.object({ reasoningLevel: external_exports.string().min(1).optional() }).optional()
15883
- });
15884
- var levelSchema = external_exports.object({ value: external_exports.string(), label: external_exports.string() });
15885
- var modelSchema = external_exports.object({
15886
- ref: nativeModelSchema,
15887
- label: external_exports.string(),
15888
- providerLabel: external_exports.string().optional(),
15889
- disabledReason: external_exports.string().optional(),
15890
- contextWindow: external_exports.number().int().positive().optional(),
15891
- reasoning: external_exports.object({
15892
- enabled: external_exports.boolean().optional(),
15893
- levels: external_exports.array(levelSchema),
15894
- defaultLevel: external_exports.string().optional()
15895
- }).transform((reasoning) => ({
15896
- ...reasoning,
15897
- enabled: reasoning.enabled ?? reasoning.levels.length > 0
15898
- })).optional()
15899
- }).transform(({ providerLabel, ...model }) => ({
15900
- ...model,
15901
- label: providerLabel ? `${providerLabel} / ${model.label}` : model.label
15902
- }));
15903
- var settingsSchema = external_exports.object({
15904
- model: external_exports.object({
15905
- current: nativeModelSchema.optional(),
15906
- available: external_exports.array(modelSchema),
15907
- lastUsed: nativeModelSchema.optional()
15908
- }),
15909
- thoughtLevel: external_exports.object({
15910
- enabled: external_exports.boolean(),
15911
- current: external_exports.string().optional(),
15912
- defaultLevel: external_exports.string().optional(),
15913
- available: external_exports.array(levelSchema)
15914
- }),
15915
- mode: external_exports.object({ current: external_exports.enum(["build", "edit", "plan", "yolo", "auto"]) })
15916
- });
15917
- var workspaceSchema = external_exports.object({
15918
- workspacePath: external_exports.string().min(1),
15919
- workspaceKey: external_exports.string().min(1),
15920
- workspaceIdentity: external_exports.string().optional()
15921
- });
15922
- var summarySchema = external_exports.object({
15923
- sessionId: external_exports.string().min(1),
15924
- workspace: workspaceSchema,
15925
- title: external_exports.string(),
15926
- status: external_exports.string(),
15927
- mode: external_exports.string(),
15928
- createdAt: external_exports.number(),
15929
- updatedAt: external_exports.number(),
15930
- parentSessionId: external_exports.string().optional(),
15931
- sessionKind: external_exports.string()
15932
- });
15933
- var partSchema = external_exports.object({
15934
- partId: external_exports.string().min(1),
15935
- messageId: external_exports.string(),
15936
- sessionId: external_exports.string(),
15937
- type: external_exports.string()
15938
- }).catchall(external_exports.unknown());
15939
- var messageSchema = external_exports.object({
15940
- info: external_exports.object({
15941
- messageId: external_exports.string().min(1),
15942
- sessionId: external_exports.string(),
15943
- role: external_exports.enum(["user", "assistant"]),
15944
- parentMessageId: external_exports.string().optional(),
15945
- time: external_exports.object({ created: external_exports.number(), completed: external_exports.number().optional() }),
15946
- model: nativeModelSchema.optional(),
15947
- finish: external_exports.string().optional(),
15948
- error: recordSchema.optional(),
15949
- synthetic: external_exports.boolean().optional(),
15950
- visibility: external_exports.string().optional(),
15951
- semantics: recordSchema.optional()
15952
- }),
15953
- parts: external_exports.array(partSchema)
15954
- });
15955
- var snapshotSchema = external_exports.object({
15956
- protocol: external_exports.object({ name: external_exports.literal("ZCode Protocol"), version: external_exports.literal(1) }),
15957
- session: summarySchema,
15958
- settings: settingsSchema,
15959
- projection: external_exports.object({
15960
- status: external_exports.string(),
15961
- contextUsed: external_exports.number(),
15962
- contextWindow: external_exports.number(),
15963
- currentTurnId: external_exports.string().optional(),
15964
- backgroundJobs: external_exports.array(external_exports.unknown()).optional(),
15965
- target: recordSchema.nullable().optional()
15966
- }),
15967
- messages: external_exports.array(messageSchema),
15968
- runtime: recordSchema,
15969
- target: recordSchema.nullable().optional(),
15970
- slashCommands: external_exports.array(external_exports.object({ name: external_exports.string(), description: external_exports.string(), source: external_exports.string().optional() })).optional()
15971
- });
15972
- var workspaceStateSchema = external_exports.object({
15973
- workspace: workspaceSchema,
15974
- settings: settingsSchema
15975
- });
15976
- var eventSchema = external_exports.object({
15977
- eventId: external_exports.string(),
15978
- sessionId: external_exports.string(),
15979
- turnId: external_exports.string().optional(),
15980
- seq: external_exports.number(),
15981
- timestamp: external_exports.number(),
15982
- type: external_exports.string(),
15983
- payload: recordSchema.optional()
15984
- });
15985
- var runtimeUsageSchema = external_exports.object({
15986
- contextUsage: external_exports.object({
15987
- used: external_exports.number().int().nonnegative(),
15988
- cache: external_exports.object({
15989
- totalCacheReadTokens: external_exports.number().int().nonnegative(),
15990
- totalCacheWriteTokens: external_exports.number().int().nonnegative(),
15991
- latestHitRate: external_exports.number().min(0).max(1).nullish()
15992
- }).nullish()
15993
- })
15994
- });
15995
- function record2(value) {
15996
- return recordSchema.safeParse(value).data ?? {};
15997
- }
15998
- function text(value) {
15999
- return typeof value === "string" ? value : "";
16000
- }
16001
-
16002
16583
  // dist/installation.js
16003
16584
  import { open, stat } from "node:fs/promises";
16004
16585
  import { homedir } from "node:os";
16005
- import path from "node:path";
16586
+ import path2 from "node:path";
16006
16587
  var DEFAULT_DARWIN_APP = "/Applications/ZCode.app";
16007
16588
  var DEFAULT_LINUX_APP = "/opt/ZCode";
16008
16589
  async function isFile(file2) {
@@ -16047,11 +16628,11 @@ async function resolveDefaultApp(environment, platform2) {
16047
16628
  if (platform2 === "linux")
16048
16629
  return DEFAULT_LINUX_APP;
16049
16630
  const candidates = [
16050
- environment.LOCALAPPDATA && path.join(environment.LOCALAPPDATA, "Programs", "ZCode"),
16051
- environment.ProgramFiles && path.join(environment.ProgramFiles, "ZCode")
16631
+ environment.LOCALAPPDATA && path2.join(environment.LOCALAPPDATA, "Programs", "ZCode"),
16632
+ environment.ProgramFiles && path2.join(environment.ProgramFiles, "ZCode")
16052
16633
  ].filter(Boolean);
16053
16634
  for (const candidate of candidates) {
16054
- if (await isFile(path.join(candidate, "resources", "app.asar")))
16635
+ if (await isFile(path2.join(candidate, "resources", "app.asar")))
16055
16636
  return candidate;
16056
16637
  }
16057
16638
  return candidates[0] ?? "";
@@ -16063,30 +16644,30 @@ async function resolveInstallation(environment, app, platform2 = process.platfor
16063
16644
  const explicitApp = app?.trim() || environment.CODEXHOST_ZCODE_APP?.trim();
16064
16645
  const targetApp = explicitApp || await resolveDefaultApp(environment, platform2);
16065
16646
  const missing = () => new ZcodeError("notInstalled", `ZCode Desktop was not found at ${targetApp}; install it or set its application path`);
16066
- const resources = platform2 === "darwin" ? path.join(targetApp, "Contents", "Resources") : path.join(targetApp, "resources");
16067
- const pkg = await readPackageJsonFromAsar(path.join(resources, "app.asar"));
16647
+ const resources = platform2 === "darwin" ? path2.join(targetApp, "Contents", "Resources") : path2.join(targetApp, "resources");
16648
+ const pkg = await readPackageJsonFromAsar(path2.join(resources, "app.asar"));
16068
16649
  if (!pkg?.productName || !pkg.version)
16069
16650
  throw missing();
16070
16651
  let runtime;
16071
16652
  if (platform2 === "darwin") {
16072
- runtime = path.join(targetApp, "Contents", "Frameworks", `${pkg.productName} Helper.app`, "Contents", "MacOS", `${pkg.productName} Helper`);
16653
+ runtime = path2.join(targetApp, "Contents", "Frameworks", `${pkg.productName} Helper.app`, "Contents", "MacOS", `${pkg.productName} Helper`);
16073
16654
  } else if (platform2 === "win32") {
16074
- runtime = path.join(targetApp, `${pkg.productName}.exe`);
16655
+ runtime = path2.join(targetApp, `${pkg.productName}.exe`);
16075
16656
  } else {
16076
16657
  const linuxExecutableName = pkg.productName.toLowerCase().replace(/\s+/g, "-");
16077
- runtime = path.join(targetApp, linuxExecutableName);
16658
+ runtime = path2.join(targetApp, linuxExecutableName);
16078
16659
  }
16079
- const cli = path.join(resources, "glm", "zcode.cjs");
16080
- const builtinProviderConfig = environment.ZCODE_BUILTIN_PROVIDER_CONFIG_FILE || path.join(resources, "config", "provider", "zcode-builtin.json");
16660
+ const cli = path2.join(resources, "glm", "zcode.cjs");
16661
+ const builtinProviderConfig = environment.ZCODE_BUILTIN_PROVIDER_CONFIG_FILE || path2.join(resources, "config", "provider", "zcode-builtin.json");
16081
16662
  if (!await isFile(runtime) || !await isFile(cli) || !await isFile(builtinProviderConfig))
16082
16663
  throw missing();
16083
- const dataRoot = path.join(environment.ZCODE_DATA_BASE_DIR?.trim() || environment.HOME || homedir(), ".zcode", "v2");
16664
+ const dataRoot = path2.join(environment.ZCODE_DATA_BASE_DIR?.trim() || environment.HOME || homedir(), ".zcode", "v2");
16084
16665
  return {
16085
16666
  runtime,
16086
16667
  version: pkg.version,
16087
16668
  cli,
16088
16669
  builtinProviderConfig,
16089
- personalProviderConfig: environment.ZCODE_PERSONAL_PROVIDER_CONFIG_FILE || path.join(dataRoot, "provider_config.json"),
16670
+ personalProviderConfig: environment.ZCODE_PERSONAL_PROVIDER_CONFIG_FILE || path2.join(dataRoot, "provider_config.json"),
16090
16671
  dataRoot
16091
16672
  };
16092
16673
  }
@@ -16108,25 +16689,15 @@ function createZcodeInstallation(environment, app) {
16108
16689
  }
16109
16690
 
16110
16691
  // dist/account.js
16692
+ import { createHash as createHash3 } from "node:crypto";
16693
+ import { readFile as readFile3 } from "node:fs/promises";
16694
+ import path5 from "node:path";
16695
+
16696
+ // dist/credentials.js
16111
16697
  import { createDecipheriv, createHash } from "node:crypto";
16112
16698
  import { readFile } from "node:fs/promises";
16113
16699
  import { homedir as homedir2, platform, userInfo } from "node:os";
16114
- import path2 from "node:path";
16115
- var SIGN_IN = "Sign in to ZCode Desktop with a Start Plan account, then try again";
16116
- var builtinSchema = external_exports.object({
16117
- revision: external_exports.union([external_exports.number(), external_exports.string()]),
16118
- config: external_exports.object({
16119
- providerConfigRules: external_exports.object({
16120
- providerRules: external_exports.array(external_exports.object({
16121
- providerId: external_exports.string().min(1),
16122
- config: external_exports.object({
16123
- builtinModelIds: external_exports.array(external_exports.string()).optional(),
16124
- access: external_exports.object({ mode: external_exports.string(), accountType: external_exports.string() }).partial().optional()
16125
- })
16126
- }))
16127
- })
16128
- })
16129
- });
16700
+ import path3 from "node:path";
16130
16701
  function decrypt(value, environment) {
16131
16702
  if (!value.startsWith("enc:v1:"))
16132
16703
  return value;
@@ -16147,25 +16718,231 @@ function decrypt(value, environment) {
16147
16718
  throw new ZcodeError("authenticationRequired", "Cannot decrypt ZCode credentials; ZCODE_CREDENTIAL_SECRET must match ZCode Desktop");
16148
16719
  }
16149
16720
  }
16150
- async function readCredential(installation, environment, key) {
16721
+ async function readCredentials(installation, environment) {
16151
16722
  let store;
16152
16723
  try {
16153
- store = JSON.parse(await readFile(path2.join(installation.dataRoot, "credentials.json"), "utf8"));
16724
+ store = JSON.parse(await readFile(path3.join(installation.dataRoot, "credentials.json"), "utf8"));
16154
16725
  } catch (error51) {
16155
16726
  if (error51.code === "ENOENT")
16156
- return "";
16727
+ return () => "";
16157
16728
  throw new ZcodeError("authenticationRequired", "Cannot read ZCode credentials");
16158
16729
  }
16159
- const value = external_exports.record(external_exports.string(), external_exports.string()).safeParse(store).data?.[key];
16160
- return value ? decrypt(value, environment) : "";
16730
+ const values = external_exports.record(external_exports.string(), external_exports.string()).safeParse(store).data;
16731
+ return (key) => {
16732
+ const value = values?.[key];
16733
+ return value ? decrypt(value, environment) : "";
16734
+ };
16735
+ }
16736
+ async function readCredential(installation, environment, key) {
16737
+ return (await readCredentials(installation, environment))(key);
16738
+ }
16739
+
16740
+ // dist/personal-coding-plan.js
16741
+ import { createHash as createHash2 } from "node:crypto";
16742
+ import { readFile as readFile2 } from "node:fs/promises";
16743
+ import { homedir as homedir3 } from "node:os";
16744
+ import path4 from "node:path";
16745
+ var familySchema = external_exports.enum(["zai", "bigmodel"]);
16746
+ var recordSchema2 = external_exports.record(external_exports.string(), external_exports.unknown());
16747
+ var CONNECT = "Connect Personal Coding Plan in ZCode Desktop, then re-detect ZCode and reopen the Thread";
16748
+ function personalCodingPlanOrigin(family, environment) {
16749
+ const test = environment.ZCODE_ENV?.trim().toLowerCase() === "test";
16750
+ const prefix = family === "zai" ? "ZAI" : "BIGMODEL";
16751
+ const suffix = family === "zai" ? "BUSINESS_BASE_URL" : "API_BASE_URL";
16752
+ const origin = environment[`${prefix}_${suffix}`]?.trim() || environment[`${prefix}_${test ? "TEST" : "PRODUCTION"}_${suffix}`]?.trim() || (family === "zai" ? test ? "https://api.chatglm.site" : "https://api.z.ai" : test ? "https://dev.bigmodel.cn" : "https://bigmodel.cn");
16753
+ const url2 = new URL(origin);
16754
+ if (!["http:", "https:"].includes(url2.protocol) || url2.username || url2.password)
16755
+ throw new Error("Invalid ZCode business origin");
16756
+ return url2.origin;
16757
+ }
16758
+ async function readSelection(environment, family) {
16759
+ const home = environment.ZCODE_DESKTOP_HOME_DIR?.trim() || environment.HOME?.trim() || environment.USERPROFILE?.trim() || homedir3();
16760
+ let raw;
16761
+ try {
16762
+ raw = JSON.parse(await readFile2(path4.join(home, ".zcode", "v2", "setting.json"), "utf8"));
16763
+ } catch (error51) {
16764
+ if (error51.code === "ENOENT")
16765
+ return false;
16766
+ throw new ZcodeError("configurationRequired", CONNECT);
16767
+ }
16768
+ const settings = recordSchema2.parse(raw);
16769
+ if (settings.providerFamilyDomain !== family)
16770
+ return false;
16771
+ if (Object.hasOwn(settings, "providerFamilyConnectionSelections")) {
16772
+ const selections = recordSchema2.parse(settings.providerFamilyConnectionSelections);
16773
+ return external_exports.object({ kind: external_exports.literal("individual-coding-plan") }).safeParse(selections[family]).success;
16774
+ }
16775
+ const modes = recordSchema2.safeParse(settings.modelProviderFamilyModes).data;
16776
+ const keys = recordSchema2.safeParse(settings.modelProviderFamilySelectedKeys).data;
16777
+ return modes?.[family] !== "apiKey" && keys?.[family] === `coding-plan:builtin:${family}-coding-plan`;
16778
+ }
16779
+ var envelopeSchema = external_exports.object({
16780
+ success: external_exports.boolean().optional(),
16781
+ code: external_exports.number().optional(),
16782
+ data: external_exports.array(external_exports.unknown())
16783
+ });
16784
+ var subscriptionSchema = external_exports.object({
16785
+ productId: external_exports.string().optional(),
16786
+ productName: external_exports.string().optional(),
16787
+ status: external_exports.string(),
16788
+ inCurrentPeriod: external_exports.boolean()
16789
+ });
16790
+ function codingProduct(value) {
16791
+ const entry = recordSchema2.safeParse(value).data;
16792
+ return [entry?.productId, entry?.productName].some((field2) => typeof field2 === "string" && field2.toLowerCase().includes("coding"));
16161
16793
  }
16794
+ async function queryEntitlement(family, apiKey, environment) {
16795
+ try {
16796
+ const response = await fetch(`${personalCodingPlanOrigin(family, environment)}/api/biz/subscription/list`, {
16797
+ method: "GET",
16798
+ // The subscription endpoint accepts the model API Key, not the OAuth token or Start JWT.
16799
+ headers: { Authorization: apiKey.trim() },
16800
+ redirect: "error",
16801
+ signal: AbortSignal.timeout(15e3)
16802
+ });
16803
+ if (response.status === 401 || response.status === 403)
16804
+ return "credential-failed";
16805
+ if (!response.ok)
16806
+ return "unknown";
16807
+ const parsed = envelopeSchema.safeParse(await response.json());
16808
+ if (!parsed.success)
16809
+ return "unknown";
16810
+ const payload = parsed.data;
16811
+ if (payload.success === false || payload.code !== void 0 && ![0, 200].includes(payload.code))
16812
+ return "unknown";
16813
+ let malformed = false;
16814
+ for (const item of payload.data) {
16815
+ if (!codingProduct(item))
16816
+ continue;
16817
+ const subscription = subscriptionSchema.safeParse(item);
16818
+ if (!subscription.success)
16819
+ malformed = true;
16820
+ else if (subscription.data.status === "VALID" && subscription.data.inCurrentPeriod)
16821
+ return "available";
16822
+ }
16823
+ return malformed ? "unknown" : "unavailable";
16824
+ } catch {
16825
+ return "unknown";
16826
+ }
16827
+ }
16828
+ var PersonalCodingPlanAccount = class {
16829
+ installation;
16830
+ environment;
16831
+ #authorized = /* @__PURE__ */ new Map();
16832
+ constructor(installation, environment) {
16833
+ this.installation = installation;
16834
+ this.environment = environment;
16835
+ }
16836
+ async #context(providerId, family) {
16837
+ const [credential, current] = await Promise.all([
16838
+ readCredentials(this.installation, this.environment),
16839
+ readSelection(this.environment, family)
16840
+ ]);
16841
+ if (credential("oauth:active_provider") !== family)
16842
+ return void 0;
16843
+ const raw = credential(`oauth:${family}:user_info`);
16844
+ if (!raw)
16845
+ return void 0;
16846
+ const profile = recordSchema2.parse(JSON.parse(raw));
16847
+ const normalized = external_exports.object({ id: external_exports.string(), username: external_exports.string(), displayName: external_exports.string() }).safeParse(profile).data;
16848
+ const identity = normalized ? normalized.id.trim() : family === "zai" && typeof profile.user_id === "string" ? profile.user_id.trim() : "";
16849
+ if (!identity || identity === "unknown")
16850
+ return void 0;
16851
+ const key = `account-provider:coding-plan:${providerId}:account:${encodeURIComponent(identity)}:api-key`;
16852
+ return { identity, current, apiKey: credential(key).trim() };
16853
+ }
16854
+ async inspect(providerId, accountType) {
16855
+ const family = familySchema.parse(accountType);
16856
+ this.#authorized.delete(providerId);
16857
+ let current = false;
16858
+ try {
16859
+ const context = await this.#context(providerId, family);
16860
+ if (!context)
16861
+ return {
16862
+ availability: "unavailable",
16863
+ entitled: false,
16864
+ current,
16865
+ unavailableReason: "not-connected"
16866
+ };
16867
+ current = context.current;
16868
+ const connectionKey = createHash2("sha256").update(JSON.stringify([family, context.identity, "individual-coding-plan"])).digest("hex");
16869
+ const base = { current, connectionKey };
16870
+ if (!context.apiKey)
16871
+ return {
16872
+ ...base,
16873
+ availability: "unavailable",
16874
+ entitled: false,
16875
+ unavailableReason: "credential-failed"
16876
+ };
16877
+ const entitlement = await queryEntitlement(family, context.apiKey, this.environment);
16878
+ const after = await this.#context(providerId, family);
16879
+ if (!after || after.identity !== context.identity || after.current !== current || after.apiKey !== context.apiKey)
16880
+ return { availability: "unknown", entitled: false, current: false };
16881
+ if (entitlement === "available") {
16882
+ if (current)
16883
+ this.#authorized.set(providerId, { family, identity: context.identity });
16884
+ return { ...base, availability: "available", entitled: true };
16885
+ }
16886
+ return {
16887
+ ...base,
16888
+ availability: entitlement === "unknown" ? "unknown" : "unavailable",
16889
+ entitled: false,
16890
+ ...entitlement === "unknown" ? {} : {
16891
+ unavailableReason: entitlement === "unavailable" ? "not-entitled" : "credential-failed"
16892
+ }
16893
+ };
16894
+ } catch {
16895
+ return { availability: "unknown", entitled: false, current };
16896
+ }
16897
+ }
16898
+ async requestAuth(request, signal) {
16899
+ const parsed = external_exports.object({
16900
+ providerId: external_exports.string(),
16901
+ modelSelection: external_exports.object({ providerId: external_exports.string() }),
16902
+ accountAccess: external_exports.object({
16903
+ type: external_exports.literal("zhipu-account"),
16904
+ mode: external_exports.literal("individual-coding-plan"),
16905
+ accountType: familySchema
16906
+ })
16907
+ }).safeParse(request);
16908
+ if (!parsed.success)
16909
+ throw new ZcodeError("authenticationRequired", CONNECT);
16910
+ const { providerId, modelSelection, accountAccess } = parsed.data;
16911
+ const authorized = this.#authorized.get(providerId);
16912
+ if (!authorized || authorized.family !== accountAccess.accountType || modelSelection.providerId !== providerId)
16913
+ throw new ZcodeError("authenticationRequired", CONNECT);
16914
+ signal.throwIfAborted();
16915
+ const context = await this.#context(providerId, authorized.family);
16916
+ signal.throwIfAborted();
16917
+ if (!context?.current || context.identity !== authorized.identity || !context.apiKey)
16918
+ throw new ZcodeError("authenticationRequired", CONNECT);
16919
+ return { apiKey: context.apiKey };
16920
+ }
16921
+ };
16922
+
16923
+ // dist/account.js
16924
+ var SIGN_IN = "Sign in to ZCode Desktop with a Start Plan account, then try again";
16925
+ var builtinSchema = external_exports.object({
16926
+ revision: external_exports.union([external_exports.number(), external_exports.string()]),
16927
+ config: external_exports.object({
16928
+ providerConfigRules: external_exports.object({
16929
+ providerRules: external_exports.array(external_exports.object({
16930
+ providerId: external_exports.string().min(1),
16931
+ config: external_exports.object({
16932
+ builtinModelIds: external_exports.array(external_exports.string()).optional(),
16933
+ access: external_exports.object({ mode: external_exports.string(), accountType: external_exports.string() }).partial().optional()
16934
+ })
16935
+ }))
16936
+ })
16937
+ })
16938
+ });
16162
16939
  function resolveEndpointOrigin(environment) {
16163
16940
  return environment.ZCODE_BASE_URL?.trim() || "https://zcode.z.ai";
16164
16941
  }
16165
16942
  async function readDeviceMid(installation) {
16166
16943
  try {
16167
- const file2 = path2.join(installation.dataRoot, "telemetry-state.json");
16168
- const parsed = JSON.parse(await readFile(file2, "utf8"));
16944
+ const file2 = path5.join(installation.dataRoot, "telemetry-state.json");
16945
+ const parsed = JSON.parse(await readFile3(file2, "utf8"));
16169
16946
  return typeof parsed?.deviceMid === "string" ? parsed.deviceMid.trim() : "";
16170
16947
  } catch {
16171
16948
  return "";
@@ -16263,24 +17040,38 @@ async function queryStartPlanBalance(origin, appVersion, jwt2, deviceMid) {
16263
17040
  }
16264
17041
  async function accountConfig(installation, environment) {
16265
17042
  const file2 = installation.builtinProviderConfig;
16266
- const builtin = builtinSchema.parse(JSON.parse(await readFile(file2, "utf8")));
16267
- const basedOnZCodeBuiltinRevision = `zcode-builtin:${builtin.revision}:${createHash("sha256").update(path2.resolve(file2)).digest("hex")}`;
17043
+ const builtin = builtinSchema.parse(JSON.parse(await readFile3(file2, "utf8")));
17044
+ const basedOnZCodeBuiltinRevision = `zcode-builtin:${builtin.revision}:${createHash3("sha256").update(path5.resolve(file2)).digest("hex")}`;
16268
17045
  const family = await readCredential(installation, environment, "oauth:active_provider");
16269
17046
  let balanceData;
16270
17047
  if (family) {
16271
- const jwt2 = await readCredential(installation, environment, "zcodejwttoken");
16272
- const deviceMid = await readDeviceMid(installation);
16273
- if (jwt2 && deviceMid) {
16274
- const origin = resolveEndpointOrigin(environment);
16275
- balanceData = await queryStartPlanBalance(origin, installation.version, jwt2, deviceMid);
17048
+ try {
17049
+ const jwt2 = await readCredential(installation, environment, "zcodejwttoken");
17050
+ const deviceMid = await readDeviceMid(installation);
17051
+ if (jwt2 && deviceMid) {
17052
+ const origin = resolveEndpointOrigin(environment);
17053
+ balanceData = await queryStartPlanBalance(origin, installation.version, jwt2, deviceMid);
17054
+ }
17055
+ } catch {
16276
17056
  }
16277
17057
  }
16278
17058
  let startPlan = false;
17059
+ const codingPlan = new PersonalCodingPlanAccount(installation, environment);
16279
17060
  const providers = {};
16280
17061
  const states = {};
16281
17062
  for (const rule of builtin.config.providerConfigRules.providerRules) {
16282
17063
  const access = rule.config.access;
16283
- if (!family || access?.mode !== "start-plan" || access.accountType !== family)
17064
+ if (!family || access?.accountType !== family)
17065
+ continue;
17066
+ if (access.mode === "individual-coding-plan" && (family === "zai" || family === "bigmodel")) {
17067
+ const state = await codingPlan.inspect(rule.providerId, family);
17068
+ providers[rule.providerId] = {
17069
+ access: { type: "zhipu-account", entitled: state.entitled }
17070
+ };
17071
+ states[rule.providerId] = state;
17072
+ continue;
17073
+ }
17074
+ if (access.mode !== "start-plan")
16284
17075
  continue;
16285
17076
  const allowedModels = resolveStartPlanModels(balanceData, rule.config.builtinModelIds);
16286
17077
  if (allowedModels.length > 0) {
@@ -16302,7 +17093,7 @@ async function accountConfig(installation, environment) {
16302
17093
  };
16303
17094
  }
16304
17095
  }
16305
- const overlayDigest = createHash("sha256").update(JSON.stringify([providers, states])).digest("hex").slice(0, 16);
17096
+ const overlayDigest = createHash3("sha256").update(JSON.stringify([providers, states])).digest("hex").slice(0, 16);
16306
17097
  return {
16307
17098
  params: {
16308
17099
  revision: `codexhost:${family || "signed-out"}:${builtin.revision}:${overlayDigest}`,
@@ -16310,16 +17101,20 @@ async function accountConfig(installation, environment) {
16310
17101
  providers,
16311
17102
  states
16312
17103
  },
16313
- startPlan
17104
+ startPlan,
17105
+ codingPlan
16314
17106
  };
16315
17107
  }
16316
- async function providerRuntimeHeaders(accountAccess, signal, installation, environment, verifier) {
16317
- if (external_exports.object({ mode: external_exports.literal("start-plan") }).safeParse(accountAccess).success !== true)
16318
- return {
16319
- headersApplied: false,
16320
- errorMessage: "codexhost supports only the ZCode Start Plan account"
16321
- };
17108
+ async function providerRuntimeHeaders(request, signal, installation, environment, verifier, codingPlan) {
17109
+ const mode = external_exports.object({ mode: external_exports.string() }).safeParse(request.accountAccess).data?.mode;
16322
17110
  try {
17111
+ if (mode === "individual-coding-plan")
17112
+ return { headersApplied: true, requestAuth: await codingPlan.requestAuth(request, signal) };
17113
+ if (mode !== "start-plan")
17114
+ return {
17115
+ headersApplied: false,
17116
+ errorMessage: "codexhost supports ZCode Start Plan and Personal Coding Plan; Team Coding Plan is not supported"
17117
+ };
16323
17118
  const apiKey = await readCredential(installation, environment, "zcodejwttoken");
16324
17119
  if (!apiKey)
16325
17120
  return { headersApplied: false, errorMessage: SIGN_IN };
@@ -16328,7 +17123,7 @@ async function providerRuntimeHeaders(accountAccess, signal, installation, envir
16328
17123
  } catch (error51) {
16329
17124
  return {
16330
17125
  headersApplied: false,
16331
- errorMessage: error51 instanceof ZcodeError ? error51.message : "ZCode Start Plan verification failed"
17126
+ errorMessage: error51 instanceof ZcodeError ? error51.message : "ZCode account authentication failed"
16332
17127
  };
16333
17128
  }
16334
17129
  }
@@ -16412,6 +17207,7 @@ var CliTransport = class {
16412
17207
  // Aborting these cancels only this transport's running and queued shared verifications.
16413
17208
  #headerRequests = /* @__PURE__ */ new Map();
16414
17209
  #startPlan = false;
17210
+ #codingPlan;
16415
17211
  #fault;
16416
17212
  #closed = false;
16417
17213
  #closePromise;
@@ -16434,9 +17230,10 @@ var CliTransport = class {
16434
17230
  if (this.#child || this.#closed)
16435
17231
  throw new ZcodeError("invalidState", "ZCode transport already started or closed");
16436
17232
  const installation = await resolveInstallation(this.options.environment, this.options.app);
16437
- const { params: accountParams, startPlan } = await accountConfig(installation, this.options.environment);
17233
+ const { params: accountParams, startPlan, codingPlan } = await accountConfig(installation, this.options.environment);
16438
17234
  this.#installation = installation;
16439
17235
  this.#startPlan = startPlan;
17236
+ this.#codingPlan = codingPlan;
16440
17237
  const child = spawn(installation.runtime, [installation.cli, "app-server", "--stdio", "--surface", "desktop"], {
16441
17238
  cwd: this.options.cwd,
16442
17239
  env: {
@@ -16561,7 +17358,7 @@ var CliTransport = class {
16561
17358
  this.#headerRequests.set(requestId, controller);
16562
17359
  try {
16563
17360
  reply({
16564
- result: await providerRuntimeHeaders(params.accountAccess, controller.signal, this.#installation, this.options.environment, () => this.options.verifier(this.#installation.version))
17361
+ result: await providerRuntimeHeaders(params, controller.signal, this.#installation, this.options.environment, () => this.options.verifier(this.#installation.version), this.#codingPlan)
16565
17362
  });
16566
17363
  } finally {
16567
17364
  this.#headerRequests.delete(requestId);
@@ -17292,32 +18089,32 @@ import { randomUUID as randomUUID2 } from "node:crypto";
17292
18089
 
17293
18090
  // dist/models.js
17294
18091
  var ZCODE_ID = harnessIdSchema.parse("zcode");
17295
- function encodeModel(model) {
18092
+ function encodeModel(model2) {
17296
18093
  return harnessModelRefSchema.parse({
17297
- id: `zcode-local-v1.${Buffer.from(JSON.stringify([model.providerId, model.modelId])).toString("base64url")}`
18094
+ id: `zcode-local-v1.${Buffer.from(JSON.stringify([model2.providerId, model2.modelId])).toString("base64url")}`
17298
18095
  });
17299
18096
  }
17300
- function decodeModel(model) {
18097
+ function decodeModel(model2) {
17301
18098
  try {
17302
18099
  const prefix = "zcode-local-v1.";
17303
- const value = JSON.parse(Buffer.from(model.id.slice(prefix.length), "base64url").toString("utf8"));
17304
- if (!model.id.startsWith(prefix) || !Array.isArray(value) || value.length !== 2)
18100
+ const value = JSON.parse(Buffer.from(model2.id.slice(prefix.length), "base64url").toString("utf8"));
18101
+ if (!model2.id.startsWith(prefix) || !Array.isArray(value) || value.length !== 2)
17305
18102
  throw new Error();
17306
18103
  const native = nativeModelSchema.parse({ providerId: value[0], modelId: value[1] });
17307
- if (encodeModel(native).id !== model.id)
18104
+ if (encodeModel(native).id !== model2.id)
17308
18105
  throw new Error();
17309
18106
  return native;
17310
18107
  } catch {
17311
18108
  throw new ZcodeError("invalidRequest", "Invalid ZCode model reference");
17312
18109
  }
17313
18110
  }
17314
- function selectNativeModel(model, settings, thinkingOption) {
17315
- const native = decodeModel(model);
17316
- const entry = settings.model.available.find((entry2) => encodeModel(entry2.ref).id === model.id && !entry2.disabledReason);
18111
+ function selectNativeModel(model2, settings, thinkingOption) {
18112
+ const native = decodeModel(model2);
18113
+ const entry = settings.model.available.find((entry2) => encodeModel(entry2.ref).id === model2.id && !entry2.disabledReason);
17317
18114
  if (!entry)
17318
18115
  throw new ZcodeError("invalidRequest", "ZCode model is not available");
17319
18116
  const current = settings.model.current;
17320
- const level = thinkingOption ?? (current && encodeModel(current).id === model.id ? current.options?.reasoningLevel : void 0) ?? entry.reasoning?.defaultLevel;
18117
+ const level = thinkingOption ?? (current && encodeModel(current).id === model2.id ? current.options?.reasoningLevel : void 0) ?? entry.reasoning?.defaultLevel;
17321
18118
  if (level === void 0)
17322
18119
  return native;
17323
18120
  if (!entry.reasoning?.levels.some((option) => option.value === level))
@@ -17325,20 +18122,20 @@ function selectNativeModel(model, settings, thinkingOption) {
17325
18122
  return { ...native, options: { reasoningLevel: level } };
17326
18123
  }
17327
18124
  function modelCatalog(settings) {
17328
- const available = settings.model.available.filter((model) => !model.disabledReason);
18125
+ const available = settings.model.available.filter((model2) => !model2.disabledReason);
17329
18126
  const levels = new Map(settings.thoughtLevel.available.map((level) => [level.value, level]));
17330
- for (const model of available)
17331
- for (const level of model.reasoning?.levels ?? [])
18127
+ for (const model2 of available)
18128
+ for (const level of model2.reasoning?.levels ?? [])
17332
18129
  levels.set(level.value, level);
17333
18130
  const current = settings.model.current ? encodeModel(settings.model.current) : void 0;
17334
18131
  const defaultThinking = settings.thoughtLevel.current ?? settings.thoughtLevel.defaultLevel;
17335
18132
  return harnessModelCatalogSchema.parse({
17336
- models: available.map((model) => ({
17337
- ref: encodeModel(model.ref),
17338
- label: model.label,
17339
- supportedThinkingOptionIds: model.reasoning?.enabled ? model.reasoning.levels.map((level) => level.value) : []
18133
+ models: available.map((model2) => ({
18134
+ ref: encodeModel(model2.ref),
18135
+ label: model2.label,
18136
+ supportedThinkingOptionIds: model2.reasoning?.enabled ? model2.reasoning.levels.map((level) => level.value) : []
17340
18137
  })),
17341
- ...current && available.some((model) => encodeModel(model.ref).id === current.id) ? { defaultModel: current } : {},
18138
+ ...current && available.some((model2) => encodeModel(model2.ref).id === current.id) ? { defaultModel: current } : {},
17342
18139
  thinkingOptions: [...levels.values()].map((level) => ({ id: level.value, label: level.label })),
17343
18140
  ...defaultThinking && levels.has(defaultThinking) ? { defaultThinkingOptionId: defaultThinking } : {}
17344
18141
  });
@@ -17363,7 +18160,7 @@ function permissionModes(current = "build") {
17363
18160
  function sessionState(snapshot, locator) {
17364
18161
  const settings = snapshot.settings;
17365
18162
  const current = settings.model.current ? encodeModel(settings.model.current) : void 0;
17366
- const model = settings.model.available.find((candidate) => encodeModel(candidate.ref).id === current?.id);
18163
+ const model2 = settings.model.available.find((candidate) => encodeModel(candidate.ref).id === current?.id);
17367
18164
  return {
17368
18165
  nativeRef: nativeSessionRefSchema.parse({
17369
18166
  harnessId: ZCODE_ID,
@@ -17372,7 +18169,7 @@ function sessionState(snapshot, locator) {
17372
18169
  locator: { ...locator, cwd: snapshot.session.workspace.workspacePath }
17373
18170
  }),
17374
18171
  ...current && settings.model.current?.providerId !== "zcode-unconfigured" ? { effectiveModel: current } : {},
17375
- ...model ? { resolvedModelLabel: model.label } : {},
18172
+ ...model2 ? { resolvedModelLabel: model2.label } : {},
17376
18173
  ...settings.thoughtLevel.enabled && settings.thoughtLevel.current ? {
17377
18174
  effectiveThinkingOptionId: harnessThinkingOptionIdSchema.parse(settings.thoughtLevel.current)
17378
18175
  } : {},
@@ -17386,7 +18183,7 @@ function sessionState(snapshot, locator) {
17386
18183
  function sessionUsage(snapshot, catalog) {
17387
18184
  const runtime = runtimeUsageSchema.safeParse(snapshot.runtime).data?.contextUsage;
17388
18185
  const current = snapshot.settings.model.current;
17389
- const window = catalog.model.available.find((model) => model.ref.providerId === current?.providerId && model.ref.modelId === current.modelId)?.contextWindow ?? snapshot.projection.contextWindow;
18186
+ const window = catalog.model.available.find((model2) => model2.ref.providerId === current?.providerId && model2.ref.modelId === current.modelId)?.contextWindow ?? snapshot.projection.contextWindow;
17390
18187
  const cache = runtime?.cache;
17391
18188
  const usage = {
17392
18189
  ...window > 0 ? {
@@ -17502,16 +18299,16 @@ var Diff = class {
17502
18299
  }
17503
18300
  }
17504
18301
  }
17505
- addToPath(path4, added, removed, oldPosInc, options) {
17506
- const last = path4.lastComponent;
18302
+ addToPath(path7, added, removed, oldPosInc, options) {
18303
+ const last = path7.lastComponent;
17507
18304
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
17508
18305
  return {
17509
- oldPos: path4.oldPos + oldPosInc,
18306
+ oldPos: path7.oldPos + oldPosInc,
17510
18307
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
17511
18308
  };
17512
18309
  } else {
17513
18310
  return {
17514
- oldPos: path4.oldPos + oldPosInc,
18311
+ oldPos: path7.oldPos + oldPosInc,
17515
18312
  lastComponent: { count: 1, added, removed, previousComponent: last }
17516
18313
  };
17517
18314
  }
@@ -18572,6 +19369,7 @@ var ZcodeSession = class {
18572
19369
  };
18573
19370
  #state;
18574
19371
  #snapshot;
19372
+ #usage;
18575
19373
  #active;
18576
19374
  #pendingInteractions = /* @__PURE__ */ new Map();
18577
19375
  #closed = false;
@@ -18590,6 +19388,7 @@ var ZcodeSession = class {
18590
19388
  this.capabilities = ZCODE_CAPABILITIES;
18591
19389
  this.catalog = modelCatalog(nativeCatalog);
18592
19390
  this.#snapshot = snapshot;
19391
+ this.#usage = new ZcodeUsage(snapshot.session.sessionId, (event) => this.#emit(event));
18593
19392
  this.#goalActive = (snapshot.target === void 0 ? snapshot.projection.target : snapshot.target)?.status === "active";
18594
19393
  this.#state = sessionState(snapshot, transport.locator);
18595
19394
  this.initialState = structuredClone(this.#state);
@@ -18607,6 +19406,7 @@ var ZcodeSession = class {
18607
19406
  this.#channel.emit({ kind: "event", event });
18608
19407
  }
18609
19408
  async subscribe() {
19409
+ this.#usage.replay(this.#snapshot.messages, true);
18610
19410
  await this.transport.listen("onDynamicSessionEvent", {
18611
19411
  sessionId: this.sessionId,
18612
19412
  deliveryKind: "desktop-continuous",
@@ -18750,7 +19550,7 @@ var ZcodeSession = class {
18750
19550
  try {
18751
19551
  let method, params;
18752
19552
  if (command.type === "model.select") {
18753
- if (!this.catalog.models.some((model) => model.ref.id === command.model.id))
19553
+ if (!this.catalog.models.some((model2) => model2.ref.id === command.model.id))
18754
19554
  return failure("invalidRequest", "ZCode model is not available");
18755
19555
  method = "setModel";
18756
19556
  params = {
@@ -18889,6 +19689,7 @@ var ZcodeSession = class {
18889
19689
  if (event.seq <= this.#lastSeq)
18890
19690
  return;
18891
19691
  this.#lastSeq = event.seq;
19692
+ this.#usage.observe(event);
18892
19693
  if (event.type === "session.updated" && event.payload && Object.hasOwn(event.payload, "target"))
18893
19694
  this.#goalActive = record2(event.payload.target).status === "active";
18894
19695
  if (event.type === "turn.started") {
@@ -18963,6 +19764,9 @@ var ZcodeSession = class {
18963
19764
  } : turn?.outcome;
18964
19765
  if (!outcome || outcome.status === "unknown")
18965
19766
  throw new ZcodeError("protocolError", "ZCode completed without a confirmed turn outcome");
19767
+ if (this.#active !== active || this.#closed || this.#faulted)
19768
+ return;
19769
+ this.#usage.replay(snapshot.messages, false);
18966
19770
  this.#finish(active, {
18967
19771
  ...outcome,
18968
19772
  ...turn?.checkpoint ? { checkpoint: turn.checkpoint } : {}
@@ -19077,8 +19881,10 @@ var ZcodeAdapter = class {
19077
19881
  // One verification page and SDK instance for the whole Host, as in ZCode Desktop.
19078
19882
  #verifier;
19079
19883
  #prewarmed = false;
19884
+ usageStatistics;
19080
19885
  constructor(options = {}) {
19081
19886
  this.options = options;
19887
+ this.usageStatistics = createZcodeUsageStatistics(options.environment ?? process.env);
19082
19888
  }
19083
19889
  #sharedVerifier = (appVersion) => this.#verifier ??= (this.options.createVerifier ?? createZcodeVerifier)({
19084
19890
  appVersion,
@@ -19110,7 +19916,7 @@ var ZcodeAdapter = class {
19110
19916
  async inspect(input = {}) {
19111
19917
  let transport;
19112
19918
  try {
19113
- transport = await this.#transport(path3.resolve(input.cwd ?? process.cwd()));
19919
+ transport = await this.#transport(path6.resolve(input.cwd ?? process.cwd()));
19114
19920
  const settings = await readCatalog(transport);
19115
19921
  const catalog = modelCatalog(settings);
19116
19922
  if (!catalog.models.length)
@@ -19118,7 +19924,7 @@ var ZcodeAdapter = class {
19118
19924
  status: "unavailable",
19119
19925
  error: {
19120
19926
  code: "authenticationRequired",
19121
- message: "ZCode has no available models. Sign in to ZCode Desktop with a Start Plan account or add a personal provider in ZCode.",
19927
+ message: "ZCode has no available models. Connect Start Plan or Personal Coding Plan in ZCode Desktop, or add a personal provider, then re-detect ZCode. Team Coding Plan is not supported.",
19122
19928
  retryable: true
19123
19929
  }
19124
19930
  };
@@ -19156,18 +19962,18 @@ var ZcodeAdapter = class {
19156
19962
  let transport;
19157
19963
  let createdId;
19158
19964
  try {
19159
- transport = await this.#transport(path3.resolve(input.cwd), input.environment);
19965
+ transport = await this.#transport(path6.resolve(input.cwd), input.environment);
19160
19966
  let snapshot, settings;
19161
19967
  if (input.kind === "create") {
19162
19968
  settings = await readCatalog(transport);
19163
19969
  if (input.permissionModeId && !permissionModes().modes.some((m) => m.id === input.permissionModeId))
19164
19970
  throw new ZcodeError("invalidRequest", "Unknown ZCode permission mode");
19165
- const model = input.model ? selectNativeModel(input.model, settings, input.thinkingOptionId) : void 0;
19971
+ const model2 = input.model ? selectNativeModel(input.model, settings, input.thinkingOptionId) : void 0;
19166
19972
  const mode = input.executionPolicy === "unattended-full-access" ? "yolo" : input.permissionModeId;
19167
19973
  const created = await transport.command(null, "createSession", {
19168
19974
  workspaceId: input.cwd,
19169
19975
  config: {
19170
- ...model ? { modelSelection: model } : {},
19976
+ ...model2 ? { modelSelection: model2 } : {},
19171
19977
  ...mode ? { mode } : {},
19172
19978
  ...input.thinkingOptionId ? { thought: input.thinkingOptionId } : {}
19173
19979
  }