@principal-ai/principal-studio-cli 0.35.3

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 (184) hide show
  1. package/README.md +172 -0
  2. package/dist/commands/agent-session.d.ts +3 -0
  3. package/dist/commands/agent-session.d.ts.map +1 -0
  4. package/dist/commands/agent-session.js +67 -0
  5. package/dist/commands/agent-sessions.d.ts +11 -0
  6. package/dist/commands/agent-sessions.d.ts.map +1 -0
  7. package/dist/commands/agent-sessions.js +39 -0
  8. package/dist/commands/auxiliary/index.d.ts +3 -0
  9. package/dist/commands/auxiliary/index.d.ts.map +1 -0
  10. package/dist/commands/auxiliary/index.js +9 -0
  11. package/dist/commands/auxiliary/validate.d.ts +3 -0
  12. package/dist/commands/auxiliary/validate.d.ts.map +1 -0
  13. package/dist/commands/auxiliary/validate.js +123 -0
  14. package/dist/commands/collector/check.d.ts +6 -0
  15. package/dist/commands/collector/check.d.ts.map +1 -0
  16. package/dist/commands/collector/check.js +153 -0
  17. package/dist/commands/collector/diagnose.d.ts +6 -0
  18. package/dist/commands/collector/diagnose.d.ts.map +1 -0
  19. package/dist/commands/collector/diagnose.js +229 -0
  20. package/dist/commands/collector/index.d.ts +6 -0
  21. package/dist/commands/collector/index.d.ts.map +1 -0
  22. package/dist/commands/collector/index.js +16 -0
  23. package/dist/commands/collector/status.d.ts +6 -0
  24. package/dist/commands/collector/status.d.ts.map +1 -0
  25. package/dist/commands/collector/status.js +77 -0
  26. package/dist/commands/collector/utils.d.ts +92 -0
  27. package/dist/commands/collector/utils.d.ts.map +1 -0
  28. package/dist/commands/collector/utils.js +154 -0
  29. package/dist/commands/coverage.d.ts +9 -0
  30. package/dist/commands/coverage.d.ts.map +1 -0
  31. package/dist/commands/coverage.js +252 -0
  32. package/dist/commands/create.d.ts +6 -0
  33. package/dist/commands/create.d.ts.map +1 -0
  34. package/dist/commands/create.js +50 -0
  35. package/dist/commands/events/index.d.ts +3 -0
  36. package/dist/commands/events/index.d.ts.map +1 -0
  37. package/dist/commands/events/index.js +9 -0
  38. package/dist/commands/events/validate.d.ts +3 -0
  39. package/dist/commands/events/validate.d.ts.map +1 -0
  40. package/dist/commands/events/validate.js +124 -0
  41. package/dist/commands/formats.d.ts +6 -0
  42. package/dist/commands/formats.d.ts.map +1 -0
  43. package/dist/commands/formats.js +1118 -0
  44. package/dist/commands/hooks.d.ts +9 -0
  45. package/dist/commands/hooks.d.ts.map +1 -0
  46. package/dist/commands/hooks.js +295 -0
  47. package/dist/commands/inbox.d.ts +13 -0
  48. package/dist/commands/inbox.d.ts.map +1 -0
  49. package/dist/commands/inbox.js +179 -0
  50. package/dist/commands/init.d.ts +6 -0
  51. package/dist/commands/init.d.ts.map +1 -0
  52. package/dist/commands/init.js +220 -0
  53. package/dist/commands/lint.d.ts +11 -0
  54. package/dist/commands/lint.d.ts.map +1 -0
  55. package/dist/commands/lint.js +71 -0
  56. package/dist/commands/list.d.ts +6 -0
  57. package/dist/commands/list.d.ts.map +1 -0
  58. package/dist/commands/list.js +78 -0
  59. package/dist/commands/migrate-nodes.d.ts +9 -0
  60. package/dist/commands/migrate-nodes.d.ts.map +1 -0
  61. package/dist/commands/migrate-nodes.js +363 -0
  62. package/dist/commands/migrate-scopes-to-canvas.d.ts +3 -0
  63. package/dist/commands/migrate-scopes-to-canvas.d.ts.map +1 -0
  64. package/dist/commands/migrate-scopes-to-canvas.js +143 -0
  65. package/dist/commands/migration.d.ts +6 -0
  66. package/dist/commands/migration.d.ts.map +1 -0
  67. package/dist/commands/migration.js +247 -0
  68. package/dist/commands/open-studio.d.ts +10 -0
  69. package/dist/commands/open-studio.d.ts.map +1 -0
  70. package/dist/commands/open-studio.js +32 -0
  71. package/dist/commands/opencode/fetch.d.ts +3 -0
  72. package/dist/commands/opencode/fetch.d.ts.map +1 -0
  73. package/dist/commands/opencode/fetch.js +25 -0
  74. package/dist/commands/opencode/index.d.ts +3 -0
  75. package/dist/commands/opencode/index.d.ts.map +1 -0
  76. package/dist/commands/opencode/index.js +11 -0
  77. package/dist/commands/opencode/list-sessions.d.ts +3 -0
  78. package/dist/commands/opencode/list-sessions.d.ts.map +1 -0
  79. package/dist/commands/opencode/list-sessions.js +20 -0
  80. package/dist/commands/repo.d.ts +18 -0
  81. package/dist/commands/repo.d.ts.map +1 -0
  82. package/dist/commands/repo.js +233 -0
  83. package/dist/commands/schema.d.ts +6 -0
  84. package/dist/commands/schema.d.ts.map +1 -0
  85. package/dist/commands/schema.js +367 -0
  86. package/dist/commands/scopes/index.d.ts +3 -0
  87. package/dist/commands/scopes/index.d.ts.map +1 -0
  88. package/dist/commands/scopes/index.js +9 -0
  89. package/dist/commands/scopes/validate.d.ts +3 -0
  90. package/dist/commands/scopes/validate.d.ts.map +1 -0
  91. package/dist/commands/scopes/validate.js +187 -0
  92. package/dist/commands/setup.d.ts +6 -0
  93. package/dist/commands/setup.d.ts.map +1 -0
  94. package/dist/commands/setup.js +406 -0
  95. package/dist/commands/starred-collections.d.ts +12 -0
  96. package/dist/commands/starred-collections.d.ts.map +1 -0
  97. package/dist/commands/starred-collections.js +310 -0
  98. package/dist/commands/subsystem-model.d.ts +11 -0
  99. package/dist/commands/subsystem-model.d.ts.map +1 -0
  100. package/dist/commands/subsystem-model.js +249 -0
  101. package/dist/commands/topic.d.ts +15 -0
  102. package/dist/commands/topic.d.ts.map +1 -0
  103. package/dist/commands/topic.js +683 -0
  104. package/dist/commands/tour.d.ts +23 -0
  105. package/dist/commands/tour.d.ts.map +1 -0
  106. package/dist/commands/tour.js +783 -0
  107. package/dist/commands/trace/flow.d.ts +6 -0
  108. package/dist/commands/trace/flow.d.ts.map +1 -0
  109. package/dist/commands/trace/flow.js +158 -0
  110. package/dist/commands/trace/index.d.ts +6 -0
  111. package/dist/commands/trace/index.d.ts.map +1 -0
  112. package/dist/commands/trace/index.js +20 -0
  113. package/dist/commands/trace/inspect.d.ts +6 -0
  114. package/dist/commands/trace/inspect.d.ts.map +1 -0
  115. package/dist/commands/trace/inspect.js +187 -0
  116. package/dist/commands/trace/list.d.ts +6 -0
  117. package/dist/commands/trace/list.d.ts.map +1 -0
  118. package/dist/commands/trace/list.js +145 -0
  119. package/dist/commands/trace/registrations.d.ts +6 -0
  120. package/dist/commands/trace/registrations.d.ts.map +1 -0
  121. package/dist/commands/trace/registrations.js +81 -0
  122. package/dist/commands/trace/validate.d.ts +6 -0
  123. package/dist/commands/trace/validate.d.ts.map +1 -0
  124. package/dist/commands/trace/validate.js +276 -0
  125. package/dist/commands/trail.d.ts +36 -0
  126. package/dist/commands/trail.d.ts.map +1 -0
  127. package/dist/commands/trail.js +622 -0
  128. package/dist/commands/validate.d.ts +12 -0
  129. package/dist/commands/validate.d.ts.map +1 -0
  130. package/dist/commands/validate.js +3334 -0
  131. package/dist/commands/workflow/implementation.d.ts +3 -0
  132. package/dist/commands/workflow/implementation.d.ts.map +1 -0
  133. package/dist/commands/workflow/implementation.js +51 -0
  134. package/dist/commands/workflow/index.d.ts +3 -0
  135. package/dist/commands/workflow/index.d.ts.map +1 -0
  136. package/dist/commands/workflow/index.js +19 -0
  137. package/dist/commands/workflow/inspect.d.ts +3 -0
  138. package/dist/commands/workflow/inspect.d.ts.map +1 -0
  139. package/dist/commands/workflow/inspect.js +123 -0
  140. package/dist/commands/workflow/list.d.ts +3 -0
  141. package/dist/commands/workflow/list.d.ts.map +1 -0
  142. package/dist/commands/workflow/list.js +95 -0
  143. package/dist/commands/workflow/render.d.ts +3 -0
  144. package/dist/commands/workflow/render.d.ts.map +1 -0
  145. package/dist/commands/workflow/render.js +88 -0
  146. package/dist/commands/workflow/test.d.ts +3 -0
  147. package/dist/commands/workflow/test.d.ts.map +1 -0
  148. package/dist/commands/workflow/test.js +141 -0
  149. package/dist/commands/workflow/utils.d.ts +49 -0
  150. package/dist/commands/workflow/utils.d.ts.map +1 -0
  151. package/dist/commands/workflow/utils.js +164 -0
  152. package/dist/commands/workflow/validate.d.ts +3 -0
  153. package/dist/commands/workflow/validate.d.ts.map +1 -0
  154. package/dist/commands/workflow/validate.js +344 -0
  155. package/dist/file-utils.d.ts +15 -0
  156. package/dist/file-utils.d.ts.map +1 -0
  157. package/dist/file-utils.js +29 -0
  158. package/dist/index.cjs +285718 -0
  159. package/dist/index.cjs.map +7 -0
  160. package/dist/index.d.ts +8 -0
  161. package/dist/index.d.ts.map +1 -0
  162. package/dist/index.js +81 -0
  163. package/dist/lib/bridge-ipc.d.ts +29 -0
  164. package/dist/lib/bridge-ipc.d.ts.map +1 -0
  165. package/dist/lib/bridge-ipc.js +128 -0
  166. package/dist/lib/github-user.d.ts +17 -0
  167. package/dist/lib/github-user.d.ts.map +1 -0
  168. package/dist/lib/github-user.js +53 -0
  169. package/dist/lib/open-url.d.ts +11 -0
  170. package/dist/lib/open-url.d.ts.map +1 -0
  171. package/dist/lib/open-url.js +45 -0
  172. package/dist/lib/subsystem-model-store.d.ts +74 -0
  173. package/dist/lib/subsystem-model-store.d.ts.map +1 -0
  174. package/dist/lib/subsystem-model-store.js +292 -0
  175. package/dist/lib/tour-cache.d.ts +26 -0
  176. package/dist/lib/tour-cache.d.ts.map +1 -0
  177. package/dist/lib/tour-cache.js +46 -0
  178. package/dist/lib/trail-cache.d.ts +40 -0
  179. package/dist/lib/trail-cache.d.ts.map +1 -0
  180. package/dist/lib/trail-cache.js +97 -0
  181. package/dist/lib/viewer-ipc.d.ts +44 -0
  182. package/dist/lib/viewer-ipc.d.ts.map +1 -0
  183. package/dist/lib/viewer-ipc.js +68 -0
  184. package/package.json +68 -0
