scoutline 0.10.2 → 0.12.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 (151) hide show
  1. package/README.md +99 -44
  2. package/dist/capabilities/diagnostics.d.ts +75 -0
  3. package/dist/capabilities/diagnostics.d.ts.map +1 -1
  4. package/dist/capabilities/diagnostics.js.map +1 -1
  5. package/dist/capabilities/quota.d.ts +64 -1
  6. package/dist/capabilities/quota.d.ts.map +1 -1
  7. package/dist/capabilities/quota.js.map +1 -1
  8. package/dist/capabilities/vision.d.ts +4 -3
  9. package/dist/capabilities/vision.d.ts.map +1 -1
  10. package/dist/capabilities/vision.js +7 -5
  11. package/dist/capabilities/vision.js.map +1 -1
  12. package/dist/commands/code.d.ts +9 -1
  13. package/dist/commands/code.d.ts.map +1 -1
  14. package/dist/commands/code.js +4 -4
  15. package/dist/commands/code.js.map +1 -1
  16. package/dist/commands/crawl.d.ts.map +1 -1
  17. package/dist/commands/crawl.js +14 -3
  18. package/dist/commands/crawl.js.map +1 -1
  19. package/dist/commands/doctor.d.ts +71 -1
  20. package/dist/commands/doctor.d.ts.map +1 -1
  21. package/dist/commands/doctor.js +96 -15
  22. package/dist/commands/doctor.js.map +1 -1
  23. package/dist/commands/init.d.ts +186 -0
  24. package/dist/commands/init.d.ts.map +1 -0
  25. package/dist/commands/init.js +1221 -0
  26. package/dist/commands/init.js.map +1 -0
  27. package/dist/commands/map.d.ts.map +1 -1
  28. package/dist/commands/map.js +16 -3
  29. package/dist/commands/map.js.map +1 -1
  30. package/dist/commands/quota.d.ts +32 -0
  31. package/dist/commands/quota.d.ts.map +1 -1
  32. package/dist/commands/quota.js +165 -24
  33. package/dist/commands/quota.js.map +1 -1
  34. package/dist/commands/read.d.ts.map +1 -1
  35. package/dist/commands/read.js +9 -3
  36. package/dist/commands/read.js.map +1 -1
  37. package/dist/commands/repo.d.ts.map +1 -1
  38. package/dist/commands/repo.js +5 -3
  39. package/dist/commands/repo.js.map +1 -1
  40. package/dist/commands/research.d.ts +35 -7
  41. package/dist/commands/research.d.ts.map +1 -1
  42. package/dist/commands/research.js +93 -15
  43. package/dist/commands/research.js.map +1 -1
  44. package/dist/commands/tools.d.ts +8 -0
  45. package/dist/commands/tools.d.ts.map +1 -1
  46. package/dist/commands/tools.js +4 -4
  47. package/dist/commands/tools.js.map +1 -1
  48. package/dist/commands/vision.d.ts +10 -0
  49. package/dist/commands/vision.d.ts.map +1 -1
  50. package/dist/commands/vision.js +25 -2
  51. package/dist/commands/vision.js.map +1 -1
  52. package/dist/index.d.ts +136 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +894 -298
  55. package/dist/index.js.map +1 -1
  56. package/dist/lib/api-client.d.ts +1 -1
  57. package/dist/lib/api-client.d.ts.map +1 -1
  58. package/dist/lib/api-client.js +6 -2
  59. package/dist/lib/api-client.js.map +1 -1
  60. package/dist/lib/cache.d.ts +9 -2
  61. package/dist/lib/cache.d.ts.map +1 -1
  62. package/dist/lib/cache.js +9 -2
  63. package/dist/lib/cache.js.map +1 -1
  64. package/dist/lib/code-mode.d.ts +8 -0
  65. package/dist/lib/code-mode.d.ts.map +1 -1
  66. package/dist/lib/code-mode.js +3 -1
  67. package/dist/lib/code-mode.js.map +1 -1
  68. package/dist/lib/config-store.d.ts +165 -0
  69. package/dist/lib/config-store.d.ts.map +1 -0
  70. package/dist/lib/config-store.js +332 -0
  71. package/dist/lib/config-store.js.map +1 -0
  72. package/dist/lib/config.d.ts +2 -2
  73. package/dist/lib/config.d.ts.map +1 -1
  74. package/dist/lib/config.js +19 -11
  75. package/dist/lib/config.js.map +1 -1
  76. package/dist/lib/consumption.d.ts +144 -0
  77. package/dist/lib/consumption.d.ts.map +1 -0
  78. package/dist/lib/consumption.js +161 -0
  79. package/dist/lib/consumption.js.map +1 -0
  80. package/dist/lib/errors.d.ts +11 -0
  81. package/dist/lib/errors.d.ts.map +1 -1
  82. package/dist/lib/errors.js +14 -0
  83. package/dist/lib/errors.js.map +1 -1
  84. package/dist/lib/execution.d.ts +32 -4
  85. package/dist/lib/execution.d.ts.map +1 -1
  86. package/dist/lib/execution.js +156 -13
  87. package/dist/lib/execution.js.map +1 -1
  88. package/dist/lib/mcp-client.d.ts +12 -0
  89. package/dist/lib/mcp-client.d.ts.map +1 -1
  90. package/dist/lib/mcp-client.js +16 -7
  91. package/dist/lib/mcp-client.js.map +1 -1
  92. package/dist/lib/mcp-config.d.ts +10 -0
  93. package/dist/lib/mcp-config.d.ts.map +1 -1
  94. package/dist/lib/mcp-config.js +13 -7
  95. package/dist/lib/mcp-config.js.map +1 -1
  96. package/dist/lib/monitor-client.d.ts +19 -3
  97. package/dist/lib/monitor-client.d.ts.map +1 -1
  98. package/dist/lib/monitor-client.js +21 -5
  99. package/dist/lib/monitor-client.js.map +1 -1
  100. package/dist/lib/provider-fallback.d.ts +150 -0
  101. package/dist/lib/provider-fallback.d.ts.map +1 -0
  102. package/dist/lib/provider-fallback.js +510 -0
  103. package/dist/lib/provider-fallback.js.map +1 -0
  104. package/dist/lib/quota-mapping.d.ts +402 -0
  105. package/dist/lib/quota-mapping.d.ts.map +1 -0
  106. package/dist/lib/quota-mapping.js +539 -0
  107. package/dist/lib/quota-mapping.js.map +1 -0
  108. package/dist/lib/quota-store.d.ts +271 -0
  109. package/dist/lib/quota-store.d.ts.map +1 -0
  110. package/dist/lib/quota-store.js +540 -0
  111. package/dist/lib/quota-store.js.map +1 -0
  112. package/dist/lib/trigger-detection.d.ts +149 -0
  113. package/dist/lib/trigger-detection.d.ts.map +1 -0
  114. package/dist/lib/trigger-detection.js +149 -0
  115. package/dist/lib/trigger-detection.js.map +1 -0
  116. package/dist/lib/tty.d.ts +8 -1
  117. package/dist/lib/tty.d.ts.map +1 -1
  118. package/dist/lib/tty.js +53 -1
  119. package/dist/lib/tty.js.map +1 -1
  120. package/dist/providers/brave/adapter.d.ts +26 -0
  121. package/dist/providers/brave/adapter.d.ts.map +1 -1
  122. package/dist/providers/brave/adapter.js +66 -4
  123. package/dist/providers/brave/adapter.js.map +1 -1
  124. package/dist/providers/brave/client.d.ts +46 -2
  125. package/dist/providers/brave/client.d.ts.map +1 -1
  126. package/dist/providers/brave/client.js +55 -3
  127. package/dist/providers/brave/client.js.map +1 -1
  128. package/dist/providers/exa/adapter.d.ts.map +1 -1
  129. package/dist/providers/exa/adapter.js +10 -1
  130. package/dist/providers/exa/adapter.js.map +1 -1
  131. package/dist/providers/firecrawl/adapter.d.ts.map +1 -1
  132. package/dist/providers/firecrawl/adapter.js +13 -3
  133. package/dist/providers/firecrawl/adapter.js.map +1 -1
  134. package/dist/providers/minimax/adapter.d.ts.map +1 -1
  135. package/dist/providers/minimax/adapter.js +4 -0
  136. package/dist/providers/minimax/adapter.js.map +1 -1
  137. package/dist/providers/selection.d.ts +114 -1
  138. package/dist/providers/selection.d.ts.map +1 -1
  139. package/dist/providers/selection.js +99 -3
  140. package/dist/providers/selection.js.map +1 -1
  141. package/dist/providers/tavily/adapter.d.ts.map +1 -1
  142. package/dist/providers/tavily/adapter.js +2 -0
  143. package/dist/providers/tavily/adapter.js.map +1 -1
  144. package/dist/providers/types.d.ts +33 -1
  145. package/dist/providers/types.d.ts.map +1 -1
  146. package/dist/providers/types.js +8 -0
  147. package/dist/providers/types.js.map +1 -1
  148. package/dist/providers/zai/adapter.d.ts.map +1 -1
  149. package/dist/providers/zai/adapter.js +18 -5
  150. package/dist/providers/zai/adapter.js.map +1 -1
  151. package/package.json +2 -1
