@documentation-robotics/cli 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 (169) hide show
  1. package/PYTHON_CLI_PARITY.md +265 -0
  2. package/PYTHON_CLI_STRUCTURE_UPDATE.md +246 -0
  3. package/README.md +926 -0
  4. package/biome.json +42 -0
  5. package/bunfig.toml +3 -0
  6. package/dist/ai/claude-client.js +71 -0
  7. package/dist/ai/claude-client.js.map +7 -0
  8. package/dist/ai/context-provider.js +129 -0
  9. package/dist/ai/context-provider.js.map +7 -0
  10. package/dist/ai/tools.js +231 -0
  11. package/dist/ai/tools.js.map +7 -0
  12. package/dist/cli.js +224 -0
  13. package/dist/cli.js.map +7 -0
  14. package/dist/commands/add.js +51 -0
  15. package/dist/commands/add.js.map +7 -0
  16. package/dist/commands/changeset.js +174 -0
  17. package/dist/commands/changeset.js.map +7 -0
  18. package/dist/commands/chat.js +111 -0
  19. package/dist/commands/chat.js.map +7 -0
  20. package/dist/commands/conformance.js +132 -0
  21. package/dist/commands/conformance.js.map +7 -0
  22. package/dist/commands/delete.js +31 -0
  23. package/dist/commands/delete.js.map +7 -0
  24. package/dist/commands/element.js +28 -0
  25. package/dist/commands/element.js.map +7 -0
  26. package/dist/commands/export.js +65 -0
  27. package/dist/commands/export.js.map +7 -0
  28. package/dist/commands/info.js +40 -0
  29. package/dist/commands/info.js.map +7 -0
  30. package/dist/commands/init.js +45 -0
  31. package/dist/commands/init.js.map +7 -0
  32. package/dist/commands/list.js +32 -0
  33. package/dist/commands/list.js.map +7 -0
  34. package/dist/commands/migrate.js +36 -0
  35. package/dist/commands/migrate.js.map +7 -0
  36. package/dist/commands/project.js +74 -0
  37. package/dist/commands/project.js.map +7 -0
  38. package/dist/commands/relationship.js +118 -0
  39. package/dist/commands/relationship.js.map +7 -0
  40. package/dist/commands/search.js +48 -0
  41. package/dist/commands/search.js.map +7 -0
  42. package/dist/commands/show.js +38 -0
  43. package/dist/commands/show.js.map +7 -0
  44. package/dist/commands/trace.js +60 -0
  45. package/dist/commands/trace.js.map +7 -0
  46. package/dist/commands/update.js +37 -0
  47. package/dist/commands/update.js.map +7 -0
  48. package/dist/commands/upgrade.js +152 -0
  49. package/dist/commands/upgrade.js.map +7 -0
  50. package/dist/commands/validate.js +71 -0
  51. package/dist/commands/validate.js.map +7 -0
  52. package/dist/commands/version.js +20 -0
  53. package/dist/commands/version.js.map +7 -0
  54. package/dist/commands/visualize.js +51 -0
  55. package/dist/commands/visualize.js.map +7 -0
  56. package/dist/core/active-changeset.js +52 -0
  57. package/dist/core/active-changeset.js.map +7 -0
  58. package/dist/core/changeset.js +244 -0
  59. package/dist/core/changeset.js.map +7 -0
  60. package/dist/core/dependency-tracker.js +322 -0
  61. package/dist/core/dependency-tracker.js.map +7 -0
  62. package/dist/core/element.js +65 -0
  63. package/dist/core/element.js.map +7 -0
  64. package/dist/core/layer.js +75 -0
  65. package/dist/core/layer.js.map +7 -0
  66. package/dist/core/manifest.js +57 -0
  67. package/dist/core/manifest.js.map +7 -0
  68. package/dist/core/migration-registry.js +131 -0
  69. package/dist/core/migration-registry.js.map +7 -0
  70. package/dist/core/model.js +455 -0
  71. package/dist/core/model.js.map +7 -0
  72. package/dist/core/projection-engine.js +288 -0
  73. package/dist/core/projection-engine.js.map +7 -0
  74. package/dist/core/reference-registry.js +188 -0
  75. package/dist/core/reference-registry.js.map +7 -0
  76. package/dist/core/relationship-registry.js +114 -0
  77. package/dist/core/relationship-registry.js.map +7 -0
  78. package/dist/core/relationships.js +78 -0
  79. package/dist/core/relationships.js.map +7 -0
  80. package/dist/export/archimate-exporter.js +111 -0
  81. package/dist/export/archimate-exporter.js.map +7 -0
  82. package/dist/export/export-manager.js +63 -0
  83. package/dist/export/export-manager.js.map +7 -0
  84. package/dist/export/graphml-exporter.js +39 -0
  85. package/dist/export/graphml-exporter.js.map +7 -0
  86. package/dist/export/index.js +17 -0
  87. package/dist/export/index.js.map +7 -0
  88. package/dist/export/json-schema-exporter.js +60 -0
  89. package/dist/export/json-schema-exporter.js.map +7 -0
  90. package/dist/export/markdown-exporter.js +99 -0
  91. package/dist/export/markdown-exporter.js.map +7 -0
  92. package/dist/export/openapi-exporter.js +85 -0
  93. package/dist/export/openapi-exporter.js.map +7 -0
  94. package/dist/export/plantuml-exporter.js +60 -0
  95. package/dist/export/plantuml-exporter.js.map +7 -0
  96. package/dist/export/types.js +36 -0
  97. package/dist/export/types.js.map +7 -0
  98. package/dist/schemas/bundled/01-motivation-layer.schema.json +942 -0
  99. package/dist/schemas/bundled/02-business-layer.schema.json +1293 -0
  100. package/dist/schemas/bundled/03-security-layer.schema.json +2177 -0
  101. package/dist/schemas/bundled/04-application-layer.schema.json +1328 -0
  102. package/dist/schemas/bundled/05-technology-layer.schema.json +1465 -0
  103. package/dist/schemas/bundled/06-api-layer.schema.json +1743 -0
  104. package/dist/schemas/bundled/07-data-model-layer.schema.json +1253 -0
  105. package/dist/schemas/bundled/08-datastore-layer.schema.json +892 -0
  106. package/dist/schemas/bundled/09-ux-layer.schema.json +1506 -0
  107. package/dist/schemas/bundled/10-navigation-layer.schema.json +843 -0
  108. package/dist/schemas/bundled/11-apm-observability-layer.schema.json +1430 -0
  109. package/dist/schemas/bundled/12-testing-layer.schema.json +1091 -0
  110. package/dist/schemas/bundled/common/layer-extensions.schema.json +266 -0
  111. package/dist/schemas/bundled/common/predicates.schema.json +493 -0
  112. package/dist/schemas/bundled/common/relationships.schema.json +791 -0
  113. package/dist/schemas/bundled/common/source-references.schema.json +71 -0
  114. package/dist/schemas/bundled/link-registry.json +1839 -0
  115. package/dist/schemas/bundled/link-registry.schema.json +339 -0
  116. package/dist/schemas/bundled/relationship-catalog.json +1302 -0
  117. package/dist/schemas/bundled/relationship-type.schema.json +221 -0
  118. package/dist/server/server.js +1207 -0
  119. package/dist/server/server.js.map +7 -0
  120. package/dist/server/telemetry-middleware.js +24 -0
  121. package/dist/server/telemetry-middleware.js.map +7 -0
  122. package/dist/telemetry/console-interceptor.js +34 -0
  123. package/dist/telemetry/console-interceptor.js.map +7 -0
  124. package/dist/telemetry/index.js +54 -0
  125. package/dist/telemetry/index.js.map +7 -0
  126. package/dist/telemetry/resilient-exporter.js +41 -0
  127. package/dist/telemetry/resilient-exporter.js.map +7 -0
  128. package/dist/telemetry/resilient-log-exporter.js +41 -0
  129. package/dist/telemetry/resilient-log-exporter.js.map +7 -0
  130. package/dist/telemetry/test-instrumentation.js +32 -0
  131. package/dist/telemetry/test-instrumentation.js.map +7 -0
  132. package/dist/types/index.js +1 -0
  133. package/dist/types/index.js.map +7 -0
  134. package/dist/utils/element-utils.js +11 -0
  135. package/dist/utils/element-utils.js.map +7 -0
  136. package/dist/utils/errors.js +105 -0
  137. package/dist/utils/errors.js.map +7 -0
  138. package/dist/utils/file-io.js +69 -0
  139. package/dist/utils/file-io.js.map +7 -0
  140. package/dist/utils/globals.js +28 -0
  141. package/dist/utils/globals.js.map +7 -0
  142. package/dist/utils/model-path.js +22 -0
  143. package/dist/utils/model-path.js.map +7 -0
  144. package/dist/utils/project-paths.js +45 -0
  145. package/dist/utils/project-paths.js.map +7 -0
  146. package/dist/utils/spec-installer.js +85 -0
  147. package/dist/utils/spec-installer.js.map +7 -0
  148. package/dist/utils/spec-version.js +33 -0
  149. package/dist/utils/spec-version.js.map +7 -0
  150. package/dist/validators/index.js +15 -0
  151. package/dist/validators/index.js.map +7 -0
  152. package/dist/validators/naming-validator.js +82 -0
  153. package/dist/validators/naming-validator.js.map +7 -0
  154. package/dist/validators/reference-validator.js +106 -0
  155. package/dist/validators/reference-validator.js.map +7 -0
  156. package/dist/validators/schema-validator.js +148 -0
  157. package/dist/validators/schema-validator.js.map +7 -0
  158. package/dist/validators/semantic-validator.js +80 -0
  159. package/dist/validators/semantic-validator.js.map +7 -0
  160. package/dist/validators/types.js +48 -0
  161. package/dist/validators/types.js.map +7 -0
  162. package/dist/validators/validator.js +67 -0
  163. package/dist/validators/validator.js.map +7 -0
  164. package/docs/TEST-INSTRUMENTATION.md +405 -0
  165. package/docs/telemetry.md +427 -0
  166. package/package.json +70 -0
  167. package/test-debug.js +33 -0
  168. package/test-special.mjs +46 -0
  169. package/test_runner.ts +7 -0
