scoutline 0.1.0 → 0.2.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 (206) hide show
  1. package/README.md +170 -5
  2. package/bin/scoutline.js +36 -15
  3. package/dist/capabilities/diagnostics.d.ts +97 -0
  4. package/dist/capabilities/diagnostics.d.ts.map +1 -0
  5. package/dist/capabilities/diagnostics.js +88 -0
  6. package/dist/capabilities/diagnostics.js.map +1 -0
  7. package/dist/capabilities/quota.d.ts +99 -0
  8. package/dist/capabilities/quota.d.ts.map +1 -0
  9. package/dist/capabilities/quota.js +129 -0
  10. package/dist/capabilities/quota.js.map +1 -0
  11. package/dist/capabilities/search.d.ts +110 -0
  12. package/dist/capabilities/search.d.ts.map +1 -0
  13. package/dist/capabilities/search.js +21 -0
  14. package/dist/capabilities/search.js.map +1 -0
  15. package/dist/capabilities/vision.d.ts +156 -0
  16. package/dist/capabilities/vision.d.ts.map +1 -0
  17. package/dist/capabilities/vision.js +111 -0
  18. package/dist/capabilities/vision.js.map +1 -0
  19. package/dist/command-invocation.d.ts +58 -0
  20. package/dist/command-invocation.d.ts.map +1 -0
  21. package/dist/command-invocation.js +95 -0
  22. package/dist/command-invocation.js.map +1 -0
  23. package/dist/commands/code.d.ts +11 -4
  24. package/dist/commands/code.d.ts.map +1 -1
  25. package/dist/commands/code.js +16 -42
  26. package/dist/commands/code.js.map +1 -1
  27. package/dist/commands/doctor.d.ts +58 -3
  28. package/dist/commands/doctor.d.ts.map +1 -1
  29. package/dist/commands/doctor.js +154 -52
  30. package/dist/commands/doctor.js.map +1 -1
  31. package/dist/commands/quota.d.ts +45 -3
  32. package/dist/commands/quota.d.ts.map +1 -1
  33. package/dist/commands/quota.js +116 -60
  34. package/dist/commands/quota.js.map +1 -1
  35. package/dist/commands/read.d.ts +15 -1
  36. package/dist/commands/read.d.ts.map +1 -1
  37. package/dist/commands/read.js +53 -54
  38. package/dist/commands/read.js.map +1 -1
  39. package/dist/commands/repo.d.ts +8 -3
  40. package/dist/commands/repo.d.ts.map +1 -1
  41. package/dist/commands/repo.js +40 -78
  42. package/dist/commands/repo.js.map +1 -1
  43. package/dist/commands/search.d.ts +27 -2
  44. package/dist/commands/search.d.ts.map +1 -1
  45. package/dist/commands/search.js +95 -103
  46. package/dist/commands/search.js.map +1 -1
  47. package/dist/commands/tools.d.ts +9 -3
  48. package/dist/commands/tools.d.ts.map +1 -1
  49. package/dist/commands/tools.js +29 -59
  50. package/dist/commands/tools.js.map +1 -1
  51. package/dist/commands/vision.d.ts +35 -9
  52. package/dist/commands/vision.d.ts.map +1 -1
  53. package/dist/commands/vision.js +184 -131
  54. package/dist/commands/vision.js.map +1 -1
  55. package/dist/index.d.ts +42 -1
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +389 -207
  58. package/dist/index.js.map +1 -1
  59. package/dist/lib/cache.d.ts +61 -0
  60. package/dist/lib/cache.d.ts.map +1 -1
  61. package/dist/lib/cache.js +74 -11
  62. package/dist/lib/cache.js.map +1 -1
  63. package/dist/lib/code-mode.d.ts +13 -0
  64. package/dist/lib/code-mode.d.ts.map +1 -1
  65. package/dist/lib/code-mode.js +26 -6
  66. package/dist/lib/code-mode.js.map +1 -1
  67. package/dist/lib/config.d.ts.map +1 -1
  68. package/dist/lib/config.js +15 -18
  69. package/dist/lib/config.js.map +1 -1
  70. package/dist/lib/errors.d.ts +65 -10
  71. package/dist/lib/errors.d.ts.map +1 -1
  72. package/dist/lib/errors.js +135 -19
  73. package/dist/lib/errors.js.map +1 -1
  74. package/dist/lib/execution.d.ts +76 -0
  75. package/dist/lib/execution.d.ts.map +1 -0
  76. package/dist/lib/execution.js +177 -0
  77. package/dist/lib/execution.js.map +1 -0
  78. package/dist/lib/index.d.ts +10 -2
  79. package/dist/lib/index.d.ts.map +1 -1
  80. package/dist/lib/index.js +10 -2
  81. package/dist/lib/index.js.map +1 -1
  82. package/dist/lib/mcp-client.d.ts +46 -11
  83. package/dist/lib/mcp-client.d.ts.map +1 -1
  84. package/dist/lib/mcp-client.js +92 -27
  85. package/dist/lib/mcp-client.js.map +1 -1
  86. package/dist/lib/mcp-config.d.ts +17 -0
  87. package/dist/lib/mcp-config.d.ts.map +1 -1
  88. package/dist/lib/mcp-config.js +29 -0
  89. package/dist/lib/mcp-config.js.map +1 -1
  90. package/dist/lib/monitor-client.d.ts +17 -3
  91. package/dist/lib/monitor-client.d.ts.map +1 -1
  92. package/dist/lib/monitor-client.js +23 -69
  93. package/dist/lib/monitor-client.js.map +1 -1
  94. package/dist/lib/output.d.ts +53 -7
  95. package/dist/lib/output.d.ts.map +1 -1
  96. package/dist/lib/output.js +126 -39
  97. package/dist/lib/output.js.map +1 -1
  98. package/dist/lib/redact.d.ts +62 -3
  99. package/dist/lib/redact.d.ts.map +1 -1
  100. package/dist/lib/redact.js +165 -31
  101. package/dist/lib/redact.js.map +1 -1
  102. package/dist/lib/tty.d.ts +7 -20
  103. package/dist/lib/tty.d.ts.map +1 -1
  104. package/dist/lib/tty.js +51 -30
  105. package/dist/lib/tty.js.map +1 -1
  106. package/dist/node-command-invocation-adapter.d.ts +28 -0
  107. package/dist/node-command-invocation-adapter.d.ts.map +1 -0
  108. package/dist/node-command-invocation-adapter.js +88 -0
  109. package/dist/node-command-invocation-adapter.js.map +1 -0
  110. package/dist/providers/minimax/adapter.d.ts +47 -0
  111. package/dist/providers/minimax/adapter.d.ts.map +1 -0
  112. package/dist/providers/minimax/adapter.js +443 -0
  113. package/dist/providers/minimax/adapter.js.map +1 -0
  114. package/dist/providers/minimax/config.d.ts +32 -0
  115. package/dist/providers/minimax/config.d.ts.map +1 -0
  116. package/dist/providers/minimax/config.js +84 -0
  117. package/dist/providers/minimax/config.js.map +1 -0
  118. package/dist/providers/minimax/media.d.ts +34 -0
  119. package/dist/providers/minimax/media.d.ts.map +1 -0
  120. package/dist/providers/minimax/media.js +92 -0
  121. package/dist/providers/minimax/media.js.map +1 -0
  122. package/dist/providers/minimax/quota-client.d.ts +37 -0
  123. package/dist/providers/minimax/quota-client.d.ts.map +1 -0
  124. package/dist/providers/minimax/quota-client.js +78 -0
  125. package/dist/providers/minimax/quota-client.js.map +1 -0
  126. package/dist/providers/minimax/quota.d.ts +48 -0
  127. package/dist/providers/minimax/quota.d.ts.map +1 -0
  128. package/dist/providers/minimax/quota.js +120 -0
  129. package/dist/providers/minimax/quota.js.map +1 -0
  130. package/dist/providers/minimax/sdk-client.d.ts +29 -0
  131. package/dist/providers/minimax/sdk-client.d.ts.map +1 -0
  132. package/dist/providers/minimax/sdk-client.js +50 -0
  133. package/dist/providers/minimax/sdk-client.js.map +1 -0
  134. package/dist/providers/minimax/vision-attestations.d.ts +29 -0
  135. package/dist/providers/minimax/vision-attestations.d.ts.map +1 -0
  136. package/dist/providers/minimax/vision-attestations.js +54 -0
  137. package/dist/providers/minimax/vision-attestations.js.map +1 -0
  138. package/dist/providers/minimax/vision-conformance.d.ts +184 -0
  139. package/dist/providers/minimax/vision-conformance.d.ts.map +1 -0
  140. package/dist/providers/minimax/vision-conformance.js +369 -0
  141. package/dist/providers/minimax/vision-conformance.js.map +1 -0
  142. package/dist/providers/minimax/vision-mappings/chart.d.ts +35 -0
  143. package/dist/providers/minimax/vision-mappings/chart.d.ts.map +1 -0
  144. package/dist/providers/minimax/vision-mappings/chart.js +55 -0
  145. package/dist/providers/minimax/vision-mappings/chart.js.map +1 -0
  146. package/dist/providers/minimax/vision-mappings/common.d.ts +60 -0
  147. package/dist/providers/minimax/vision-mappings/common.d.ts.map +1 -0
  148. package/dist/providers/minimax/vision-mappings/common.js +75 -0
  149. package/dist/providers/minimax/vision-mappings/common.js.map +1 -0
  150. package/dist/providers/minimax/vision-mappings/diagnose-error.d.ts +35 -0
  151. package/dist/providers/minimax/vision-mappings/diagnose-error.d.ts.map +1 -0
  152. package/dist/providers/minimax/vision-mappings/diagnose-error.js +55 -0
  153. package/dist/providers/minimax/vision-mappings/diagnose-error.js.map +1 -0
  154. package/dist/providers/minimax/vision-mappings/diagram.d.ts +35 -0
  155. package/dist/providers/minimax/vision-mappings/diagram.d.ts.map +1 -0
  156. package/dist/providers/minimax/vision-mappings/diagram.js +55 -0
  157. package/dist/providers/minimax/vision-mappings/diagram.js.map +1 -0
  158. package/dist/providers/minimax/vision-mappings/extract-text.d.ts +35 -0
  159. package/dist/providers/minimax/vision-mappings/extract-text.d.ts.map +1 -0
  160. package/dist/providers/minimax/vision-mappings/extract-text.js +55 -0
  161. package/dist/providers/minimax/vision-mappings/extract-text.js.map +1 -0
  162. package/dist/providers/minimax/vision-mappings/ui-artifact.d.ts +35 -0
  163. package/dist/providers/minimax/vision-mappings/ui-artifact.d.ts.map +1 -0
  164. package/dist/providers/minimax/vision-mappings/ui-artifact.js +69 -0
  165. package/dist/providers/minimax/vision-mappings/ui-artifact.js.map +1 -0
  166. package/dist/providers/minimax/vision-mappings.generated.d.ts +29 -0
  167. package/dist/providers/minimax/vision-mappings.generated.d.ts.map +1 -0
  168. package/dist/providers/minimax/vision-mappings.generated.js +29 -0
  169. package/dist/providers/minimax/vision-mappings.generated.js.map +1 -0
  170. package/dist/providers/minimax/vision-revisions.d.ts +22 -0
  171. package/dist/providers/minimax/vision-revisions.d.ts.map +1 -0
  172. package/dist/providers/minimax/vision-revisions.js +27 -0
  173. package/dist/providers/minimax/vision-revisions.js.map +1 -0
  174. package/dist/providers/registry.d.ts +36 -0
  175. package/dist/providers/registry.d.ts.map +1 -0
  176. package/dist/providers/registry.js +45 -0
  177. package/dist/providers/registry.js.map +1 -0
  178. package/dist/providers/selection.d.ts +44 -0
  179. package/dist/providers/selection.d.ts.map +1 -0
  180. package/dist/providers/selection.js +85 -0
  181. package/dist/providers/selection.js.map +1 -0
  182. package/dist/providers/types.d.ts +247 -0
  183. package/dist/providers/types.d.ts.map +1 -0
  184. package/dist/providers/types.js +127 -0
  185. package/dist/providers/types.js.map +1 -0
  186. package/dist/providers/zai/adapter.d.ts +35 -0
  187. package/dist/providers/zai/adapter.d.ts.map +1 -0
  188. package/dist/providers/zai/adapter.js +619 -0
  189. package/dist/providers/zai/adapter.js.map +1 -0
  190. package/dist/providers/zai/credentials.d.ts +38 -0
  191. package/dist/providers/zai/credentials.d.ts.map +1 -0
  192. package/dist/providers/zai/credentials.js +60 -0
  193. package/dist/providers/zai/credentials.js.map +1 -0
  194. package/dist/providers/zai/media.d.ts +38 -0
  195. package/dist/providers/zai/media.d.ts.map +1 -0
  196. package/dist/providers/zai/media.js +107 -0
  197. package/dist/providers/zai/media.js.map +1 -0
  198. package/dist/providers/zai/monitor-client.d.ts +53 -0
  199. package/dist/providers/zai/monitor-client.d.ts.map +1 -0
  200. package/dist/providers/zai/monitor-client.js +117 -0
  201. package/dist/providers/zai/monitor-client.js.map +1 -0
  202. package/dist/providers/zai/quota.d.ts +47 -0
  203. package/dist/providers/zai/quota.d.ts.map +1 -0
  204. package/dist/providers/zai/quota.js +127 -0
  205. package/dist/providers/zai/quota.js.map +1 -0
  206. package/package.json +10 -5
