scoutline 0.2.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 (110) hide show
  1. package/README.md +240 -18
  2. package/dist/capabilities/diagnostics.d.ts +70 -32
  3. package/dist/capabilities/diagnostics.d.ts.map +1 -1
  4. package/dist/capabilities/diagnostics.js +97 -46
  5. package/dist/capabilities/diagnostics.js.map +1 -1
  6. package/dist/capabilities/reader.d.ts +227 -0
  7. package/dist/capabilities/reader.d.ts.map +1 -0
  8. package/dist/capabilities/reader.js +100 -0
  9. package/dist/capabilities/reader.js.map +1 -0
  10. package/dist/capabilities/repository.d.ts +221 -0
  11. package/dist/capabilities/repository.d.ts.map +1 -0
  12. package/dist/capabilities/repository.js +172 -0
  13. package/dist/capabilities/repository.js.map +1 -0
  14. package/dist/commands/cache.d.ts +106 -0
  15. package/dist/commands/cache.d.ts.map +1 -0
  16. package/dist/commands/cache.js +203 -0
  17. package/dist/commands/cache.js.map +1 -0
  18. package/dist/commands/doctor.d.ts +17 -6
  19. package/dist/commands/doctor.d.ts.map +1 -1
  20. package/dist/commands/doctor.js +42 -17
  21. package/dist/commands/doctor.js.map +1 -1
  22. package/dist/commands/read.d.ts +74 -14
  23. package/dist/commands/read.d.ts.map +1 -1
  24. package/dist/commands/read.js +257 -117
  25. package/dist/commands/read.js.map +1 -1
  26. package/dist/commands/repo.d.ts +53 -7
  27. package/dist/commands/repo.d.ts.map +1 -1
  28. package/dist/commands/repo.js +104 -123
  29. package/dist/commands/repo.js.map +1 -1
  30. package/dist/commands/repository-explorer.d.ts +147 -0
  31. package/dist/commands/repository-explorer.d.ts.map +1 -0
  32. package/dist/commands/repository-explorer.js +550 -0
  33. package/dist/commands/repository-explorer.js.map +1 -0
  34. package/dist/index.d.ts +20 -0
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +209 -34
  37. package/dist/index.js.map +1 -1
  38. package/dist/lib/cache.d.ts +123 -18
  39. package/dist/lib/cache.d.ts.map +1 -1
  40. package/dist/lib/cache.js +324 -49
  41. package/dist/lib/cache.js.map +1 -1
  42. package/dist/lib/errors.d.ts +24 -1
  43. package/dist/lib/errors.d.ts.map +1 -1
  44. package/dist/lib/errors.js +33 -2
  45. package/dist/lib/errors.js.map +1 -1
  46. package/dist/lib/execution.d.ts +119 -5
  47. package/dist/lib/execution.d.ts.map +1 -1
  48. package/dist/lib/execution.js +216 -10
  49. package/dist/lib/execution.js.map +1 -1
  50. package/dist/lib/index.d.ts +1 -1
  51. package/dist/lib/index.d.ts.map +1 -1
  52. package/dist/lib/index.js +1 -1
  53. package/dist/lib/index.js.map +1 -1
  54. package/dist/lib/mcp-client.d.ts +29 -5
  55. package/dist/lib/mcp-client.d.ts.map +1 -1
  56. package/dist/lib/mcp-client.js +88 -88
  57. package/dist/lib/mcp-client.js.map +1 -1
  58. package/dist/lib/tool-cache.d.ts +86 -0
  59. package/dist/lib/tool-cache.d.ts.map +1 -0
  60. package/dist/lib/tool-cache.js +123 -0
  61. package/dist/lib/tool-cache.js.map +1 -0
  62. package/dist/providers/minimax/adapter.d.ts +6 -4
  63. package/dist/providers/minimax/adapter.d.ts.map +1 -1
  64. package/dist/providers/minimax/adapter.js +64 -57
  65. package/dist/providers/minimax/adapter.js.map +1 -1
  66. package/dist/providers/minimax/coding-plan-client.d.ts +60 -0
  67. package/dist/providers/minimax/coding-plan-client.d.ts.map +1 -0
  68. package/dist/providers/minimax/coding-plan-client.js +204 -0
  69. package/dist/providers/minimax/coding-plan-client.js.map +1 -0
  70. package/dist/providers/minimax/media.d.ts +60 -6
  71. package/dist/providers/minimax/media.d.ts.map +1 -1
  72. package/dist/providers/minimax/media.js +147 -7
  73. package/dist/providers/minimax/media.js.map +1 -1
  74. package/dist/providers/minimax/quota-client.d.ts +13 -6
  75. package/dist/providers/minimax/quota-client.d.ts.map +1 -1
  76. package/dist/providers/minimax/quota-client.js +5 -0
  77. package/dist/providers/minimax/quota-client.js.map +1 -1
  78. package/dist/providers/minimax/vision-attestations.d.ts +23 -0
  79. package/dist/providers/minimax/vision-attestations.d.ts.map +1 -1
  80. package/dist/providers/minimax/vision-attestations.js +35 -10
  81. package/dist/providers/minimax/vision-attestations.js.map +1 -1
  82. package/dist/providers/minimax/vision-conformance.d.ts +8 -6
  83. package/dist/providers/minimax/vision-conformance.d.ts.map +1 -1
  84. package/dist/providers/minimax/vision-conformance.js +8 -6
  85. package/dist/providers/minimax/vision-conformance.js.map +1 -1
  86. package/dist/providers/minimax/vision-revisions.d.ts +8 -1
  87. package/dist/providers/minimax/vision-revisions.d.ts.map +1 -1
  88. package/dist/providers/minimax/vision-revisions.js +13 -6
  89. package/dist/providers/minimax/vision-revisions.js.map +1 -1
  90. package/dist/providers/selection.d.ts +3 -3
  91. package/dist/providers/selection.js +3 -3
  92. package/dist/providers/types.d.ts +66 -32
  93. package/dist/providers/types.d.ts.map +1 -1
  94. package/dist/providers/types.js.map +1 -1
  95. package/dist/providers/zai/adapter.d.ts.map +1 -1
  96. package/dist/providers/zai/adapter.js +71 -5
  97. package/dist/providers/zai/adapter.js.map +1 -1
  98. package/dist/providers/zai/encoded-error.d.ts +90 -0
  99. package/dist/providers/zai/encoded-error.d.ts.map +1 -0
  100. package/dist/providers/zai/encoded-error.js +169 -0
  101. package/dist/providers/zai/encoded-error.js.map +1 -0
  102. package/dist/providers/zai/reader.d.ts +82 -0
  103. package/dist/providers/zai/reader.d.ts.map +1 -0
  104. package/dist/providers/zai/reader.js +490 -0
  105. package/dist/providers/zai/reader.js.map +1 -0
  106. package/dist/providers/zai/repository.d.ts +76 -0
  107. package/dist/providers/zai/repository.d.ts.map +1 -0
  108. package/dist/providers/zai/repository.js +715 -0
  109. package/dist/providers/zai/repository.js.map +1 -0
  110. package/package.json +3 -3
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Provider-neutral Repository Capability Contract (DESIGN.md §18,
3
+ * PRD FR-081, FR-083, FR-086, FR-089; NFR-004, NFR-006, NFR-007).
4
+ *
5
+ * This module declares the three repository operations (Search, Read File,
6
+ * Directory Listing), their provider-neutral request, identity, cache, and
7
+ * result shapes, and the total normalized cache decoders used by shared
8
+ * execution. It imports NO concrete Provider, transport, or Adapter. It
9
+ * does no path canonicalization, raw ZRead parsing, Provider field
10
+ * mapping, Provider selection, retries, or presentation.
11
+ *
12
+ * Scope of this file:
13
+ * - request, operation, cache-identity, and result type contracts;
14
+ * - total decoders for the three cacheable normalized result types
15
+ * (`decodeRepositorySearch`, `decodeRepositoryFile`,
16
+ * `decodeRepositoryDirectoryListing`);
17
+ * - the discriminated `RepositoryOperationKind` union shared by shared
18
+ * execution, retry policy, and diagnostics.
19
+ *
20
+ * P6-02 introduces ONLY this contract and the decoders. P6-03 supplies
21
+ * shared execution, P6-04 the Z.AI Adapter, and P6-05 the Explorer. The
22
+ * capability surface here is the boundary between those tickets and the
23
+ * commands; nothing in this file is allowed to widen the boundary.
24
+ */
25
+ // ===========================================================================
26
+ // Total normalized cache decoders
27
+ // ===========================================================================
28
+ //
29
+ // Every decoder accepts `unknown`, returns the typed result or `null`,
30
+ // never throws, and never trusts a generic cast. The shape contract is
31
+ // local; the three adapters in P6-04 are responsible for producing
32
+ // values that conform to the Result interfaces.
33
+ //
34
+ // Rules encoded in each decoder:
35
+ // - reject primitives and arrays at the top level (results are objects);
36
+ // - reject required scalar fields that are missing or of the wrong
37
+ // type;
38
+ // - reject arrays that are themselves nullable or contain malformed
39
+ // items — partial goodness is NEVER a success;
40
+ // - preserve exact order, exact strings, exact numeric values;
41
+ // - accept an empty array as valid (a future Adapter contract).
42
+ function isPlainObject(value) {
43
+ return typeof value === "object" && value !== null && !Array.isArray(value);
44
+ }
45
+ /**
46
+ * Type guard for a non-empty string. `""` is rejected.
47
+ */
48
+ function isNonEmptyString(value) {
49
+ return typeof value === "string" && value.length > 0;
50
+ }
51
+ /**
52
+ * Type guard for a non-negative finite integer (0 or positive, no
53
+ * fractional part). `Number.NaN`, `Infinity`, and negatives are rejected.
54
+ */
55
+ function isNonNegativeFiniteInteger(value) {
56
+ return (typeof value === "number" &&
57
+ Number.isFinite(value) &&
58
+ Number.isInteger(value) &&
59
+ value >= 0);
60
+ }
61
+ /**
62
+ * Decode a Search result from the cache. Returns the canonical
63
+ * `RepositorySearchResult` on success, `null` for any malformed value.
64
+ */
65
+ export function decodeRepositorySearch(value) {
66
+ if (!isPlainObject(value))
67
+ return null;
68
+ if (value.schemaVersion !== 1)
69
+ return null;
70
+ if (typeof value.repository !== "string")
71
+ return null;
72
+ if (typeof value.query !== "string")
73
+ return null;
74
+ const language = value.language;
75
+ if (language !== "en" && language !== "zh")
76
+ return null;
77
+ if (typeof value.truncated !== "boolean")
78
+ return null;
79
+ if (!isNonNegativeFiniteInteger(value.originalTextLength))
80
+ return null;
81
+ const rawExcerpts = value.excerpts;
82
+ if (!Array.isArray(rawExcerpts))
83
+ return null;
84
+ const excerpts = [];
85
+ for (const item of rawExcerpts) {
86
+ if (!isPlainObject(item))
87
+ return null;
88
+ if (typeof item.text !== "string")
89
+ return null;
90
+ excerpts.push({ text: item.text });
91
+ }
92
+ return {
93
+ schemaVersion: 1,
94
+ repository: value.repository,
95
+ query: value.query,
96
+ language,
97
+ excerpts,
98
+ truncated: value.truncated,
99
+ originalTextLength: value.originalTextLength,
100
+ };
101
+ }
102
+ /**
103
+ * Decode a File result from the cache. Returns the canonical
104
+ * `RepositoryFileResult` on success, `null` otherwise. `path` MUST be
105
+ * non-empty — File is always non-root; `path: ""` is rejected here
106
+ * without performing any other path canonicalization.
107
+ */
108
+ export function decodeRepositoryFile(value) {
109
+ if (!isPlainObject(value))
110
+ return null;
111
+ if (value.schemaVersion !== 1)
112
+ return null;
113
+ if (typeof value.repository !== "string")
114
+ return null;
115
+ if (!isNonEmptyString(value.path))
116
+ return null;
117
+ if (typeof value.content !== "string")
118
+ return null;
119
+ if (typeof value.truncated !== "boolean")
120
+ return null;
121
+ if (!isNonNegativeFiniteInteger(value.originalContentLength))
122
+ return null;
123
+ return {
124
+ schemaVersion: 1,
125
+ repository: value.repository,
126
+ path: value.path,
127
+ content: value.content,
128
+ truncated: value.truncated,
129
+ originalContentLength: value.originalContentLength,
130
+ };
131
+ }
132
+ /**
133
+ * Decode a Directory Listing from the cache. Returns the canonical
134
+ * `RepositoryDirectoryListing` on success, `null` otherwise. The
135
+ * listing's own `path` may be `""` (root); every entry's `name` and
136
+ * `path` MUST be non-empty. Empty entries arrays are valid (a future
137
+ * Adapter contract). Each entry preserves Provider sibling order
138
+ * verbatim.
139
+ */
140
+ export function decodeRepositoryDirectoryListing(value) {
141
+ if (!isPlainObject(value))
142
+ return null;
143
+ if (typeof value.repository !== "string")
144
+ return null;
145
+ if (typeof value.path !== "string")
146
+ return null;
147
+ const rawEntries = value.entries;
148
+ if (!Array.isArray(rawEntries))
149
+ return null;
150
+ const entries = [];
151
+ for (const item of rawEntries) {
152
+ if (!isPlainObject(item))
153
+ return null;
154
+ if (!isNonEmptyString(item.name))
155
+ return null;
156
+ if (!isNonEmptyString(item.path))
157
+ return null;
158
+ if (item.kind !== "file" && item.kind !== "directory")
159
+ return null;
160
+ entries.push({
161
+ name: item.name,
162
+ path: item.path,
163
+ kind: item.kind,
164
+ });
165
+ }
166
+ return {
167
+ repository: value.repository,
168
+ path: value.path,
169
+ entries,
170
+ };
171
+ }
172
+ //# sourceMappingURL=repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/capabilities/repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Cache command — local cache inspection and clearing
3
+ * (Cache Module Unification Ticket 03).
4
+ *
5
+ * The command is presentation-only: it receives already-resolved stats
6
+ * or clear results through injected dependencies and wraps them with a
7
+ * TTY presentation override. Directory resolution, env-var policy, and
8
+ * on-disk I/O live in `src/lib/cache.ts` (Ticket 01). The dispatcher
9
+ * (`src/index.ts`) wires production to the real `cacheStats()` and
10
+ * `clearAllCaches()` and threads them through these dependencies; tests
11
+ * inject doubles.
12
+ *
13
+ * Output format (core-flows artifact):
14
+ *
15
+ * ```text
16
+ * Cache directory: ~/.scoutline/
17
+ * Status: enabled (TTL 24h, cap 100MB)
18
+ *
19
+ * Response cache:
20
+ * Entries: 47
21
+ * Size: 12.3 MB
22
+ *
23
+ * Tool cache:
24
+ * Entries: 1
25
+ * Size: 8.2 KB
26
+ * ```
27
+ *
28
+ * L1 fix: Doctor's one-line cache summary is computed from the same
29
+ * `cacheStats()` shape but formatted by the dispatcher, not by this
30
+ * module. See `formatDoctorCacheSummary`.
31
+ */
32
+ import type { CommandResult } from "../command-invocation.js";
33
+ export interface CacheStatsReport {
34
+ readonly dir: string;
35
+ readonly enabled: boolean;
36
+ readonly ttlMs: number;
37
+ readonly sizeCapBytes: number;
38
+ readonly responseCache: {
39
+ readonly entries: number;
40
+ readonly totalBytes: number;
41
+ };
42
+ readonly toolCache: {
43
+ readonly entries: number;
44
+ readonly totalBytes: number;
45
+ };
46
+ }
47
+ export interface CacheClearReport {
48
+ readonly responsesCleared: number;
49
+ readonly toolsCleared: number;
50
+ readonly bytesFreed: number;
51
+ }
52
+ /**
53
+ * Format a byte count as e.g. `"12.3 MB"`, `"8.2 KB"`, `"510 B"`. Used
54
+ * by `cache stats` presentation and by Doctor's one-line summary. Pure:
55
+ * no I/O, no env reads.
56
+ */
57
+ export declare function formatBytes(bytes: number): string;
58
+ /**
59
+ * Format a TTL in ms as `"24h"`, `"30m"`, or `"60s"`. Chooses the
60
+ * largest whole-unit that divides the input evenly so the default
61
+ * 24h renders as `24h` rather than `86400000ms`.
62
+ */
63
+ export declare function formatTtl(ms: number): string;
64
+ /**
65
+ * Format the inventory of both caches as a multi-line TTY block per
66
+ * the core-flows artifact. Used as the TTY/compact/markdown/refs
67
+ * presentation for `cache stats`. Pure.
68
+ */
69
+ export declare function formatCacheStats(stats: CacheStatsReport): string;
70
+ /**
71
+ * Format a clear result as a one-line TTY notice.
72
+ */
73
+ export declare function formatCacheClear(result: CacheClearReport): string;
74
+ /**
75
+ * Format the one-line Doctor cache summary from a `cacheStats()` value.
76
+ * The dispatcher calls this before invoking `buildDiagnosticsReport`;
77
+ * the report builder embeds the result verbatim. Examples:
78
+ *
79
+ * ```text
80
+ * Cache: enabled, 47 response entries (12.3 MB), 1 tool entry (8.2 KB), ~/.scoutline/
81
+ * Cache: disabled
82
+ * ```
83
+ *
84
+ * Pure: never reads env or touches the filesystem.
85
+ */
86
+ export declare function formatDoctorCacheSummary(stats: CacheStatsReport): string;
87
+ export interface CacheStatsDependencies {
88
+ readonly getStats: () => Promise<CacheStatsReport>;
89
+ }
90
+ export interface CacheClearDependencies {
91
+ readonly clear: () => Promise<CacheClearReport>;
92
+ }
93
+ /**
94
+ * Run the `cache stats` subcommand. Returns the inventory as base data
95
+ * with a TTY presentation override. Exit code is always 0 on success;
96
+ * I/O failures propagate as ordinary errors through the dispatcher.
97
+ */
98
+ export declare function cacheStatsCommand(deps: CacheStatsDependencies): Promise<CommandResult<CacheStatsReport>>;
99
+ /**
100
+ * Run the `cache clear` subcommand. Returns the count of cleared
101
+ * entries and bytes freed as base data with a TTY presentation
102
+ * override.
103
+ */
104
+ export declare function cacheClearCommand(deps: CacheClearDependencies): Promise<CommandResult<CacheClearReport>>;
105
+ export declare const CACHE_HELP: string;
106
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/commands/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,0BAA0B,CAAC;AAS9E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,QAAQ,CAAC,SAAS,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/E;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAMD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWjD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAK5C;AAkBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAmBhE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAMjE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAOxE;AAMD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACjD;AAkBD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAO1C;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAO1C;AAED,eAAO,MAAM,UAAU,QA8Bf,CAAC"}
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Cache command — local cache inspection and clearing
3
+ * (Cache Module Unification Ticket 03).
4
+ *
5
+ * The command is presentation-only: it receives already-resolved stats
6
+ * or clear results through injected dependencies and wraps them with a
7
+ * TTY presentation override. Directory resolution, env-var policy, and
8
+ * on-disk I/O live in `src/lib/cache.ts` (Ticket 01). The dispatcher
9
+ * (`src/index.ts`) wires production to the real `cacheStats()` and
10
+ * `clearAllCaches()` and threads them through these dependencies; tests
11
+ * inject doubles.
12
+ *
13
+ * Output format (core-flows artifact):
14
+ *
15
+ * ```text
16
+ * Cache directory: ~/.scoutline/
17
+ * Status: enabled (TTL 24h, cap 100MB)
18
+ *
19
+ * Response cache:
20
+ * Entries: 47
21
+ * Size: 12.3 MB
22
+ *
23
+ * Tool cache:
24
+ * Entries: 1
25
+ * Size: 8.2 KB
26
+ * ```
27
+ *
28
+ * L1 fix: Doctor's one-line cache summary is computed from the same
29
+ * `cacheStats()` shape but formatted by the dispatcher, not by this
30
+ * module. See `formatDoctorCacheSummary`.
31
+ */
32
+ // ---------------------------------------------------------------------------
33
+ // Pure formatting helpers
34
+ // ---------------------------------------------------------------------------
35
+ /**
36
+ * Format a byte count as e.g. `"12.3 MB"`, `"8.2 KB"`, `"510 B"`. Used
37
+ * by `cache stats` presentation and by Doctor's one-line summary. Pure:
38
+ * no I/O, no env reads.
39
+ */
40
+ export function formatBytes(bytes) {
41
+ if (!Number.isFinite(bytes) || bytes < 0)
42
+ return "0 B";
43
+ if (bytes < 1024)
44
+ return `${bytes} B`;
45
+ const units = ["KB", "MB", "GB", "TB"];
46
+ let value = bytes / 1024;
47
+ let unitIndex = 0;
48
+ while (value >= 1024 && unitIndex < units.length - 1) {
49
+ value /= 1024;
50
+ unitIndex += 1;
51
+ }
52
+ return `${value.toFixed(1)} ${units[unitIndex]}`;
53
+ }
54
+ /**
55
+ * Format a TTL in ms as `"24h"`, `"30m"`, or `"60s"`. Chooses the
56
+ * largest whole-unit that divides the input evenly so the default
57
+ * 24h renders as `24h` rather than `86400000ms`.
58
+ */
59
+ export function formatTtl(ms) {
60
+ if (!Number.isFinite(ms) || ms <= 0)
61
+ return "0s";
62
+ if (ms % 3_600_000 === 0)
63
+ return `${ms / 3_600_000}h`;
64
+ if (ms % 60_000 === 0)
65
+ return `${ms / 60_000}m`;
66
+ return `${Math.round(ms / 1000)}s`;
67
+ }
68
+ /**
69
+ * Format the size cap (bytes) as e.g. `"100MB"`. Mirrors the
70
+ * `SCOUTLINE_CACHE_SIZE_MB` env-var spelling so the operator surface
71
+ * matches the documentation.
72
+ */
73
+ function formatSizeCap(bytes) {
74
+ return `${Math.round(bytes / (1024 * 1024))}MB`;
75
+ }
76
+ /**
77
+ * Pluralize "entry"/"entries" for a count.
78
+ */
79
+ function pluralEntry(count) {
80
+ return count === 1 ? "entry" : "entries";
81
+ }
82
+ /**
83
+ * Format the inventory of both caches as a multi-line TTY block per
84
+ * the core-flows artifact. Used as the TTY/compact/markdown/refs
85
+ * presentation for `cache stats`. Pure.
86
+ */
87
+ export function formatCacheStats(stats) {
88
+ const lines = [];
89
+ lines.push(`Cache directory: ${stats.dir}`);
90
+ if (stats.enabled) {
91
+ lines.push(`Status: enabled (TTL ${formatTtl(stats.ttlMs)}, cap ${formatSizeCap(stats.sizeCapBytes)})`);
92
+ }
93
+ else {
94
+ lines.push(`Status: disabled`);
95
+ }
96
+ lines.push("");
97
+ lines.push("Response cache:");
98
+ lines.push(` Entries: ${stats.responseCache.entries}`);
99
+ lines.push(` Size: ${formatBytes(stats.responseCache.totalBytes)}`);
100
+ lines.push("");
101
+ lines.push("Tool cache:");
102
+ lines.push(` Entries: ${stats.toolCache.entries}`);
103
+ lines.push(` Size: ${formatBytes(stats.toolCache.totalBytes)}`);
104
+ return lines.join("\n");
105
+ }
106
+ /**
107
+ * Format a clear result as a one-line TTY notice.
108
+ */
109
+ export function formatCacheClear(result) {
110
+ return (`Cleared ${result.responsesCleared} response ${pluralEntry(result.responsesCleared)} ` +
111
+ `and ${result.toolsCleared} tool ${pluralEntry(result.toolsCleared)} ` +
112
+ `(${formatBytes(result.bytesFreed)} freed)`);
113
+ }
114
+ /**
115
+ * Format the one-line Doctor cache summary from a `cacheStats()` value.
116
+ * The dispatcher calls this before invoking `buildDiagnosticsReport`;
117
+ * the report builder embeds the result verbatim. Examples:
118
+ *
119
+ * ```text
120
+ * Cache: enabled, 47 response entries (12.3 MB), 1 tool entry (8.2 KB), ~/.scoutline/
121
+ * Cache: disabled
122
+ * ```
123
+ *
124
+ * Pure: never reads env or touches the filesystem.
125
+ */
126
+ export function formatDoctorCacheSummary(stats) {
127
+ if (!stats.enabled)
128
+ return "Cache: disabled";
129
+ return (`Cache: enabled, ${stats.responseCache.entries} response ${pluralEntry(stats.responseCache.entries)} ` +
130
+ `(${formatBytes(stats.responseCache.totalBytes)}), ${stats.toolCache.entries} tool ${pluralEntry(stats.toolCache.entries)} ` +
131
+ `(${formatBytes(stats.toolCache.totalBytes)}), ${stats.dir}`);
132
+ }
133
+ // ---------------------------------------------------------------------------
134
+ // Commands
135
+ // ---------------------------------------------------------------------------
136
+ /** All text modes share the same multi-line inventory rendering. */
137
+ function statsPresentations(stats) {
138
+ const text = formatCacheStats(stats);
139
+ return { compact: text, markdown: text, refs: text, tty: text };
140
+ }
141
+ /** All text modes share the same one-line clear notice. */
142
+ function clearPresentations(result) {
143
+ const text = formatCacheClear(result);
144
+ return { compact: text, markdown: text, refs: text, tty: text };
145
+ }
146
+ /**
147
+ * Run the `cache stats` subcommand. Returns the inventory as base data
148
+ * with a TTY presentation override. Exit code is always 0 on success;
149
+ * I/O failures propagate as ordinary errors through the dispatcher.
150
+ */
151
+ export async function cacheStatsCommand(deps) {
152
+ const stats = await deps.getStats();
153
+ return {
154
+ kind: "data",
155
+ data: stats,
156
+ presentations: statsPresentations(stats),
157
+ };
158
+ }
159
+ /**
160
+ * Run the `cache clear` subcommand. Returns the count of cleared
161
+ * entries and bytes freed as base data with a TTY presentation
162
+ * override.
163
+ */
164
+ export async function cacheClearCommand(deps) {
165
+ const result = await deps.clear();
166
+ return {
167
+ kind: "data",
168
+ data: result,
169
+ presentations: clearPresentations(result),
170
+ };
171
+ }
172
+ export const CACHE_HELP = `
173
+ Cache - Inspect and clear the local cache
174
+
175
+ Usage:
176
+ scoutline cache stats # show inventory of both cache subdirectories
177
+ scoutline cache clear # delete every file in both cache subdirectories
178
+
179
+ Subcommands:
180
+ stats Print the cache directory, status (enabled/disabled, TTL, size
181
+ cap), and per-subdirectory entry count and total size for both
182
+ the response cache (~/.scoutline/cache/) and the tool cache
183
+ (~/.scoutline/tools/).
184
+ clear Delete every file under <root>/cache/ and <root>/tools/. The
185
+ directories themselves are preserved so the next invocation
186
+ recreates entries without a directory-creation race. The
187
+ orphaned legacy ~/.cache/zai-cli/ directory is never touched.
188
+
189
+ The cache root defaults to ~/.scoutline/ on every platform; override it
190
+ with SCOUTLINE_CACHE_DIR (ZAI_MCP_CACHE_DIR and ZAI_CACHE_DIR are
191
+ accepted as lower-precedence legacy aliases). Disable both caches with
192
+ SCOUTLINE_CACHE=0 (legacy alias: ZAI_CACHE=0).
193
+
194
+ Exit codes:
195
+ 0 Success.
196
+ 1 I/O error (reported as a sanitized JSON error envelope).
197
+
198
+ Examples:
199
+ scoutline cache stats
200
+ scoutline cache clear
201
+ scoutline cache --help
202
+ `.trim();
203
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/commands/cache.ts"],"names":[],"mappings":"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"}
@@ -27,14 +27,25 @@ export interface DoctorDiagnosticsDependencies {
27
27
  readonly env: NodeJS.ProcessEnv;
28
28
  readonly sleep: (ms: number) => Promise<void>;
29
29
  readonly random: () => number;
30
+ /**
31
+ * Pre-formatted one-line cache summary (Cache Module Unification
32
+ * Ticket 03). The dispatcher formats this from `cacheStats()` output
33
+ * before invoking the report builder; the report builder only embeds
34
+ * it. Optional for backward compatibility with existing tests that
35
+ * don't cover the cache surface. When omitted, the returned report
36
+ * simply leaves out the `cache` field.
37
+ */
38
+ readonly cacheSummary?: string;
30
39
  }
