scoutline 0.1.0 → 0.6.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 (242) hide show
  1. package/README.md +394 -7
  2. package/bin/scoutline.js +36 -15
  3. package/dist/capabilities/diagnostics.d.ts +135 -0
  4. package/dist/capabilities/diagnostics.d.ts.map +1 -0
  5. package/dist/capabilities/diagnostics.js +139 -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/reader.d.ts +227 -0
  12. package/dist/capabilities/reader.d.ts.map +1 -0
  13. package/dist/capabilities/reader.js +100 -0
  14. package/dist/capabilities/reader.js.map +1 -0
  15. package/dist/capabilities/repository.d.ts +221 -0
  16. package/dist/capabilities/repository.d.ts.map +1 -0
  17. package/dist/capabilities/repository.js +172 -0
  18. package/dist/capabilities/repository.js.map +1 -0
  19. package/dist/capabilities/search.d.ts +110 -0
  20. package/dist/capabilities/search.d.ts.map +1 -0
  21. package/dist/capabilities/search.js +21 -0
  22. package/dist/capabilities/search.js.map +1 -0
  23. package/dist/capabilities/vision.d.ts +156 -0
  24. package/dist/capabilities/vision.d.ts.map +1 -0
  25. package/dist/capabilities/vision.js +111 -0
  26. package/dist/capabilities/vision.js.map +1 -0
  27. package/dist/command-invocation.d.ts +58 -0
  28. package/dist/command-invocation.d.ts.map +1 -0
  29. package/dist/command-invocation.js +95 -0
  30. package/dist/command-invocation.js.map +1 -0
  31. package/dist/commands/cache.d.ts +106 -0
  32. package/dist/commands/cache.d.ts.map +1 -0
  33. package/dist/commands/cache.js +203 -0
  34. package/dist/commands/cache.js.map +1 -0
  35. package/dist/commands/code.d.ts +11 -4
  36. package/dist/commands/code.d.ts.map +1 -1
  37. package/dist/commands/code.js +16 -42
  38. package/dist/commands/code.js.map +1 -1
  39. package/dist/commands/doctor.d.ts +69 -3
  40. package/dist/commands/doctor.d.ts.map +1 -1
  41. package/dist/commands/doctor.js +179 -52
  42. package/dist/commands/doctor.js.map +1 -1
  43. package/dist/commands/quota.d.ts +45 -3
  44. package/dist/commands/quota.d.ts.map +1 -1
  45. package/dist/commands/quota.js +116 -60
  46. package/dist/commands/quota.js.map +1 -1
  47. package/dist/commands/read.d.ts +76 -2
  48. package/dist/commands/read.d.ts.map +1 -1
  49. package/dist/commands/read.js +260 -121
  50. package/dist/commands/read.js.map +1 -1
  51. package/dist/commands/repo.d.ts +55 -4
  52. package/dist/commands/repo.d.ts.map +1 -1
  53. package/dist/commands/repo.js +115 -172
  54. package/dist/commands/repo.js.map +1 -1
  55. package/dist/commands/repository-explorer.d.ts +147 -0
  56. package/dist/commands/repository-explorer.d.ts.map +1 -0
  57. package/dist/commands/repository-explorer.js +550 -0
  58. package/dist/commands/repository-explorer.js.map +1 -0
  59. package/dist/commands/search.d.ts +27 -2
  60. package/dist/commands/search.d.ts.map +1 -1
  61. package/dist/commands/search.js +95 -103
  62. package/dist/commands/search.js.map +1 -1
  63. package/dist/commands/tools.d.ts +9 -3
  64. package/dist/commands/tools.d.ts.map +1 -1
  65. package/dist/commands/tools.js +29 -59
  66. package/dist/commands/tools.js.map +1 -1
  67. package/dist/commands/vision.d.ts +35 -9
  68. package/dist/commands/vision.d.ts.map +1 -1
  69. package/dist/commands/vision.js +184 -131
  70. package/dist/commands/vision.js.map +1 -1
  71. package/dist/index.d.ts +62 -1
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +580 -223
  74. package/dist/index.js.map +1 -1
  75. package/dist/lib/cache.d.ts +178 -12
  76. package/dist/lib/cache.d.ts.map +1 -1
  77. package/dist/lib/cache.js +377 -39
  78. package/dist/lib/cache.js.map +1 -1
  79. package/dist/lib/code-mode.d.ts +13 -0
  80. package/dist/lib/code-mode.d.ts.map +1 -1
  81. package/dist/lib/code-mode.js +26 -6
  82. package/dist/lib/code-mode.js.map +1 -1
  83. package/dist/lib/config.d.ts.map +1 -1
  84. package/dist/lib/config.js +15 -18
  85. package/dist/lib/config.js.map +1 -1
  86. package/dist/lib/errors.d.ts +89 -11
  87. package/dist/lib/errors.d.ts.map +1 -1
  88. package/dist/lib/errors.js +168 -21
  89. package/dist/lib/errors.js.map +1 -1
  90. package/dist/lib/execution.d.ts +190 -0
  91. package/dist/lib/execution.d.ts.map +1 -0
  92. package/dist/lib/execution.js +383 -0
  93. package/dist/lib/execution.js.map +1 -0
  94. package/dist/lib/index.d.ts +10 -2
  95. package/dist/lib/index.d.ts.map +1 -1
  96. package/dist/lib/index.js +10 -2
  97. package/dist/lib/index.js.map +1 -1
  98. package/dist/lib/mcp-client.d.ts +75 -16
  99. package/dist/lib/mcp-client.d.ts.map +1 -1
  100. package/dist/lib/mcp-client.js +173 -108
  101. package/dist/lib/mcp-client.js.map +1 -1
  102. package/dist/lib/mcp-config.d.ts +17 -0
  103. package/dist/lib/mcp-config.d.ts.map +1 -1
  104. package/dist/lib/mcp-config.js +29 -0
  105. package/dist/lib/mcp-config.js.map +1 -1
  106. package/dist/lib/monitor-client.d.ts +17 -3
  107. package/dist/lib/monitor-client.d.ts.map +1 -1
  108. package/dist/lib/monitor-client.js +23 -69
  109. package/dist/lib/monitor-client.js.map +1 -1
  110. package/dist/lib/output.d.ts +53 -7
  111. package/dist/lib/output.d.ts.map +1 -1
  112. package/dist/lib/output.js +126 -39
  113. package/dist/lib/output.js.map +1 -1
  114. package/dist/lib/redact.d.ts +62 -3
  115. package/dist/lib/redact.d.ts.map +1 -1
  116. package/dist/lib/redact.js +165 -31
  117. package/dist/lib/redact.js.map +1 -1
  118. package/dist/lib/tool-cache.d.ts +86 -0
  119. package/dist/lib/tool-cache.d.ts.map +1 -0
  120. package/dist/lib/tool-cache.js +123 -0
  121. package/dist/lib/tool-cache.js.map +1 -0
  122. package/dist/lib/tty.d.ts +7 -20
  123. package/dist/lib/tty.d.ts.map +1 -1
  124. package/dist/lib/tty.js +51 -30
  125. package/dist/lib/tty.js.map +1 -1
  126. package/dist/node-command-invocation-adapter.d.ts +28 -0
  127. package/dist/node-command-invocation-adapter.d.ts.map +1 -0
  128. package/dist/node-command-invocation-adapter.js +88 -0
  129. package/dist/node-command-invocation-adapter.js.map +1 -0
  130. package/dist/providers/minimax/adapter.d.ts +49 -0
  131. package/dist/providers/minimax/adapter.d.ts.map +1 -0
  132. package/dist/providers/minimax/adapter.js +450 -0
  133. package/dist/providers/minimax/adapter.js.map +1 -0
  134. package/dist/providers/minimax/coding-plan-client.d.ts +60 -0
  135. package/dist/providers/minimax/coding-plan-client.d.ts.map +1 -0
  136. package/dist/providers/minimax/coding-plan-client.js +204 -0
  137. package/dist/providers/minimax/coding-plan-client.js.map +1 -0
  138. package/dist/providers/minimax/config.d.ts +32 -0
  139. package/dist/providers/minimax/config.d.ts.map +1 -0
  140. package/dist/providers/minimax/config.js +84 -0
  141. package/dist/providers/minimax/config.js.map +1 -0
  142. package/dist/providers/minimax/media.d.ts +88 -0
  143. package/dist/providers/minimax/media.d.ts.map +1 -0
  144. package/dist/providers/minimax/media.js +232 -0
  145. package/dist/providers/minimax/media.js.map +1 -0
  146. package/dist/providers/minimax/quota-client.d.ts +44 -0
  147. package/dist/providers/minimax/quota-client.d.ts.map +1 -0
  148. package/dist/providers/minimax/quota-client.js +83 -0
  149. package/dist/providers/minimax/quota-client.js.map +1 -0
  150. package/dist/providers/minimax/quota.d.ts +48 -0
  151. package/dist/providers/minimax/quota.d.ts.map +1 -0
  152. package/dist/providers/minimax/quota.js +120 -0
  153. package/dist/providers/minimax/quota.js.map +1 -0
  154. package/dist/providers/minimax/sdk-client.d.ts +29 -0
  155. package/dist/providers/minimax/sdk-client.d.ts.map +1 -0
  156. package/dist/providers/minimax/sdk-client.js +50 -0
  157. package/dist/providers/minimax/sdk-client.js.map +1 -0
  158. package/dist/providers/minimax/vision-attestations.d.ts +52 -0
  159. package/dist/providers/minimax/vision-attestations.d.ts.map +1 -0
  160. package/dist/providers/minimax/vision-attestations.js +79 -0
  161. package/dist/providers/minimax/vision-attestations.js.map +1 -0
  162. package/dist/providers/minimax/vision-conformance.d.ts +186 -0
  163. package/dist/providers/minimax/vision-conformance.d.ts.map +1 -0
  164. package/dist/providers/minimax/vision-conformance.js +371 -0
  165. package/dist/providers/minimax/vision-conformance.js.map +1 -0
  166. package/dist/providers/minimax/vision-mappings/chart.d.ts +35 -0
  167. package/dist/providers/minimax/vision-mappings/chart.d.ts.map +1 -0
  168. package/dist/providers/minimax/vision-mappings/chart.js +55 -0
  169. package/dist/providers/minimax/vision-mappings/chart.js.map +1 -0
  170. package/dist/providers/minimax/vision-mappings/common.d.ts +60 -0
  171. package/dist/providers/minimax/vision-mappings/common.d.ts.map +1 -0
  172. package/dist/providers/minimax/vision-mappings/common.js +75 -0
  173. package/dist/providers/minimax/vision-mappings/common.js.map +1 -0
  174. package/dist/providers/minimax/vision-mappings/diagnose-error.d.ts +35 -0
  175. package/dist/providers/minimax/vision-mappings/diagnose-error.d.ts.map +1 -0
  176. package/dist/providers/minimax/vision-mappings/diagnose-error.js +55 -0
  177. package/dist/providers/minimax/vision-mappings/diagnose-error.js.map +1 -0
  178. package/dist/providers/minimax/vision-mappings/diagram.d.ts +35 -0
  179. package/dist/providers/minimax/vision-mappings/diagram.d.ts.map +1 -0
  180. package/dist/providers/minimax/vision-mappings/diagram.js +55 -0
  181. package/dist/providers/minimax/vision-mappings/diagram.js.map +1 -0
  182. package/dist/providers/minimax/vision-mappings/extract-text.d.ts +35 -0
  183. package/dist/providers/minimax/vision-mappings/extract-text.d.ts.map +1 -0
  184. package/dist/providers/minimax/vision-mappings/extract-text.js +55 -0
  185. package/dist/providers/minimax/vision-mappings/extract-text.js.map +1 -0
  186. package/dist/providers/minimax/vision-mappings/ui-artifact.d.ts +35 -0
  187. package/dist/providers/minimax/vision-mappings/ui-artifact.d.ts.map +1 -0
  188. package/dist/providers/minimax/vision-mappings/ui-artifact.js +69 -0
  189. package/dist/providers/minimax/vision-mappings/ui-artifact.js.map +1 -0
  190. package/dist/providers/minimax/vision-mappings.generated.d.ts +29 -0
  191. package/dist/providers/minimax/vision-mappings.generated.d.ts.map +1 -0
  192. package/dist/providers/minimax/vision-mappings.generated.js +29 -0
  193. package/dist/providers/minimax/vision-mappings.generated.js.map +1 -0
  194. package/dist/providers/minimax/vision-revisions.d.ts +29 -0
  195. package/dist/providers/minimax/vision-revisions.d.ts.map +1 -0
  196. package/dist/providers/minimax/vision-revisions.js +34 -0
  197. package/dist/providers/minimax/vision-revisions.js.map +1 -0
  198. package/dist/providers/registry.d.ts +36 -0
  199. package/dist/providers/registry.d.ts.map +1 -0
  200. package/dist/providers/registry.js +45 -0
  201. package/dist/providers/registry.js.map +1 -0
  202. package/dist/providers/selection.d.ts +44 -0
  203. package/dist/providers/selection.d.ts.map +1 -0
  204. package/dist/providers/selection.js +85 -0
  205. package/dist/providers/selection.js.map +1 -0
  206. package/dist/providers/types.d.ts +281 -0
  207. package/dist/providers/types.d.ts.map +1 -0
  208. package/dist/providers/types.js +127 -0
  209. package/dist/providers/types.js.map +1 -0
  210. package/dist/providers/zai/adapter.d.ts +35 -0
  211. package/dist/providers/zai/adapter.d.ts.map +1 -0
  212. package/dist/providers/zai/adapter.js +685 -0
  213. package/dist/providers/zai/adapter.js.map +1 -0
  214. package/dist/providers/zai/credentials.d.ts +38 -0
  215. package/dist/providers/zai/credentials.d.ts.map +1 -0
  216. package/dist/providers/zai/credentials.js +60 -0
  217. package/dist/providers/zai/credentials.js.map +1 -0
  218. package/dist/providers/zai/encoded-error.d.ts +90 -0
  219. package/dist/providers/zai/encoded-error.d.ts.map +1 -0
  220. package/dist/providers/zai/encoded-error.js +169 -0
  221. package/dist/providers/zai/encoded-error.js.map +1 -0
  222. package/dist/providers/zai/media.d.ts +38 -0
  223. package/dist/providers/zai/media.d.ts.map +1 -0
  224. package/dist/providers/zai/media.js +107 -0
  225. package/dist/providers/zai/media.js.map +1 -0
  226. package/dist/providers/zai/monitor-client.d.ts +53 -0
  227. package/dist/providers/zai/monitor-client.d.ts.map +1 -0
  228. package/dist/providers/zai/monitor-client.js +117 -0
  229. package/dist/providers/zai/monitor-client.js.map +1 -0
  230. package/dist/providers/zai/quota.d.ts +47 -0
  231. package/dist/providers/zai/quota.d.ts.map +1 -0
  232. package/dist/providers/zai/quota.js +127 -0
  233. package/dist/providers/zai/quota.js.map +1 -0
  234. package/dist/providers/zai/reader.d.ts +82 -0
  235. package/dist/providers/zai/reader.d.ts.map +1 -0
  236. package/dist/providers/zai/reader.js +490 -0
  237. package/dist/providers/zai/reader.js.map +1 -0
  238. package/dist/providers/zai/repository.d.ts +76 -0
  239. package/dist/providers/zai/repository.d.ts.map +1 -0
  240. package/dist/providers/zai/repository.js +715 -0
  241. package/dist/providers/zai/repository.js.map +1 -0
  242. package/package.json +11 -6