@@ -1,77 +1,133 @@
1
1
  /**
2
- * Quota command — authoritative Z.AI Coding Plan usage from the monitor API.
2
+ * Quota command — Provider-neutral quota dashboard (P4-03, ADR-0001).
3
+ *
4
+ * The command is presentation-only: it receives a dashboard builder
5
+ * through injected dependencies and wraps the resulting
6
+ * {@link QuotaDashboard} as base data with a TTY presentation override.
7
+ * Provider resolution, capability invocation, settled collection, and
8
+ * failure redaction live in {@link buildQuotaDashboard} so the command
9
+ * never imports a Provider monitor client or maps a Provider response.
10
+ *
11
+ * Default mode (effective Provider) propagates quota failures through
12
+ * the ordinary error path (thrown → invokeCommand). All-provider mode
13
+ * (`--all-providers`) uses settled collection, emits successful and
14
+ * failed entries, and yields exit 1 when any configured Provider fails.
3
15
  */
4
- import { getQuotaLimit, getTimeLimit, getTokensLimit, formatResetTime, } from "../lib/monitor-client.js";
5
- import { outputSuccess, getOutputMode } from "../lib/output.js";
6
- import { formatErrorOutput } from "../lib/errors.js";
7
- import { formatQuotaPretty } from "../lib/tty.js";
8
- export async function quota(_options = {}) {
9
- try {
10
- const data = await getQuotaLimit();
11
- const timeLimit = getTimeLimit(data);
12
- const tokensLimit = getTokensLimit(data);
13
- const formatted = {
14
- plan: data.level,
15
- timeWindow: timeLimit
16
- ? {
17
- used: timeLimit.currentValue,
18
- limit: timeLimit.usage,
19
- remaining: timeLimit.remaining,
20
- percentage: timeLimit.percentage,
21
- windowHours: timeLimit.unit,
22
- resetsAt: timeLimit.nextResetTime
23
- ? new Date(timeLimit.nextResetTime).toISOString()
24
- : null,
25
- resetsIn: timeLimit.nextResetTime ? formatResetTime(timeLimit.nextResetTime) : null,
26
- byTool: timeLimit.usageDetails,
27
- }
28
- : null,
29
- tokens: tokensLimit
30
- ? {
31
- percentage: tokensLimit.percentage,
32
- resetsAt: tokensLimit.nextResetTime
33
- ? new Date(tokensLimit.nextResetTime).toISOString()
34
- : null,
35
- resetsIn: tokensLimit.nextResetTime ? formatResetTime(tokensLimit.nextResetTime) : null,
36
- }
37
- : null,
38
- };
39
- const mode = getOutputMode();
40
- if (mode === "tty") {
41
- outputSuccess(formatQuotaPretty(formatted));
42
- }
43
- else {
44
- outputSuccess(formatted);
45
- }
16
+ import { quotaFailureFromError } from "../capabilities/quota.js";
17
+ import { executeProviderOperation } from "../lib/execution.js";
18
+ import { ConfigurationError, UnsupportedCapabilityError } from "../lib/errors.js";
19
+ import { getProviderDescriptor } from "../providers/selection.js";
20
+ import { redactSecrets, configuredSecrets } from "../lib/redact.js";
21
+ import { formatQuotaDashboard } from "../lib/tty.js";
22
+ /**
23
+ * Invoke one Provider's quota Capability through shared execution. The
24
+ * Adapter transport performs a single attempt; the retry policy lives
25
+ * in `executeProviderOperation("quota", ...)`. Quota never uses the
26
+ * response cache.
27
+ */
28
+ async function invokeProviderQuota(descriptor, env, sleep, random) {
29
+ const adapter = descriptor.create({ env });
30
+ const capability = adapter.quota;
31
+ if (!capability) {
32
+ throw new UnsupportedCapabilityError(descriptor.id, "quota");
46
33
  }
47
- catch (error) {
48
- console.error(formatErrorOutput(error));
49
- process.exit(1);
34
+ return executeProviderOperation("quota", () => capability.invoke(), { sleep, random });
35
+ }
36
+ /**
37
+ * Default-mode dashboard. Resolves the effective Provider, requires it
38
+ * to be configured (ConfigurationError, exit 3, before transport), then
39
+ * invokes its quota Capability. Failures propagate through the ordinary
40
+ * error path.
41
+ */
42
+ async function buildDefaultDashboard(deps) {
43
+ const descriptor = getProviderDescriptor(deps.effectiveProvider, deps.descriptors);
44
+ if (!descriptor.isConfigured(deps.env)) {
45
+ throw new ConfigurationError(`Provider "${deps.effectiveProvider}" is not configured. Set Z_AI_API_KEY or MINIMAX_API_KEY.`);
46
+ }
47
+ const success = await invokeProviderQuota(descriptor, deps.env, deps.sleep, deps.random);
48
+ return {
49
+ schemaVersion: 1,
50
+ effectiveProvider: deps.effectiveProvider,
51
+ providers: [success],
52
+ };
53
+ }
54
+ /**
55
+ * All-provider dashboard. Queries every configured Provider in static
56
+ * registry order using settled collection. No unconfigured Provider is
57
+ * invoked; the effective Provider is dashboard metadata only. Failures
58
+ * are normalized and recursively redacted before joining the dashboard.
59
+ * No configured Provider is a configuration failure, not an empty
60
+ * success.
61
+ */
62
+ async function buildAllProvidersDashboard(deps) {
63
+ const configured = deps.descriptors.filter((d) => d.isConfigured(deps.env));
64
+ if (configured.length === 0) {
65
+ throw new ConfigurationError("No provider is configured. Set Z_AI_API_KEY and/or MINIMAX_API_KEY.");
50
66
  }
67
+ const secrets = configuredSecrets(deps.env);
68
+ const settled = await Promise.allSettled(configured.map((d) => invokeProviderQuota(d, deps.env, deps.sleep, deps.random)));
69
+ const providers = configured.map((d, i) => {
70
+ const result = settled[i];
71
+ if (result.status === "fulfilled") {
72
+ return result.value;
73
+ }
74
+ return redactSecrets(quotaFailureFromError(d.id, result.reason), secrets);
75
+ });
76
+ return {
77
+ schemaVersion: 1,
78
+ effectiveProvider: deps.effectiveProvider,
79
+ providers,
80
+ };
81
+ }
82
+ /**
83
+ * Build a {@link QuotaDashboard} for the selected mode. The effective
84
+ * Provider is resolved by the dispatcher (`index.ts`) and passed in as
85
+ * metadata; config validation happens here.
86
+ */
87
+ export async function buildQuotaDashboard(deps) {
88
+ return deps.allProviders ? buildAllProvidersDashboard(deps) : buildDefaultDashboard(deps);
89
+ }
90
+ /**
91
+ * Run the quota command. Returns the dashboard as base data with a TTY
92
+ * presentation override. Exit code is 1 when any dashboard entry failed
93
+ * (all-provider mode); otherwise 0.
94
+ */
95
+ export async function quota(deps) {
96
+ const dashboard = await deps.buildDashboard();
97
+ const hasFailure = dashboard.providers.some((p) => p.status === "error");
98
+ return {
99
+ kind: "data",
100
+ data: dashboard,
101
+ presentations: { tty: formatQuotaDashboard(dashboard) },
102
+ exitCode: hasFailure ? 1 : 0,
103
+ };
51
104
  }
52
105
  export const QUOTA_HELP = `
53
- Quota Command - Authoritative Z.AI Coding Plan usage from the monitor API
106
+ Quota Command - Provider-normalized plan usage dashboard
54
107
 
55
108
  Usage: scoutline quota [options]
56
109
 
57
- Hits GET https://api.z.ai/api/monitor/usage/quota/limit directly (NOT the MCP
58
- endpoint) to return real-time plan usage, including:
59
- - Plan tier (pro / lite / max)
60
- - 5-hour rolling window: calls used / limit / remaining / reset time
61
- - Per-tool breakdown (search-prime, web-reader, zread)
62
- - Token budget percentage + reset time
110
+ Reports plan usage for the effective Provider (or every configured
111
+ Provider with --all-providers) as a normalized, schema-version-1
112
+ dashboard (ADR-0001). Each entry carries named quota categories with
113
+ current and optional weekly windows, counts, remaining percentage, and
114
+ ISO reset time. No Provider-specific field crosses the Interface.
63
115
 
64
116
  Options:
65
- (none yet future versions may add --history for 24h/7d/30d windows)
117
+ --all-providers Query every configured Provider in registry order.
118
+ Successful and failed entries both appear; the
119
+ command exits 1 when any Provider fails.
66
120
 
67
121
  Examples:
68
- scoutline quota
69
- scoutline quota -O pretty # human-readable with progress bars
70
- scoutline quota -O json # envelope-wrapped for scripts
122
+ scoutline quota # effective Provider usage
123
+ scoutline quota --all-providers # every configured Provider
124
+ scoutline quota -O pretty # human-readable with progress bars
125
+ scoutline quota -O json # envelope-wrapped for scripts
71
126
 
72
127
  Notes:
73
- - This call hits a different endpoint than search/read/repo and is not
74
- cached by the local response cache.
75
- - Auth: tries raw API key first, falls back to Bearer prefix on 401.
128
+ - Quota is never cached by the local response cache.
129
+ - Default-mode failures propagate as ordinary errors (exit 3 for an
130
+ unconfigured effective Provider).
131
+ - All-provider mode never invokes an unconfigured Provider.
76
132
  `.trim();
77
133
  //# sourceMappingURL=quota.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"quota.js","sourceRoot":"","sources":["../../src/commands/quota.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,aAAa,EACb,YAAY,EACZ,cAAc,EACd,eAAe,GAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAMlD,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,QAAQ,GAAiB,EAAE;IACrD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,aAAa,EAAE,CAAC;QACnC,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QAEzC,MAAM,SAAS,GAAG;YAChB,IAAI,EAAE,IAAI,CAAC,KAAK;YAChB,UAAU,EAAE,SAAS;gBACnB,CAAC,CAAC;oBACE,IAAI,EAAE,SAAS,CAAC,YAAY;oBAC5B,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,SAAS,EAAE,SAAS,CAAC,SAAS;oBAC9B,UAAU,EAAE,SAAS,CAAC,UAAU;oBAChC,WAAW,EAAE,SAAS,CAAC,IAAI;oBAC3B,QAAQ,EAAE,SAAS,CAAC,aAAa;wBAC/B,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE;wBACjD,CAAC,CAAC,IAAI;oBACR,QAAQ,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI;oBACnF,MAAM,EAAE,SAAS,CAAC,YAAY;iBAC/B;gBACH,CAAC,CAAC,IAAI;YACR,MAAM,EAAE,WAAW;gBACjB,CAAC,CAAC;oBACE,UAAU,EAAE,WAAW,CAAC,UAAU;oBAClC,QAAQ,EAAE,WAAW,CAAC,aAAa;wBACjC,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE;wBACnD,CAAC,CAAC,IAAI;oBACR,QAAQ,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI;iBACxF;gBACH,CAAC,CAAC,IAAI;SACT,CAAC;QAEF,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;QAC7B,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACnB,aAAa,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;CAwBzB,CAAC,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"quota.js","sourceRoot":"","sources":["../../src/commands/quota.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,21 @@
1
1
  /**
2
2
  * Web reader command using Z.AI WebReader MCP
3
+ *
4
+ * P1-05: returns a CommandResult instead of writing directly to
5
+ * stdout/stderr. Notices (URL rewrite hint, truncation warning, extract
6
+ * count) flow through the invocation context; errors are thrown and
7
+ * converted by invokeCommand.
8
+ *
9
+ * Behaviour preserved from Phase 0:
10
+ * - By default the data is the page content (string).
11
+ * - With --full-envelope the data is the structured reader envelope.
12
+ * - With -O json/pretty (without --full-envelope) the data is also the
13
+ * envelope so consumers always get the structured object in JSON
14
+ * modes. The `outputMode` parameter is passed by the dispatcher.
3
15
  */
4
16
  import { type ExtractMode } from "../lib/extract.js";
17
+ import type { CommandContext, CommandResult } from "../command-invocation.js";
18
+ import type { OutputMode } from "../lib/output.js";
5
19
  export interface ReadOptions {
6
20
  format?: "markdown" | "text";
7
21
  noImages?: boolean;
@@ -15,6 +29,6 @@ export interface ReadOptions {
15
29
  fullEnvelope?: boolean;
16
30
  extract?: ExtractMode;
17
31
  }
18
- export declare function read(url: string, options?: ReadOptions): Promise<void>;
32
+ export declare function read(url: string, options?: ReadOptions, outputMode?: OutputMode, context?: CommandContext): Promise<CommandResult>;
19
33
  export declare const READ_HELP: string;
20
34
  //# sourceMappingURL=read.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/commands/read.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAA0B,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE7E,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAwDD,wBAAsB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiFhF;AAGD,eAAO,MAAM,SAAS,QAuCd,CAAC"}
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/commands/read.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAA0B,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAwDD,wBAAsB,IAAI,CACxB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,WAAgB,EACzB,UAAU,CAAC,EAAE,UAAU,EACvB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,aAAa,CAAC,CAkExB;AAGD,eAAO,MAAM,SAAS,QAuCd,CAAC"}
@@ -1,10 +1,20 @@
1
1
  /**
2
2
  * Web reader command using Z.AI WebReader MCP
3
+ *
4
+ * P1-05: returns a CommandResult instead of writing directly to
5
+ * stdout/stderr. Notices (URL rewrite hint, truncation warning, extract
6
+ * count) flow through the invocation context; errors are thrown and
7
+ * converted by invokeCommand.
8
+ *
9
+ * Behaviour preserved from Phase 0:
10
+ * - By default the data is the page content (string).
11
+ * - With --full-envelope the data is the structured reader envelope.
12
+ * - With -O json/pretty (without --full-envelope) the data is also the
13
+ * envelope so consumers always get the structured object in JSON
14
+ * modes. The `outputMode` parameter is passed by the dispatcher.
3
15
  */
4
16
  import { ZaiMcpClient } from "../lib/mcp-client.js";
5
- import { outputSuccess, getOutputMode } from "../lib/output.js";
6
- import { formatErrorOutput, ValidationError } from "../lib/errors.js";
7
- import { silenceConsole, restoreConsole } from "../lib/silence.js";
17
+ import { ValidationError } from "../lib/errors.js";
8
18
  import { extract, isExtractMode } from "../lib/extract.js";
9
19
  /**
10
20
  * Rewrite rendered GitHub gist/file URLs to their raw form so Z.AI's reader
@@ -57,69 +67,58 @@ function truncate(content, max) {
57
67
  }
58
68
  return { text: content.slice(0, max - 1).trimEnd() + "…", originalLen, truncated: true };
59
69
  }
60
- export async function read(url, options = {}) {
61
- // Validate URL first (before silencing)
70
+ export async function read(url, options = {}, outputMode, context) {
71
+ // Validate URL first (before any client work).
62
72
  if (!url.startsWith("http://") && !url.startsWith("https://")) {
63
- console.error(formatErrorOutput(new ValidationError("URL must start with http:// or https://")));
64
- process.exit(1);
73
+ throw new ValidationError("URL must start with http:// or https://");
65
74
  }
66
75
  if (options.extract && !isExtractMode(options.extract)) {
67
- console.error(formatErrorOutput(new ValidationError(`Invalid --extract mode: ${options.extract}. Use one of: code, links, tables, headings`)));
68
- process.exit(1);
76
+ throw new ValidationError(`Invalid --extract mode: ${options.extract}. Use one of: code, links, tables, headings`);
69
77
  }
70
78
  const finalUrl = maybeRewriteToRaw(url);
71
- if (finalUrl !== url) {
72
- process.stderr.write(`ℹ️ rewrote gist URL to raw form: ${finalUrl}\n`);
79
+ if (finalUrl !== url && context) {
80
+ context.notice(`ℹ️ rewrote gist URL to raw form: ${finalUrl}`);
73
81
  }
74
- silenceConsole();
75
82
  const client = new ZaiMcpClient({ enableVision: false, noCache: options.noCache });
76
83
  try {
77
- try {
78
- const response = await client.webRead({
79
- url: finalUrl,
80
- format: options.format || "markdown",
81
- retainImages: !options.noImages,
82
- withLinksSummary: options.withLinks,
83
- timeout: options.timeout,
84
- noCache: options.noCache,
85
- noGfm: options.noGfm,
86
- keepImgDataUrl: options.keepImgDataUrl,
87
- withImagesSummary: options.withImagesSummary,
88
- });
89
- const { content: rawContent } = extractContent(response);
90
- // --extract short-circuits: returns the extracted slice as a JSON array,
91
- // bypassing truncation and envelope logic.
92
- if (options.extract) {
93
- const extracted = extract(rawContent, options.extract);
94
- process.stderr.write(`ℹ️ extracted ${extracted.length} ${options.extract}\n`);
95
- outputSuccess(extracted);
96
- return;
97
- }
98
- const { text, originalLen, truncated } = truncate(rawContent, options.maxChars);
99
- if (truncated) {
100
- process.stderr.write(`⚠️ content truncated from ${originalLen.toLocaleString()} to ${text.length.toLocaleString()} chars; use a higher --max-chars or omit it for full content\n`);
101
- }
102
- // Default: content-only (drops title/metadata/external envelope).
103
- // --full-envelope or --output-format json/pretty keeps the structured object.
104
- const wantEnvelope = options.fullEnvelope || getOutputMode() === "json" || getOutputMode() === "pretty";
105
- if (wantEnvelope) {
106
- const envelope = response && typeof response === "object"
107
- ? { ...response, content: text }
108
- : { content: text };
109
- outputSuccess(envelope);
110
- }
111
- else {
112
- outputSuccess(text);
84
+ const response = await client.webRead({
85
+ url: finalUrl,
86
+ format: options.format || "markdown",
87
+ retainImages: !options.noImages,
88
+ withLinksSummary: options.withLinks,
89
+ timeout: options.timeout,
90
+ noCache: options.noCache,
91
+ noGfm: options.noGfm,
92
+ keepImgDataUrl: options.keepImgDataUrl,
93
+ withImagesSummary: options.withImagesSummary,
94
+ });
95
+ const { content: rawContent } = extractContent(response);
96
+ // --extract short-circuits: returns the extracted slice as a JSON array,
97
+ // bypassing truncation and envelope logic.
98
+ if (options.extract) {
99
+ const extracted = extract(rawContent, options.extract);
100
+ if (context) {
101
+ context.notice(`ℹ️ extracted ${extracted.length} ${options.extract}`);
113
102
  }
103
+ return { kind: "data", data: extracted };
104
+ }
105
+ const { text, originalLen, truncated } = truncate(rawContent, options.maxChars);
106
+ if (truncated && context) {
107
+ context.notice(`⚠️ content truncated from ${originalLen.toLocaleString()} to ${text.length.toLocaleString()} chars; use a higher --max-chars or omit it for full content`);
114
108
  }
115
- finally {
116
- await client.close().catch(() => { });
117
- restoreConsole();
109
+ // Default: content-only (drops title/metadata/external envelope).
110
+ // --full-envelope, json, or pretty keeps the structured object.
111
+ const wantEnvelope = options.fullEnvelope || outputMode === "json" || outputMode === "pretty";
112
+ if (wantEnvelope) {
113
+ const envelope = response && typeof response === "object"
114
+ ? { ...response, content: text }
115
+ : { content: text };
116
+ return { kind: "data", data: envelope };
118
117
  }
118
+ return { kind: "data", data: text };
119
119
  }
120
- catch (error) {
121
- console.error(formatErrorOutput(error));
122
- process.exit(1);
120
+ finally {
121
+ await client.close().catch(() => { });
123
122
  }
124
123
  }
125
124
  // Help text
@@ -1 +1 @@
1
- {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/commands/read.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/commands/read.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,11 @@
1
1
  /**
2
2
  * Repo commands for GitHub repository exploration (ZRead)
3
+ *
4
+ * P1-05: each command returns a CommandResult instead of writing
5
+ * directly to stdout/stderr. Validation errors are thrown and converted
6
+ * by invokeCommand.
3
7
  */
8
+ import type { CommandContext, CommandResult } from "../command-invocation.js";
4
9
  export interface RepoSearchOptions {
5
10
  language?: "en" | "zh";
6
11
  maxChars?: number;
@@ -15,8 +20,8 @@ export interface RepoReadOptions {
15
20
  maxChars?: number;
16
21
  noCache?: boolean;
17
22
  }
18
- export declare function repoSearch(repo: string, query: string, options?: RepoSearchOptions): Promise<void>;
19
- export declare function repoTree(repo: string, options?: RepoTreeOptions): Promise<void>;
20
- export declare function repoRead(repo: string, path: string, options?: RepoReadOptions): Promise<void>;
23
+ export declare function repoSearch(repo: string, query: string, options?: RepoSearchOptions, _context?: CommandContext): Promise<CommandResult>;
24
+ export declare function repoTree(repo: string, options?: RepoTreeOptions, _context?: CommandContext): Promise<CommandResult>;
25
+ export declare function repoRead(repo: string, path: string, options?: RepoReadOptions, _context?: CommandContext): Promise<CommandResult>;
21
26
  export declare const REPO_HELP: string;
22
27
  //# sourceMappingURL=repo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/commands/repo.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgBH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAiFD,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyCzF;AAED,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAsBf;AAGD,eAAO,MAAM,SAAS,QA2Cd,CAAC"}
1
+ {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/commands/repo.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAW9E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAiFD,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,iBAAsB,EAC/B,QAAQ,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC,aAAa,CAAC,CAcxB;AAED,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,eAAoB,EAC7B,QAAQ,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC,aAAa,CAAC,CA+BxB;AAED,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,eAAoB,EAC7B,QAAQ,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC,aAAa,CAAC,CAUxB;AAGD,eAAO,MAAM,SAAS,QA2Cd,CAAC"}
@@ -1,10 +1,12 @@
1
1
  /**
2
2
  * Repo commands for GitHub repository exploration (ZRead)
3
+ *
4
+ * P1-05: each command returns a CommandResult instead of writing
5
+ * directly to stdout/stderr. Validation errors are thrown and converted
6
+ * by invokeCommand.
3
7
  */
4
8
  import { ZReadMcpClient } from "../lib/mcp-client.js";
5
- import { outputSuccess } from "../lib/output.js";
6
- import { formatErrorOutput, ValidationError } from "../lib/errors.js";
7
- import { silenceConsole, restoreConsole } from "../lib/silence.js";
9
+ import { ValidationError } from "../lib/errors.js";
8
10
  import path from "node:path";
9
11
  function validateRepo(repo) {
10
12
  if (!repo.includes("/")) {
@@ -74,101 +76,61 @@ async function collectTreeSnapshots(client, repo, basePath, depth) {
74
76
  }
75
77
  return snapshots;
76
78
  }
77
- export async function repoSearch(repo, query, options = {}) {
78
- try {
79
- validateRepo(repo);
80
- if (options.language && options.language !== "en" && options.language !== "zh") {
81
- throw new ValidationError('Language must be "en" or "zh"');
82
- }
79
+ export async function repoSearch(repo, query, options = {}, _context) {
80
+ validateRepo(repo);
81
+ if (options.language && options.language !== "en" && options.language !== "zh") {
82
+ throw new ValidationError('Language must be "en" or "zh"');
83
83
  }
84
- catch (error) {
85
- console.error(formatErrorOutput(error));
86
- process.exit(1);
87
- }
88
- silenceConsole();
89
84
  const client = new ZReadMcpClient({ enableVision: false, noCache: options.noCache });
90
85
  try {
91
- try {
92
- const language = options.language || "en";
93
- const results = await client.searchDoc(repo, query, language);
94
- outputSuccess(truncateText(results, options.maxChars));
95
- }
96
- finally {
97
- await client.close().catch(() => { });
98
- restoreConsole();
99
- }
86
+ const language = options.language || "en";
87
+ const results = await client.searchDoc(repo, query, language);
88
+ return { kind: "data", data: truncateText(results, options.maxChars) };
100
89
  }
101
- catch (error) {
102
- console.error(formatErrorOutput(error));
103
- process.exit(1);
90
+ finally {
91
+ await client.close().catch(() => { });
104
92
  }
105
93
  }
106
- export async function repoTree(repo, options = {}) {
107
- try {
108
- validateRepo(repo);
109
- if (options.depth !== undefined) {
110
- const depthValue = Number(options.depth);
111
- if (!Number.isFinite(depthValue) || depthValue < 1) {
112
- throw new ValidationError("Depth must be a positive integer");
113
- }
94
+ export async function repoTree(repo, options = {}, _context) {
95
+ validateRepo(repo);
96
+ if (options.depth !== undefined) {
97
+ const depthValue = Number(options.depth);
98
+ if (!Number.isFinite(depthValue) || depthValue < 1) {
99
+ throw new ValidationError("Depth must be a positive integer");
114
100
  }
115
101
  }
116
- catch (error) {
117
- console.error(formatErrorOutput(error));
118
- process.exit(1);
119
- }
120
- silenceConsole();
121
102
  const client = new ZReadMcpClient({ enableVision: false, noCache: options.noCache });
122
103
  try {
123
- try {
124
- const depth = Math.max(1, Math.floor(options.depth || 1));
125
- const dirPath = normalizeDirPath(options.path);
126
- if (depth === 1) {
127
- const structure = await client.getRepoStructure(repo, dirPath);
128
- outputSuccess(structure);
129
- return;
130
- }
131
- const snapshots = await collectTreeSnapshots(client, repo, dirPath, depth);
132
- outputSuccess({
104
+ const depth = Math.max(1, Math.floor(options.depth || 1));
105
+ const dirPath = normalizeDirPath(options.path);
106
+ if (depth === 1) {
107
+ const structure = await client.getRepoStructure(repo, dirPath);
108
+ return { kind: "data", data: structure };
109
+ }
110
+ const snapshots = await collectTreeSnapshots(client, repo, dirPath, depth);
111
+ return {
112
+ kind: "data",
113
+ data: {
133
114
  repo,
134
115
  depth,
135
116
  basePath: dirPath || "/",
136
117
  snapshots,
137
- });
138
- }
139
- finally {
140
- await client.close().catch(() => { });
141
- restoreConsole();
142
- }
118
+ },
119
+ };
143
120
  }
144
- catch (error) {
145
- console.error(formatErrorOutput(error));
146
- process.exit(1);
121
+ finally {
122
+ await client.close().catch(() => { });
147
123
  }
148
124
  }
149
- export async function repoRead(repo, path, options = {}) {
150
- try {
151
- validateRepo(repo);
152
- }
153
- catch (error) {
154
- console.error(formatErrorOutput(error));
155
- process.exit(1);
156
- }
157
- silenceConsole();
125
+ export async function repoRead(repo, path, options = {}, _context) {
126
+ validateRepo(repo);
158
127
  const client = new ZReadMcpClient({ enableVision: false, noCache: options.noCache });
159
128
  try {
160
- try {
161
- const content = await client.readFile(repo, path);
162
- outputSuccess(truncateText(content, options.maxChars));
163
- }
164
- finally {
165
- await client.close().catch(() => { });
166
- restoreConsole();
167
- }
129
+ const content = await client.readFile(repo, path);
130
+ return { kind: "data", data: truncateText(content, options.maxChars) };
168
131
  }
169
- catch (error) {
170
- console.error(formatErrorOutput(error));
171
- process.exit(1);
132
+ finally {
133
+ await client.close().catch(() => { });
172
134
  }
173
135
  }
174
136
  // Help text