@@ -18,8 +18,10 @@
18
18
  * evaluation and constructs no Adapter and no transport (FR-034).
19
19
  */
20
20
  import type { CommandResult } from "../command-invocation.js";
21
- import type { DiagnosticsReport } from "../capabilities/diagnostics.js";
21
+ import type { DiagnosticsReport, ProviderVerificationSummary } from "../capabilities/diagnostics.js";
22
22
  import type { ProviderDescriptor, ProviderId } from "../providers/types.js";
23
+ import type { VerificationPromotionStore } from "../lib/config-store.js";
24
+ import { type QuotaState } from "../lib/quota-store.js";
23
25
  export interface DoctorDiagnosticsDependencies {
24
26
  readonly noTools: boolean;
25
27
  readonly effectiveProvider: ProviderId;
@@ -36,6 +38,65 @@ export interface DoctorDiagnosticsDependencies {
36
38
  * simply leaves out the `cache` field.
37
39
  */
38
40
  readonly cacheSummary?: string;
41
+ /**
42
+ * Optional verification promoter (T3b — review item 10). When
43
+ * supplied, Doctor flips `verification.status: unverified → verified`
44
+ * for each Provider whose probe SUCCEEDS. The promotion is
45
+ * best-effort: a write failure is reported through
46
+ * {@link DoctorDiagnosticsDependencies.onPromotionError} (when
47
+ * supplied) and never turns a successful probe into a Doctor failure.
48
+ * Skipped, failed, no-tools, and network-deferred records are NOT
49
+ * promoted (the probe result is authoritative). When omitted, Doctor
50
+ * runs without promotion (backward-compatible with existing tests).
51
+ */
52
+ readonly verificationPromoter?: VerificationPromotionStore;
53
+ /**
54
+ * Optional clock used for the promoted `checkedAt` timestamp.
55
+ * Defaults to `Date.now`; tests inject a fixed clock for
56
+ * deterministic timestamps.
57
+ */
58
+ readonly now?: () => number;
59
+ /**
60
+ * Optional sink for promotion-write failures. Doctor isolates write
61
+ * failures (a successful probe never becomes a Doctor failure on the
62
+ * back of a write error); when this sink is supplied, the failure is
63
+ * reported there so the dispatcher can surface it as a stderr notice
64
+ * without affecting the exit code. When omitted, write failures are
65
+ * silently swallowed.
66
+ */
67
+ readonly onPromotionError?: (providerId: ProviderId, error: unknown) => void;
68
+ /**
69
+ * Optional quota snapshot for the per-Provider `quota` summary
70
+ * (PB-T5 — Plan B). When supplied, each Provider entry embeds a
71
+ * `{ source, observedAt?, authoritative }` summary derived from its
72
+ * snapshot entry. When omitted, the `quota` field is omitted on
73
+ * every entry (backward-compatible with pre-PB-T5 callers). Doctor
74
+ * NEVER live-probes quota — it only reads the snapshot; the live
75
+ * probe belongs to the `quota` command. Under `--no-tools` the
76
+ * field still appears when a snapshot is available (a snapshot
77
+ * read is a local state read, not transport).
78
+ */
79
+ readonly quotaSnapshot?: QuotaState;
80
+ /**
81
+ * Optional verification records (Plan A — surfaced in Doctor by
82
+ * PB-T5). When supplied, each Provider entry embeds a
83
+ * `verification` summary mirroring the Provider's
84
+ * `config.providers[id].verification` record. The dispatcher maps
85
+ * the config-store `ProviderVerification` shape to the capability
86
+ * contract's `ProviderVerificationSummary` (structural twin — kept
87
+ * separate so the capability contract does not import
88
+ * `lib/config-store.ts`). When omitted, the field is omitted
89
+ * (backward-compatible).
90
+ */
91
+ readonly verificationRecords?: Partial<Record<ProviderId, ProviderVerificationSummary>>;
92
+ /**
93
+ * Optional staleness threshold for the per-Provider `quota`
94
+ * summary's `authoritative` flag. Defaults to
95
+ * {@link DEFAULT_QUOTA_STALE_THRESHOLD_MS} (10 min — Tavily's
96
+ * 10/10min key limit is the floor). Only consulted when
97
+ * `quotaSnapshot` is supplied.
98
+ */
99
+ readonly thresholdMs?: number;
39
100
  }
40
101
  /**
41
102
  * Build a schema-version-2 {@link DiagnosticsReport}. Inventory
@@ -45,6 +106,15 @@ export interface DoctorDiagnosticsDependencies {
45
106
  * configured-state evaluation. Otherwise each configured Provider is
46
107
  * probed through shared execution with settled collection, preserving
47
108
  * registry order and normalized redacted failures.
109
+ *
110
+ * PB-T5: when `deps.quotaSnapshot` is supplied, each entry carries a
111
+ * `quota` summary derived from the snapshot (source/freshness). When
112
+ * `deps.verificationRecords` is supplied, each entry carries a
113
+ * `verification` summary mirroring Plan A's config record. Both fields
114
+ * are omitted when their dependency is absent (backward-compatible).
115
+ * Doctor never live-probes quota — it only reads the snapshot. The
116
+ * `quota` field appears even under `--no-tools` (snapshot reads are
117
+ * local state, not transport).
48
118
  */
49
119
  export declare function buildDiagnosticsReport(deps: DoctorDiagnosticsDependencies): Promise<DiagnosticsReport>;
50
120
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAEV,iBAAiB,EAElB,MAAM,gCAAgC,CAAC;AAKxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAsB,MAAM,uBAAuB,CAAC;AAMhG,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,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;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AA6CD;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,6BAA6B,GAClC,OAAO,CAAC,iBAAiB,CAAC,CAiC5B;AA4CD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAKhE;AAMD,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACxD;AAED;;;;GAIG;AACH,wBAAsB,MAAM,CAC1B,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC,CAO3C;AAED,eAAO,MAAM,WAAW,QA+DhB,CAAC"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAEV,iBAAiB,EAGjB,2BAA2B,EAC5B,MAAM,gCAAgC,CAAC;AAKxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAsB,MAAM,uBAAuB,CAAC;AAChG,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,uBAAuB,CAAC;AAM/B,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,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;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,0BAA0B,CAAC;IAC3D;;;;OAIG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B;;;;;;;OAOG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7E;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,UAAU,CAAC;IACpC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,2BAA2B,CAAC,CAAC,CAAC;IACxF;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AA6CD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,6BAA6B,GAClC,OAAO,CAAC,iBAAiB,CAAC,CAiF5B;AAgED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAKhE;AAMD,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACxD;AAED;;;;GAIG;AACH,wBAAsB,MAAM,CAC1B,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC,CAO3C;AAED,eAAO,MAAM,WAAW,QAoEhB,CAAC"}
@@ -21,6 +21,7 @@ import { deriveCapabilityMatrix, diagnosticErrorFromError } from "../capabilitie
21
21
  import { executeProviderOperation } from "../lib/execution.js";
