claude-cli-advanced-starter-pack 1.0.16 → 1.8.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 (61) hide show
  1. package/OVERVIEW.md +5 -1
  2. package/README.md +241 -132
  3. package/bin/gtask.js +53 -0
  4. package/package.json +1 -1
  5. package/src/cli/menu.js +27 -0
  6. package/src/commands/explore-mcp/mcp-registry.js +99 -0
  7. package/src/commands/init.js +309 -80
  8. package/src/commands/install-panel-hook.js +108 -0
  9. package/src/commands/install-scripts.js +232 -0
  10. package/src/commands/install-skill.js +220 -0
  11. package/src/commands/panel.js +297 -0
  12. package/src/commands/setup-wizard.js +4 -3
  13. package/src/commands/test-setup.js +4 -5
  14. package/src/data/releases.json +209 -0
  15. package/src/panel/queue.js +188 -0
  16. package/templates/commands/ask-claude.template.md +118 -0
  17. package/templates/commands/ccasp-panel.template.md +72 -0
  18. package/templates/commands/ccasp-setup.template.md +470 -79
  19. package/templates/commands/create-smoke-test.template.md +186 -0
  20. package/templates/commands/project-impl.template.md +9 -113
  21. package/templates/commands/refactor-check.template.md +112 -0
  22. package/templates/commands/refactor-cleanup.template.md +144 -0
  23. package/templates/commands/refactor-prep.template.md +192 -0
  24. package/templates/docs/AI_ARCHITECTURE_CONSTITUTION.template.md +198 -0
  25. package/templates/docs/DETAILED_GOTCHAS.template.md +347 -0
  26. package/templates/docs/PHASE-DEV-CHECKLIST.template.md +241 -0
  27. package/templates/docs/PROGRESS_JSON_TEMPLATE.json +117 -0
  28. package/templates/docs/background-agent.template.md +264 -0
  29. package/templates/hooks/autonomous-decision-logger.template.js +207 -0
  30. package/templates/hooks/branch-merge-checker.template.js +272 -0
  31. package/templates/hooks/context-injector.template.js +261 -0
  32. package/templates/hooks/git-commit-tracker.template.js +267 -0
  33. package/templates/hooks/happy-mode-detector.template.js +214 -0
  34. package/templates/hooks/happy-title-generator.template.js +260 -0
  35. package/templates/hooks/issue-completion-detector.template.js +205 -0
  36. package/templates/hooks/panel-queue-reader.template.js +83 -0
  37. package/templates/hooks/phase-validation-gates.template.js +307 -0
  38. package/templates/hooks/session-id-generator.template.js +236 -0
  39. package/templates/hooks/token-budget-loader.template.js +234 -0
  40. package/templates/hooks/token-usage-monitor.template.js +193 -0
  41. package/templates/hooks/tool-output-cacher.template.js +219 -0
  42. package/templates/patterns/README.md +129 -0
  43. package/templates/patterns/l1-l2-orchestration.md +189 -0
  44. package/templates/patterns/multi-phase-orchestration.md +258 -0
  45. package/templates/patterns/two-tier-query-pipeline.md +192 -0
  46. package/templates/scripts/README.md +109 -0
  47. package/templates/scripts/analyze-delegation-log.js +299 -0
  48. package/templates/scripts/autonomous-decision-logger.js +277 -0
  49. package/templates/scripts/git-history-analyzer.py +269 -0
  50. package/templates/scripts/phase-validation-gates.js +307 -0
  51. package/templates/scripts/poll-deployment-status.js +260 -0
  52. package/templates/scripts/roadmap-scanner.js +263 -0
  53. package/templates/scripts/validate-deployment.js +293 -0
  54. package/templates/skills/agent-creator/skill.json +18 -0
  55. package/templates/skills/agent-creator/skill.md +335 -0
  56. package/templates/skills/hook-creator/skill.json +18 -0
  57. package/templates/skills/hook-creator/skill.md +318 -0
  58. package/templates/skills/panel/skill.json +18 -0
  59. package/templates/skills/panel/skill.md +90 -0
  60. package/templates/skills/rag-agent-creator/skill.json +18 -0
  61. package/templates/skills/rag-agent-creator/skill.md +307 -0