@@ -0,0 +1,229 @@
1
+ /**
2
+ * collector diagnose - Comprehensive diagnostic for troubleshooting collector issues
3
+ */
4
+ import { Command } from 'commander';
5
+ import chalk from 'chalk';
6
+ import { DEFAULT_COLLECTOR_PORT, checkHealth, getServiceStats, checkPort, createTestTrace, sendTestTrace, formatRelativeTime, } from './utils.js';
7
+ export function createDiagnoseCommand() {
8
+ const command = new Command('diagnose');
9
+ command
10
+ .description('Run comprehensive diagnostics on the OTEL collector')
11
+ .option('-p, --port <port>', `Collector port (default: ${DEFAULT_COLLECTOR_PORT})`)
12
+ .option('--json', 'Output as JSON')
13
+ .action(async (options) => {
14
+ try {
15
+ const port = options.port ? parseInt(options.port, 10) : DEFAULT_COLLECTOR_PORT;
16
+ // Port checks
17
+ const portChecks = [];
18
+ const portsToCheck = [
19
+ { port, name: 'OTLP' },
20
+ { port: port + 1, name: 'wrapper' },
21
+ { port: port + 2, name: 'internal' },
22
+ ];
23
+ for (const { port: p, name } of portsToCheck) {
24
+ const result = await checkPort(p);
25
+ portChecks.push({
26
+ port: p,
27
+ name,
28
+ status: result.open ? 'listening' : 'closed',
29
+ service: result.service,
30
+ });
31
+ }
32
+ // Endpoint checks
33
+ const endpointChecks = [];
34
+ const mainPortOpen = portChecks[0].status === 'listening';
35
+ // Health endpoint
36
+ if (mainPortOpen) {
37
+ const health = await checkHealth(port);
38
+ endpointChecks.push({
39
+ method: 'GET',
40
+ path: '/health',
41
+ status: health ? 'ok' : 'error',
42
+ statusCode: health ? 200 : undefined,
43
+ });
44
+ }
45
+ else {
46
+ endpointChecks.push({
47
+ method: 'GET',
48
+ path: '/health',
49
+ status: 'skipped',
50
+ note: 'Port not open',
51
+ });
52
+ }
53
+ // Services stats endpoint
54
+ if (mainPortOpen) {
55
+ const stats = await getServiceStats(port);
56
+ endpointChecks.push({
57
+ method: 'GET',
58
+ path: '/services/stats',
59
+ status: stats ? 'ok' : 'error',
60
+ statusCode: stats ? 200 : undefined,
61
+ });
62
+ }
63
+ else {
64
+ endpointChecks.push({
65
+ method: 'GET',
66
+ path: '/services/stats',
67
+ status: 'skipped',
68
+ note: 'Port not open',
69
+ });
70
+ }
71
+ // Traces endpoint
72
+ if (mainPortOpen) {
73
+ const trace = createTestTrace('principal-cli-diagnose');
74
+ const result = await sendTestTrace(port, trace);
75
+ endpointChecks.push({
76
+ method: 'POST',
77
+ path: '/v1/traces',
78
+ status: result.success ? 'ok' : 'error',
79
+ statusCode: result.statusCode,
80
+ note: result.success ? 'test trace accepted' : result.error,
81
+ });
82
+ }
83
+ else {
84
+ endpointChecks.push({
85
+ method: 'POST',
86
+ path: '/v1/traces',
87
+ status: 'skipped',
88
+ note: 'Port not open',
89
+ });
90
+ }
91
+ // Logs endpoint (just check if it responds, don't actually send)
92
+ if (mainPortOpen) {
93
+ try {
94
+ const response = await fetch(`http://localhost:${port}/v1/logs`, {
95
+ method: 'POST',
96
+ headers: { 'Content-Type': 'application/json' },
97
+ body: JSON.stringify({ resourceLogs: [] }),
98
+ signal: AbortSignal.timeout(2000),
99
+ });
100
+ endpointChecks.push({
101
+ method: 'POST',
102
+ path: '/v1/logs',
103
+ status: response.ok ? 'ok' : 'error',
104
+ statusCode: response.status,
105
+ });
106
+ }
107
+ catch {
108
+ endpointChecks.push({
109
+ method: 'POST',
110
+ path: '/v1/logs',
111
+ status: 'error',
112
+ note: 'Request failed',
113
+ });
114
+ }
115
+ }
116
+ else {
117
+ endpointChecks.push({
118
+ method: 'POST',
119
+ path: '/v1/logs',
120
+ status: 'skipped',
121
+ note: 'Port not open',
122
+ });
123
+ }
124
+ // Get recent activity
125
+ const stats = mainPortOpen ? await getServiceStats(port) : null;
126
+ const health = mainPortOpen ? await checkHealth(port) : null;
127
+ let recentActivity = null;
128
+ if (stats && health) {
129
+ const sortedServices = Object.entries(stats.services)
130
+ .sort((a, b) => new Date(b[1].lastSeen).getTime() - new Date(a[1].lastSeen).getTime())
131
+ .slice(0, 5);
132
+ recentActivity = {
133
+ lastTrace: sortedServices.length > 0 ? formatRelativeTime(sortedServices[0][1].lastSeen) : undefined,
134
+ tracesTotal: health.tracesReceived ?? 0,
135
+ logsTotal: health.logsReceived ?? 0,
136
+ services: sortedServices.map(([name, info]) => ({
137
+ name,
138
+ lastSeen: formatRelativeTime(info.lastSeen),
139
+ traces: info.totalTraces,
140
+ })),
141
+ };
142
+ }
143
+ // Determine issues
144
+ const issues = [];
145
+ if (!mainPortOpen) {
146
+ issues.push(`Main OTLP port (${port}) is not responding`);
147
+ }
148
+ const failedEndpoints = endpointChecks.filter((e) => e.status === 'error');
149
+ for (const endpoint of failedEndpoints) {
150
+ issues.push(`${endpoint.method} ${endpoint.path} failed: ${endpoint.note || `HTTP ${endpoint.statusCode}`}`);
151
+ }
152
+ if (options.json) {
153
+ console.log(JSON.stringify({
154
+ ports: portChecks,
155
+ endpoints: endpointChecks,
156
+ recentActivity,
157
+ issues,
158
+ healthy: issues.length === 0,
159
+ }, null, 2));
160
+ }
161
+ else {
162
+ console.log(chalk.bold('\nCollector Diagnostics'));
163
+ console.log('━'.repeat(60));
164
+ // Port availability
165
+ console.log(chalk.bold('\nPort Availability:'));
166
+ for (const check of portChecks) {
167
+ const icon = check.status === 'listening' ? chalk.green('✓') : chalk.red('✗');
168
+ const status = check.status === 'listening'
169
+ ? chalk.green('listening') + chalk.gray(` (${check.service})`)
170
+ : chalk.red('closed');
171
+ console.log(` ${check.port} (${check.name}).......... ${icon} ${status}`);
172
+ }
173
+ // Endpoints
174
+ console.log(chalk.bold('\nEndpoints:'));
175
+ for (const check of endpointChecks) {
176
+ const icon = check.status === 'ok'
177
+ ? chalk.green('✓')
178
+ : check.status === 'skipped'
179
+ ? chalk.gray('─')
180
+ : chalk.red('✗');
181
+ const status = check.status === 'ok'
182
+ ? chalk.green(`${check.statusCode} OK`)
183
+ : check.status === 'skipped'
184
+ ? chalk.gray('skipped')
185
+ : chalk.red(check.note || `${check.statusCode}`);
186
+ const note = check.status === 'ok' && check.note ? chalk.gray(` (${check.note})`) : '';
187
+ console.log(` ${check.method.padEnd(4)} ${check.path.padEnd(15)} ${icon} ${status}${note}`);
188
+ }
189
+ // Recent activity
190
+ if (recentActivity) {
191
+ console.log(chalk.bold('\nRecent Activity:'));
192
+ if (recentActivity.lastTrace) {
193
+ console.log(` Last trace: ${recentActivity.lastTrace}`);
194
+ }
195
+ else {
196
+ console.log(chalk.gray(' Last trace: no traces received'));
197
+ }
198
+ console.log(` Traces total: ${recentActivity.tracesTotal}`);
199
+ console.log(` Logs total: ${recentActivity.logsTotal}`);
200
+ if (recentActivity.services.length > 0) {
201
+ console.log(chalk.bold('\n Recent Services:'));
202
+ for (const svc of recentActivity.services) {
203
+ console.log(chalk.gray(` • ${svc.name}: ${svc.traces} traces, last seen ${svc.lastSeen}`));
204
+ }
205
+ }
206
+ }
207
+ console.log('\n' + '━'.repeat(60));
208
+ if (issues.length === 0) {
209
+ console.log(chalk.green('No issues detected.'));
210
+ }
211
+ else {
212
+ console.log(chalk.red(`${issues.length} issue(s) detected:`));
213
+ for (const issue of issues) {
214
+ console.log(chalk.yellow(` • ${issue}`));
215
+ }
216
+ }
217
+ console.log();
218
+ }
219
+ if (issues.length > 0) {
220
+ process.exit(1);
221
+ }
222
+ }
223
+ catch (error) {
224
+ console.error(chalk.red('Error:'), error.message);
225
+ process.exit(1);
226
+ }
227
+ });
228
+ return command;
229
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Collector commands - Check OTEL collector status and connectivity
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare function createCollectorCommand(): Command;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/collector/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,sBAAsB,IAAI,OAAO,CAUhD"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Collector commands - Check OTEL collector status and connectivity
3
+ */
4
+ import { Command } from 'commander';
5
+ import { createStatusCommand } from './status.js';
6
+ import { createCheckCommand } from './check.js';
7
+ import { createDiagnoseCommand } from './diagnose.js';
8
+ export function createCollectorCommand() {
9
+ const command = new Command('collector');
10
+ command
11
+ .description('Check OTEL collector status and connectivity')
12
+ .addCommand(createStatusCommand())
13
+ .addCommand(createCheckCommand())
14
+ .addCommand(createDiagnoseCommand());
15
+ return command;
16
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * collector status - Check OTEL collector health and service statistics
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare function createStatusCommand(): Command;
6
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/collector/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,wBAAgB,mBAAmB,IAAI,OAAO,CAyF7C"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * collector status - Check OTEL collector health and service statistics
3
+ */
4
+ import { Command } from 'commander';
5
+ import chalk from 'chalk';
6
+ import { DEFAULT_COLLECTOR_PORT, checkHealth, getServiceStats, formatRelativeTime, } from './utils.js';
7
+ export function createStatusCommand() {
8
+ const command = new Command('status');
9
+ command
10
+ .description('Check OTEL collector health and active services')
11
+ .option('-p, --port <port>', `Collector port (default: ${DEFAULT_COLLECTOR_PORT})`)
12
+ .option('--json', 'Output as JSON')
13
+ .action(async (options) => {
14
+ try {
15
+ const port = options.port ? parseInt(options.port, 10) : DEFAULT_COLLECTOR_PORT;
16
+ const endpoint = `http://localhost:${port}`;
17
+ // Get health status
18
+ const health = await checkHealth(port);
19
+ const stats = health ? await getServiceStats(port) : null;
20
+ if (options.json) {
21
+ console.log(JSON.stringify({
22
+ endpoint,
23
+ healthy: health !== null,
24
+ tracesReceived: health?.tracesReceived ?? 0,
25
+ logsReceived: health?.logsReceived ?? 0,
26
+ services: stats ?? null,
27
+ }, null, 2));
28
+ }
29
+ else {
30
+ console.log(chalk.bold('\nOTEL Collector Status'));
31
+ console.log('━'.repeat(60));
32
+ console.log(`\n Endpoint: ${endpoint}`);
33
+ if (health) {
34
+ console.log(` Status: ${chalk.green('✓ healthy')}`);
35
+ console.log(` Traces received: ${health.tracesReceived ?? 0}`);
36
+ console.log(` Logs received: ${health.logsReceived ?? 0}`);
37
+ if (stats && stats.summary.totalServices > 0) {
38
+ console.log(`\n Services (${stats.summary.aliveServices} active, ${stats.summary.totalServices} total):`);
39
+ const sortedServices = Object.entries(stats.services).sort((a, b) => {
40
+ // Sort by lastSeen (most recent first)
41
+ return new Date(b[1].lastSeen).getTime() - new Date(a[1].lastSeen).getTime();
42
+ });
43
+ for (const [serviceName, info] of sortedServices) {
44
+ const statusIcon = info.isAlive ? chalk.green('✓') : chalk.gray('○');
45
+ const lastSeen = formatRelativeTime(info.lastSeen);
46
+ const traceCount = `(${info.totalTraces} traces)`;
47
+ console.log(` ${statusIcon} ${serviceName.padEnd(20)} ${chalk.gray(`last seen ${lastSeen}`)} ${chalk.gray(traceCount)}`);
48
+ }
49
+ }
50
+ else {
51
+ console.log(chalk.gray('\n No services have sent traces yet.'));
52
+ }
53
+ console.log('\n' + '━'.repeat(60));
54
+ console.log(chalk.green('Collector is ready to receive traces.'));
55
+ }
56
+ else {
57
+ console.log(` Status: ${chalk.red('✗ unreachable')}`);
58
+ console.log('\n' + '━'.repeat(60));
59
+ console.log(chalk.bold('\n Troubleshooting:'));
60
+ console.log(chalk.gray(' • Verify the collector is running'));
61
+ console.log(chalk.gray(` • Check if port ${port} is in use by another process`));
62
+ console.log(chalk.gray(` • Try: curl ${endpoint}/health`));
63
+ }
64
+ console.log();
65
+ }
66
+ // Exit with error if not healthy
67
+ if (!health) {
68
+ process.exit(1);
69
+ }
70
+ }
71
+ catch (error) {
72
+ console.error(chalk.red('Error:'), error.message);
73
+ process.exit(1);
74
+ }
75
+ });
76
+ return command;
77
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Shared utilities for collector commands
3
+ */
4
+ export declare const DEFAULT_COLLECTOR_PORT = 4318;
5
+ export interface HealthResponse {
6
+ status: string;
7
+ tracesReceived?: number;
8
+ logsReceived?: number;
9
+ }
10
+ export interface ServiceStats {
11
+ summary: {
12
+ totalServices: number;
13
+ aliveServices: number;
14
+ totalTraces: number;
15
+ };
16
+ services: Record<string, ServiceInfo>;
17
+ }
18
+ export interface ServiceInfo {
19
+ firstSeen: string;
20
+ lastSeen: string;
21
+ totalTraces: number;
22
+ isAlive: boolean;
23
+ }
24
+ export interface OTLPTracePayload {
25
+ resourceSpans: Array<{
26
+ resource: {
27
+ attributes: Array<{
28
+ key: string;
29
+ value: {
30
+ stringValue?: string;
31
+ boolValue?: boolean;
32
+ };
33
+ }>;
34
+ };
35
+ scopeSpans: Array<{
36
+ scope: {
37
+ name: string;
38
+ };
39
+ spans: Array<{
40
+ traceId: string;
41
+ spanId: string;
42
+ name: string;
43
+ kind: number;
44
+ startTimeUnixNano: string;
45
+ endTimeUnixNano: string;
46
+ attributes: Array<{
47
+ key: string;
48
+ value: {
49
+ stringValue?: string;
50
+ };
51
+ }>;
52
+ status: {
53
+ code: number;
54
+ };
55
+ }>;
56
+ }>;
57
+ }>;
58
+ }
59
+ /**
60
+ * Check if the collector is healthy
61
+ */
62
+ export declare function checkHealth(port: number): Promise<HealthResponse | null>;
63
+ /**
64
+ * Get service statistics from the collector
65
+ */
66
+ export declare function getServiceStats(port: number): Promise<ServiceStats | null>;
67
+ /**
68
+ * Create a minimal test trace payload
69
+ */
70
+ export declare function createTestTrace(serviceName: string): OTLPTracePayload;
71
+ export interface SendTraceResult {
72
+ success: boolean;
73
+ statusCode?: number;
74
+ latencyMs: number;
75
+ error?: string;
76
+ }
77
+ /**
78
+ * Send a test trace to the collector
79
+ */
80
+ export declare function sendTestTrace(port: number, trace: OTLPTracePayload, authToken?: string): Promise<SendTraceResult>;
81
+ /**
82
+ * Format relative time (e.g., "30s ago", "2m ago")
83
+ */
84
+ export declare function formatRelativeTime(isoString: string): string;
85
+ /**
86
+ * Check if a port is responding (basic connectivity check)
87
+ */
88
+ export declare function checkPort(port: number): Promise<{
89
+ open: boolean;
90
+ service?: string;
91
+ }>;
92
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/commands/collector/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAG3C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE;QACP,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,KAAK,CAAC;QACnB,QAAQ,EAAE;YACR,UAAU,EAAE,KAAK,CAAC;gBAAE,GAAG,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE;oBAAE,WAAW,CAAC,EAAE,MAAM,CAAC;oBAAC,SAAS,CAAC,EAAE,OAAO,CAAA;iBAAE,CAAA;aAAE,CAAC,CAAC;SAC1F,CAAC;QACF,UAAU,EAAE,KAAK,CAAC;YAChB,KAAK,EAAE;gBAAE,IAAI,EAAE,MAAM,CAAA;aAAE,CAAC;YACxB,KAAK,EAAE,KAAK,CAAC;gBACX,OAAO,EAAE,MAAM,CAAC;gBAChB,MAAM,EAAE,MAAM,CAAC;gBACf,IAAI,EAAE,MAAM,CAAC;gBACb,IAAI,EAAE,MAAM,CAAC;gBACb,iBAAiB,EAAE,MAAM,CAAC;gBAC1B,eAAe,EAAE,MAAM,CAAC;gBACxB,UAAU,EAAE,KAAK,CAAC;oBAAE,GAAG,EAAE,MAAM,CAAC;oBAAC,KAAK,EAAE;wBAAE,WAAW,CAAC,EAAE,MAAM,CAAA;qBAAE,CAAA;iBAAE,CAAC,CAAC;gBACpE,MAAM,EAAE;oBAAE,IAAI,EAAE,MAAM,CAAA;iBAAE,CAAC;aAC1B,CAAC,CAAC;SACJ,CAAC,CAAC;KACJ,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAc9E;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAchF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,CAuCrE;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,gBAAgB,EACvB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,CAAC,CAkC1B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAkB5D;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAc1F"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Shared utilities for collector commands
3
+ */
4
+ import crypto from 'node:crypto';
5
+ export const DEFAULT_COLLECTOR_PORT = 4318;
6
+ const DEFAULT_TIMEOUT_MS = 2000;
7
+ /**
8
+ * Check if the collector is healthy
9
+ */
10
+ export async function checkHealth(port) {
11
+ try {
12
+ const response = await fetch(`http://localhost:${port}/health`, {
13
+ signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),
14
+ });
15
+ if (!response.ok) {
16
+ return null;
17
+ }
18
+ return (await response.json());
19
+ }
20
+ catch {
21
+ return null;
22
+ }
23
+ }
24
+ /**
25
+ * Get service statistics from the collector
26
+ */
27
+ export async function getServiceStats(port) {
28
+ try {
29
+ const response = await fetch(`http://localhost:${port}/services/stats`, {
30
+ signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),
31
+ });
32
+ if (!response.ok) {
33
+ return null;
34
+ }
35
+ return (await response.json());
36
+ }
37
+ catch {
38
+ return null;
39
+ }
40
+ }
41
+ /**
42
+ * Create a minimal test trace payload
43
+ */
44
+ export function createTestTrace(serviceName) {
45
+ const traceId = crypto.randomUUID().replace(/-/g, '');
46
+ const spanId = crypto.randomUUID().replace(/-/g, '').slice(0, 16);
47
+ const now = Date.now() * 1_000_000; // Convert to nanoseconds
48
+ return {
49
+ resourceSpans: [
50
+ {
51
+ resource: {
52
+ attributes: [
53
+ { key: 'service.name', value: { stringValue: serviceName } },
54
+ { key: 'principal.cli.test', value: { boolValue: true } },
55
+ ],
56
+ },
57
+ scopeSpans: [
58
+ {
59
+ scope: { name: 'principal-cli-check' },
60
+ spans: [
61
+ {
62
+ traceId,
63
+ spanId,
64
+ name: 'cli.connectivity.test',
65
+ kind: 1, // INTERNAL
66
+ startTimeUnixNano: String(now),
67
+ endTimeUnixNano: String(now + 1_000_000), // 1ms duration
68
+ attributes: [
69
+ {
70
+ key: 'test.timestamp',
71
+ value: { stringValue: new Date().toISOString() },
72
+ },
73
+ ],
74
+ status: { code: 1 }, // OK
75
+ },
76
+ ],
77
+ },
78
+ ],
79
+ },
80
+ ],
81
+ };
82
+ }
83
+ /**
84
+ * Send a test trace to the collector
85
+ */
86
+ export async function sendTestTrace(port, trace, authToken) {
87
+ const start = Date.now();
88
+ try {
89
+ const headers = {
90
+ 'Content-Type': 'application/json',
91
+ };
92
+ if (authToken) {
93
+ headers['Authorization'] = `Bearer ${authToken}`;
94
+ }
95
+ const response = await fetch(`http://localhost:${port}/v1/traces`, {
96
+ method: 'POST',
97
+ headers,
98
+ body: JSON.stringify(trace),
99
+ signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),
100
+ });
101
+ const latencyMs = Date.now() - start;
102
+ return {
103
+ success: response.ok,
104
+ statusCode: response.status,
105
+ latencyMs,
106
+ error: response.ok ? undefined : `HTTP ${response.status}`,
107
+ };
108
+ }
109
+ catch (error) {
110
+ return {
111
+ success: false,
112
+ latencyMs: Date.now() - start,
113
+ error: error.message,
114
+ };
115
+ }
116
+ }
117
+ /**
118
+ * Format relative time (e.g., "30s ago", "2m ago")
119
+ */
120
+ export function formatRelativeTime(isoString) {
121
+ const date = new Date(isoString);
122
+ const now = Date.now();
123
+ const diffMs = now - date.getTime();
124
+ if (diffMs < 0)
125
+ return 'just now';
126
+ const seconds = Math.floor(diffMs / 1000);
127
+ if (seconds < 60)
128
+ return `${seconds}s ago`;
129
+ const minutes = Math.floor(seconds / 60);
130
+ if (minutes < 60)
131
+ return `${minutes}m ago`;
132
+ const hours = Math.floor(minutes / 60);
133
+ if (hours < 24)
134
+ return `${hours}h ago`;
135
+ const days = Math.floor(hours / 24);
136
+ return `${days}d ago`;
137
+ }
138
+ /**
139
+ * Check if a port is responding (basic connectivity check)
140
+ */
141
+ export async function checkPort(port) {
142
+ try {
143
+ const response = await fetch(`http://localhost:${port}/health`, {
144
+ signal: AbortSignal.timeout(1000),
145
+ });
146
+ if (response.ok) {
147
+ return { open: true, service: 'collector' };
148
+ }
149
+ return { open: true, service: 'unknown' };
150
+ }
151
+ catch {
152
+ return { open: false };
153
+ }
154
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Coverage command - Measure telemetry coverage for canvas nodes
3
+ *
4
+ * This command analyzes .otel.canvas files and checks which implementation files
5
+ * contain the OpenTelemetry events documented in canvas nodes.
6
+ */
7
+ import { Command } from 'commander';
8
+ export declare function createCoverageCommand(): Command;
9
+ //# sourceMappingURL=coverage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../src/commands/coverage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuNpC,wBAAgB,qBAAqB,IAAI,OAAO,CAkE/C"}