zcode-acp-server 0.40.0 → 0.41.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 (80) hide show
  1. package/README.md +7 -5
  2. package/README.zh-CN.md +4 -2
  3. package/dist/backend/credentials.d.ts.map +1 -1
  4. package/dist/backend/credentials.js +14 -3
  5. package/dist/backend/credentials.js.map +1 -1
  6. package/dist/backend/resolve.d.ts +3 -3
  7. package/dist/backend/resolve.d.ts.map +1 -1
  8. package/dist/backend/resolve.js +22 -4
  9. package/dist/backend/resolve.js.map +1 -1
  10. package/dist/bin/quota.d.ts +1 -1
  11. package/dist/bin/quota.d.ts.map +1 -1
  12. package/dist/bin/quota.js +28 -17
  13. package/dist/bin/quota.js.map +1 -1
  14. package/dist/code-fingerprint.json +2 -2
  15. package/dist/config/options.d.ts +13 -0
  16. package/dist/config/options.d.ts.map +1 -1
  17. package/dist/config/options.js +1 -1
  18. package/dist/config/options.js.map +1 -1
  19. package/dist/config/user-config.d.ts +10 -0
  20. package/dist/config/user-config.d.ts.map +1 -1
  21. package/dist/config/user-config.js +31 -4
  22. package/dist/config/user-config.js.map +1 -1
  23. package/dist/handlers/account.d.ts +21 -6
  24. package/dist/handlers/account.d.ts.map +1 -1
  25. package/dist/handlers/account.js +25 -8
  26. package/dist/handlers/account.js.map +1 -1
  27. package/dist/handlers/background-tasks.d.ts +9 -0
  28. package/dist/handlers/background-tasks.d.ts.map +1 -1
  29. package/dist/handlers/background-tasks.js +42 -0
  30. package/dist/handlers/background-tasks.js.map +1 -1
  31. package/dist/handlers/extensions.d.ts.map +1 -1
  32. package/dist/handlers/extensions.js +8 -0
  33. package/dist/handlers/extensions.js.map +1 -1
  34. package/dist/handlers/session.d.ts.map +1 -1
  35. package/dist/handlers/session.js +55 -5
  36. package/dist/handlers/session.js.map +1 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +8 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/quota/combined.d.ts +13 -9
  41. package/dist/quota/combined.d.ts.map +1 -1
  42. package/dist/quota/combined.js +54 -29
  43. package/dist/quota/combined.js.map +1 -1
  44. package/dist/quota/ollama-cloud/cache.d.ts +16 -0
  45. package/dist/quota/ollama-cloud/cache.d.ts.map +1 -0
  46. package/dist/quota/ollama-cloud/cache.js +30 -0
  47. package/dist/quota/ollama-cloud/cache.js.map +1 -0
  48. package/dist/quota/ollama-cloud/client.d.ts +23 -0
  49. package/dist/quota/ollama-cloud/client.d.ts.map +1 -0
  50. package/dist/quota/ollama-cloud/client.js +33 -0
  51. package/dist/quota/ollama-cloud/client.js.map +1 -0
  52. package/dist/quota/ollama-cloud/config.d.ts +25 -0
  53. package/dist/quota/ollama-cloud/config.d.ts.map +1 -0
  54. package/dist/quota/ollama-cloud/config.js +31 -0
  55. package/dist/quota/ollama-cloud/config.js.map +1 -0
  56. package/dist/quota/ollama-cloud/format.d.ts +28 -0
  57. package/dist/quota/ollama-cloud/format.d.ts.map +1 -0
  58. package/dist/quota/ollama-cloud/format.js +53 -0
  59. package/dist/quota/ollama-cloud/format.js.map +1 -0
  60. package/dist/quota/ollama-cloud/index.d.ts +27 -0
  61. package/dist/quota/ollama-cloud/index.d.ts.map +1 -0
  62. package/dist/quota/ollama-cloud/index.js +91 -0
  63. package/dist/quota/ollama-cloud/index.js.map +1 -0
  64. package/dist/quota/ollama-cloud/types.d.ts +44 -0
  65. package/dist/quota/ollama-cloud/types.d.ts.map +1 -0
  66. package/dist/quota/ollama-cloud/types.js +15 -0
  67. package/dist/quota/ollama-cloud/types.js.map +1 -0
  68. package/dist/quota/opencode-go/config.d.ts +11 -11
  69. package/dist/quota/opencode-go/config.js +11 -11
  70. package/dist/quota/opencode-go/index.d.ts.map +1 -1
  71. package/dist/quota/opencode-go/index.js +16 -7
  72. package/dist/quota/opencode-go/index.js.map +1 -1
  73. package/dist/server.d.ts +15 -0
  74. package/dist/server.d.ts.map +1 -1
  75. package/dist/server.js +25 -0
  76. package/dist/server.js.map +1 -1
  77. package/docs/BACKLOG.md +3 -1
  78. package/docs/CLI.md +45 -13
  79. package/docs/REMOTE-CLIENTS.md +16 -2
  80. package/package.json +1 -1