@@ -0,0 +1,405 @@
1
+ # Test Instrumentation Guide
2
+
3
+ This guide explains how to use the test instrumentation utilities to enable filtering and debugging test telemetry in observability platforms like SigNoz.
4
+
5
+ ## Overview
6
+
7
+ Test instrumentation creates OpenTelemetry spans with test-specific attributes, allowing you to:
8
+
9
+ - **Filter test spans** in SigNoz by test name, suite, file, or project
10
+ - **View test results** (pass/fail/skip) as span attributes
11
+ - **Debug test failures** with error messages and stack traces in spans
12
+ - **Correlate tests with CLI commands** by tracing context propagation
13
+
14
+ ## Architecture
15
+
16
+ ### Span Hierarchy
17
+
18
+ ```
19
+ test.file span (parent)
20
+ ├── attributes:
21
+ │ ├── test.file: "tests/unit/example.test.ts"
22
+ │ ├── test.framework: "bun"
23
+ │ ├── dr.project.name: "my-project"
24
+ │
25
+ ├── test.case span (child 1)
26
+ │ ├── attributes:
27
+ │ │ ├── test.name: "should validate input"
28
+ │ │ ├── test.suite: "ValidationTests"
29
+ │ │ ├── test.status: "pass"
30
+ │ │ ├── dr.project.name: "my-project"
31
+ │
32
+ └── test.case span (child 2)
33
+ ├── attributes:
34
+ ├── test.name: "should handle errors"
35
+ ├── test.suite: "ValidationTests"
36
+ ├── test.status: "fail"
37
+ ├── test.error.message: "Expected string, got number"
38
+ ├── test.error.stack: "Error: Expected string...\n at..."
39
+ ├── dr.project.name: "my-project"
40
+ ```
41
+
42
+ ### Span Attributes
43
+
44
+ #### File-Level Span (`test.file`)
45
+
46
+ | Attribute | Type | Example | Description |
47
+ |-----------|------|---------|-------------|
48
+ | `test.file` | string | `tests/unit/example.test.ts` | Path to the test file |
49
+ | `test.framework` | string | `bun` | Test framework being used |
50
+ | `dr.project.name` | string | `my-project` | Project name (inherited from resource) |
51
+
52
+ #### Test Case Span (`test.case`)
53
+
54
+ | Attribute | Type | Example | Description |
55
+ |-----------|------|---------|-------------|
56
+ | `test.name` | string | `should validate input` | Test case name |
57
+ | `test.suite` | string | `ValidationTests` | Describe block name (optional) |
58
+ | `test.file` | string | `tests/unit/example.test.ts` | Parent test file |
59
+ | `test.status` | string | `pass`, `fail`, `skip` | Test result status |
60
+ | `dr.project.name` | string | `my-project` | Project name (inherited from resource) |
61
+
62
+ #### Error Attributes (on failed tests)
63
+
64
+ | Attribute | Type | Example |
65
+ |-----------|------|---------|
66
+ | `test.error.message` | string | `Expected string, got number` |
67
+ | `test.error.stack` | string | `Error: Expected...\n at ...` |
68
+
69
+ ## Basic Usage
70
+
71
+ ### Setup: File-Level Span
72
+
73
+ Add this to the top of your test file to create a file-level span:
74
+
75
+ ```typescript
76
+ import { describe, test, beforeAll, afterAll } from 'bun:test';
77
+ import {
78
+ startTestFileSpan,
79
+ endTestFileSpan,
80
+ instrumentTest,
81
+ } from '../../src/telemetry/test-instrumentation.js';
82
+
83
+ // Create file-level span at the beginning of tests
84
+ beforeAll(() => {
85
+ startTestFileSpan('tests/unit/my.test.ts');
86
+ });
87
+
88
+ // Clean up at the end of tests
89
+ afterAll(() => {
90
+ endTestFileSpan();
91
+ });
92
+ ```
93
+
94
+ ### Simple Tests with Helper
95
+
96
+ Use `instrumentTest()` to wrap test functions:
97
+
98
+ ```typescript
99
+ describe('ValidationTests', () => {
100
+ test(
101
+ 'should validate positive numbers',
102
+ instrumentTest(
103
+ 'should validate positive numbers',
104
+ async () => {
105
+ const isValid = (n: number) => n > 0;
106
+ expect(isValid(42)).toBe(true);
107
+ },
108
+ 'ValidationTests'
109
+ )
110
+ );
111
+ });
112
+ ```
113
+
114
+ ### Advanced: Manual Span Management
115
+
116
+ For complex tests, manage spans manually:
117
+
118
+ ```typescript
119
+ import {
120
+ createTestCaseSpan,
121
+ recordTestResult,
122
+ } from '../../src/telemetry/test-instrumentation.js';
123
+
124
+ test('complex test', async () => {
125
+ const span = createTestCaseSpan('complex test', 'ComplexTests');
126
+ try {
127
+ // test code
128
+ recordTestResult(span, 'pass');
129
+ } catch (error) {
130
+ recordTestResult(span, 'fail', error as Error);
131
+ throw error; // Re-throw to fail the test
132
+ }
133
+ });
134
+ ```
135
+
136
+ ### Using Helpers
137
+
138
+ Import the helper functions for cleaner setup:
139
+
140
+ ```typescript
141
+ import { setupTestTelemetry } from '../../tests/helpers/test-instrumentation-helpers.js';
142
+ import { describe, test, beforeAll, afterAll } from 'bun:test';
143
+
144
+ const { beforeAll: setupTelemetry, afterAll: teardownTelemetry } =
145
+ setupTestTelemetry('tests/unit/my.test.ts');
146
+
147
+ beforeAll(setupTelemetry);
148
+ afterAll(teardownTelemetry);
149
+
150
+ describe('MyTests', () => {
151
+ test('my test', () => {
152
+ // test code
153
+ });
154
+ });
155
+ ```
156
+
157
+ ## Complete Example
158
+
159
+ ```typescript
160
+ // tests/unit/example.test.ts
161
+ import { describe, test, beforeAll, afterAll, expect } from 'bun:test';
162
+ import {
163
+ startTestFileSpan,
164
+ endTestFileSpan,
165
+ instrumentTest,
166
+ } from '../../src/telemetry/test-instrumentation.js';
167
+
168
+ // File-level setup
169
+ beforeAll(() => {
170
+ startTestFileSpan('tests/unit/example.test.ts');
171
+ });
172
+
173
+ afterAll(() => {
174
+ endTestFileSpan();
175
+ });
176
+
177
+ describe('ValidationTests', () => {
178
+ test(
179
+ 'should validate email',
180
+ instrumentTest(
181
+ 'should validate email',
182
+ async () => {
183
+ const validateEmail = (email: string) => {
184
+ if (!email.includes('@')) throw new Error('Invalid email');
185
+ return true;
186
+ };
187
+
188
+ expect(validateEmail('user@example.com')).toBe(true);
189
+ expect(() => validateEmail('invalid')).toThrow('Invalid email');
190
+ },
191
+ 'ValidationTests'
192
+ )
193
+ );
194
+
195
+ test(
196
+ 'should handle edge cases',
197
+ instrumentTest(
198
+ 'should handle edge cases',
199
+ async () => {
200
+ const isEmpty = (s: string) => s.length === 0;
201
+ expect(isEmpty('')).toBe(true);
202
+ expect(isEmpty('a')).toBe(false);
203
+ },
204
+ 'ValidationTests'
205
+ )
206
+ );
207
+ });
208
+ ```
209
+
210
+ ## Telemetry Flow
211
+
212
+ When telemetry is enabled (`TELEMETRY_ENABLED=true`):
213
+
214
+ 1. **Test file starts** → `startTestFileSpan()` creates parent span
215
+ 2. **Each test runs** → `instrumentTest()` wraps test function
216
+ 3. **Test span created** → Child span with `test.name`, `test.suite`
217
+ 4. **Test completes** → `recordTestResult()` sets `test.status`
218
+ 5. **On failure** → Error attributes (`test.error.message`, `test.error.stack`) added
219
+ 6. **Span exported** → SimpleSpanProcessor sends to OTLP collector
220
+ 7. **Test file ends** → `endTestFileSpan()` closes parent span
221
+
222
+ ### Export Endpoint
223
+
224
+ By default, spans are sent to:
225
+ ```
226
+ http://localhost:4318/v1/traces
227
+ ```
228
+
229
+ Configure via environment variables:
230
+ ```bash
231
+ OTEL_EXPORTER_OTLP_ENDPOINT=http://your-collector:4318
232
+ ```
233
+
234
+ ## SigNoz Integration
235
+
236
+ ### Viewing Test Spans
237
+
238
+ 1. Open SigNoz dashboard
239
+ 2. Go to **Traces** section
240
+ 3. Filter by attributes:
241
+ ```
242
+ dr.project.name = "my-project"
243
+ test.framework = "bun"
244
+ ```
245
+
246
+ ### Query Examples
247
+
248
+ **Find all failed tests:**
249
+ ```
250
+ test.status = "fail"
251
+ ```
252
+
253
+ **Find tests in a specific file:**
254
+ ```
255
+ test.file = "tests/unit/example.test.ts"
256
+ ```
257
+
258
+ **Find tests in a suite:**
259
+ ```
260
+ test.suite = "ValidationTests"
261
+ ```
262
+
263
+ **Find tests with errors matching pattern:**
264
+ ```
265
+ test.error.message LIKE "%assertion%"
266
+ ```
267
+
268
+ ### Viewing Error Details
269
+
270
+ Click a failed test span to see:
271
+ - `test.error.message` - Error message
272
+ - `test.error.stack` - Full stack trace
273
+ - Exception record with full error context
274
+
275
+ ## Performance Considerations
276
+
277
+ ### Production Mode
278
+
279
+ In production builds, `TELEMETRY_ENABLED=false` and all instrumentation becomes zero-cost:
280
+
281
+ ```typescript
282
+ // Compiled out in production
283
+ if (TELEMETRY_ENABLED) {
284
+ const span = startTestFileSpan('...'); // → Eliminated
285
+ }
286
+ ```
287
+
288
+ ### Debug Mode
289
+
290
+ In debug mode, overhead is minimal:
291
+ - File span: ~1ms overhead per test file
292
+ - Test span: ~0.1ms overhead per test case
293
+ - Exporter timeout: 500ms (non-blocking, happens in background)
294
+
295
+ ### Circuit-Breaker Protection
296
+
297
+ If the OTLP collector is unreachable:
298
+ 1. First export attempt fails with 500ms timeout
299
+ 2. Circuit-breaker activates for 30 seconds
300
+ 3. Spans discarded silently (no CLI impact)
301
+ 4. After 30s, collector connection retried
302
+
303
+ ## Troubleshooting
304
+
305
+ ### Spans Not Appearing in SigNoz
306
+
307
+ 1. **Check collector is running:**
308
+ ```bash
309
+ curl http://localhost:4318/v1/traces
310
+ ```
311
+
312
+ 2. **Verify telemetry is enabled:**
313
+ - Debug build should have `TELEMETRY_ENABLED=true`
314
+ - Check CLI log output for telemetry initialization
315
+
316
+ 3. **Check resource attributes:**
317
+ - In SigNoz, look for spans with `service.name=dr-cli`
318
+ - Filter by `dr.project.name` to verify project context
319
+
320
+ ### Empty `test.suite` Attribute
321
+
322
+ If `test.suite` is empty string:
323
+ - Means the optional `suiteName` parameter wasn't provided
324
+ - This is fine - tests are still tracked by `test.name`
325
+
326
+ ### Stack Traces Not Visible
327
+
328
+ - Verify error has `stack` property
329
+ - Check `test.error.stack` attribute in span
330
+ - Very old Error objects may not have stack traces
331
+
332
+ ## Integration with Manifest
333
+
334
+ Test spans automatically include the project name from your model manifest:
335
+
336
+ ```json
337
+ // .dr/manifest.json
338
+ {
339
+ "name": "my-project",
340
+ "version": "1.0.0"
341
+ }
342
+ ```
343
+
344
+ This becomes the `dr.project.name` attribute on all test spans, enabling filtering by project.
345
+
346
+ ## Best Practices
347
+
348
+ 1. **Always set up file span** - Use `beforeAll`/`afterAll` hooks
349
+ 2. **Use suite names** - Help organize tests in SigNoz
350
+ 3. **Let errors bubble** - Re-throw after `recordTestResult(span, 'fail', error)`
351
+ 4. **Consistent naming** - Use readable test names for better filtering
352
+ 5. **Group related tests** - Use describe blocks with suite names
353
+
354
+ ## API Reference
355
+
356
+ ### `startTestFileSpan(filePath: string): Span | null`
357
+
358
+ Creates a file-level span for the test file.
359
+
360
+ - **Returns:** Span object (or null if telemetry disabled)
361
+ - **Call:** In `beforeAll()` hook
362
+
363
+ ### `endTestFileSpan(): void`
364
+
365
+ Ends the file-level span and cleans up context.
366
+
367
+ - **Call:** In `afterAll()` hook
368
+
369
+ ### `createTestCaseSpan(testName: string, suiteName?: string): Span | null`
370
+
371
+ Creates a span for a test case.
372
+
373
+ - **Parameters:**
374
+ - `testName`: Name of the test case
375
+ - `suiteName`: Optional describe block name
376
+ - **Returns:** Span object (or null if telemetry disabled)
377
+
378
+ ### `recordTestResult(span: Span | null, status: 'pass' | 'fail' | 'skip', error?: Error): void`
379
+
380
+ Records test result and ends the span.
381
+
382
+ - **Parameters:**
383
+ - `span`: Test case span (from `createTestCaseSpan`)
384
+ - `status`: Test result
385
+ - `error`: Optional Error object for failed tests
386
+ - **Effect:** Sets attributes and ends span
387
+
388
+ ### `instrumentTest(testName: string, testFn: () => void | Promise<void>, suiteName?: string): () => Promise<void>`
389
+
390
+ Wraps a test function with automatic instrumentation.
391
+
392
+ - **Parameters:**
393
+ - `testName`: Name of the test
394
+ - `testFn`: Test function (sync or async)
395
+ - `suiteName`: Optional describe block name
396
+ - **Returns:** Wrapped async function for use with `test()`
397
+ - **Behavior:** Automatically creates span, executes test, records result
398
+
399
+ ## Examples
400
+
401
+ See the following files for complete examples:
402
+
403
+ - `tests/unit/test-instrumentation.example.test.ts` - Basic usage examples
404
+ - `tests/unit/test-instrumentation.test.ts` - Unit tests for instrumentation
405
+ - `tests/unit/test-instrumentation-integration.test.ts` - Integration examples