@stoneforge/quarry 1.10.1 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -135,7 +135,7 @@ Arguments:
135
135
  id Element identifier (e.g., el-abc123)
136
136
 
137
137
  Options:
138
- -n, --limit <n> Maximum events to show (default: 50)
138
+ -l, --limit <n> Maximum events to show (default: 50)
139
139
  -t, --type <type> Filter by event type
140
140
  -a, --actor <actor> Filter by actor
141
141
  --after <time> Show events after this time (ISO 8601)
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Log Command - Show operation log entries
3
+ *
4
+ * Provides CLI access to the persistent operation log, allowing users
5
+ * to query system events (dispatch, session, merge, rate-limit, recovery).
6
+ *
7
+ * Examples:
8
+ * sf log Show last 20 entries
9
+ * sf log --level error Filter by level
10
+ * sf log --category rate-limit Filter by category
11
+ * sf log --since 2h Relative time filter
12
+ * sf log --task el-xxxx Filter by task
13
+ * sf log --agent el-xxxx Filter by agent
14
+ * sf log --limit 50 Control output count
15
+ */
16
+ import type { Command } from '../types.js';
17
+ export declare const logCommand: Command;
18
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAA+C,MAAM,aAAa,CAAC;AA+SxF,eAAO,MAAM,UAAU,EAAE,OAiCxB,CAAC"}
@@ -0,0 +1,282 @@
1
+ /**
2
+ * Log Command - Show operation log entries
3
+ *
4
+ * Provides CLI access to the persistent operation log, allowing users
5
+ * to query system events (dispatch, session, merge, rate-limit, recovery).
6
+ *
7
+ * Examples:
8
+ * sf log Show last 20 entries
9
+ * sf log --level error Filter by level
10
+ * sf log --category rate-limit Filter by category
11
+ * sf log --since 2h Relative time filter
12
+ * sf log --task el-xxxx Filter by task
13
+ * sf log --agent el-xxxx Filter by agent
14
+ * sf log --limit 50 Control output count
15
+ */
16
+ import { success, failure, ExitCode } from '../types.js';
17
+ import { getOutputMode } from '../formatter.js';
18
+ import { createAPI } from '../db.js';
19
+ // ============================================================================
20
+ // Helpers
21
+ // ============================================================================
22
+ const VALID_LEVELS = ['info', 'warn', 'error'];
23
+ const VALID_CATEGORIES = ['dispatch', 'merge', 'session', 'rate-limit', 'steward', 'recovery'];
24
+ /**
25
+ * Parse a relative time string (e.g. "2h", "30m", "1d") into an ISO timestamp.
26
+ * Falls back to treating the string as an ISO 8601 timestamp.
27
+ */
28
+ function parseSinceValue(value) {
29
+ const relativeMatch = value.match(/^(\d+(?:\.\d+)?)\s*(s|m|h|d|w)$/i);
30
+ if (relativeMatch) {
31
+ const amount = parseFloat(relativeMatch[1]);
32
+ const unit = relativeMatch[2].toLowerCase();
33
+ const multipliers = {
34
+ s: 1000,
35
+ m: 60 * 1000,
36
+ h: 60 * 60 * 1000,
37
+ d: 24 * 60 * 60 * 1000,
38
+ w: 7 * 24 * 60 * 60 * 1000,
39
+ };
40
+ const ms = amount * multipliers[unit];
41
+ return new Date(Date.now() - ms).toISOString();
42
+ }
43
+ // Treat as ISO timestamp — validate it parses
44
+ const date = new Date(value);
45
+ if (isNaN(date.getTime())) {
46
+ throw new Error(`Invalid --since value: "${value}". Use relative time (e.g. 2h, 30m, 1d) or ISO 8601 timestamp.`);
47
+ }
48
+ return date.toISOString();
49
+ }
50
+ /**
51
+ * Format a timestamp for display.
52
+ * Shows relative time for recent entries, full timestamp for older ones.
53
+ */
54
+ function formatTimestamp(isoTimestamp) {
55
+ const date = new Date(isoTimestamp);
56
+ const now = Date.now();
57
+ const diffMs = now - date.getTime();
58
+ if (diffMs < 60_000) {
59
+ return `${Math.floor(diffMs / 1000)}s ago`;
60
+ }
61
+ if (diffMs < 3600_000) {
62
+ return `${Math.floor(diffMs / 60_000)}m ago`;
63
+ }
64
+ if (diffMs < 86400_000) {
65
+ return `${Math.floor(diffMs / 3600_000)}h ago`;
66
+ }
67
+ // For older entries, show the date and time
68
+ return date.toLocaleString('en-US', {
69
+ month: 'short',
70
+ day: 'numeric',
71
+ hour: '2-digit',
72
+ minute: '2-digit',
73
+ hour12: false,
74
+ });
75
+ }
76
+ /**
77
+ * Format a log level with consistent width and visual indicator
78
+ */
79
+ function formatLevel(level) {
80
+ switch (level) {
81
+ case 'error':
82
+ return 'ERR ';
83
+ case 'warn':
84
+ return 'WARN';
85
+ case 'info':
86
+ return 'INFO';
87
+ default:
88
+ return level.toUpperCase().padEnd(4);
89
+ }
90
+ }
91
+ // ============================================================================
92
+ // Command Options
93
+ // ============================================================================
94
+ const logOptions = [
95
+ {
96
+ name: 'level',
97
+ description: `Filter by log level (${VALID_LEVELS.join(', ')})`,
98
+ hasValue: true,
99
+ },
100
+ {
101
+ name: 'category',
102
+ short: 'c',
103
+ description: `Filter by category (${VALID_CATEGORIES.join(', ')})`,
104
+ hasValue: true,
105
+ },
106
+ {
107
+ name: 'since',
108
+ short: 's',
109
+ description: 'Show entries since time (e.g. 2h, 30m, 1d) or ISO 8601 timestamp',
110
+ hasValue: true,
111
+ },
112
+ {
113
+ name: 'task',
114
+ short: 't',
115
+ description: 'Filter by task ID',
116
+ hasValue: true,
117
+ },
118
+ {
119
+ name: 'agent',
120
+ short: 'a',
121
+ description: 'Filter by agent ID',
122
+ hasValue: true,
123
+ },
124
+ {
125
+ name: 'limit',
126
+ short: 'l',
127
+ description: 'Maximum number of entries to show (default: 20)',
128
+ hasValue: true,
129
+ },
130
+ ];
131
+ // ============================================================================
132
+ // Handler
133
+ // ============================================================================
134
+ async function logHandler(_args, options) {
135
+ const { backend, error } = createAPI(options);
136
+ if (error) {
137
+ return failure(error, ExitCode.GENERAL_ERROR);
138
+ }
139
+ try {
140
+ // Validate level
141
+ if (options.level && !VALID_LEVELS.includes(options.level)) {
142
+ return failure(`Invalid --level: "${options.level}". Must be one of: ${VALID_LEVELS.join(', ')}`, ExitCode.VALIDATION);
143
+ }
144
+ // Validate category
145
+ if (options.category && !VALID_CATEGORIES.includes(options.category)) {
146
+ return failure(`Invalid --category: "${options.category}". Must be one of: ${VALID_CATEGORIES.join(', ')}`, ExitCode.VALIDATION);
147
+ }
148
+ // Validate and parse limit
149
+ let limit = 20;
150
+ if (options.limit) {
151
+ limit = parseInt(options.limit, 10);
152
+ if (isNaN(limit) || limit < 1) {
153
+ return failure('--limit must be a positive number', ExitCode.VALIDATION);
154
+ }
155
+ }
156
+ // Parse --since
157
+ let since;
158
+ if (options.since) {
159
+ try {
160
+ since = parseSinceValue(options.since);
161
+ }
162
+ catch (err) {
163
+ const msg = err instanceof Error ? err.message : String(err);
164
+ return failure(msg, ExitCode.VALIDATION);
165
+ }
166
+ }
167
+ // Build SQL query directly (the CLI has direct storage access)
168
+ const conditions = [];
169
+ const params = [];
170
+ if (options.level) {
171
+ conditions.push('level = ?');
172
+ params.push(options.level);
173
+ }
174
+ if (options.category) {
175
+ conditions.push('category = ?');
176
+ params.push(options.category);
177
+ }
178
+ if (since) {
179
+ conditions.push('timestamp >= ?');
180
+ params.push(since);
181
+ }
182
+ if (options.task) {
183
+ conditions.push('task_id = ?');
184
+ params.push(options.task);
185
+ }
186
+ if (options.agent) {
187
+ conditions.push('agent_id = ?');
188
+ params.push(options.agent);
189
+ }
190
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
191
+ const rows = backend.query(`SELECT id, timestamp, level, category, agent_id, task_id, message, details
192
+ FROM operation_log
193
+ ${whereClause}
194
+ ORDER BY timestamp DESC
195
+ LIMIT ?`, [...params, limit]);
196
+ // Map rows to a JSON-friendly shape
197
+ const entries = rows.map((row) => ({
198
+ id: row.id,
199
+ timestamp: row.timestamp,
200
+ level: row.level,
201
+ category: row.category,
202
+ agentId: row.agent_id ?? undefined,
203
+ taskId: row.task_id ?? undefined,
204
+ message: row.message,
205
+ details: row.details ? JSON.parse(row.details) : undefined,
206
+ }));
207
+ const mode = getOutputMode(options);
208
+ if (mode === 'json') {
209
+ return success(entries);
210
+ }
211
+ if (mode === 'quiet') {
212
+ const ids = entries.map((e) => e.id).join('\n');
213
+ return success(ids);
214
+ }
215
+ // Human-readable output
216
+ if (entries.length === 0) {
217
+ return success([], 'No log entries found.');
218
+ }
219
+ const lines = [];
220
+ // Show entries in reverse chronological order (newest first)
221
+ for (const entry of entries) {
222
+ const time = formatTimestamp(entry.timestamp);
223
+ const level = formatLevel(entry.level);
224
+ const cat = entry.category.padEnd(10);
225
+ let line = `${time.padEnd(14)} ${level} ${cat} ${entry.message}`;
226
+ // Append context tags
227
+ const tags = [];
228
+ if (entry.taskId)
229
+ tags.push(`task=${entry.taskId}`);
230
+ if (entry.agentId)
231
+ tags.push(`agent=${entry.agentId}`);
232
+ if (tags.length > 0) {
233
+ line += ` [${tags.join(', ')}]`;
234
+ }
235
+ lines.push(line);
236
+ }
237
+ const header = `Operation Log (${entries.length} entries):\n`;
238
+ return success(entries, header + lines.join('\n'));
239
+ }
240
+ catch (err) {
241
+ const message = err instanceof Error ? err.message : String(err);
242
+ return failure(`Failed to query operation log: ${message}`, ExitCode.GENERAL_ERROR);
243
+ }
244
+ }
245
+ // ============================================================================
246
+ // Command Definition
247
+ // ============================================================================
248
+ export const logCommand = {
249
+ name: 'log',
250
+ description: 'Show operation log entries',
251
+ usage: 'sf log [options]',
252
+ help: `Show persistent operation log entries for system observability.
253
+
254
+ The operation log captures key events from the orchestration system including
255
+ dispatch, session, merge, rate-limit, steward, and recovery events.
256
+
257
+ Options:
258
+ --level <level> Filter by level: info, warn, error
259
+ -c, --category <cat> Filter by category: dispatch, merge, session,
260
+ rate-limit, steward, recovery
261
+ -s, --since <time> Show entries since time. Accepts relative time
262
+ (e.g. 2h, 30m, 1d, 1w) or ISO 8601 timestamp
263
+ -t, --task <id> Filter by task ID
264
+ -a, --agent <id> Filter by agent ID
265
+ -l, --limit <n> Maximum entries to show (default: 20)
266
+
267
+ Examples:
268
+ sf log Show last 20 entries
269
+ sf log --level error Show only errors
270
+ sf log --category session Show session events
271
+ sf log --category rate-limit Show rate limit events
272
+ sf log --since 2h Show entries from last 2 hours
273
+ sf log --since 2026-02-23T00:00:00 Show entries since specific time
274
+ sf log --task el-xxxx Show entries for a specific task
275
+ sf log --agent el-xxxx Show entries for a specific agent
276
+ sf log --limit 50 Show last 50 entries
277
+ sf log --level error --since 1d Combine filters
278
+ sf log --json Output as JSON`,
279
+ options: logOptions,
280
+ handler: logHandler,
281
+ };
282
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../../src/cli/commands/log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Metrics Command - Show provider metrics
3
+ *
4
+ * Displays LLM provider usage metrics including token counts,
5
+ * estimated costs, session counts, and error rates.
6
+ */
7
+ import type { Command } from '../types.js';
8
+ export declare const metricsCommand: Command;
9
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/metrics.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAA+C,MAAM,aAAa,CAAC;AAwQxF,eAAO,MAAM,cAAc,EAAE,OAoB5B,CAAC"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Metrics Command - Show provider metrics
3
+ *
4
+ * Displays LLM provider usage metrics including token counts,
5
+ * estimated costs, session counts, and error rates.
6
+ */
7
+ import { success, failure, ExitCode } from '../types.js';
8
+ import { createAPI } from '../db.js';
9
+ // ============================================================================
10
+ // Helpers
11
+ // ============================================================================
12
+ /**
13
+ * Parse a time range string (e.g., '7d', '14d', '30d') to number of days.
14
+ */
15
+ function parseTimeRange(value) {
16
+ if (!value)
17
+ return 7;
18
+ const match = value.match(/^(\d+)d$/);
19
+ if (match) {
20
+ const days = parseInt(match[1], 10);
21
+ if (days > 0 && days <= 365)
22
+ return days;
23
+ }
24
+ return 7;
25
+ }
26
+ /**
27
+ * Rough cost estimate based on token counts.
28
+ * Uses approximate Claude pricing: $3/MTok input, $15/MTok output.
29
+ */
30
+ function estimateCost(inputTokens, outputTokens) {
31
+ const inputCost = (inputTokens / 1_000_000) * 3;
32
+ const outputCost = (outputTokens / 1_000_000) * 15;
33
+ return inputCost + outputCost;
34
+ }
35
+ /**
36
+ * Format a number with thousands separators
37
+ */
38
+ function formatNumber(n) {
39
+ return n.toLocaleString('en-US');
40
+ }
41
+ /**
42
+ * Format milliseconds as human-readable duration
43
+ */
44
+ function formatDuration(ms) {
45
+ if (ms < 1000)
46
+ return `${ms}ms`;
47
+ const seconds = Math.round(ms / 1000);
48
+ if (seconds < 60)
49
+ return `${seconds}s`;
50
+ const minutes = Math.floor(seconds / 60);
51
+ const remainingSeconds = seconds % 60;
52
+ if (minutes < 60)
53
+ return `${minutes}m ${remainingSeconds}s`;
54
+ const hours = Math.floor(minutes / 60);
55
+ const remainingMinutes = minutes % 60;
56
+ return `${hours}h ${remainingMinutes}m`;
57
+ }
58
+ /**
59
+ * Format cost as a dollar amount
60
+ */
61
+ function formatCost(cost) {
62
+ if (cost < 0.01)
63
+ return '$0.00';
64
+ return `$${cost.toFixed(2)}`;
65
+ }
66
+ /**
67
+ * Query aggregated metrics directly from the database
68
+ */
69
+ function queryMetrics(backend, days, groupBy, providerFilter) {
70
+ const cutoff = new Date();
71
+ cutoff.setDate(cutoff.getDate() - days);
72
+ const cutoffStr = cutoff.toISOString();
73
+ const groupExpr = groupBy === 'provider' ? 'provider' : "COALESCE(model, 'unknown')";
74
+ const params = [cutoffStr];
75
+ let whereClause = 'WHERE timestamp >= ?';
76
+ if (providerFilter) {
77
+ whereClause += ' AND provider = ?';
78
+ params.push(providerFilter);
79
+ }
80
+ return backend.query(`SELECT
81
+ ${groupExpr} AS group_key,
82
+ COALESCE(SUM(input_tokens), 0) AS total_input_tokens,
83
+ COALESCE(SUM(output_tokens), 0) AS total_output_tokens,
84
+ COUNT(*) AS session_count,
85
+ COALESCE(AVG(duration_ms), 0) AS avg_duration_ms,
86
+ COALESCE(SUM(CASE WHEN outcome = 'failed' THEN 1 ELSE 0 END), 0) AS failed_count,
87
+ COALESCE(SUM(CASE WHEN outcome = 'rate_limited' THEN 1 ELSE 0 END), 0) AS rate_limited_count
88
+ FROM provider_metrics
89
+ ${whereClause}
90
+ GROUP BY group_key
91
+ ORDER BY total_input_tokens + total_output_tokens DESC`, params);
92
+ }
93
+ // ============================================================================
94
+ // Handler
95
+ // ============================================================================
96
+ async function metricsHandler(_args, options) {
97
+ const { backend, error } = createAPI(options);
98
+ if (error) {
99
+ return failure(error, ExitCode.GENERAL_ERROR);
100
+ }
101
+ try {
102
+ const days = parseTimeRange(options.range);
103
+ const providerFilter = options.provider;
104
+ const groupBy = options['group-by'] === 'model' ? 'model' : 'provider';
105
+ const rows = queryMetrics(backend, days, groupBy, providerFilter);
106
+ const metrics = rows.map(row => ({
107
+ group: row.group_key,
108
+ totalInputTokens: Number(row.total_input_tokens),
109
+ totalOutputTokens: Number(row.total_output_tokens),
110
+ totalTokens: Number(row.total_input_tokens) + Number(row.total_output_tokens),
111
+ sessionCount: Number(row.session_count),
112
+ avgDurationMs: Math.round(Number(row.avg_duration_ms)),
113
+ errorRate: Number(row.session_count) > 0
114
+ ? Number(row.failed_count) / Number(row.session_count)
115
+ : 0,
116
+ failedCount: Number(row.failed_count),
117
+ rateLimitedCount: Number(row.rate_limited_count),
118
+ estimatedCost: estimateCost(Number(row.total_input_tokens), Number(row.total_output_tokens)),
119
+ }));
120
+ const totals = {
121
+ totalInputTokens: metrics.reduce((sum, m) => sum + m.totalInputTokens, 0),
122
+ totalOutputTokens: metrics.reduce((sum, m) => sum + m.totalOutputTokens, 0),
123
+ totalTokens: metrics.reduce((sum, m) => sum + m.totalTokens, 0),
124
+ sessionCount: metrics.reduce((sum, m) => sum + m.sessionCount, 0),
125
+ estimatedCost: metrics.reduce((sum, m) => sum + m.estimatedCost, 0),
126
+ };
127
+ const summary = {
128
+ timeRange: { days, label: `${days}d` },
129
+ groupBy,
130
+ metrics,
131
+ totals,
132
+ };
133
+ // Build human-readable output
134
+ const lines = [];
135
+ const groupLabel = groupBy === 'provider' ? 'Provider' : 'Model';
136
+ lines.push(`Provider Metrics (last ${days} days)`);
137
+ if (providerFilter) {
138
+ lines.push(`Filtered by provider: ${providerFilter}`);
139
+ }
140
+ lines.push('');
141
+ if (metrics.length === 0) {
142
+ lines.push('No metrics recorded for the selected time range.');
143
+ return success(summary, lines.join('\n'));
144
+ }
145
+ // Summary totals
146
+ lines.push('Summary:');
147
+ lines.push(` Total tokens: ${formatNumber(totals.totalTokens)}`);
148
+ lines.push(` Input tokens: ${formatNumber(totals.totalInputTokens)}`);
149
+ lines.push(` Output tokens: ${formatNumber(totals.totalOutputTokens)}`);
150
+ lines.push(` Sessions: ${formatNumber(totals.sessionCount)}`);
151
+ lines.push(` Estimated cost: ${formatCost(totals.estimatedCost)}`);
152
+ lines.push('');
153
+ // Per-group breakdown
154
+ lines.push(`By ${groupLabel}:`);
155
+ lines.push('');
156
+ for (const m of metrics) {
157
+ lines.push(` ${m.group}`);
158
+ lines.push(` Tokens: ${formatNumber(m.totalTokens)} (in: ${formatNumber(m.totalInputTokens)}, out: ${formatNumber(m.totalOutputTokens)})`);
159
+ lines.push(` Sessions: ${formatNumber(m.sessionCount)}`);
160
+ lines.push(` Avg duration: ${formatDuration(m.avgDurationMs)}`);
161
+ lines.push(` Error rate: ${(m.errorRate * 100).toFixed(1)}% (${m.failedCount} failed, ${m.rateLimitedCount} rate limited)`);
162
+ lines.push(` Est. cost: ${formatCost(m.estimatedCost)}`);
163
+ lines.push('');
164
+ }
165
+ return success(summary, lines.join('\n'));
166
+ }
167
+ catch (err) {
168
+ const message = err instanceof Error ? err.message : String(err);
169
+ return failure(`Failed to get metrics: ${message}`, ExitCode.GENERAL_ERROR);
170
+ }
171
+ }
172
+ // ============================================================================
173
+ // Command Options
174
+ // ============================================================================
175
+ const metricsOptions = [
176
+ {
177
+ name: 'range',
178
+ short: 'r',
179
+ description: 'Time range (e.g., 7d, 14d, 30d)',
180
+ hasValue: true,
181
+ },
182
+ {
183
+ name: 'provider',
184
+ short: 'p',
185
+ description: 'Filter by provider name',
186
+ hasValue: true,
187
+ },
188
+ {
189
+ name: 'group-by',
190
+ short: 'g',
191
+ description: 'Group by: provider (default) or model',
192
+ hasValue: true,
193
+ },
194
+ ];
195
+ // ============================================================================
196
+ // Command Definition
197
+ // ============================================================================
198
+ export const metricsCommand = {
199
+ name: 'metrics',
200
+ description: 'Show provider metrics and usage statistics',
201
+ usage: 'sf metrics [options]',
202
+ help: `Show LLM provider usage metrics including token counts, estimated costs,
203
+ session counts, average duration, and error rates.
204
+
205
+ Options:
206
+ --range, -r Time range (e.g., 7d, 14d, 30d). Default: 7d
207
+ --provider, -p Filter by provider name (e.g., claude-code)
208
+ --group-by, -g Group by: provider (default) or model
209
+
210
+ Examples:
211
+ sf metrics Show metrics for last 7 days
212
+ sf metrics --range 30d Show metrics for last 30 days
213
+ sf metrics --provider claude-code Filter by provider
214
+ sf metrics --group-by model Group by model
215
+ sf metrics --json Output as JSON`,
216
+ handler: metricsHandler,
217
+ options: metricsOptions,
218
+ };
219
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../src/cli/commands/metrics.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/cli/runner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAgC,MAAM,YAAY,CAAC;AAiBxE;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAEtD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAEtE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAI5D;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,EAAE,CAE1C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAEnD;AAwDD;;GAEG;AACH,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAkGzD;AAgCD;;GAEG;AACH,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,KAAK,CAAC,CAuKjF"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/cli/runner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAgC,MAAM,YAAY,CAAC;AAiBxE;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAEtD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAEtE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAI5D;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,EAAE,CAE1C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAEnD;AAwDD;;GAEG;AACH,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAkGzD;AAgCD;;GAEG;AACH,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,KAAK,CAAC,CA6KjF"}
@@ -222,9 +222,11 @@ export async function main(argv = process.argv.slice(2)) {
222
222
  const { identityCommand, whoamiCommand } = await import('./commands/identity.js');
223
223
  const { entityCommand } = await import('./commands/entity.js');
224
224
  const { statsCommand } = await import('./commands/stats.js');
225
+ const { metricsCommand } = await import('./commands/metrics.js');
225
226
  const { doctorCommand, migrateCommand } = await import('./commands/admin.js');
226
227
  const { gcCommand } = await import('./commands/gc.js');
227
228
  const { historyCommand } = await import('./commands/history.js');
229
+ const { logCommand } = await import('./commands/log.js');
228
230
  const { planCommand } = await import('./commands/plan.js');
229
231
  const { workflowCommand } = await import('./commands/workflow.js');
230
232
  const { playbookCommand } = await import('./commands/playbook.js');
@@ -274,11 +276,14 @@ export async function main(argv = process.argv.slice(2)) {
274
276
  registerCommand(entityCommand);
275
277
  // Admin commands
276
278
  registerCommand(statsCommand);
279
+ registerCommand(metricsCommand);
277
280
  registerCommand(doctorCommand);
278
281
  registerCommand(migrateCommand);
279
282
  registerCommand(gcCommand);
280
283
  // History command
281
284
  registerCommand(historyCommand);
285
+ // Operation log command
286
+ registerCommand(logCommand);
282
287
  // Collection commands
283
288
  registerCommand(planCommand);
284
289
  registerCommand(workflowCommand);