@@ -2,20 +2,23 @@
2
2
  * Combined multi-provider quota — the orchestration layer used by the
3
3
  * `zcode-acp quota` CLI when no provider subcommand is given (default mode).
4
4
  *
5
- * Queries GLM Coding Plan and Opencode Go in parallel and renders a single
6
- * merged card with one section per provider. The `/quota` slash command does
7
- * NOT use this — it stays on the single-provider GLM {@link formatQuota}.
5
+ * Queries GLM Coding Plan, Opencode Go, and Ollama Cloud in parallel and
6
+ * renders a single merged card with one section per provider. The `/quota`
7
+ * slash command does NOT use this — it stays on the single-provider GLM
8
+ * {@link formatQuota}.
8
9
  *
9
10
  * Design notes:
10
- * - `Promise.all` so a slow Opencode Go scrape doesn't delay the GLM card.
11
- * - A `not_configured` Opencode Go result is silently dropped (no header,
12
- * no error line) in `all` mode, so GLM-only users see no noise. In `go`
13
- * mode it surfaces as a help line because the user explicitly asked.
11
+ * - `Promise.all` so a slow provider scrape doesn't delay the others.
12
+ * - A `not_configured` non-GLM result is silently dropped (no header,
13
+ * no error line) in `all` mode, so GLM-only users see no noise. In that
14
+ * provider's own mode it surfaces as a help line because the user
15
+ * explicitly asked.
14
16
  * - The divider width is computed from the widest body line so the frame
15
17
  * stays balanced regardless of which windows/counts are present.
16
18
  */
17
19
  import { renderGlmSection } from "./format.js";
18
20
  import { queryQuota } from "./index.js";
21
+ import { formatOcSection, queryOcUsage } from "./ollama-cloud/index.js";
19
22
  import { formatGoSection, queryGoUsage } from "./opencode-go/index.js";
20
23
  /**
21
24
  * Which Opencode Go windows to render. All three (rolling + weekly + monthly)
@@ -38,28 +41,37 @@ export function defaultGoWindows(provider) {
38
41
  * always resolves.
39
42
  */
40
43
  export async function queryCombined(provider) {
41
- // For `glm`-only we skip the Go fetch entirely; for `go`-only we skip GLM.
42
- // Skipping is cheaper and avoids touching Go credentials the user may not
43
- // have set. We still return both fields so the formatter's shape is uniform.
44
- const tasks = provider === "glm"
45
- ? [queryQuota(), Promise.resolve({ kind: "not_configured" })]
46
- : provider === "go"
47
- ? [Promise.resolve({ kind: "unavailable" }), queryGoUsage()]
48
- : [queryQuota(), queryGoUsage()];
49
- const [glm, go] = await Promise.all(tasks);
50
- return { glm, go };
44
+ // Single-provider modes skip the other fetches entirely. Skipping is
45
+ // cheaper and avoids touching credentials the user may not have set. We
46
+ // still return all fields so the formatter's shape is uniform.
47
+ const NONE_GLM = { kind: "unavailable" };
48
+ const NONE = { kind: "not_configured" };
49
+ const tasks = {
50
+ glm: provider === "go" || provider === "oc" ? Promise.resolve(NONE_GLM) : queryQuota(),
51
+ go: provider === "glm" || provider === "oc"
52
+ ? Promise.resolve(NONE)
53
+ : queryGoUsage(),
54
+ oc: provider === "glm" || provider === "go"
55
+ ? Promise.resolve(NONE)
56
+ : queryOcUsage(),
57
+ };
58
+ const [glm, go, oc] = await Promise.all([tasks.glm, tasks.go, tasks.oc]);
59
+ return { glm, go, oc };
51
60
  }