31
40
  /**
32
- * Build a schema-version-1 {@link DiagnosticsReport}. Report metadata is
33
- * built from static descriptors without constructing any Adapter. Under
34
- * `--no-tools` the command returns after metadata + configured-state
35
- * evaluation. Otherwise each configured Provider is probed through
36
- * shared execution with settled collection, preserving registry order
37
- * and normalized redacted failures.
41
+ * Build a schema-version-1 {@link DiagnosticsReport}. Inventory
42
+ * (`sharedCapabilities`, `zaiOnlyCapabilities`) is derived purely from
43
+ * `deps.descriptors` no descriptor.create(), no transport, no
44
+ * production registry import. Under `--no-tools` the command returns
45
+ * after metadata + configured-state evaluation. Otherwise each
46
+ * configured Provider is probed through shared execution with settled
47
+ * collection, preserving registry order and normalized redacted
48
+ * failures.
38
49
  */
39
50
  export declare function buildDiagnosticsReport(deps: DoctorDiagnosticsDependencies): Promise<DiagnosticsReport>;
40
51
  /**
@@ -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;AASxC,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;CAC/B;AA6CD;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,6BAA6B,GAClC,OAAO,CAAC,iBAAiB,CAAC,CA4B5B;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,QAqChB,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,EAElB,MAAM,gCAAgC,CAAC;AASxC,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;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,6BAA6B,GAClC,OAAO,CAAC,iBAAiB,CAAC,CAkC5B;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,QAuDhB,CAAC"}
@@ -17,7 +17,7 @@
17
17
  * Under `--no-tools` the command returns after metadata + configured-state
18
18
  * evaluation and constructs no Adapter and no transport (FR-034).
19
19
  */