@@ -0,0 +1,192 @@
1
+ # Two-Tier Query Pipeline Pattern
2
+
3
+ Intent classification followed by specialized execution.
4
+
5
+ ## Overview
6
+
7
+ A two-tier architecture that separates:
8
+ 1. **Tier 1**: Intent classification (what kind of request is this?)
9
+ 2. **Tier 2**: Specialized execution (handle based on intent)
10
+
11
+ ## When to Use
12
+
13
+ - Multiple types of requests need different handling
14
+ - Request routing is complex
15
+ - You want to add new handlers without changing core logic
16
+
17
+ ## Architecture
18
+
19
+ ```
20
+ User Request
21
+
22
+ ┌──────────────────────┐
23
+ │ Tier 1: Classifier │ (Fast, lightweight)
24
+ │ - Parse intent │
25
+ │ - Extract entities │
26
+ │ - Route to handler │
27
+ └──────────────────────┘
28
+
29
+ ┌──────────────────────┐
30
+ │ Tier 2: Handler │ (Specialized, thorough)
31
+ │ - Execute task │
32
+ │ - Return result │
33
+ └──────────────────────┘
34
+ ```
35
+
36
+ ## Implementation
37
+
38
+ ### Tier 1: Classifier
39
+
40
+ ```typescript
41
+ interface ClassificationResult {
42
+ intent: string;
43
+ confidence: number;
44
+ entities: Record<string, string>;
45
+ handler: string;
46
+ }
47
+
48
+ async function classifyIntent(request: string): Promise<ClassificationResult> {
49
+ // Pattern matching for common intents
50
+ const patterns = {
51
+ 'create': /create|add|new|make/i,
52
+ 'read': /get|show|list|find|search/i,
53
+ 'update': /update|edit|modify|change/i,
54
+ 'delete': /delete|remove|destroy/i,
55
+ 'analyze': /analyze|check|review|audit/i
56
+ };
57
+
58
+ for (const [intent, pattern] of Object.entries(patterns)) {
59
+ if (pattern.test(request)) {
60
+ return {
61
+ intent,
62
+ confidence: 0.8,
63
+ entities: extractEntities(request),
64
+ handler: `${intent}Handler`
65
+ };
66
+ }
67
+ }
68
+
69
+ return { intent: 'unknown', confidence: 0.5, entities: {}, handler: 'fallbackHandler' };
70
+ }
71
+ ```
72
+
73
+ ### Tier 2: Handlers
74
+
75
+ ```typescript
76
+ const handlers = {
77
+ createHandler: async (entities) => {
78
+ // Launch specialized creation agent
79
+ return Task({
80
+ description: `Create ${entities.type}`,
81
+ prompt: `Create a new ${entities.type} with: ${JSON.stringify(entities)}`,
82
+ subagent_type: 'general-purpose'
83
+ });
84
+ },
85
+
86
+ readHandler: async (entities) => {
87
+ // Launch exploration agent
88
+ return Task({
89
+ description: `Find ${entities.target}`,
90
+ prompt: `Search for ${entities.target} in the codebase`,
91
+ subagent_type: 'Explore'
92
+ });
93
+ },
94
+
95
+ analyzeHandler: async (entities) => {
96
+ // Launch analysis agent
97
+ return Task({
98
+ description: `Analyze ${entities.scope}`,
99
+ prompt: `Perform analysis on ${entities.scope}`,
100
+ subagent_type: 'Plan'
101
+ });
102
+ },
103
+
104
+ fallbackHandler: async (entities) => {
105
+ // Ask for clarification
106
+ return { needsClarification: true, entities };
107
+ }
108
+ };
109
+ ```
110
+
111
+ ### Pipeline Execution
112
+
113
+ ```typescript
114
+ async function executeQuery(request: string) {
115
+ // Tier 1: Classify
116
+ const classification = await classifyIntent(request);
117
+
118
+ if (classification.confidence < 0.7) {
119
+ // Low confidence - ask for clarification
120
+ return askForClarification(classification);
121
+ }
122
+
123
+ // Tier 2: Execute
124
+ const handler = handlers[classification.handler];
125
+ if (!handler) {
126
+ throw new Error(`Unknown handler: ${classification.handler}`);
127
+ }
128
+
129
+ return handler(classification.entities);
130
+ }
131
+ ```
132
+
133
+ ## Example: Command Router
134
+
135
+ ```typescript
136
+ // User asks: "Create a new hook for validating file writes"
137
+
138
+ // Tier 1 Classification:
139
+ {
140
+ intent: 'create',
141
+ confidence: 0.9,
142
+ entities: {
143
+ type: 'hook',
144
+ target: 'file writes',
145
+ purpose: 'validation'
146
+ },
147
+ handler: 'createHandler'
148
+ }
149
+
150
+ // Tier 2 Execution:
151
+ // Launches create-hook skill with extracted parameters
152
+ ```
153
+
154
+ ## Benefits
155
+
156
+ 1. **Separation of Concerns**: Classification logic is separate from execution
157
+ 2. **Extensibility**: Add new handlers without changing classifier
158
+ 3. **Testability**: Each tier can be tested independently
159
+ 4. **Confidence Handling**: Low-confidence routes can be handled specially
160
+
161
+ ## Variations
162
+
163
+ ### Multi-Intent
164
+
165
+ Handle requests with multiple intents:
166
+
167
+ ```typescript
168
+ // "Create a user and send them a welcome email"
169
+ // Intent 1: create user
170
+ // Intent 2: send email
171
+ ```
172
+
173
+ ### Fallback Chain
174
+
175
+ Multiple classifiers with fallback:
176
+
177
+ ```typescript
178
+ const classifiers = [patternClassifier, mlClassifier, heuristicClassifier];
179
+
180
+ async function classifyWithFallback(request) {
181
+ for (const classifier of classifiers) {
182
+ const result = await classifier(request);
183
+ if (result.confidence > 0.7) return result;
184
+ }
185
+ return { intent: 'unknown', confidence: 0 };
186
+ }
187
+ ```
188
+
189
+ ## Related Patterns
190
+
191
+ - L1→L2 Orchestration
192
+ - Multi-Phase Orchestration
@@ -0,0 +1,109 @@
1
+ # Utility Scripts Library
2
+
3
+ Standalone scripts for deployment validation, logging analysis, and project health monitoring.
4
+
5
+ ## Available Scripts
6
+
7
+ | Script | Purpose | Language |
8
+ |--------|---------|----------|
9
+ | [validate-deployment.js](validate-deployment.js) | Pre-deployment environment validation | Node.js |
10
+ | [poll-deployment-status.js](poll-deployment-status.js) | Poll deployment until complete | Node.js |
11
+ | [roadmap-scanner.js](roadmap-scanner.js) | Multi-roadmap progress dashboard | Node.js |
12
+ | [analyze-delegation-log.js](analyze-delegation-log.js) | Model usage analysis from JSONL logs | Node.js |
13
+ | [autonomous-decision-logger.js](autonomous-decision-logger.js) | JSONL audit trail for agent decisions | Node.js |
14
+ | [phase-validation-gates.js](phase-validation-gates.js) | 5-gate validation before phase transitions | Node.js |
15
+ | [git-history-analyzer.py](git-history-analyzer.py) | Security audit for sensitive data in git | Python |
16
+
17
+ ## Installation
18
+
19
+ Copy scripts to your project:
20
+
21
+ ```bash
22
+ # Copy all scripts
23
+ cp -r templates/scripts/ .claude/scripts/
24
+
25
+ # Or install via ccasp
26
+ ccasp install-scripts
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ ### Pre-Deployment Validation
32
+
33
+ ```bash
34
+ # Validate Railway environment
35
+ node .claude/scripts/validate-deployment.js --platform railway
36
+
37
+ # Validate Cloudflare Pages
38
+ node .claude/scripts/validate-deployment.js --platform cloudflare
39
+ ```
40
+
41
+ ### Deployment Polling
42
+
43
+ ```bash
44
+ # Poll Railway deployment until complete
45
+ node .claude/scripts/poll-deployment-status.js \
46
+ --platform railway \
47
+ --project-id YOUR_PROJECT_ID \
48
+ --timeout 300
49
+
50
+ # Poll Cloudflare Pages deployment
51
+ node .claude/scripts/poll-deployment-status.js \
52
+ --platform cloudflare \
53
+ --project-name your-project
54
+ ```
55
+
56
+ ### Roadmap Scanning
57
+
58
+ ```bash
59
+ # Scan all roadmaps in current directory
60
+ node .claude/scripts/roadmap-scanner.js
61
+
62
+ # Generate JSON report
63
+ node .claude/scripts/roadmap-scanner.js --output json
64
+ ```
65
+
66
+ ### Log Analysis
67
+
68
+ ```bash
69
+ # Analyze delegation log for model usage
70
+ node .claude/scripts/analyze-delegation-log.js \
71
+ ~/.claude/logs/delegation.jsonl
72
+
73
+ # Generate cost estimate
74
+ node .claude/scripts/analyze-delegation-log.js \
75
+ ~/.claude/logs/delegation.jsonl --cost-estimate
76
+ ```
77
+
78
+ ### Git History Audit
79
+
80
+ ```bash
81
+ # Check for sensitive data in git history
82
+ python .claude/scripts/git-history-analyzer.py
83
+
84
+ # Check specific patterns
85
+ python .claude/scripts/git-history-analyzer.py \
86
+ --patterns "password|secret|api.key"
87
+ ```
88
+
89
+ ## Integration with Claude Code
90
+
91
+ These scripts can be invoked via Claude Code commands:
92
+
93
+ ```markdown
94
+ <!-- .claude/commands/validate-deploy.md -->
95
+ Run the deployment validation script:
96
+ \`\`\`bash
97
+ node .claude/scripts/validate-deployment.js --platform {{platform}}
98
+ \`\`\`
99
+ ```
100
+
101
+ ## Environment Variables
102
+
103
+ Some scripts require environment variables:
104
+
105
+ | Variable | Used By | Description |
106
+ |----------|---------|-------------|
107
+ | `RAILWAY_API_TOKEN` | validate-deployment.js | Railway API access |
108
+ | `CLOUDFLARE_API_TOKEN` | validate-deployment.js | Cloudflare API access |
109
+ | `GITHUB_TOKEN` | git-history-analyzer.py | GitHub API (optional) |
@@ -0,0 +1,299 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Analyze Delegation Log
4
+ *
5
+ * Analyzes Claude Code delegation logs to understand model usage,
6
+ * token consumption, and agent patterns.
7
+ *
8
+ * Usage:
9
+ * node analyze-delegation-log.js ~/.claude/logs/delegation.jsonl
10
+ * node analyze-delegation-log.js log.jsonl --cost-estimate
11
+ * node analyze-delegation-log.js log.jsonl --output json
12
+ */
13
+
14
+ import { readFileSync, existsSync } from 'fs';
15
+
16
+ // Approximate costs per 1M tokens (as of 2025)
17
+ const MODEL_COSTS = {
18
+ 'claude-opus-4-5': { input: 15.00, output: 75.00 },
19
+ 'claude-sonnet-4': { input: 3.00, output: 15.00 },
20
+ 'claude-haiku': { input: 0.25, output: 1.25 },
21
+ 'default': { input: 3.00, output: 15.00 },
22
+ };
23
+
24
+ class DelegationAnalyzer {
25
+ constructor(logPath, options = {}) {
26
+ this.logPath = logPath;
27
+ this.options = options;
28
+ this.entries = [];
29
+ this.analysis = {
30
+ models: {},
31
+ agents: {},
32
+ tools: {},
33
+ sessions: {},
34
+ timeline: [],
35
+ };
36
+ }
37
+
38
+ async analyze() {
39
+ console.log(`\n📊 Analyzing delegation log: ${this.logPath}\n`);
40
+
41
+ if (!existsSync(this.logPath)) {
42
+ console.error(`Error: File not found: ${this.logPath}`);
43
+ process.exit(1);
44
+ }
45
+
46
+ await this.parseLog();
47
+ await this.computeMetrics();
48
+
49
+ if (this.options.output === 'json') {
50
+ this.outputJson();
51
+ } else {
52
+ this.outputText();
53
+ }
54
+ }
55
+
56
+ async parseLog() {
57
+ const content = readFileSync(this.logPath, 'utf8');
58
+ const lines = content.split('\n').filter(line => line.trim());
59
+
60
+ for (const line of lines) {
61
+ try {
62
+ const entry = JSON.parse(line);
63
+ this.entries.push(entry);
64
+ } catch (e) {
65
+ // Skip invalid lines
66
+ }
67
+ }
68
+
69
+ console.log(`Parsed ${this.entries.length} log entries\n`);
70
+ }
71
+
72
+ async computeMetrics() {
73
+ for (const entry of this.entries) {
74
+ // Track by model
75
+ const model = entry.model || 'unknown';
76
+ if (!this.analysis.models[model]) {
77
+ this.analysis.models[model] = {
78
+ calls: 0,
79
+ inputTokens: 0,
80
+ outputTokens: 0,
81
+ errors: 0,
82
+ avgLatency: 0,
83
+ latencies: [],
84
+ };
85
+ }
86
+
87
+ const modelStats = this.analysis.models[model];
88
+ modelStats.calls++;
89
+ modelStats.inputTokens += entry.inputTokens || 0;
90
+ modelStats.outputTokens += entry.outputTokens || 0;
91
+ if (entry.error) modelStats.errors++;
92
+ if (entry.latencyMs) modelStats.latencies.push(entry.latencyMs);
93
+
94
+ // Track by agent type
95
+ const agentType = entry.agentType || entry.subagentType || 'main';
96
+ if (!this.analysis.agents[agentType]) {
97
+ this.analysis.agents[agentType] = {
98
+ invocations: 0,
99
+ totalTokens: 0,
100
+ avgTokensPerCall: 0,
101
+ };
102
+ }
103
+
104
+ const agentStats = this.analysis.agents[agentType];
105
+ agentStats.invocations++;
106
+ agentStats.totalTokens += (entry.inputTokens || 0) + (entry.outputTokens || 0);
107
+
108
+ // Track by tool
109
+ if (entry.tool) {
110
+ if (!this.analysis.tools[entry.tool]) {
111
+ this.analysis.tools[entry.tool] = { calls: 0, errors: 0 };
112
+ }
113
+ this.analysis.tools[entry.tool].calls++;
114
+ if (entry.error) this.analysis.tools[entry.tool].errors++;
115
+ }
116
+
117
+ // Track by session
118
+ const sessionId = entry.sessionId || 'default';
119
+ if (!this.analysis.sessions[sessionId]) {
120
+ this.analysis.sessions[sessionId] = {
121
+ calls: 0,
122
+ tokens: 0,
123
+ start: entry.timestamp,
124
+ end: entry.timestamp,
125
+ };
126
+ }
127
+
128
+ const session = this.analysis.sessions[sessionId];
129
+ session.calls++;
130
+ session.tokens += (entry.inputTokens || 0) + (entry.outputTokens || 0);
131
+ if (entry.timestamp > session.end) session.end = entry.timestamp;
132
+ }
133
+
134
+ // Compute averages
135
+ for (const model of Object.keys(this.analysis.models)) {
136
+ const stats = this.analysis.models[model];
137
+ if (stats.latencies.length > 0) {
138
+ stats.avgLatency = Math.round(
139
+ stats.latencies.reduce((a, b) => a + b, 0) / stats.latencies.length
140
+ );
141
+ }
142
+ delete stats.latencies;
143
+ }
144
+
145
+ for (const agent of Object.keys(this.analysis.agents)) {
146
+ const stats = this.analysis.agents[agent];
147
+ stats.avgTokensPerCall = Math.round(stats.totalTokens / stats.invocations);
148
+ }
149
+ }
150
+
151
+ estimateCost() {
152
+ let totalCost = 0;
153
+ const breakdown = {};
154
+
155
+ for (const [model, stats] of Object.entries(this.analysis.models)) {
156
+ const costs = MODEL_COSTS[model] || MODEL_COSTS['default'];
157
+ const inputCost = (stats.inputTokens / 1_000_000) * costs.input;
158
+ const outputCost = (stats.outputTokens / 1_000_000) * costs.output;
159
+ const modelCost = inputCost + outputCost;
160
+
161
+ breakdown[model] = {
162
+ inputCost: inputCost.toFixed(4),
163
+ outputCost: outputCost.toFixed(4),
164
+ totalCost: modelCost.toFixed(4),
165
+ };
166
+
167
+ totalCost += modelCost;
168
+ }
169
+
170
+ return { breakdown, totalCost: totalCost.toFixed(4) };
171
+ }
172
+
173
+ outputText() {
174
+ console.log('='.repeat(70));
175
+ console.log(' DELEGATION LOG ANALYSIS');
176
+ console.log('='.repeat(70));
177
+
178
+ // Model usage
179
+ console.log('\n📊 Model Usage\n');
180
+ console.log('Model Calls Input Tokens Output Tokens Errors');
181
+ console.log('-'.repeat(70));
182
+
183
+ for (const [model, stats] of Object.entries(this.analysis.models)) {
184
+ const modelName = model.padEnd(24);
185
+ const calls = stats.calls.toString().padStart(6);
186
+ const input = stats.inputTokens.toLocaleString().padStart(15);
187
+ const output = stats.outputTokens.toLocaleString().padStart(16);
188
+ const errors = stats.errors.toString().padStart(8);
189
+ console.log(`${modelName}${calls}${input}${output}${errors}`);
190
+ }
191
+
192
+ // Agent usage
193
+ console.log('\n🤖 Agent Types\n');
194
+ console.log('Agent Type Invocations Total Tokens Avg Tokens/Call');
195
+ console.log('-'.repeat(70));
196
+
197
+ for (const [agent, stats] of Object.entries(this.analysis.agents)) {
198
+ const agentName = agent.padEnd(22);
199
+ const invocations = stats.invocations.toString().padStart(12);
200
+ const tokens = stats.totalTokens.toLocaleString().padStart(15);
201
+ const avg = stats.avgTokensPerCall.toLocaleString().padStart(17);
202
+ console.log(`${agentName}${invocations}${tokens}${avg}`);
203
+ }
204
+
205
+ // Tool usage (top 10)
206
+ const toolEntries = Object.entries(this.analysis.tools)
207
+ .sort((a, b) => b[1].calls - a[1].calls)
208
+ .slice(0, 10);
209
+
210
+ if (toolEntries.length > 0) {
211
+ console.log('\n🔧 Top 10 Tools\n');
212
+ console.log('Tool Calls Errors');
213
+ console.log('-'.repeat(50));
214
+
215
+ for (const [tool, stats] of toolEntries) {
216
+ const toolName = tool.padEnd(30);
217
+ const calls = stats.calls.toString().padStart(6);
218
+ const errors = stats.errors.toString().padStart(9);
219
+ console.log(`${toolName}${calls}${errors}`);
220
+ }
221
+ }
222
+
223
+ // Cost estimate
224
+ if (this.options.costEstimate) {
225
+ const cost = this.estimateCost();
226
+
227
+ console.log('\n💰 Cost Estimate\n');
228
+ console.log('Model Input Cost Output Cost Total Cost');
229
+ console.log('-'.repeat(70));
230
+
231
+ for (const [model, costs] of Object.entries(cost.breakdown)) {
232
+ const modelName = model.padEnd(26);
233
+ const input = `$${costs.inputCost}`.padStart(12);
234
+ const output = `$${costs.outputCost}`.padStart(14);
235
+ const total = `$${costs.totalCost}`.padStart(13);
236
+ console.log(`${modelName}${input}${output}${total}`);
237
+ }
238
+
239
+ console.log('-'.repeat(70));
240
+ console.log(`${'TOTAL'.padEnd(26)}${''.padStart(26)}$${cost.totalCost}`.padStart(13));
241
+ }
242
+
243
+ // Summary
244
+ const totalCalls = Object.values(this.analysis.models)
245
+ .reduce((acc, m) => acc + m.calls, 0);
246
+ const totalTokens = Object.values(this.analysis.models)
247
+ .reduce((acc, m) => acc + m.inputTokens + m.outputTokens, 0);
248
+ const totalErrors = Object.values(this.analysis.models)
249
+ .reduce((acc, m) => acc + m.errors, 0);
250
+
251
+ console.log('\n' + '='.repeat(70));
252
+ console.log('SUMMARY');
253
+ console.log('='.repeat(70));
254
+ console.log(`\n Total API Calls: ${totalCalls.toLocaleString()}`);
255
+ console.log(` Total Tokens: ${totalTokens.toLocaleString()}`);
256
+ console.log(` Error Rate: ${((totalErrors / totalCalls) * 100).toFixed(2)}%`);
257
+ console.log(` Sessions: ${Object.keys(this.analysis.sessions).length}`);
258
+ console.log('\n' + '='.repeat(70) + '\n');
259
+ }
260
+
261
+ outputJson() {
262
+ const output = {
263
+ analyzedAt: new Date().toISOString(),
264
+ logPath: this.logPath,
265
+ totalEntries: this.entries.length,
266
+ analysis: this.analysis,
267
+ };
268
+
269
+ if (this.options.costEstimate) {
270
+ output.costEstimate = this.estimateCost();
271
+ }
272
+
273
+ console.log(JSON.stringify(output, null, 2));
274
+ }
275
+ }
276
+
277
+ // CLI entry point
278
+ async function main() {
279
+ const args = process.argv.slice(2);
280
+
281
+ if (args.length === 0 || args[0].startsWith('--')) {
282
+ console.error('Usage: node analyze-delegation-log.js <log-file> [options]');
283
+ console.error('Options:');
284
+ console.error(' --cost-estimate Include cost estimate');
285
+ console.error(' --output json Output as JSON');
286
+ process.exit(1);
287
+ }
288
+
289
+ const logPath = args[0];
290
+ const options = {
291
+ costEstimate: args.includes('--cost-estimate'),
292
+ output: args.includes('--output') ? args[args.indexOf('--output') + 1] : 'text',
293
+ };
294
+
295
+ const analyzer = new DelegationAnalyzer(logPath, options);
296
+ await analyzer.analyze();
297
+ }
298
+
299
+ main().catch(console.error);