52
61
  /**
53
- * Decide whether the Go section should appear at all in `all` mode.
62
+ * Decide whether a non-GLM section should appear at all in `all` mode.
54
63
  *
55
64
  * `not_configured` is silently dropped (the user hasn't set credentials and
56
- * didn't explicitly ask for Go). All other kinds — including `unavailable`
57
- * and `auth_error` — render so the user sees that something is wrong.
65
+ * didn't explicitly ask for that provider). All other kinds — including
66
+ * `unavailable` and `auth_error` — render so the user sees that something is
67
+ * wrong.
58
68
  */
59
- function shouldShowGo(provider, go) {
60
- if (provider === "glm")
69
+ function shouldShowSection(result, provider,
70
+ /** The single-provider token that explicitly selects this section. */
71
+ own) {
72
+ if (provider !== "all" && provider !== own)
61
73
  return false;
62
- if (go.kind === "not_configured" && provider === "all")
74
+ if (result.kind === "not_configured" && provider === "all")
63
75
  return false;
64
76
  return true;
65
77
  }
@@ -109,7 +121,7 @@ function renderCombinedLines(combined, provider, glmOpts, goWindows, color = fal
109
121
  /** Optional refresh countdown rendered on the separator line after the
110
122
  * first section (e.g. `refresh in 29s`). */
111
123
  refreshSuffix) {
112
- const { glm, go } = combined;
124
+ const { glm, go, oc } = combined;
113
125
  const sep = separatorLine(refreshSuffix);
114
126
  // Fold the color flag into the GLM FormatOptions so it reaches renderGlmSection
115
127
  // alongside detail/compact without each caller having to set it.
@@ -128,33 +140,46 @@ refreshSuffix) {
128
140
  const lines = [section.header, ...section.body];
129
141
  return sep ? [...lines, sep] : lines;
130
142
  }
143
+ // Single-provider Ollama Cloud: header + body, no banner/divider.
144
+ if (provider === "oc") {
145
+ const section = formatOcSection(oc, color);
146
+ const lines = [section.header, ...section.body];
147
+ return sep ? [...lines, sep] : lines;
148
+ }
131
149
  // Combined `all` mode. GLM renders full (MCP on its own line) — the layout
132
150
  // is short enough now that compact mode isn't worth the lost detail.
133
151
  const glmSection = renderGlmSection(glm, glmOptsColor);
134
- const showGo = shouldShowGo("all", go);
152
+ const showGo = shouldShowSection(go, provider, "go");
135
153
  const goSection = showGo
136
154
  ? formatGoSection(go, goWindows ?? defaultGoWindows("all"), Date.now(), color)
137
155
  : null;
156
+ const ocSection = shouldShowSection(oc, provider, "oc") ? formatOcSection(oc, color) : null;
138
157
  const hasGlm = glmSection.body.length > 0;
139
158
  const hasGo = !!goSection && goSection.body.length > 0;
159
+ const hasOc = !!ocSection && ocSection.body.length > 0;
140
160
  // The separator line always follows the FIRST rendered section, so its row
141
- // is fixed whether or not a second section appears.
161
+ // is fixed regardless of how many sections follow.
142
162
  const sections = [];
143
163
  if (hasGlm)
144
164
  sections.push([` ${glmSection.header}`, ...glmSection.body]);
145
165
  if (hasGo)
146
166
  sections.push([` ${goSection.header}`, ...goSection.body]);
167
+ if (hasOc)
168
+ sections.push([` ${ocSection.header}`, ...ocSection.body]);
147
169
  if (sections.length === 0) {
148
170
  return [" ⚠ no usage data available"];
149
171
  }
150
172
  // No banner or top divider — the section headers themselves identify each
151
173
  // provider, and an extra banner line adds noise without information. The
152
- // refresh countdown sits on the separator row between sections (or after
153
- // the only section), right-aligned.
174
+ // refresh countdown sits on the separator row after the FIRST section
175
+ // (right-aligned); later separators stay blank so the countdown is not
176
+ // duplicated across rows.
154
177
  const body = [];
155
178
  sections.forEach((sec, i) => {
156
- if (i > 0)
179
+ if (i === 1)
157
180
  body.push(sep);
181
+ if (i > 1)
182
+ body.push("");
158
183
  body.push(...sec);
159
184
  });
160
185
  // If there's only one section, the separator still trails it so the refresh
@@ -1 +1 @@
1
- {"version":3,"file":"combined.js","sourceRoot":"","sources":["../../src/quota/combined.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"combined.js","sourceRoot":"","sources":["../../src/quota/combined.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * In-memory TTL cache for Ollama Cloud results.
3
+ *
4
+ * Mirrors {@link ../../cache.ts} but typed for {@link OcQueryResult}. Same
5
+ * 10s TTL — matches the quota cache and the CLI's minimum watch interval.
6
+ */
7
+ import type { OcQueryResult } from "./types.js";
8
+ /** Return the cached result if still fresh, else `null`. */
9
+ export declare function getCached(): OcQueryResult | null;
10
+ /** Store a fresh result, stamping it with the current time. */
11
+ export declare function setCached(result: OcQueryResult): void;
12
+ /** Clear the cache (test helper, and used by CLI watch mode per tick). */
13
+ export declare function clearCache(): void;
14
+ /** Override the clock (test-only). Pass `undefined` to restore real time. */
15
+ export declare function setClock(fn?: () => number): void;
16
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/quota/ollama-cloud/cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAUhD,4DAA4D;AAC5D,wBAAgB,SAAS,IAAI,aAAa,GAAG,IAAI,CAGhD;AAED,+DAA+D;AAC/D,wBAAgB,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAErD;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,IAAI,IAAI,CAEjC;AAED,6EAA6E;AAC7E,wBAAgB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAEhD"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * In-memory TTL cache for Ollama Cloud results.
3
+ *
4
+ * Mirrors {@link ../../cache.ts} but typed for {@link OcQueryResult}. Same
5
+ * 10s TTL — matches the quota cache and the CLI's minimum watch interval.
6
+ */
7
+ /** How long a cached result is served before re-querying. */
8
+ const TTL_MS = 10_000;
9
+ let slot = null;
10
+ /** Inject a fake clock — only tests should need this. */
11
+ let now = () => Date.now();
12
+ /** Return the cached result if still fresh, else `null`. */
13
+ export function getCached() {
14
+ if (slot && now() - slot.at < TTL_MS)
15
+ return slot.result;
16
+ return null;
17
+ }
18
+ /** Store a fresh result, stamping it with the current time. */
19
+ export function setCached(result) {
20
+ slot = { result, at: now() };
21
+ }
22
+ /** Clear the cache (test helper, and used by CLI watch mode per tick). */
23
+ export function clearCache() {
24
+ slot = null;
25
+ }
26
+ /** Override the clock (test-only). Pass `undefined` to restore real time. */
27
+ export function setClock(fn) {
28
+ now = fn ?? (() => Date.now());
29
+ }
30
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/quota/ollama-cloud/cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,6DAA6D;AAC7D,MAAM,MAAM,GAAG,MAAM,CAAC;AAEtB,IAAI,IAAI,GAAiD,IAAI,CAAC;AAE9D,yDAAyD;AACzD,IAAI,GAAG,GAAiB,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;AAEzC,4DAA4D;AAC5D,MAAM,UAAU,SAAS;IACvB,IAAI,IAAI,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM;QAAE,OAAO,IAAI,CAAC,MAAM,CAAC;IACzD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,SAAS,CAAC,MAAqB;IAC7C,IAAI,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;AAC/B,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,UAAU;IACxB,IAAI,GAAG,IAAI,CAAC;AACd,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,QAAQ,CAAC,EAAiB;IACxC,GAAG,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Ollama Cloud usage HTTP client.
3
+ *
4
+ * Talks to `https://ollama.com/api/usage` — an undocumented but live endpoint
5
+ * that returns `{limits:{session:{usage},weekly:{usage}}}` with usage as a
6
+ * 0..1 fraction. Auth is a plain Bearer API key (docs.ollama.com). No
7
+ * rate-limit headers exist on any Ollama endpoint, so the body is the only
8
+ * data source.
9
+ */
10
+ /** The undocumented usage endpoint (verified live 2026-09). */
11
+ export declare const USAGE_URL = "https://ollama.com/api/usage";
12
+ /**
13
+ * Fetch the usage JSON body.
14
+ *
15
+ * @throws on network errors or timeout. The caller maps these to
16
+ * `unavailable`. Auth failures are NOT thrown — the status is
17
+ * returned so the orchestrator can classify 401/403 as `auth_error`.
18
+ */
19
+ export declare function fetchOcUsage(apiKey: string, fetchImpl?: typeof globalThis.fetch): Promise<{
20
+ status: number;
21
+ text: string;
22
+ }>;
23
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/quota/ollama-cloud/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,+DAA+D;AAC/D,eAAO,MAAM,SAAS,iCAAiC,CAAC;AAExD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,OAAO,UAAU,CAAC,KAAwB,GACpD,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAW3C"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Ollama Cloud usage HTTP client.
3
+ *
4
+ * Talks to `https://ollama.com/api/usage` — an undocumented but live endpoint
5
+ * that returns `{limits:{session:{usage},weekly:{usage}}}` with usage as a
6
+ * 0..1 fraction. Auth is a plain Bearer API key (docs.ollama.com). No
7
+ * rate-limit headers exist on any Ollama endpoint, so the body is the only
8
+ * data source.
9
+ */
10
+ /** Request timeout (ms). Small JSON response; 10s is plenty. */
11
+ const TIMEOUT_MS = 10_000;
12
+ /** The undocumented usage endpoint (verified live 2026-09). */
13
+ export const USAGE_URL = "https://ollama.com/api/usage";
14
+ /**
15
+ * Fetch the usage JSON body.
16
+ *
17
+ * @throws on network errors or timeout. The caller maps these to
18
+ * `unavailable`. Auth failures are NOT thrown — the status is
19
+ * returned so the orchestrator can classify 401/403 as `auth_error`.
20
+ */
21
+ export async function fetchOcUsage(apiKey, fetchImpl = globalThis.fetch) {
22
+ const resp = await fetchImpl(USAGE_URL, {
23
+ method: "GET",
24
+ headers: {
25
+ Authorization: `Bearer ${apiKey}`,
26
+ Accept: "application/json",
27
+ },
28
+ signal: AbortSignal.timeout(TIMEOUT_MS),
29
+ });
30
+ const text = await resp.text();
31
+ return { status: resp.status, text };
32
+ }
33
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/quota/ollama-cloud/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,gEAAgE;AAChE,MAAM,UAAU,GAAG,MAAM,CAAC;AAE1B,+DAA+D;AAC/D,MAAM,CAAC,MAAM,SAAS,GAAG,8BAA8B,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAc,EACd,YAAqC,UAAU,CAAC,KAAK;IAErD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,SAAS,EAAE;QACtC,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,MAAM,EAAE;YACjC,MAAM,EAAE,kBAAkB;SAC3B;QACD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC;KACxC,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;AACvC,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Ollama Cloud credential discovery.
3
+ *
4
+ * The API key comes from two sources, with the **config file taking
5
+ * precedence** over the environment variable (the user-config convention —
6
+ * the file is the authoritative home for stable preferences):
7
+ * 1. `quota.ollamaApiKey` in `~/.config/zcode-acp/config.json`.
8
+ * 2. `OLLAMA_API_KEY` env var — the name Ollama's own docs use for cloud
9
+ * authentication (`Authorization: Bearer $OLLAMA_API_KEY`), kept as a
10
+ * full fallback for setups without a config file and one-off overrides.
11
+ *
12
+ * Unlike Opencode Go (which reuses `~/.pi/agent/` for historical reasons),
13
+ * the Ollama key is a plain static API key and belongs in our own config.
14
+ *
15
+ * A missing/blank key yields `not_configured` (the section is silently
16
+ * skipped in `all` mode).
17
+ */
18
+ /** Env var name — documented in the CLI help and README. */
19
+ export declare const ENV_API_KEY = "OLLAMA_API_KEY";
20
+ /**
21
+ * Resolve the API key: config file first, env var as fallback. Blank strings
22
+ * count as absent.
23
+ */
24
+ export declare function loadApiKey(): string | null;
25
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/quota/ollama-cloud/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,4DAA4D;AAC5D,eAAO,MAAM,WAAW,mBAAmB,CAAC;AAE5C;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,GAAG,IAAI,CAI1C"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Ollama Cloud credential discovery.
3
+ *
4
+ * The API key comes from two sources, with the **config file taking
5
+ * precedence** over the environment variable (the user-config convention —
6
+ * the file is the authoritative home for stable preferences):
7
+ * 1. `quota.ollamaApiKey` in `~/.config/zcode-acp/config.json`.
8
+ * 2. `OLLAMA_API_KEY` env var — the name Ollama's own docs use for cloud
9
+ * authentication (`Authorization: Bearer $OLLAMA_API_KEY`), kept as a
10
+ * full fallback for setups without a config file and one-off overrides.
11
+ *
12
+ * Unlike Opencode Go (which reuses `~/.pi/agent/` for historical reasons),
13
+ * the Ollama key is a plain static API key and belongs in our own config.
14
+ *
15
+ * A missing/blank key yields `not_configured` (the section is silently
16
+ * skipped in `all` mode).
17
+ */
18
+ import process from "node:process";
19
+ import { loadUserConfig } from "../../config/user-config.js";
20
+ /** Env var name — documented in the CLI help and README. */
21
+ export const ENV_API_KEY = "OLLAMA_API_KEY";
22
+ /**
23
+ * Resolve the API key: config file first, env var as fallback. Blank strings
24
+ * count as absent.
25
+ */
26
+ export function loadApiKey() {
27
+ const file = loadUserConfig().quota?.ollamaApiKey;
28
+ const key = (file ?? process.env[ENV_API_KEY] ?? "").trim();
29
+ return key.length > 0 ? key : null;
30
+ }
31
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/quota/ollama-cloud/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,4DAA4D;AAC5D,MAAM,CAAC,MAAM,WAAW,GAAG,gBAAgB,CAAC;AAE5C;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC;IAClD,MAAM,GAAG,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5D,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACrC,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Ollama Cloud usage formatting.
3
+ *
4
+ * Renders the plan's usage windows as progress bars in the same style as the
5
+ * GLM and Opencode Go sections, so all sections read as one card in the
6
+ * combined view. Which windows exist depends on the account's plan: legacy
7
+ * plans expose session (5h) + weekly; current credit plans expose monthly.
8
+ * The API exposes no reset timestamps, so — unlike the other providers — the
9
+ * lines carry no reset stamp, just the percent.
10
+ */
11
+ import type { OcQueryResult } from "./types.js";
12
+ /** A rendered section: a header line and zero or more body lines. */
13
+ export interface RenderedSection {
14
+ header: string;
15
+ body: string[];
16
+ }
17
+ /**
18
+ * Render the Ollama Cloud section.
19
+ *
20
+ * Used by the combined formatter. The header is always `Ollama Cloud`; body
21
+ * has one bar line per window. Non-success kinds return a header + a single
22
+ * explanatory line.
23
+ *
24
+ * When `color` is true the bar is a heat-colored 24-bit ANSI bar with the
25
+ * percent overlaid inside, mirroring the other providers' color layout.
26
+ */
27
+ export declare function formatOcSection(result: OcQueryResult, color?: boolean): RenderedSection;
28
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/quota/ollama-cloud/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAWhD,qEAAqE;AACrE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,UAAQ,GAAG,eAAe,CAwBrF"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Ollama Cloud usage formatting.
3
+ *
4
+ * Renders the plan's usage windows as progress bars in the same style as the
5
+ * GLM and Opencode Go sections, so all sections read as one card in the
6
+ * combined view. Which windows exist depends on the account's plan: legacy
7
+ * plans expose session (5h) + weekly; current credit plans expose monthly.
8
+ * The API exposes no reset timestamps, so — unlike the other providers — the
9
+ * lines carry no reset stamp, just the percent.
10
+ */
11
+ import { pickOverlay, renderColorBar } from "../color.js";
12
+ import { renderBar } from "../format.js";
13
+ import { roundTenth } from "../rounding.js";
14
+ /** Label + window metadata, in display order. Which rows appear depends on
15
+ * the account's plan: legacy plans carry session (5h) + weekly; current
16
+ * credit plans carry monthly only. */
17
+ const WINDOW_META = [
18
+ { key: "session", label: "5h" },
19
+ { key: "weekly", label: "Week" },
20
+ { key: "monthly", label: "Month" },
21
+ ];
22
+ /**
23
+ * Render the Ollama Cloud section.
24
+ *
25
+ * Used by the combined formatter. The header is always `Ollama Cloud`; body
26
+ * has one bar line per window. Non-success kinds return a header + a single
27
+ * explanatory line.
28
+ *
29
+ * When `color` is true the bar is a heat-colored 24-bit ANSI bar with the
30
+ * percent overlaid inside, mirroring the other providers' color layout.
31
+ */
32
+ export function formatOcSection(result, color = false) {
33
+ const header = "Ollama Cloud";
34
+ if (result.kind !== "success") {
35
+ const msg = result.kind === "not_configured"
36
+ ? "not configured (set OLLAMA_API_KEY)"
37
+ : result.kind === "auth_error"
38
+ ? "auth failed — check your Ollama API key"
39
+ : "unavailable";
40
+ return { header, body: [msg] };
41
+ }
42
+ const body = WINDOW_META.filter((m) => result[m.key] !== undefined).map((m) => {
43
+ const fraction = result[m.key];
44
+ const pct = roundTenth(fraction * 100);
45
+ if (color) {
46
+ const bar = renderColorBar(pct, { overlay: pickOverlay({ usedPercent: pct }) });
47
+ return `${m.label.padEnd(5)} ${bar}`;
48
+ }
49
+ return `${m.label.padEnd(5)} ${renderBar(pct)} ${String(pct).padStart(2)}%`;
50
+ });
51
+ return { header, body };
52
+ }
53
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/quota/ollama-cloud/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG5C;;uCAEuC;AACvC,MAAM,WAAW,GAAoE;IACnF,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE;IAC/B,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE;IAChC,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE;CACnC,CAAC;AAQF;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,MAAqB,EAAE,KAAK,GAAG,KAAK;IAClE,MAAM,MAAM,GAAG,cAAc,CAAC;IAE9B,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,GAAG,GACP,MAAM,CAAC,IAAI,KAAK,gBAAgB;YAC9B,CAAC,CAAC,qCAAqC;YACvC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY;gBAC5B,CAAC,CAAC,yCAAyC;gBAC3C,CAAC,CAAC,aAAa,CAAC;QACtB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IACjC,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC5E,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAE,CAAC;QAChC,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC;QACvC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAChF,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;QACvC,CAAC;QACD,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Ollama Cloud usage orchestration — the entry point used by the
3
+ * `zcode-acp quota` CLI.
4
+ *
5
+ * Flow: credential (env + config file) → cache check → fetch → status/auth
6
+ * check → parse → cache write. Any thrown error degrades to `unavailable`
7
+ * rather than propagating, so the CLI always produces output.
8
+ *
9
+ * A missing API key yields `not_configured`, which the combined view silently
10
+ * skips — so users who only care about GLM see no noise.
11
+ */
12
+ import type { OcQueryResult } from "./types.js";
13
+ /**
14
+ * Query Ollama Cloud usage and return a normalised {@link OcQueryResult}.
15
+ *
16
+ * - No key → `not_configured`.
17
+ * - Serves a cached result when fresh (< 10s).
18
+ * - HTTP 401/403 → `auth_error` (bad or revoked key).
19
+ * - Network/timeout/parse failure → `unavailable`.
20
+ */
21
+ export declare function queryOcUsage(): Promise<OcQueryResult>;
22
+ export { clearCache, clearCache as clearOcCache } from "./cache.js";
23
+ export { fetchOcUsage, USAGE_URL } from "./client.js";
24
+ export { formatOcSection } from "./format.js";
25
+ export { loadApiKey, ENV_API_KEY } from "./config.js";
26
+ export type { OcQueryResult, OcUsageResponse } from "./types.js";
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/quota/ollama-cloud/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAchD;;;;;;;GAOG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,aAAa,CAAC,CAoD3D;AAGD,OAAO,EAAE,UAAU,EAAE,UAAU,IAAI,YAAY,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Ollama Cloud usage orchestration — the entry point used by the
3
+ * `zcode-acp quota` CLI.
4
+ *
5
+ * Flow: credential (env + config file) → cache check → fetch → status/auth
6
+ * check → parse → cache write. Any thrown error degrades to `unavailable`
7
+ * rather than propagating, so the CLI always produces output.
8
+ *
9
+ * A missing API key yields `not_configured`, which the combined view silently
10
+ * skips — so users who only care about GLM see no noise.
11
+ */
12
+ import { log } from "../../utils.js";
13
+ import { getCached, setCached } from "./cache.js";
14
+ import { loadApiKey } from "./config.js";
15
+ import { fetchOcUsage } from "./client.js";
16
+ /**
17
+ * Validate a usage value from the response body: a finite number in [0, 1].
18
+ *
19
+ * Values > 1 are rejected on purpose: the endpoint is undocumented, and if
20
+ * Ollama ever switches to percent-valued numbers, silently treating 42 as a
21
+ * 4200% fraction would render a nonsensical full bar. The same guard is used
22
+ * by the pi-multi-account reference client.
23
+ */
24
+ function validFraction(v) {
25
+ return typeof v === "number" && Number.isFinite(v) && v >= 0 && v <= 1;
26
+ }
27
+ /**
28
+ * Query Ollama Cloud usage and return a normalised {@link OcQueryResult}.
29
+ *
30
+ * - No key → `not_configured`.
31
+ * - Serves a cached result when fresh (< 10s).
32
+ * - HTTP 401/403 → `auth_error` (bad or revoked key).
33
+ * - Network/timeout/parse failure → `unavailable`.
34
+ */
35
+ export async function queryOcUsage() {
36
+ const cached = getCached();
37
+ if (cached) {
38
+ log("ollama-cloud: serving cached result");
39
+ return cached;
40
+ }
41
+ const apiKey = loadApiKey();
42
+ if (!apiKey)
43
+ return { kind: "not_configured" };
44
+ let result;
45
+ try {
46
+ const resp = await fetchOcUsage(apiKey);
47
+ if (resp.status === 401 || resp.status === 403) {
48
+ result = { kind: "auth_error" };
49
+ }
50
+ else if (resp.status !== 200) {
51
+ // 429 = quota exhausted, 5xx = server-side; neither is a usage snapshot.
52
+ log(`ollama-cloud: unexpected status ${resp.status}`);
53
+ result = { kind: "unavailable" };
54
+ }
55
+ else {
56
+ const parsed = JSON.parse(resp.text);
57
+ const limits = parsed.limits ?? {};
58
+ const window = (key) => validFraction(limits[key]?.usage) ? limits[key].usage : undefined;
59
+ const session = window("session");
60
+ const weekly = window("weekly");
61
+ const monthly = window("monthly");
62
+ if (session !== undefined || weekly !== undefined || monthly !== undefined) {
63
+ // At least one recognised window — legacy plans carry session+weekly,
64
+ // current credit plans carry monthly only.
65
+ result = {
66
+ kind: "success",
67
+ ...(session !== undefined && { session }),
68
+ ...(weekly !== undefined && { weekly }),
69
+ ...(monthly !== undefined && { monthly }),
70
+ fetchedAt: Date.now(),
71
+ };
72
+ }
73
+ else {
74
+ log("ollama-cloud: response shape not recognised (endpoint may have changed)");
75
+ result = { kind: "unavailable" };
76
+ }
77
+ }
78
+ }
79
+ catch (e) {
80
+ log(`ollama-cloud: fetch failed (${e instanceof Error ? e.message : String(e)})`);
81
+ result = { kind: "unavailable" };
82
+ }
83
+ setCached(result);
84
+ return result;
85
+ }
86
+ // Re-exports for consumers (CLI + tests).
87
+ export { clearCache, clearCache as clearOcCache } from "./cache.js";
88
+ export { fetchOcUsage, USAGE_URL } from "./client.js";
89
+ export { formatOcSection } from "./format.js";
90
+ export { loadApiKey, ENV_API_KEY } from "./config.js";
91
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/quota/ollama-cloud/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Type definitions for the Ollama Cloud subscription usage feature.
3
+ *
4
+ * `zcode-acp quota` queries the undocumented-but-live
5
+ * `GET https://ollama.com/api/usage` endpoint with the user's API key. The
6
+ * response carries two usage fractions (session = 5h rolling window, weekly =
7
+ * 7d window) in [0, 1] and NO reset timestamps — the server does not expose
8
+ * them, so the card shows bars + percents only (no countdown stamps).
9
+ *
10
+ * Shape verified against live probes + the pi-multi-account reference client
11
+ * (2026-09); see `.zcode/scratch/research-ollama-cloud-usage.md`. Undocumented
12
+ * — treat parse failures as `unavailable`, never as a crash.
13
+ */
14
+ /**
15
+ * Result of querying Ollama Cloud usage — a 4-state sum type mirroring
16
+ * {@link ../opencode-go/types.js GoQueryResult}.
17
+ *
18
+ * `not_configured` is distinct from `unavailable`: the CLI uses it to silently
19
+ * skip the Ollama section in default (all-provider) mode when the user has not
20
+ * supplied an API key, rather than printing an error.
21
+ */
22
+ export type OcQueryResult = {
23
+ kind: "success";
24
+ /** Present windows only — the account's plan decides which exist.
25
+ * Fractions in [0, 1]. Legacy plans expose session+weekly; current
26
+ * credit plans expose monthly (with per-model request counts). */
27
+ session?: number;
28
+ weekly?: number;
29
+ monthly?: number;
30
+ /** Epoch ms of the fetch (kept for symmetry with the other providers). */
31
+ fetchedAt: number;
32
+ } | {
33
+ kind: "not_configured";
34
+ } | {
35
+ kind: "auth_error";
36
+ } | {
37
+ kind: "unavailable";
38
+ };
39
+ /** Raw /api/usage fetch result — status + body text. */
40
+ export interface OcUsageResponse {
41
+ status: number;
42
+ text: string;
43
+ }
44
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/quota/ollama-cloud/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GACrB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB;;uEAEmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;CACnB,GACD;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAE5B,wDAAwD;AACxD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd"}