20
- import { SHARED_CAPABILITIES, ZAI_ONLY_CAPABILITIES, diagnosticErrorFromError, } from "../capabilities/diagnostics.js";
20
+ import { deriveSharedCapabilities, deriveZaiOnlyCapabilities, diagnosticErrorFromError, } from "../capabilities/diagnostics.js";
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";
@@ -43,12 +43,14 @@ async function probeProvider(descriptor, env, sleep, random) {
43
43
  });
44
44
  }
45
45
  /**
46
- * Build a schema-version-1 {@link DiagnosticsReport}. Report metadata is
47
- * built from static descriptors without constructing any Adapter. Under
48
- * `--no-tools` the command returns after metadata + configured-state
49
- * evaluation. Otherwise each configured Provider is probed through
50
- * shared execution with settled collection, preserving registry order
51
- * and normalized redacted failures.
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.
52
54
  */
53
55
  export async function buildDiagnosticsReport(deps) {
54
56
  const secrets = configuredSecrets(deps.env);
@@ -64,16 +66,21 @@ export async function buildDiagnosticsReport(deps) {
64
66
  reason: entry.configured ? "tools-disabled" : "not-configured",
65
67
  }))
66
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 };
67
73
  return {
68
74
  schemaVersion: 1,
69
75
  effectiveProvider: deps.effectiveProvider,
70
- sharedCapabilities: SHARED_CAPABILITIES,
71
- zaiOnlyCapabilities: ZAI_ONLY_CAPABILITIES,
76
+ sharedCapabilities: deriveSharedCapabilities(deps.descriptors),
77
+ zaiOnlyCapabilities: deriveZaiOnlyCapabilities(deps.descriptors),
72
78
  node: {
73
79
  version: process.version,
74
80
  visionMcpCompatible: nodeMajor() >= 22,
75
81
  },
76
82
  providers,
83
+ ...(cache !== undefined ? { cache } : {}),
77
84
  };