22
22
  import { UnsupportedCapabilityError } from "../lib/errors.js";
23
23
  import { redactSecrets, configuredSecrets } from "../lib/redact.js";
24
+ import { DEFAULT_QUOTA_STALE_THRESHOLD_MS, isQuotaSnapshotStale, } from "../lib/quota-store.js";
24
25
  function nodeMajor() {
25
26
  const [major] = process.versions.node.split(".");
26
27
  return parseInt(major, 10);
@@ -50,21 +51,78 @@ async function probeProvider(descriptor, env, sleep, random) {
50
51
  * configured-state evaluation. Otherwise each configured Provider is
51
52
  * probed through shared execution with settled collection, preserving
52
53
  * registry order and normalized redacted failures.
54
+ *
55
+ * PB-T5: when `deps.quotaSnapshot` is supplied, each entry carries a
56
+ * `quota` summary derived from the snapshot (source/freshness). When
57
+ * `deps.verificationRecords` is supplied, each entry carries a
58
+ * `verification` summary mirroring Plan A's config record. Both fields
59
+ * are omitted when their dependency is absent (backward-compatible).
60
+ * Doctor never live-probes quota — it only reads the snapshot. The
61
+ * `quota` field appears even under `--no-tools` (snapshot reads are
62
+ * local state, not transport).
53
63
  */
54
64
  export async function buildDiagnosticsReport(deps) {
55
65
  const secrets = configuredSecrets(deps.env);
66
+ const now = (deps.now ?? Date.now)();
67
+ const thresholdMs = deps.thresholdMs ?? DEFAULT_QUOTA_STALE_THRESHOLD_MS;
56
68
  const baseEntries = deps.descriptors.map((descriptor) => ({
57
69
  provider: descriptor.id,
58
70
  configured: descriptor.isConfigured(deps.env),
59
71
  capabilities: [...descriptor.capabilities()],
60
72
  }));
73
+ // PB-T5 — compute the additive `quota` and `verification` fields
74
+ // once per Provider. Both are pure lookups against injected state
75
+ // (snapshot/config records), never transport. Returned as a side
76
+ // table so the probe branches can attach them without re-reading.
77
+ const quotaFor = (provider) => {
78
+ if (!deps.quotaSnapshot)
79
+ return undefined;
80
+ const snapshot = deps.quotaSnapshot.quota[provider];
81
+ if (!snapshot) {
82
+ return { source: "none", authoritative: false };
83
+ }
84
+ return {
85
+ source: "snapshot",
86
+ observedAt: snapshot.observedAt,
87
+ authoritative: !isQuotaSnapshotStale(snapshot, now, thresholdMs),
88
+ };
89
+ };
90
+ const verificationFor = (provider) => deps.verificationRecords?.[provider];
61
91
  const providers = deps.noTools
62
92
  ? baseEntries.map((entry) => ({
63
93
  ...entry,
64
94
  status: "skipped",
65
95
  reason: entry.configured ? "tools-disabled" : "not-configured",
96
+ ...(quotaFor(entry.provider) !== undefined ? { quota: quotaFor(entry.provider) } : {}),
97
+ ...(verificationFor(entry.provider) !== undefined
98
+ ? { verification: verificationFor(entry.provider) }
99
+ : {}),
66
100
  }))
67
- : await probeEntries(baseEntries, deps, secrets);
101
+ : await probeEntries(baseEntries, deps, secrets, quotaFor, verificationFor);
102
+ // T3b — verification promotion (review item 10). After a successful
103
+ // probe, flip the matching Provider's `verification.status` from
104
+ // `unverified` to `verified`. Best-effort: a write failure is
105
+ // isolated through `onPromotionError` and never turns a successful
106
+ // probe into a Doctor failure. Only `status: "ok"` records are
107
+ // promotable; skipped, failed, no-tools, and network-deferred
108
+ // records are not (the probe result is authoritative). Awaited so a
109
+ // subsequent read after Doctor completion is deterministic.
110
+ if (deps.verificationPromoter) {
111
+ const checkedAt = now;
112
+ for (const entry of providers) {
113
+ if (entry.status !== "ok")
114
+ continue;
115
+ try {
116
+ await deps.verificationPromoter.promote(entry.provider, checkedAt);
117
+ }
118
+ catch (error) {
119
+ // Isolated: a write failure does not propagate. The sink (when
120
+ // supplied) lets the dispatcher surface it as a stderr notice
121
+ // without affecting the exit code.
122
+ deps.onPromotionError?.(entry.provider, error);
123
+ }
124
+ }
125
+ }
68
126
  // L1 fix: the cache summary is formatted by the CLI handler and
69
127
  // threaded through deps.cacheSummary. The report builder only embeds
70
128
  // it; it never reads `cacheStats()` itself.
@@ -87,23 +145,41 @@ export async function buildDiagnosticsReport(deps) {
87
145
  * NOT fail the report. A configured probe failure is normalized and
88
146
  * recursively redacted before joining the report; successful entries
89
147
  * are preserved alongside it.
148
+ *
149
+ * PB-T5: the additive `quota` and `verification` fields are attached
150
+ * to EVERY entry (success/skipped/error) via the injected lookup
151
+ * closures — they are pure state reads, not transport, so they appear
152
+ * regardless of the probe outcome. A failed probe with a fresh
153
+ * snapshot still surfaces the snapshot summary so a user can see both
154
+ * the probe failure and the quota state.
90
155
  */
91
- async function probeEntries(baseEntries, deps, secrets) {
156
+ async function probeEntries(baseEntries, deps, secrets, quotaFor, verificationFor) {
92
157
  const configuredIndexes = baseEntries
93
158
  .map((entry, index) => (entry.configured ? index : -1))
94
159
  .filter((index) => index >= 0);
95
160
  const settled = await Promise.allSettled(configuredIndexes.map((index) => probeProvider(deps.descriptors[index], deps.env, deps.sleep, deps.random)));
96
161
  let settledCursor = 0;
97
162
  return baseEntries.map((entry) => {
163
+ const quota = quotaFor(entry.provider);
164
+ const verification = verificationFor(entry.provider);
165
+ const additive = {
166
+ ...(quota !== undefined ? { quota } : {}),
167
+ ...(verification !== undefined ? { verification } : {}),
168
+ };
98
169
  if (!entry.configured) {
99
- return { ...entry, status: "skipped", reason: "not-configured" };
170
+ return {
171
+ ...entry,
172
+ status: "skipped",
173
+ reason: "not-configured",
174
+ ...additive,
175
+ };
100
176
  }
101
177
  const result = settled[settledCursor++];
102
178
  if (result.status === "fulfilled") {
103
- return { ...entry, status: "ok" };
179
+ return { ...entry, status: "ok", ...additive };
104
180
  }
105
181
  const redacted = redactSecrets(diagnosticErrorFromError(result.reason), secrets);
106
- return { ...entry, status: "error", error: redacted };
182
+ return { ...entry, status: "error", error: redacted, ...additive };
107
183
  });
108
184
  }
109
185
  // ---------------------------------------------------------------------------
@@ -168,21 +244,26 @@ metadata all advertise reader; MiniMax advertises and supplies
168
244
  neither. The capabilityMatrix field lists Z.AI, Tavily, and Exa for
169
245
  reader.
170
246
 
171
- Crawl and Map are Provider Capabilities owned by Tavily.
172
- Z.AI, MiniMax, and Exa do not advertise either; the capabilityMatrix
173
- lists Tavily alone for each. Research is supplied by Tavily and Exa.
174
- Selecting Z.AI or MiniMax for crawl, map, or research returns
175
- UNSUPPORTED_CAPABILITY with no fallback.
247
+ Crawl and Map are Provider Capabilities owned by Tavily and Firecrawl.
248
+ Z.AI, MiniMax, Exa, and Brave do not advertise either; the
249
+ capabilityMatrix lists Tavily and Firecrawl for each. Research is
250
+ supplied by Tavily and Exa. By default (0.11.0+) Provider fallback
251
+ emits a stderr notice and silently reroutes to the next eligible
252
+ configured supplier when a non-supplier is selected; under
253
+ --no-fallback (or SCOUTLINE_NO_FALLBACK=1) the preflight surfaces
254
+ UNSUPPORTED_CAPABILITY for the selected non-supplier.
176
255
 
177
256
  Public 'repo' and 'read' commands participate in Provider selection.
178
257
  They honour --provider / SCOUTLINE_PROVIDER / the default zai, route
179
258
  through the matching Adapter's Repository / Reader Capability, and
180
259
  return UNSUPPORTED_CAPABILITY when the selected Provider does not
181
- advertise the requested capability (e.g. 'repo --provider minimax' or
182
- 'read --provider minimax' fail without falling back to Z.AI). A
183
- supported-but-unconfigured Provider returns ConfigurationError; a
184
- supported-and-configured Provider dispatches through the corresponding
185
- Adapter.
260
+ advertise the requested capability (e.g. 'repo --provider minimax'
261
+ or 'read --provider minimax' trigger Provider fallback by default in
262
+ 0.11.0+; under --no-fallback (or SCOUTLINE_NO_FALLBACK=1) the
263
+ preflight surfaces UNSUPPORTED_CAPABILITY before any Adapter work).
264
+ A supported-but-unconfigured Provider returns ConfigurationError; a
265
+ supported-and-configured Provider dispatches through the
266
+ corresponding Adapter.
186
267
 
187
268
  Options:
188
269
  --no-tools Skip every connectivity probe (metadata-only). Under
@@ -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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"}
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Init command — interactive onboarding wizard (T3a + T3b — Plan A).
3
+ *
4
+ * This module owns the interactive `scoutline init` flow:
5
+ * - State detection (absent / corrupt / already-onboarded / fresh).
6
+ * - Provider checklist (registry-derived; none pre-checked — equal weight).
7
+ * - Per-provider ask-key-first → hidden input → inline single-attempt
8
+ * validation through `DiagnosticsCapability.invoke({probe:true})` against
9
+ * an EPHEMERAL resolved env (never persists, never mutates `process.env`).
10
+ * - Honest broad classification of probe failures: key-problems
11
+ * (`AuthError`/`ApiError`) reject + re-prompt; `NetworkError` offers
12
+ * save-unverified. No false-precise "wrong/disabled/mismatch" subtypes
13
+ * are inferred from message text — the taxonomy only distinguishes
14
+ * `AuthError`/`ApiError`/`NetworkError`.
15
+ * - Credit-cost disclosure before any paid-provider probe.
16
+ * - Fallback preference question.
17
+ * - Atomic config write (T1 `writeConfig` primitive) + redacted summary.
18
+ *
19
+ * T3b additions:
20
+ * - **Re-config menu** when an already-valid config exists: edit a
21
+ * Provider key, add a Provider, remove a Provider, change the
22
+ * fallback preference, re-run the full wizard, or cancel. Editing
23
+ * a Provider key resets `verification.status` to `unverified`
24
+ * (Doctor re-promotes after a successful probe).
25
+ * - **Corrupt-config repair**: tolerant `inspectConfig` distinguishes
26
+ * `absent` / `valid` / `corrupt`. On `corrupt` the wizard offers to
27
+ * back up the live file and rewrite a fresh config — `init` is the
28
+ * recovery path, not a victim of corruption.
29
+ * - **Formal non-TTY refuse**: without an interactive terminal the
30
+ * wizard refuses before any prompt, prints env instructions and
31
+ * the `init` hint, and exits.
32
+ * - **Stale-env-after-import warning**: when the user imports a key
33
+ * from env, the wizard notes that the env value will continue to
34
+ * take precedence (env > file in the runtime precedence rule) —
35
+ * the wizard cannot turn off the env value for the user.
36
+ * - **`hintShown` reset on re-init**: a re-config or fresh write
37
+ * resets the env-only hint marker so a user who later switches to
38
+ * env-only usage sees the hint once again.
39
+ *
40
+ * Boundary rules:
41
+ * - No Provider transport is constructed outside the per-provider probe;
42
+ * the candidate credential lives only in the ephemeral env until the
43
+ * final atomic write.
44
+ * - All prompt IO flows through the {@link InitPrompts} seam; no direct
45
+ * `process.stdin` / `process.stdout` reads in this module. Production
46
+ * wires `@inquirer/prompts`; tests inject scripted doubles.
47
+ * - Registration links render BOTH a terminal hyperlink AND the literal
48
+ * URL text so captured / non-hyperlink output stays usable.
49
+ * - No selection work (Plan B); the wizard writes at most one
50
+ * `fallbackEnabled` flag and per-Provider records.
51
+ */
52
+ import type { ConfigInspection, ScoutlineConfig, WriteConfigOptions } from "../lib/config-store.js";
53
+ import type { ProviderDescriptor } from "../providers/types.js";
54
+ /**
55
+ * Help text for `scoutline init --help`. T3b completes the wizard's
56
+ * lifecycle (re-config menu, corrupt-config repair, formal non-TTY
57
+ * refuse), so the T3a PREVIEW caveat is dropped — the public claim of
58
+ * a complete `init` is now accurate.
59
+ */
60
+ export declare const INIT_HELP: string;
61
+ /**
62
+ * Multi-select prompt choice for the provider checklist. `value` is the
63
+ * provider id; `description` carries env-detected and credit-cost hints
64
+ * surfaced in the choice description column.
65
+ */
66
+ export interface InitChoice<T> {
67
+ readonly value: T;
68
+ readonly name: string;
69
+ readonly description?: string;
70
+ /**
71
+ * Pre-checked state. The provider checklist NEVER pre-checks (equal
72
+ * weight); this field exists for forward compatibility with T3b.
73
+ */
74
+ readonly checked?: boolean;
75
+ }
76
+ /**
77
+ * Injectable prompt IO seam. Production wires `@inquirer/prompts` via
78
+ * {@link createInquirerPrompts}; tests inject scripted doubles that
79
+ * never touch a real TTY.
80
+ *
81
+ * The shape mirrors the four prompt types the wizard uses: multi-select
82
+ * checkbox, yes/no confirm, hidden password, and free-text input.
83
+ */
84
+ export interface InitPrompts {
85
+ /**
86
+ * Multi-select. Returns the chosen values in selection order. Throws
87
+ * on user cancel (Ctrl+C / EOF) — the caller catches and treats as
88
+ * no-write.
89
+ */
90
+ checkbox<T>(message: string, choices: readonly InitChoice<T>[]): Promise<T[]>;
91
+ /**
92
+ * Single-select menu. Returns the chosen value. Throws on user
93
+ * cancel. Used by the T3b re-config menu (edit/add/remove/fallback/
94
+ * rerun/cancel) and the corrupt-config-repair prompt.
95
+ */
96
+ select<T>(message: string, choices: readonly InitChoice<T>[]): Promise<T>;
97
+ /** Yes/no. `defaultYes` carries the documented default ([Y/n] vs [y/N]). */
98
+ confirm(message: string, defaultYes: boolean): Promise<boolean>;
99
+ /** Hidden password input. Returns the trimmed value (possibly empty). */
100
+ password(message: string): Promise<string>;
101
+ /** Free-text input. Used for follow-up re-prompt loops. */
102
+ input(message: string): Promise<string>;
103
+ }
104
+ /**
105
+ * Injectable config-store seam. Production wires the real
106
+ * {@link inspectConfig} / {@link writeConfig}; tests inject in-memory or
107
+ * temp-dir-backed doubles so the wizard is hermetic — no real
108
+ * `~/.scoutline/config.json` I/O during tests.
109
+ */
110
+ export interface InitConfigStore {
111
+ inspect(): Promise<ConfigInspection>;
112
+ write(config: ScoutlineConfig, options?: WriteConfigOptions): Promise<void>;
113
+ }
114
+ /**
115
+ * Wrap the real `inspectConfig` / `writeConfig` pair as an
116
+ * {@link InitConfigStore}. The default options object is captured per-call
117
+ * so the wizard can pass a temp `filePath` / atomic options through
118
+ * unchanged in tests.
119
+ */
120
+ export declare function createDefaultConfigStore(options?: WriteConfigOptions): InitConfigStore;
121
+ /**
122
+ * Injectable dependencies for the init wizard. Production supplies the
123
+ * real defaults via the composition root in `src/index.ts`; tests pass
124
+ * in-memory / temp-dir doubles for hermeticity.
125
+ */
126
+ export interface InitDependencies {
127
+ /** The provider registry — canonical checklist source/order. */
128
+ readonly descriptors: readonly ProviderDescriptor[];
129
+ /** Injectable prompt IO seam. */
130
+ readonly prompts: InitPrompts;
131
+ /** Injectable config-store seam. */
132
+ readonly configStore: InitConfigStore;
133
+ /** Injectable environment view (for env-key-import detection). */
134
+ readonly env: NodeJS.ProcessEnv;
135
+ /**
136
+ * Injectable clock, used for verification `checkedAt` timestamps.
137
+ * Production wires `Date.now`; tests inject a fixed clock.
138
+ */
139
+ readonly now: () => number;
140
+ /** Whether stdin is an interactive TTY. Non-TTY gets a graceful guard. */
141
+ readonly stdinIsTTY: boolean;
142
+ /** Progress / disclosure sink. */
143
+ readonly writeStderr: (value: string) => void;
144
+ /** Final-summary sink (the only stdout write in the wizard). */
145
+ readonly writeStdout: (value: string) => void;
146
+ }
147
+ /**
148
+ * Run the interactive init wizard. Performs the T3b state dispatch:
149
+ * - non-TTY → refuse before any prompt + exit 1.
150
+ * - corrupt config → offer backup + rewrite (init is the recovery path).
151
+ * - valid + already-onboarded → re-config menu.
152
+ * - valid + empty / absent → fresh-onboarding flow.
153
+ *
154
+ * Returns the exit code:
155
+ * - 0 on success, re-config applied, or already-onboarded + Cancel.
156
+ * - 1 on user cancel, non-TTY refuse, write failure, or declined repair.
157
+ */
158
+ export declare function runFreshOnboarding(deps: InitDependencies): Promise<number>;
159
+ /**
160
+ * Build the production {@link InitPrompts} from `@inquirer/prompts`. The
161
+ * adapter:
162
+ * - Rewires the inquirer output stream to `process.stderr` so the
163
+ * wizard keeps the codebase's data-only-stdout contract (the final
164
+ * summary line is the only stdout write).
165
+ * - Maps the four wizard prompt shapes onto the inquirer calls.
166
+ *
167
+ * Tests never call this — they inject a scripted {@link InitPrompts}
168
+ * double instead, so test runs are fully hermetic and do not need a TTY.
169
+ */
170
+ export declare function createInquirerPrompts(): InitPrompts;
171
+ /**
172
+ * Top-level init handler. Wired into the dispatch switch in `index.ts`.
173
+ *
174
+ * - `--help` / `-h` prints {@link INIT_HELP} to stdout and returns 0.
175
+ * - Otherwise dispatches to {@link runFreshOnboarding}.
176
+ *
177
+ * The CLI arg list is the same shape every other handler receives; the
178
+ * handler only inspects it for the help flag.
179
+ */
180
+ export declare function handleInitWithHelp(args: readonly string[], deps: InitDependencies): Promise<number>;
181
+ /**
182
+ * Backwards-compatible alias used by the dispatch switch. Tests that drive
183
+ * the wizard directly pass an empty arg list.
184
+ */
185
+ export declare function handleInit(deps: InitDependencies): Promise<number>;
186
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}