@@ -1,70 +1,197 @@
1
1
  /**
2
- * Doctor command for environment and MCP diagnostics
2
+ * Doctor command — Provider-aware diagnostics (P4-04, DESIGN.md §14).
3
+ *
4
+ * The command is presentation-only: it receives a report builder through
5
+ * injected dependencies and wraps the resulting {@link DiagnosticsReport}
6
+ * as base data with a computed exit code. Provider resolution, capability
7
+ * probing, settled collection, and failure redaction live in
8
+ * {@link buildDiagnosticsReport} so the command never imports a Provider
9
+ * transport (ZaiMcpClient, monitor client, or environment credential
10
+ * reads) directly.
11
+ *
12
+ * Exit semantics (DESIGN.md §14):
13
+ * - Missing effective Provider credentials -> exit 1.
14
+ * - Any configured probe error -> exit 1 (successful entries preserved).
15
+ * - All configured probes succeed, or only tools-disabled skips -> exit 0.
16
+ *
17
+ * Under `--no-tools` the command returns after metadata + configured-state
18
+ * evaluation and constructs no Adapter and no transport (FR-034).
3
19
  */
4
- import { ZaiMcpClient } from "../lib/mcp-client.js";
5
- import { outputSuccess } from "../lib/output.js";
6
- import { formatErrorOutput } from "../lib/errors.js";
7
- import { silenceConsole, restoreConsole } from "../lib/silence.js";
8
- function getNodeMajor() {
20
+ import { deriveSharedCapabilities, deriveZaiOnlyCapabilities, diagnosticErrorFromError, } from "../capabilities/diagnostics.js";
21
+ import { executeProviderOperation } from "../lib/execution.js";
22
+ import { UnsupportedCapabilityError } from "../lib/errors.js";
23
+ import { redactSecrets, configuredSecrets } from "../lib/redact.js";
24
+ function nodeMajor() {
9
25
  const [major] = process.versions.node.split(".");
10
26
  return parseInt(major, 10);
11
27
  }
12
- export async function doctor(options = {}) {
13
- const apiKey = process.env.Z_AI_API_KEY || process.env.ZAI_API_KEY;
14
- const mode = (process.env.Z_AI_MODE || process.env.PLATFORM_MODE || "ZAI").toUpperCase();
15
- const nodeMajor = getNodeMajor();
16
- const report = {
17
- env: {
18
- apiKeyPresent: Boolean(apiKey),
19
- mode,
20
- baseUrl: process.env.Z_AI_BASE_URL || undefined,
21
- },
28
+ /**
29
+ * Probe one Provider's connectivity through shared execution. The Adapter
30
+ * transport performs a single attempt (Z.AI tool discovery or MiniMax raw
31
+ * quota probe); the retry policy lives in
32
+ * `executeProviderOperation("diagnostics", ...)`.
33
+ */
34
+ async function probeProvider(descriptor, env, sleep, random) {
35
+ const adapter = descriptor.create({ env });
36
+ const capability = adapter.diagnostics;
37
+ if (!capability) {
38
+ throw new UnsupportedCapabilityError(descriptor.id, "diagnostics");
39
+ }
40
+ return executeProviderOperation("diagnostics", () => capability.invoke({ probe: true }), {
41
+ sleep,
42
+ random,
43
+ });
44
+ }
45
+ /**
46
+ * Build a schema-version-1 {@link DiagnosticsReport}. Inventory
47
+ * (`sharedCapabilities`, `zaiOnlyCapabilities`) is derived purely from
48
+ * `deps.descriptors` — no descriptor.create(), no transport, no
49
+ * production registry import. Under `--no-tools` the command returns
50
+ * after metadata + configured-state evaluation. Otherwise each
51
+ * configured Provider is probed through shared execution with settled
52
+ * collection, preserving registry order and normalized redacted
53
+ * failures.
54
+ */
55
+ export async function buildDiagnosticsReport(deps) {
56
+ const secrets = configuredSecrets(deps.env);
57
+ const baseEntries = deps.descriptors.map((descriptor) => ({
58
+ provider: descriptor.id,
59
+ configured: descriptor.isConfigured(deps.env),
60
+ capabilities: [...descriptor.capabilities()],
61
+ }));
62
+ const providers = deps.noTools
63
+ ? baseEntries.map((entry) => ({
64
+ ...entry,
65
+ status: "skipped",
66
+ reason: entry.configured ? "tools-disabled" : "not-configured",
67
+ }))
68
+ : await probeEntries(baseEntries, deps, secrets);
69
+ // L1 fix: the cache summary is formatted by the CLI handler and
70
+ // threaded through deps.cacheSummary. The report builder only embeds
71
+ // it; it never reads `cacheStats()` itself.
72
+ const cache = deps.cacheSummary === undefined ? undefined : { summary: deps.cacheSummary };
73
+ return {
74
+ schemaVersion: 1,
75
+ effectiveProvider: deps.effectiveProvider,
76
+ sharedCapabilities: deriveSharedCapabilities(deps.descriptors),
77
+ zaiOnlyCapabilities: deriveZaiOnlyCapabilities(deps.descriptors),
22
78
  node: {
23
- version: process.versions.node,
24
- visionMcpCompatible: nodeMajor >= 22,
79
+ version: process.version,
80
+ visionMcpCompatible: nodeMajor() >= 22,
25
81
  },
82
+ providers,
83
+ ...(cache !== undefined ? { cache } : {}),
84
+ };
85
+ }
86
+ /**
87
+ * Probe every configured Provider in registry order using settled
88
+ * collection. Unconfigured entries are skipped (not-configured) and do
89
+ * NOT fail the report. A configured probe failure is normalized and
90
+ * recursively redacted before joining the report; successful entries
91
+ * are preserved alongside it.
92
+ */
93
+ async function probeEntries(baseEntries, deps, secrets) {
94
+ const configuredIndexes = baseEntries
95
+ .map((entry, index) => (entry.configured ? index : -1))
96
+ .filter((index) => index >= 0);
97
+ const settled = await Promise.allSettled(configuredIndexes.map((index) => probeProvider(deps.descriptors[index], deps.env, deps.sleep, deps.random)));
98
+ let settledCursor = 0;
99
+ return baseEntries.map((entry) => {
100
+ if (!entry.configured) {
101
+ return { ...entry, status: "skipped", reason: "not-configured" };
102
+ }
103
+ const result = settled[settledCursor++];
104
+ if (result.status === "fulfilled") {
105
+ return { ...entry, status: "ok" };
106
+ }
107
+ const redacted = redactSecrets(diagnosticErrorFromError(result.reason), secrets);
108
+ return { ...entry, status: "error", error: redacted };
109
+ });
110
+ }
111
+ // ---------------------------------------------------------------------------
112
+ // Exit code
113
+ // ---------------------------------------------------------------------------
114
+ /**
115
+ * Compute the doctor exit code from a finalized report. Exit 1 when the
116
+ * effective Provider is unconfigured or any configured probe errored;
117
+ * otherwise exit 0. A tools-disabled or not-configured skip on a
118
+ * non-effective Provider never fails the report.
119
+ */
120
+ export function doctorExitCode(report) {
121
+ const effective = report.providers.find((p) => p.provider === report.effectiveProvider);
122
+ if (!effective || !effective.configured)
123
+ return 1;
124
+ if (report.providers.some((p) => p.status === "error"))
125
+ return 1;
126
+ return 0;
127
+ }
128
+ /**
129
+ * Run the doctor command. Returns the diagnostics report as base data
130
+ * with a computed exit code (1 when the effective Provider is
131
+ * unconfigured or any configured probe failed; otherwise 0).
132
+ */
133
+ export async function doctor(deps) {
134
+ const report = await deps.buildReport();
135
+ return {
136
+ kind: "data",
137
+ data: report,
138
+ exitCode: doctorExitCode(report),
26
139
  };
27
- if (options.noTools || !apiKey) {
28
- outputSuccess(report);
29
- return;
30
- }
31
- silenceConsole();
32
- const client = new ZaiMcpClient({ enableVision: options.enableVision });
33
- try {
34
- const tools = await client.listTools();
35
- const byServer = tools.reduce((acc, tool) => {
36
- const parts = tool.name.split(".");
37
- const server = parts.length >= 2 ? parts[1] : "unknown";
38
- acc[server] = (acc[server] || 0) + 1;
39
- return acc;
40
- }, {});
41
- report.mcp = {
42
- toolCount: tools.length,
43
- servers: byServer,
44
- };
45
- outputSuccess(report);
46
- }
47
- catch (error) {
48
- restoreConsole();
49
- console.error(formatErrorOutput(error));
50
- process.exit(1);
51
- }
52
- finally {
53
- await client.close().catch(() => { });
54
- restoreConsole();
55
- }
56
140
  }
57
141
  export const DOCTOR_HELP = `
58
- Doctor - Check environment and MCP connectivity
142
+ Doctor - Provider-aware environment and connectivity diagnostics
59
143
 
60
144
  Usage: scoutline doctor [options]
61
145
 
146
+ Reports a schema-version-1 diagnostics report listing every built-in
147
+ Provider (zai, minimax) with its configured state, declared
148
+ Capabilities, and connectivity status. The effective Provider (resolved
149
+ from --provider, SCOUTLINE_PROVIDER, or the default zai) is the
150
+ Provider that serves the shared Capabilities shared across every
151
+ built-in descriptor. The sharedCapabilities and zaiOnlyCapabilities
152
+ fields are derived from descriptor metadata, so they always reflect
153
+ the descriptors passed to this command.
154
+
155
+ Z.AI connectivity is probed through MCP tool discovery; MiniMax
156
+ connectivity through a single raw quota probe that authenticates
157
+ without a generative request.
158
+
159
+ Repository exploration is a Provider Capability. Z.AI descriptor
160
+ metadata advertises repository-exploration and the Z.AI Adapter
161
+ supplies it; MiniMax advertises and supplies neither. The
162
+ sharedCapabilities and zaiOnlyCapabilities fields above reflect that
163
+ descriptor state (repository-exploration currently appears in
164
+ zaiOnlyCapabilities).
165
+
166
+ Reader is a Provider Capability. Z.AI descriptor metadata advertises
167
+ reader and the Z.AI Adapter supplies it; MiniMax advertises and
168
+ supplies neither. reader currently appears in zaiOnlyCapabilities
169
+ alongside repository-exploration.
170
+
171
+ Public 'repo' and 'read' commands participate in Provider selection.
172
+ They honour --provider / SCOUTLINE_PROVIDER / the default zai, route
173
+ through the Z.AI Adapter's Repository and Reader Capabilities
174
+ respectively, and return UNSUPPORTED_CAPABILITY when the selected
175
+ Provider does not advertise the requested capability (e.g.
176
+ 'repo --provider minimax' or 'read --provider minimax' fail without
177
+ falling back to Z.AI). A supported-but-unconfigured Z.AI returns
178
+ ConfigurationError; supported-and-configured Z.AI dispatches through
179
+ the Repository Explorer / Reader Adapter.
180
+
62
181
  Options:
63
- --no-tools Skip tool discovery (env-only check)
64
- --no-vision Skip vision MCP server (faster startup)
182
+ --no-tools Skip every connectivity probe (metadata-only). Under
183
+ --no-tools no Provider transport is constructed: a
184
+ configured Provider is reported as skipped
185
+ (tools-disabled) and does not fail the report.
186
+
187
+ Exit codes:
188
+ 0 All configured probes succeeded (or only tools-disabled skips).
189
+ 1 The effective Provider is unconfigured or any configured probe
190
+ failed; successful entries are still reported.
65
191
 
66
192
  Examples:
67
- scoutline doctor
68
- scoutline doctor --no-tools
193
+ scoutline doctor # full diagnostics
194
+ scoutline doctor --provider minimax
195
+ scoutline doctor --no-tools # metadata only, no transport
69
196
  `.trim();
70
197
  //# sourceMappingURL=doctor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,51 @@
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
  */
16
+ import type { CommandResult } from "../command-invocation.js";
17
+ import type { QuotaDashboard } from "../capabilities/quota.js";
18
+ import type { ProviderDescriptor, ProviderId } from "../providers/types.js";
19
+ export interface QuotaDashboardDependencies {
20
+ readonly allProviders: boolean;
21
+ readonly effectiveProvider: ProviderId;
22
+ readonly descriptors: readonly ProviderDescriptor[];
23
+ readonly env: NodeJS.ProcessEnv;
24
+ readonly sleep: (ms: number) => Promise<void>;
25
+ readonly random: () => number;
26
+ }
27
+ /**
28
+ * Build a {@link QuotaDashboard} for the selected mode. The effective
29
+ * Provider is resolved by the dispatcher (`index.ts`) and passed in as
30
+ * metadata; config validation happens here.
31
+ */
32
+ export declare function buildQuotaDashboard(deps: QuotaDashboardDependencies): Promise<QuotaDashboard>;
4
33
  export interface QuotaOptions {
5
- window?: "current";
34
+ allProviders?: boolean;
35
+ }
36
+ /**
37
+ * Injectable dependencies for the quota command. `buildDashboard`
38
+ * resolves the effective/all-provider dashboard; the command only wraps
39
+ * it for presentation and exit-code selection.
40
+ */
41
+ export interface QuotaCommandDependencies {
42
+ readonly buildDashboard: () => Promise<QuotaDashboard>;
6
43
  }
7
- export declare function quota(_options?: QuotaOptions): Promise<void>;
44
+ /**
45
+ * Run the quota command. Returns the dashboard as base data with a TTY
46
+ * presentation override. Exit code is 1 when any dashboard entry failed
47
+ * (all-provider mode); otherwise 0.
48
+ */
49
+ export declare function quota(deps: QuotaCommandDependencies): Promise<CommandResult<QuotaDashboard>>;
8
50
  export declare const QUOTA_HELP: string;
9
51
  //# sourceMappingURL=quota.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"quota.d.ts","sourceRoot":"","sources":["../../src/commands/quota.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,wBAAsB,KAAK,CAAC,QAAQ,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CtE;AAED,eAAO,MAAM,UAAU,QAwBf,CAAC"}
1
+ {"version":3,"file":"quota.d.ts","sourceRoot":"","sources":["../../src/commands/quota.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAIV,cAAc,EACf,MAAM,0BAA0B,CAAC;AAIlC,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAS5E,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,UAAU,CAAC;IACvC,QAAQ,CAAC,WAAW,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACpD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,QAAQ,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC;CAC/B;AAqFD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,cAAc,CAAC,CAEzB;AAMD,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,cAAc,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC;CACxD;AAED;;;;GAIG;AACH,wBAAsB,KAAK,CACzB,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CASxC;AAED,eAAO,MAAM,UAAU,QA2Bf,CAAC"}
@@ -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,6 +1,44 @@
1
1
  /**
2
- * Web reader command using Z.AI WebReader MCP
2
+ * Web reader command — thin handler over the Reader Capability
3
+ * (DESIGN.md §18, reader-migration-core-flows, reader-migration-tech-plan
4
+ * Ticket 04).
5
+ *
6
+ * The handler applies parse-level validation only (URL scheme, --extract
7
+ * mode), delegates to `capability.fetch(request)` through shared
8
+ * execution, then projects the normalized `ReaderFetchResult` into the
9
+ * public v1 envelope(s) (content read vs extract read). The Adapter
10
+ * (providers/zai/reader.ts) owns URL rewrite, credentials, transport,
11
+ * raw response parsing, cache identity, and retry/terminal
12
+ * classification; the handler owns projection (`--max-chars` truncation,
13
+ * `--extract` slicing), output-mode presentation, and the
14
+ * schema-version-1 envelope migration.
15
+ *
16
+ * Provider selection, capability support, configuration, Adapter
17
+ * construction, and adapter.reader agreement live in `src/index.ts`.
18
+ *
19
+ * Handler interface (P6-07A pattern): `deps: ReadHandlerDependencies`
20
+ * is REQUIRED — production and direct tests cross the same compile-
21
+ * checked Interface. An optional trailing `CommandContext` follows when
22
+ * a caller wants to surface per-invocation context; the handler does
23
+ * not currently read it. A `CommandContext` is NOT a valid substitute
24
+ * for `deps`.
25
+ *
26
+ * Output-mode behavior (core-flows table):
27
+ *
28
+ * - data: the envelope object (content or extract).
29
+ * - json / pretty: standard `{success, data, timestamp}` envelope.
30
+ * - compact / markdown / refs / tty:
31
+ * * content read → the `content` string directly (presentations).
32
+ * * extract read → JSON fallback (the extract envelope object);
33
+ * no presentation override because extracted items are data,
34
+ * not prose.
35
+ *
36
+ * `--full-envelope` is silently accepted and ignored (D3): the v1
37
+ * envelope is always returned.
3
38
  */
39
+ import type { CommandContext, CommandResult } from "../command-invocation.js";
40
+ import type { ReaderCapability } from "../capabilities/reader.js";
41
+ import type { ExecutionDependencies } from "../lib/execution.js";
4
42
  import { type ExtractMode } from "../lib/extract.js";
5
43
  export interface ReadOptions {
6
44
  format?: "markdown" | "text";
@@ -12,9 +50,45 @@ export interface ReadOptions {
12
50
  keepImgDataUrl?: boolean;
13
51
  withImagesSummary?: boolean;
14
52
  maxChars?: number;
53
+ /**
54
+ * Silently accepted and ignored at v1 (core-flows D3). The envelope
55
+ * is always returned. Retained on the options type so callers and
56
+ * `handleRead` parse it without errors; it never reaches the Adapter
57
+ * request, the cache identity, or the projection.
58
+ */
15
59
  fullEnvelope?: boolean;
16
60
  extract?: ExtractMode;
17
61
  }
18
- export declare function read(url: string, options?: ReadOptions): Promise<void>;
62
+ /**
63
+ * Dependencies injected by `src/index.ts` after Provider selection,
64
+ * capability support check, configuration check, Adapter construction,
65
+ * and adapter.reader agreement. The handler never resolves a Provider
66
+ * descriptor itself. Required — a caller that omits `deps` is malformed
67
+ * and fails loudly (a `CommandContext` is NOT a valid substitute).
68
+ */
69
+ export interface ReadHandlerDependencies {
70
+ readonly capability: ReaderCapability;
71
+ readonly execution: ExecutionDependencies;
72
+ }
73
+ /**
74
+ * Read web page content through the injected Reader Capability.
75
+ *
76
+ * Ordering:
77
+ * 1. Parse-level validation (URL scheme, --extract mode). Throws
78
+ * `ValidationError` BEFORE the Adapter or shared execution is
79
+ * reached.
80
+ * 2. Build the Provider-neutral request and delegate to
81
+ * `executeProviderOperation` with shared cache + retry policy.
82
+ * 3. Project the normalized result:
83
+ * - `--extract` slicing into the extract envelope (sets `mode`,
84
+ * `items`, `originalItemCount`); `--max-chars` is IGNORED.
85
+ * - Otherwise, `--max-chars` truncation on `content` (sets
86
+ * `truncated`, `originalContentLength`).
87
+ * 4. Set presentations so text-oriented modes (compact/markdown/
88
+ * refs/tty) emit `content` directly for content reads. Extract
89
+ * reads omit presentations; text modes then fall back to JSON
90
+ * (the extract envelope), matching the core-flows table.
91
+ */
92
+ export declare function read(url: string, options: ReadOptions | undefined, deps: ReadHandlerDependencies, _context?: CommandContext): Promise<CommandResult>;
19
93
  export declare const READ_HELP: string;
20
94
  //# sourceMappingURL=read.d.ts.map