78
85
  }
79
86
  /**
@@ -140,18 +147,36 @@ Reports a schema-version-1 diagnostics report listing every built-in
140
147
  Provider (zai, minimax) with its configured state, declared
141
148
  Capabilities, and connectivity status. The effective Provider (resolved
142
149
  from --provider, SCOUTLINE_PROVIDER, or the default zai) is the
143
- Provider that serves the shared Capabilities:
144
-
145
- search, vision.interpret-image, quota, diagnostics
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.
146
154
 
147
155
  Z.AI connectivity is probed through MCP tool discovery; MiniMax
148
156
  connectivity through a single raw quota probe that authenticates
149
157
  without a generative request.
150
158
 
151
- The following Capabilities are Z.AI-only in the base release and are
152
- not selected by the effective Provider for other families:
153
- reader, repository-exploration, raw-provider-tools, code-mode,
154
- image-diff, video-analysis
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.
155
180
 
156
181
  Options:
157
182
  --no-tools Skip every connectivity probe (metadata-only). Under
@@ -162,7 +187,7 @@ Options:
162
187
  Exit codes:
163
188
  0 All configured probes succeeded (or only tools-disabled skips).
164
189
  1 The effective Provider is unconfigured or any configured probe
165
- failed; successful entries are still reported.
190
+ failed; successful entries are still reported.
166
191
 
167
192
  Examples:
168
193
  scoutline doctor # full diagnostics