docorbit 0.1.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 (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +660 -0
  3. package/apps/cli/bin/docorbit.js +8 -0
  4. package/apps/cli/src/commands/add.ts +44 -0
  5. package/apps/cli/src/commands/api.ts +38 -0
  6. package/apps/cli/src/commands/context.ts +47 -0
  7. package/apps/cli/src/commands/dashboard.ts +55 -0
  8. package/apps/cli/src/commands/diff.ts +30 -0
  9. package/apps/cli/src/commands/evaluate.ts +133 -0
  10. package/apps/cli/src/commands/examples.ts +39 -0
  11. package/apps/cli/src/commands/export.ts +89 -0
  12. package/apps/cli/src/commands/impact.ts +31 -0
  13. package/apps/cli/src/commands/init.ts +69 -0
  14. package/apps/cli/src/commands/inspect.ts +30 -0
  15. package/apps/cli/src/commands/mcp.ts +72 -0
  16. package/apps/cli/src/commands/pitfalls.ts +38 -0
  17. package/apps/cli/src/commands/recipes.ts +35 -0
  18. package/apps/cli/src/commands/search.ts +48 -0
  19. package/apps/cli/src/commands/update.ts +73 -0
  20. package/apps/cli/src/commands/verify.ts +48 -0
  21. package/apps/cli/src/formatters/colors.ts +23 -0
  22. package/apps/cli/src/formatters/inspection.ts +102 -0
  23. package/apps/cli/src/formatters/knowledge.ts +272 -0
  24. package/apps/cli/src/formatters/retrieval.ts +74 -0
  25. package/apps/cli/src/formatters/terminal.ts +6 -0
  26. package/apps/cli/src/formatters/verification.ts +126 -0
  27. package/apps/cli/src/index.ts +409 -0
  28. package/bin/docorbit.js +8 -0
  29. package/package.json +46 -0
  30. package/packages/core/src/dashboard/server.ts +314 -0
  31. package/packages/core/src/dashboard/ui.ts +586 -0
  32. package/packages/core/src/implementation-service.ts +451 -0
  33. package/packages/core/src/index.ts +7 -0
  34. package/packages/core/src/inspector.ts +71 -0
  35. package/packages/core/src/pipeline.ts +331 -0
  36. package/packages/crawler/src/config.ts +12 -0
  37. package/packages/crawler/src/fetcher.ts +185 -0
  38. package/packages/crawler/src/index.ts +2 -0
  39. package/packages/discovery/src/index.ts +31 -0
  40. package/packages/discovery/src/provider.ts +47 -0
  41. package/packages/discovery/src/providers/generic.ts +98 -0
  42. package/packages/discovery/src/providers/github.ts +61 -0
  43. package/packages/discovery/src/providers/llms-txt.ts +73 -0
  44. package/packages/discovery/src/providers/markdown.ts +48 -0
  45. package/packages/discovery/src/providers/openapi.ts +91 -0
  46. package/packages/discovery/src/providers/sitemap.ts +62 -0
  47. package/packages/discovery/src/providers/skill.ts +54 -0
  48. package/packages/discovery/src/ranker.ts +123 -0
  49. package/packages/evaluation/src/dataset.ts +963 -0
  50. package/packages/evaluation/src/index.ts +8 -0
  51. package/packages/evaluation/src/runner.ts +241 -0
  52. package/packages/evaluation/src/strategies/context7-runner.ts +269 -0
  53. package/packages/evaluation/src/strategies/docorbit-runner.ts +228 -0
  54. package/packages/evaluation/src/strategies/firecrawl-runner.ts +172 -0
  55. package/packages/evaluation/src/strategies/web-search-runner.ts +194 -0
  56. package/packages/evaluation/src/types.ts +34 -0
  57. package/packages/evaluation/src/version-matcher.ts +73 -0
  58. package/packages/export/src/agents-md.ts +200 -0
  59. package/packages/export/src/claude-md.ts +141 -0
  60. package/packages/export/src/docs-map.ts +150 -0
  61. package/packages/export/src/index.ts +6 -0
  62. package/packages/export/src/llms-txt.ts +96 -0
  63. package/packages/export/src/service.ts +250 -0
  64. package/packages/export/src/skill-md.ts +128 -0
  65. package/packages/mcp/src/index.ts +46 -0
  66. package/packages/mcp/src/resources/index.ts +189 -0
  67. package/packages/mcp/src/server.ts +278 -0
  68. package/packages/mcp/src/tools/analyze-impact.ts +74 -0
  69. package/packages/mcp/src/tools/check-api.ts +86 -0
  70. package/packages/mcp/src/tools/diff-docs.ts +68 -0
  71. package/packages/mcp/src/tools/export-context.ts +73 -0
  72. package/packages/mcp/src/tools/find-api.ts +99 -0
  73. package/packages/mcp/src/tools/find-example.ts +100 -0
  74. package/packages/mcp/src/tools/find-pitfall.ts +94 -0
  75. package/packages/mcp/src/tools/find-recipe.ts +98 -0
  76. package/packages/mcp/src/tools/get-doc.ts +130 -0
  77. package/packages/mcp/src/tools/get-docs-map.ts +64 -0
  78. package/packages/mcp/src/tools/get-version.ts +118 -0
  79. package/packages/mcp/src/tools/implementation-context.ts +88 -0
  80. package/packages/mcp/src/tools/index.ts +59 -0
  81. package/packages/mcp/src/tools/list-sources.ts +85 -0
  82. package/packages/mcp/src/tools/search-docs.ts +123 -0
  83. package/packages/mcp/src/tools/types.ts +28 -0
  84. package/packages/mcp/src/transports/http.ts +256 -0
  85. package/packages/mcp/src/transports/stdio.ts +105 -0
  86. package/packages/mcp/src/transports/types.ts +6 -0
  87. package/packages/mcp/src/types.ts +102 -0
  88. package/packages/normalizer/src/example-indexer.ts +240 -0
  89. package/packages/normalizer/src/html.ts +253 -0
  90. package/packages/normalizer/src/index.ts +8 -0
  91. package/packages/normalizer/src/llms.ts +83 -0
  92. package/packages/normalizer/src/openapi/endpoint-parser.ts +406 -0
  93. package/packages/normalizer/src/openapi/schema-resolver.ts +111 -0
  94. package/packages/normalizer/src/openapi.ts +2 -0
  95. package/packages/normalizer/src/page.ts +184 -0
  96. package/packages/normalizer/src/pitfall-extractor.ts +190 -0
  97. package/packages/normalizer/src/slicer.ts +455 -0
  98. package/packages/retrieval/src/engine.ts +120 -0
  99. package/packages/retrieval/src/index.ts +7 -0
  100. package/packages/retrieval/src/intent.ts +43 -0
  101. package/packages/retrieval/src/packer.ts +145 -0
  102. package/packages/retrieval/src/recipe-engine.ts +313 -0
  103. package/packages/retrieval/src/scorer.ts +139 -0
  104. package/packages/retrieval/src/weights.ts +31 -0
  105. package/packages/security/src/annotations.ts +112 -0
  106. package/packages/security/src/index.ts +2 -0
  107. package/packages/security/src/ssrf.ts +153 -0
  108. package/packages/shared/src/errors.ts +53 -0
  109. package/packages/shared/src/hashing.ts +23 -0
  110. package/packages/shared/src/index.ts +3 -0
  111. package/packages/shared/src/types.ts +881 -0
  112. package/packages/storage/src/db.ts +72 -0
  113. package/packages/storage/src/index.ts +11 -0
  114. package/packages/storage/src/interfaces.ts +115 -0
  115. package/packages/storage/src/repositories/api-repository.ts +219 -0
  116. package/packages/storage/src/repositories/chunk-repository.ts +316 -0
  117. package/packages/storage/src/repositories/example-repository.ts +206 -0
  118. package/packages/storage/src/repositories/page-repository.ts +205 -0
  119. package/packages/storage/src/repositories/pitfall-repository.ts +188 -0
  120. package/packages/storage/src/repositories/source-repository.ts +205 -0
  121. package/packages/storage/src/repository.ts +256 -0
  122. package/packages/storage/src/schema.ts +269 -0
  123. package/packages/storage/src/search-tokens.ts +28 -0
  124. package/packages/verification/src/diff-engine.ts +258 -0
  125. package/packages/verification/src/extractor.ts +339 -0
  126. package/packages/verification/src/impact-scanner.ts +203 -0
  127. package/packages/verification/src/index.ts +5 -0
  128. package/packages/verification/src/services.ts +238 -0
  129. package/packages/verification/src/verifier.ts +375 -0
  130. package/packages/workspace/src/detector.ts +143 -0
  131. package/packages/workspace/src/ecosystems/cargo.ts +84 -0
  132. package/packages/workspace/src/ecosystems/composer.ts +42 -0
  133. package/packages/workspace/src/ecosystems/go.ts +54 -0
  134. package/packages/workspace/src/ecosystems/index.ts +34 -0
  135. package/packages/workspace/src/ecosystems/maven.ts +34 -0
  136. package/packages/workspace/src/ecosystems/npm.ts +83 -0
  137. package/packages/workspace/src/ecosystems/pub.ts +40 -0
  138. package/packages/workspace/src/ecosystems/pypi.ts +100 -0
  139. package/packages/workspace/src/ecosystems/rubygems.ts +30 -0
  140. package/packages/workspace/src/ecosystems/types.ts +18 -0
  141. package/packages/workspace/src/index.ts +5 -0
  142. package/packages/workspace/src/lockfile.ts +194 -0
  143. package/packages/workspace/src/resolver.ts +234 -0
  144. package/packages/workspace/src/semver.ts +259 -0
@@ -0,0 +1,272 @@
1
+ import type {
2
+ ApiEndpoint,
3
+ IndexedExample,
4
+ Pitfall,
5
+ Recipe,
6
+ } from '../../../../packages/shared/src/index.ts';
7
+ import { RESET, BOLD, DIM, GREEN, BLUE, CYAN, YELLOW, RED, MAGENTA } from './colors.ts';
8
+
9
+ export function formatApiEndpoints(
10
+ endpoints: ApiEndpoint[],
11
+ query?: string
12
+ ): string {
13
+ const lines: string[] = [];
14
+
15
+ lines.push('');
16
+ lines.push(`${BOLD}${CYAN}DocOrbit${RESET} ${DIM}— API Intelligence for: "${query || '*'}"${RESET}`);
17
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
18
+
19
+ if (endpoints.length === 0) {
20
+ lines.push(` ${YELLOW}No matching API endpoints found.${RESET}`);
21
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
22
+ lines.push('');
23
+ return lines.join('\n');
24
+ }
25
+
26
+ for (let i = 0; i < endpoints.length; i++) {
27
+ const ep = endpoints[i];
28
+ let methodColor = GREEN;
29
+ if (ep.method === 'post') methodColor = BLUE;
30
+ else if (ep.method === 'put') methodColor = YELLOW;
31
+ else if (ep.method === 'delete') methodColor = RED;
32
+ else if (ep.method === 'patch') methodColor = MAGENTA;
33
+
34
+ const methodBadge = `${methodColor}${BOLD}[${ep.method.toUpperCase()}]${RESET}`;
35
+ const depBadge = ep.deprecated ? ` ${RED}${BOLD}[DEPRECATED]${RESET}` : '';
36
+ const verBadge = ep.docVersion ? ` ${DIM}(${ep.docVersion})${RESET}` : '';
37
+
38
+ lines.push(` ${BOLD}${i + 1}.${RESET} ${methodBadge} ${BOLD}${CYAN}${ep.path}${RESET}${depBadge}${verBadge}`);
39
+ if (ep.summary) {
40
+ lines.push(` ${BOLD}${ep.summary}${RESET}`);
41
+ }
42
+ if (ep.description && ep.description !== ep.summary) {
43
+ lines.push(` ${DIM}${ep.description.slice(0, 120)}${ep.description.length > 120 ? '...' : ''}${RESET}`);
44
+ }
45
+
46
+ if (ep.parameters.length > 0) {
47
+ const paramStr = ep.parameters.map(p => {
48
+ const req = p.required ? `${RED}*${RESET}` : '';
49
+ return `${p.name}${req} (${p.in}:${p.type || 'any'})`;
50
+ }).join(', ');
51
+ lines.push(` ${DIM}Params: ${paramStr}${RESET}`);
52
+ }
53
+
54
+ if (ep.auth.length > 0) {
55
+ const authStr = ep.auth.map(a => `${a.type}${a.scheme ? `:${a.scheme}` : ''}`).join(', ');
56
+ lines.push(` ${DIM}Auth: ${authStr}${RESET}`);
57
+ }
58
+
59
+ if (ep.pagination) {
60
+ lines.push(` ${DIM}Pagination: ${ep.pagination.type} (${ep.pagination.parameters.join(', ')})${RESET}`);
61
+ }
62
+
63
+ if (ep.errors.length > 0) {
64
+ const errorCodes = ep.errors.map(e => e.statusCode).join(', ');
65
+ lines.push(` ${DIM}Error Codes: ${errorCodes}${RESET}`);
66
+ }
67
+
68
+ if (ep.provenance?.sourceUrl) {
69
+ lines.push(` ${DIM}Source: ${ep.provenance.sourceUrl}${RESET}`);
70
+ }
71
+ lines.push('');
72
+ }
73
+
74
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
75
+ lines.push('');
76
+ return lines.join('\n');
77
+ }
78
+
79
+ export function formatIndexedExamples(
80
+ examples: IndexedExample[],
81
+ task?: string
82
+ ): string {
83
+ const lines: string[] = [];
84
+
85
+ lines.push('');
86
+ lines.push(`${BOLD}${CYAN}DocOrbit${RESET} ${DIM}— Code Example Intelligence for: "${task || '*'}"${RESET}`);
87
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
88
+
89
+ if (examples.length === 0) {
90
+ lines.push(` ${YELLOW}No matching code examples found.${RESET}`);
91
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
92
+ lines.push('');
93
+ return lines.join('\n');
94
+ }
95
+
96
+ for (let i = 0; i < examples.length; i++) {
97
+ const ex = examples[i];
98
+ const fwBadge = ex.framework ? ` ${MAGENTA}[${ex.framework}]${RESET}` : '';
99
+ const langBadge = `${GREEN}[${ex.language}]${RESET}`;
100
+ const verBadge = ex.docVersion ? ` ${DIM}(${ex.docVersion})${RESET}` : '';
101
+ const authBadge = ex.sourceAuthority === 'official' ? `${BLUE}[official]${RESET}` : `${DIM}[community]${RESET}`;
102
+
103
+ lines.push(` ${BOLD}${i + 1}.${RESET} ${CYAN}${ex.task}${RESET} ${langBadge}${fwBadge} ${authBadge}${verBadge}`);
104
+ if (ex.relatedApi) {
105
+ lines.push(` ${BOLD}Target API:${RESET} ${BLUE}${ex.relatedApi}${RESET}`);
106
+ }
107
+ if (ex.relatedSymbol) {
108
+ lines.push(` ${BOLD}Symbol:${RESET} ${MAGENTA}${ex.relatedSymbol}${RESET}`);
109
+ }
110
+
111
+ lines.push(` ${DIM}┌── code snippet ──────────────────────────${RESET}`);
112
+ const codeLines = ex.code.split('\n').slice(0, 15);
113
+ for (const cl of codeLines) {
114
+ lines.push(` ${DIM}│${RESET} ${cl}`);
115
+ }
116
+ if (ex.code.split('\n').length > 15) {
117
+ lines.push(` ${DIM}│ ... (${ex.code.split('\n').length - 15} more lines)${RESET}`);
118
+ }
119
+ lines.push(` ${DIM}└──────────────────────────────────────────${RESET}`);
120
+ lines.push(` ${DIM}Source: ${ex.sourceUrl}${RESET}`);
121
+ lines.push('');
122
+ }
123
+
124
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
125
+ lines.push('');
126
+ return lines.join('\n');
127
+ }
128
+
129
+ export function formatPitfalls(
130
+ pitfalls: Pitfall[],
131
+ task?: string
132
+ ): string {
133
+ const lines: string[] = [];
134
+
135
+ lines.push('');
136
+ lines.push(`${BOLD}${YELLOW}DocOrbit${RESET} ${DIM}— Pitfalls & Warnings for: "${task || '*'}"${RESET}`);
137
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
138
+
139
+ if (pitfalls.length === 0) {
140
+ lines.push(` ${GREEN}No matching pitfalls or warnings found.${RESET}`);
141
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
142
+ lines.push('');
143
+ return lines.join('\n');
144
+ }
145
+
146
+ for (let i = 0; i < pitfalls.length; i++) {
147
+ const pf = pitfalls[i];
148
+ let badgeColor = YELLOW;
149
+ if (pf.kind === 'breaking_change' || pf.kind === 'removed' || pf.kind === 'security') {
150
+ badgeColor = RED;
151
+ } else if (pf.kind === 'deprecated') {
152
+ badgeColor = MAGENTA;
153
+ }
154
+
155
+ const kindBadge = `${badgeColor}${BOLD}[${pf.kind.toUpperCase().replace(/_/g, ' ')}]${RESET}`;
156
+ const verBadge = pf.docVersion ? ` ${DIM}(${pf.docVersion})${RESET}` : '';
157
+
158
+ lines.push(` ${BOLD}${i + 1}.${RESET} ${kindBadge} ${BOLD}${pf.title}${RESET}${verBadge}`);
159
+ if (pf.relatedApi) {
160
+ lines.push(` ${DIM}Related API: ${BLUE}${pf.relatedApi}${RESET}`);
161
+ }
162
+ lines.push(` ${DIM}│${RESET} ${pf.content}`);
163
+ if (pf.provenance?.sourceUrl) {
164
+ lines.push(` ${DIM}Source: ${pf.provenance.sourceUrl}${RESET}`);
165
+ }
166
+ lines.push('');
167
+ }
168
+
169
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
170
+ lines.push('');
171
+ return lines.join('\n');
172
+ }
173
+
174
+ export function formatRecipe(recipe: Recipe): string {
175
+ const lines: string[] = [];
176
+
177
+ const confidencePct = Math.round(recipe.confidence * 100);
178
+ const confColor = confidencePct >= 70 ? GREEN : (confidencePct >= 40 ? YELLOW : RED);
179
+
180
+ lines.push('');
181
+ lines.push(`${BOLD}${GREEN}DocOrbit${RESET} ${DIM}— Implementation Recipe${RESET}`);
182
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
183
+ lines.push(`${BOLD}Goal:${RESET} ${CYAN}${recipe.goal}${RESET}`);
184
+ lines.push(`${BOLD}Confidence:${RESET} ${confColor}${confidencePct}%${RESET}`);
185
+ if (recipe.docVersion) {
186
+ lines.push(`${BOLD}Version:${RESET} ${MAGENTA}${recipe.docVersion}${RESET}`);
187
+ }
188
+ lines.push('');
189
+
190
+ // Prerequisites
191
+ lines.push(`${BOLD}Prerequisites (${recipe.prerequisites.length}):${RESET}`);
192
+ lines.push(`${DIM}${'─'.repeat(64)}${RESET}`);
193
+ if (recipe.prerequisites.length === 0) {
194
+ lines.push(` ${DIM}No special prerequisites documented.${RESET}`);
195
+ } else {
196
+ for (const pre of recipe.prerequisites) {
197
+ const badge = pre.evidenceLevel === 'documented_fact'
198
+ ? `${GREEN}[FACT]${RESET}`
199
+ : `${YELLOW}[INFERRED]${RESET}`;
200
+ lines.push(` • ${badge} ${pre.text}`);
201
+ }
202
+ }
203
+ lines.push('');
204
+
205
+ // Ordered Implementation Steps
206
+ lines.push(`${BOLD}Implementation Steps (${recipe.orderedSteps.length}):${RESET}`);
207
+ lines.push(`${DIM}${'─'.repeat(64)}${RESET}`);
208
+ for (const s of recipe.orderedSteps) {
209
+ let badge = `${GREEN}[FACT]${RESET}`;
210
+ if (s.evidenceLevel === 'inferred_relationship') badge = `${YELLOW}[INFERRED]${RESET}`;
211
+ else if (s.evidenceLevel === 'missing_information') badge = `${RED}[MISSING]${RESET}`;
212
+
213
+ lines.push(` ${BOLD}${s.step}.${RESET} ${badge} ${BOLD}${CYAN}${s.title}${RESET}`);
214
+ if (s.apiEndpoint) {
215
+ lines.push(` ${BOLD}API Endpoint:${RESET} ${BLUE}${s.apiEndpoint}${RESET}`);
216
+ }
217
+ lines.push(` ${s.description}`);
218
+
219
+ if (s.exampleCode) {
220
+ lines.push(` ${DIM}┌── example ────────────────────────────────${RESET}`);
221
+ const codeLines = s.exampleCode.split('\n').slice(0, 10);
222
+ for (const cl of codeLines) {
223
+ lines.push(` ${DIM}│${RESET} ${cl}`);
224
+ }
225
+ if (s.exampleCode.split('\n').length > 10) {
226
+ lines.push(` ${DIM}│ ... (${s.exampleCode.split('\n').length - 10} more lines)${RESET}`);
227
+ }
228
+ lines.push(` ${DIM}└──────────────────────────────────────────${RESET}`);
229
+ }
230
+
231
+ if (s.pitfalls && s.pitfalls.length > 0) {
232
+ for (const pf of s.pitfalls) {
233
+ lines.push(` ${YELLOW}⚠ ${pf}${RESET}`);
234
+ }
235
+ }
236
+ if (s.sourceUrl) {
237
+ lines.push(` ${DIM}Source: ${s.sourceUrl}${RESET}`);
238
+ }
239
+ lines.push('');
240
+ }
241
+
242
+ // Evidence-Based Validation Steps
243
+ lines.push(`${BOLD}Validation Steps (${recipe.validationSteps.length}):${RESET}`);
244
+ lines.push(`${DIM}${'─'.repeat(64)}${RESET}`);
245
+ for (const vs of recipe.validationSteps) {
246
+ let badge = `${GREEN}[FACT]${RESET}`;
247
+ if (vs.evidenceLevel === 'inferred_relationship') badge = `${YELLOW}[INFERRED]${RESET}`;
248
+ else if (vs.evidenceLevel === 'missing_information') badge = `${RED}[MISSING]${RESET}`;
249
+
250
+ lines.push(` ${BOLD}${vs.step}.${RESET} ${badge} ${vs.description}`);
251
+ if (vs.expectedResponse) {
252
+ lines.push(` ${DIM}Expected Response:${RESET} ${vs.expectedResponse.slice(0, 100)}`);
253
+ }
254
+ if (vs.testPattern) {
255
+ lines.push(` ${DIM}Test Pattern:${RESET} ${vs.testPattern.slice(0, 100)}`);
256
+ }
257
+ }
258
+ lines.push('');
259
+
260
+ // Sources consulted
261
+ if (recipe.sources.length > 0) {
262
+ lines.push(`${BOLD}Sources Consulted:${RESET}`);
263
+ for (const src of recipe.sources) {
264
+ lines.push(` ${DIM}• ${src}${RESET}`);
265
+ }
266
+ lines.push('');
267
+ }
268
+
269
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
270
+ lines.push('');
271
+ return lines.join('\n');
272
+ }
@@ -0,0 +1,74 @@
1
+ import type { SearchResult, ContextPackage } from '../../../../packages/shared/src/index.ts';
2
+ import { RESET, BOLD, DIM, GREEN, CYAN, YELLOW, MAGENTA } from './colors.ts';
3
+
4
+ export function formatSearchResults(query: string, results: SearchResult[]): string {
5
+ const lines: string[] = [];
6
+
7
+ lines.push('');
8
+ lines.push(`${BOLD}${CYAN}DocOrbit${RESET} ${DIM}— Search Results for: "${query}"${RESET}`);
9
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
10
+
11
+ if (results.length === 0) {
12
+ lines.push(` ${YELLOW}No matching documentation chunks found.${RESET}`);
13
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
14
+ lines.push('');
15
+ return lines.join('\n');
16
+ }
17
+
18
+ for (let i = 0; i < results.length; i++) {
19
+ const res = results[i];
20
+ const chunk = res.chunk;
21
+ const breadcrumb = chunk.sectionPath.length > 0 ? chunk.sectionPath.join(' > ') : (chunk.title || 'General');
22
+
23
+ lines.push(` ${BOLD}${i + 1}.${RESET} ${CYAN}${breadcrumb}${RESET} ${GREEN}(Score: ${res.score})${RESET}`);
24
+ lines.push(` ${DIM}Type: ${chunk.chunkType} | Est. Tokens: ~${chunk.tokenEstimate} | Chunk: ${chunk.id}${RESET}`);
25
+ if (res.matchReasons.length > 0) {
26
+ lines.push(` ${DIM}Matches: ${res.matchReasons.join(' • ')}${RESET}`);
27
+ }
28
+ if (res.symbols.length > 0) {
29
+ lines.push(` ${MAGENTA}Symbols: ${res.symbols.map(s => s.name).join(', ')}${RESET}`);
30
+ }
31
+
32
+ const preview = chunk.content.split('\n').filter(l => l.trim().length > 0).slice(0, 3).join('\n ');
33
+ lines.push(` ${DIM}│${RESET} ${preview}`);
34
+ lines.push('');
35
+ }
36
+
37
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
38
+ lines.push('');
39
+ return lines.join('\n');
40
+ }
41
+
42
+ export function formatContextPackage(pkg: ContextPackage): string {
43
+ const lines: string[] = [];
44
+
45
+ lines.push('');
46
+ lines.push(`${BOLD}${GREEN}DocOrbit${RESET} ${DIM}— Assembled Context Package${RESET}`);
47
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
48
+ lines.push(`${BOLD}Task:${RESET} ${CYAN}${pkg.task}${RESET}`);
49
+ lines.push(`${BOLD}Detected Intent:${RESET} ${MAGENTA}${pkg.detectedIntent}${RESET}`);
50
+ lines.push(`${BOLD}Estimated Tokens:${RESET} ~${pkg.totalEstimatedTokens} / ${pkg.tokenBudget} (heuristic)`);
51
+ lines.push(`${BOLD}Chunks Included:${RESET} ${pkg.chunks.length}`);
52
+ lines.push(`${BOLD}Sources Cited:${RESET} ${pkg.sources.length > 0 ? pkg.sources.join(', ') : 'Local documentation'}`);
53
+
54
+ if (pkg.warnings.length > 0) {
55
+ lines.push('');
56
+ lines.push(`${YELLOW}${BOLD}Advisories & Warnings (${pkg.warnings.length}):${RESET}`);
57
+ for (const w of pkg.warnings) {
58
+ lines.push(` ${YELLOW}⚠ ${w}${RESET}`);
59
+ }
60
+ }
61
+
62
+ lines.push('');
63
+ lines.push(`${BOLD}Package Markdown Preview:${RESET}`);
64
+ lines.push(`${DIM}${'─'.repeat(64)}${RESET}`);
65
+ const previewLines = pkg.markdown.split('\n').slice(0, 20);
66
+ lines.push(previewLines.join('\n'));
67
+ if (pkg.markdown.split('\n').length > 20) {
68
+ lines.push(`\n${DIM}... (${pkg.markdown.split('\n').length - 20} more lines in full package)${RESET}`);
69
+ }
70
+ lines.push(`${DIM}${'═'.repeat(64)}${RESET}`);
71
+ lines.push('');
72
+
73
+ return lines.join('\n');
74
+ }
@@ -0,0 +1,6 @@
1
+ export * from './colors.ts';
2
+ export * from './inspection.ts';
3
+ export * from './retrieval.ts';
4
+ export * from './knowledge.ts';
5
+ export * from './verification.ts';
6
+
@@ -0,0 +1,126 @@
1
+ import type {
2
+ DocDiffResult,
3
+ ImpactAnalysisResult,
4
+ VerificationResult,
5
+ } from '../../../../packages/shared/src/index.ts';
6
+ import { RESET, BOLD, DIM, GREEN, CYAN, YELLOW, RED } from './colors.ts';
7
+
8
+ export function formatVerificationReport(result: VerificationResult): string {
9
+ const lines: string[] = [];
10
+ const verdictColor =
11
+ result.verdict === 'verified'
12
+ ? GREEN
13
+ : result.verdict === 'warning'
14
+ ? YELLOW
15
+ : result.verdict === 'mismatch'
16
+ ? RED
17
+ : CYAN;
18
+
19
+ lines.push(`${BOLD}${CYAN}DocOrbit — Code & Schema Verification${RESET}`);
20
+ lines.push(`Verdict: ${verdictColor}${BOLD}${result.verdict.toUpperCase()}${RESET}`);
21
+ lines.push(`Summary: ${result.summary}`);
22
+ if (result.targetVersion) {
23
+ lines.push(`Target Version: ${YELLOW}${result.targetVersion}${RESET}`);
24
+ }
25
+ if (result.projectVersion) {
26
+ lines.push(`Project Version: ${YELLOW}${result.projectVersion}${RESET}`);
27
+ }
28
+ lines.push(`Total Checks: ${result.totalChecks}\n`);
29
+
30
+ if (result.findings.length === 0) {
31
+ lines.push(`${GREEN}✔ No schema mismatches, deprecations, or syntax issues detected.${RESET}`);
32
+ return lines.join('\n');
33
+ }
34
+
35
+ lines.push(`${BOLD}Findings (${result.findings.length}):${RESET}`);
36
+ for (const f of result.findings) {
37
+ const fColor = f.severity === 'error' ? RED : f.severity === 'warning' ? YELLOW : CYAN;
38
+ const loc = f.location?.line ? ` (Line ${f.location.line})` : '';
39
+ lines.push(` ${fColor}• [${f.rule.toUpperCase()}]${loc}: ${f.message}${RESET}`);
40
+ if (f.location?.snippet) {
41
+ lines.push(` ${DIM}${f.location.snippet}${RESET}`);
42
+ }
43
+ if (f.expected) {
44
+ lines.push(` ${DIM}Expected: ${String(f.expected)}${RESET}`);
45
+ }
46
+ if (f.actual) {
47
+ lines.push(` ${DIM}Actual: ${String(f.actual)}${RESET}`);
48
+ }
49
+ }
50
+
51
+ return lines.join('\n');
52
+ }
53
+
54
+ export function formatDiffReport(diff: DocDiffResult): string {
55
+ const lines: string[] = [];
56
+ const from = diff.fromVersion || diff.fromSnapshotId || 'previous';
57
+ const to = diff.toVersion || diff.toSnapshotId || 'latest';
58
+
59
+ lines.push(`${BOLD}${CYAN}DocOrbit — Documentation & API Diff${RESET}`);
60
+ lines.push(`Comparing: ${YELLOW}${from}${RESET} ➔ ${YELLOW}${to}${RESET}`);
61
+ lines.push(`Endpoints: +${diff.summary.endpointsAdded} added, -${diff.summary.endpointsRemoved} removed, ~${diff.summary.endpointsModified} modified, !${diff.summary.endpointsDeprecated} deprecated`);
62
+ lines.push(`Pitfalls: +${diff.summary.pitfallsAdded} added, -${diff.summary.pitfallsRemoved} removed\n`);
63
+
64
+ if (diff.apiChanges.length > 0) {
65
+ lines.push(`${BOLD}API Endpoint Changes:${RESET}`);
66
+ for (const ep of diff.apiChanges) {
67
+ const badge =
68
+ ep.changeType === 'added'
69
+ ? `${GREEN}[ADDED]${RESET}`
70
+ : ep.changeType === 'removed'
71
+ ? `${RED}[REMOVED]${RESET}`
72
+ : ep.changeType === 'deprecated'
73
+ ? `${YELLOW}[DEPRECATED]${RESET}`
74
+ : `${CYAN}[MODIFIED]${RESET}`;
75
+
76
+ lines.push(` ${badge} ${ep.method.toUpperCase()} ${ep.path}`);
77
+ if (ep.changes) {
78
+ for (const ch of ep.changes) {
79
+ lines.push(` ${DIM}• ${ch}${RESET}`);
80
+ }
81
+ }
82
+ }
83
+ lines.push('');
84
+ }
85
+
86
+ if (diff.pitfallChanges.length > 0) {
87
+ lines.push(`${BOLD}Pitfall Changes:${RESET}`);
88
+ for (const p of diff.pitfallChanges) {
89
+ const badge = p.changeType === 'added' ? `${YELLOW}[NEW WARNING]${RESET}` : `${DIM}[REMOVED]${RESET}`;
90
+ lines.push(` ${badge} ${p.pitfall.kind}: ${p.pitfall.title}`);
91
+ }
92
+ }
93
+
94
+ return lines.join('\n');
95
+ }
96
+
97
+ export function formatImpactReport(impact: ImpactAnalysisResult): string {
98
+ const lines: string[] = [];
99
+ lines.push(`${BOLD}${CYAN}DocOrbit — Project Impact Analysis${RESET}`);
100
+ lines.push(`Workspace: ${impact.projectDir}`);
101
+ lines.push(`Files Scanned: ${impact.totalFilesScanned}`);
102
+ lines.push(`Impacted Files: ${impact.affectedFilesCount}`);
103
+ lines.push(`Total Matches: ${impact.affectedLocations.length}\n`);
104
+
105
+ if (impact.affectedLocations.length === 0) {
106
+ lines.push(`${GREEN}✔ Zero project files impacted by documentation/API changes.${RESET}`);
107
+ return lines.join('\n');
108
+ }
109
+
110
+ lines.push(`${BOLD}Impacted Locations:${RESET}`);
111
+ for (const loc of impact.affectedLocations) {
112
+ const cert =
113
+ loc.certainty === 'high'
114
+ ? `${RED}[HIGH]${RESET}`
115
+ : loc.certainty === 'medium'
116
+ ? `${YELLOW}[MED]${RESET}`
117
+ : `${DIM}[HEUR]${RESET}`;
118
+
119
+ lines.push(` ${cert} ${BOLD}${loc.filePath}:${loc.line}${RESET}`);
120
+ lines.push(` ${YELLOW}Reason: ${loc.reason}${RESET}`);
121
+ lines.push(` ${DIM}Pattern: ${loc.matchedPattern}${RESET}`);
122
+ lines.push(` ${DIM}Snippet: ${loc.snippet}${RESET}\n`);
123
+ }
124
+
125
+ return lines.join('\n');
126
+ }