oh-my-claude-sisyphus 3.4.0 → 3.4.1
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.
- package/README.md +71 -5
- package/commands/cancel-ecomode.md +71 -0
- package/commands/cancel.md +75 -0
- package/commands/pipeline.md +231 -0
- package/commands/planner.md +174 -0
- package/commands/swarm.md +280 -0
- package/dist/analytics/cost-estimator.d.ts +14 -0
- package/dist/analytics/cost-estimator.d.ts.map +1 -0
- package/dist/analytics/cost-estimator.js +70 -0
- package/dist/analytics/cost-estimator.js.map +1 -0
- package/dist/analytics/export.d.ts +7 -0
- package/dist/analytics/export.d.ts.map +1 -0
- package/dist/analytics/export.js +93 -0
- package/dist/analytics/export.js.map +1 -0
- package/dist/analytics/index.d.ts +14 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +14 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/metrics-collector.d.ts +30 -0
- package/dist/analytics/metrics-collector.d.ts.map +1 -0
- package/dist/analytics/metrics-collector.js +96 -0
- package/dist/analytics/metrics-collector.js.map +1 -0
- package/dist/analytics/query-engine.d.ts +32 -0
- package/dist/analytics/query-engine.d.ts.map +1 -0
- package/dist/analytics/query-engine.js +151 -0
- package/dist/analytics/query-engine.js.map +1 -0
- package/dist/analytics/session-manager.d.ts +26 -0
- package/dist/analytics/session-manager.d.ts.map +1 -0
- package/dist/analytics/session-manager.js +201 -0
- package/dist/analytics/session-manager.js.map +1 -0
- package/dist/analytics/session-types.d.ts +37 -0
- package/dist/analytics/session-types.d.ts.map +1 -0
- package/dist/analytics/session-types.js +2 -0
- package/dist/analytics/session-types.js.map +1 -0
- package/dist/analytics/token-tracker.d.ts +24 -0
- package/dist/analytics/token-tracker.d.ts.map +1 -0
- package/dist/analytics/token-tracker.js +161 -0
- package/dist/analytics/token-tracker.js.map +1 -0
- package/dist/analytics/types.d.ts +37 -0
- package/dist/analytics/types.d.ts.map +1 -0
- package/dist/analytics/types.js +21 -0
- package/dist/analytics/types.js.map +1 -0
- package/dist/cli/analytics.d.ts +3 -0
- package/dist/cli/analytics.d.ts.map +1 -0
- package/dist/cli/analytics.js +74 -0
- package/dist/cli/analytics.js.map +1 -0
- package/dist/cli/commands/agents.d.ts +5 -0
- package/dist/cli/commands/agents.d.ts.map +1 -0
- package/dist/cli/commands/agents.js +29 -0
- package/dist/cli/commands/agents.js.map +1 -0
- package/dist/cli/commands/cleanup.d.ts +4 -0
- package/dist/cli/commands/cleanup.d.ts.map +1 -0
- package/dist/cli/commands/cleanup.js +17 -0
- package/dist/cli/commands/cleanup.js.map +1 -0
- package/dist/cli/commands/cost.d.ts +4 -0
- package/dist/cli/commands/cost.d.ts.map +1 -0
- package/dist/cli/commands/cost.js +53 -0
- package/dist/cli/commands/cost.js.map +1 -0
- package/dist/cli/commands/export.d.ts +5 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +30 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/sessions.d.ts +5 -0
- package/dist/cli/commands/sessions.d.ts.map +1 -0
- package/dist/cli/commands/sessions.js +37 -0
- package/dist/cli/commands/sessions.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +4 -0
- package/dist/cli/commands/stats.d.ts.map +1 -0
- package/dist/cli/commands/stats.js +43 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/utils/formatting.d.ts +22 -0
- package/dist/cli/utils/formatting.d.ts.map +1 -0
- package/dist/cli/utils/formatting.js +70 -0
- package/dist/cli/utils/formatting.js.map +1 -0
- package/dist/hud/analytics-display.d.ts +28 -0
- package/dist/hud/analytics-display.d.ts.map +1 -0
- package/dist/hud/analytics-display.js +105 -0
- package/dist/hud/analytics-display.js.map +1 -0
- package/dist/hud/background-cleanup.d.ts +28 -0
- package/dist/hud/background-cleanup.d.ts.map +1 -0
- package/dist/hud/background-cleanup.js +92 -0
- package/dist/hud/background-cleanup.js.map +1 -0
- package/dist/hud/index.js +4 -2
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/render.d.ts +1 -1
- package/dist/hud/render.d.ts.map +1 -1
- package/dist/hud/render.js +32 -1
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/state.d.ts +5 -0
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +13 -0
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/types.d.ts +11 -1
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/hud/types.js +19 -0
- package/dist/hud/types.js.map +1 -1
- package/docs/FULL-README.md +130 -16
- package/docs/MIGRATION.md +222 -1
- package/docs/SYNC-SYSTEM.md +528 -0
- package/package.json +8 -2
- package/scripts/sync-metadata.ts +363 -0
- package/skills/build-fix/SKILL.md +123 -0
- package/skills/code-review/SKILL.md +179 -0
- package/skills/security-review/SKILL.md +254 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: N coordinated agents with atomic task claiming from shared pool
|
|
3
|
+
aliases: [swarm-agents]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Swarm Command
|
|
7
|
+
|
|
8
|
+
[SWARM MODE ACTIVATED]
|
|
9
|
+
|
|
10
|
+
Spawn N coordinated agents working on a shared task list with atomic claiming. Like a dev team tackling multiple files in parallel.
|
|
11
|
+
|
|
12
|
+
## User's Request
|
|
13
|
+
|
|
14
|
+
{{ARGUMENTS}}
|
|
15
|
+
|
|
16
|
+
## Usage Pattern
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
/oh-my-claudecode:swarm N:agent-type "task description"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Parameters
|
|
23
|
+
|
|
24
|
+
- **N** - Number of agents (1-5, enforced by Claude Code limit)
|
|
25
|
+
- **agent-type** - Agent to spawn (executor, build-fixer, designer, etc.)
|
|
26
|
+
- **task** - High-level task to decompose and distribute
|
|
27
|
+
|
|
28
|
+
### Examples
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
/oh-my-claudecode:swarm 5:executor "fix all TypeScript errors"
|
|
32
|
+
/oh-my-claudecode:swarm 3:build-fixer "fix build errors in src/"
|
|
33
|
+
/oh-my-claudecode:swarm 4:designer "implement responsive layouts for all components"
|
|
34
|
+
/oh-my-claudecode:swarm 2:architect "analyze and document all API endpoints"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## How It Works
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
User: /swarm 5:executor "fix all TypeScript errors"
|
|
41
|
+
|
|
|
42
|
+
v
|
|
43
|
+
[SWARM ORCHESTRATOR]
|
|
44
|
+
|
|
|
45
|
+
+--+--+--+--+--+
|
|
46
|
+
| | | | |
|
|
47
|
+
v v v v v
|
|
48
|
+
E1 E2 E3 E4 E5
|
|
49
|
+
| | | | |
|
|
50
|
+
+--+--+--+--+
|
|
51
|
+
|
|
|
52
|
+
v
|
|
53
|
+
[SHARED TASK LIST]
|
|
54
|
+
- Fix a.ts (claimed E1)
|
|
55
|
+
- Fix b.ts (done E2)
|
|
56
|
+
- Fix c.ts (claimed E3)
|
|
57
|
+
- Fix d.ts (pending)
|
|
58
|
+
...
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Workflow
|
|
62
|
+
|
|
63
|
+
### 1. Parse Input
|
|
64
|
+
|
|
65
|
+
From `{{ARGUMENTS}}`, extract:
|
|
66
|
+
- N (agent count, validate <= 5)
|
|
67
|
+
- agent-type (executor, build-fixer, etc.)
|
|
68
|
+
- task description
|
|
69
|
+
|
|
70
|
+
### 2. Create Task List
|
|
71
|
+
|
|
72
|
+
1. Analyze codebase based on task
|
|
73
|
+
2. Break into file-specific subtasks
|
|
74
|
+
3. Initialize `.omc/state/swarm-tasks.json` with all subtasks
|
|
75
|
+
4. Each task gets: id, file, description, status, owner, timestamp
|
|
76
|
+
|
|
77
|
+
### 3. Spawn Agents
|
|
78
|
+
|
|
79
|
+
Launch N agents via Task tool:
|
|
80
|
+
- Set `run_in_background: true` for all
|
|
81
|
+
- Each agent receives:
|
|
82
|
+
- Reference to shared task list
|
|
83
|
+
- Claiming protocol instructions
|
|
84
|
+
- Completion criteria
|
|
85
|
+
|
|
86
|
+
### 4. Task Claiming Protocol
|
|
87
|
+
|
|
88
|
+
Each agent follows this loop:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
LOOP:
|
|
92
|
+
1. Read swarm-tasks.json
|
|
93
|
+
2. Find first task with status="pending"
|
|
94
|
+
3. Atomically claim task (set status="claimed", add owner, timestamp)
|
|
95
|
+
4. Execute task
|
|
96
|
+
5. Mark task as "done"
|
|
97
|
+
6. GOTO LOOP (until no pending tasks)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Atomic Claiming:**
|
|
101
|
+
- Read current task status
|
|
102
|
+
- If "pending", claim it (set owner, timeout)
|
|
103
|
+
- If already claimed, try next task
|
|
104
|
+
- Timeout: 5 minutes per task
|
|
105
|
+
- Timed-out tasks auto-release to "pending"
|
|
106
|
+
|
|
107
|
+
### 5. Progress Tracking
|
|
108
|
+
|
|
109
|
+
Orchestrator monitors via TaskOutput:
|
|
110
|
+
- Shows live stats: claimed/done/pending counts
|
|
111
|
+
- Reports which agent is working on which file
|
|
112
|
+
- Detects idle agents (no pending tasks)
|
|
113
|
+
|
|
114
|
+
### 6. Completion
|
|
115
|
+
|
|
116
|
+
Exit when:
|
|
117
|
+
- All tasks marked "done"
|
|
118
|
+
- All agents idle (no pending tasks)
|
|
119
|
+
- User cancels via `/cancel`
|
|
120
|
+
|
|
121
|
+
## State Files
|
|
122
|
+
|
|
123
|
+
### `.omc/swarm-state.json`
|
|
124
|
+
Session-level state:
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"session_id": "swarm-20260124-143022",
|
|
129
|
+
"agent_count": 5,
|
|
130
|
+
"agent_type": "executor",
|
|
131
|
+
"task_description": "fix all TypeScript errors",
|
|
132
|
+
"status": "active",
|
|
133
|
+
"started_at": "2026-01-24T14:30:22Z",
|
|
134
|
+
"agents": [
|
|
135
|
+
{"id": "agent-1", "background_task_id": "task_abc", "status": "working"},
|
|
136
|
+
{"id": "agent-2", "background_task_id": "task_def", "status": "working"}
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### `.omc/state/swarm-tasks.json`
|
|
142
|
+
Shared task list:
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"tasks": [
|
|
147
|
+
{
|
|
148
|
+
"id": "task-001",
|
|
149
|
+
"file": "src/utils/validation.ts",
|
|
150
|
+
"description": "Fix type errors in validation helpers",
|
|
151
|
+
"status": "claimed",
|
|
152
|
+
"owner": "agent-1",
|
|
153
|
+
"claimed_at": "2026-01-24T14:30:25Z",
|
|
154
|
+
"timeout_at": "2026-01-24T14:35:25Z"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"id": "task-002",
|
|
158
|
+
"file": "src/components/Header.tsx",
|
|
159
|
+
"description": "Fix missing prop types",
|
|
160
|
+
"status": "done",
|
|
161
|
+
"owner": "agent-2",
|
|
162
|
+
"claimed_at": "2026-01-24T14:30:26Z",
|
|
163
|
+
"completed_at": "2026-01-24T14:32:15Z"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"id": "task-003",
|
|
167
|
+
"file": "src/api/client.ts",
|
|
168
|
+
"description": "Add return type annotations",
|
|
169
|
+
"status": "pending",
|
|
170
|
+
"owner": null
|
|
171
|
+
}
|
|
172
|
+
],
|
|
173
|
+
"stats": {
|
|
174
|
+
"total": 15,
|
|
175
|
+
"pending": 8,
|
|
176
|
+
"claimed": 5,
|
|
177
|
+
"done": 2
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Agent Instructions Template
|
|
183
|
+
|
|
184
|
+
Each spawned agent receives:
|
|
185
|
+
|
|
186
|
+
```markdown
|
|
187
|
+
You are agent {id} in a swarm of {N} {agent-type} agents.
|
|
188
|
+
|
|
189
|
+
**Your Task:** {task_description}
|
|
190
|
+
|
|
191
|
+
**Shared Task List:** .omc/state/swarm-tasks.json
|
|
192
|
+
|
|
193
|
+
**Your Loop:**
|
|
194
|
+
1. Read swarm-tasks.json
|
|
195
|
+
2. Find first task with status="pending"
|
|
196
|
+
3. Claim it atomically (set status="claimed", owner="{id}", timeout)
|
|
197
|
+
4. Execute the task
|
|
198
|
+
5. Mark status="done", set completed_at
|
|
199
|
+
6. Repeat until no pending tasks
|
|
200
|
+
|
|
201
|
+
**Claiming Protocol:**
|
|
202
|
+
- Read file, check status="pending"
|
|
203
|
+
- Update status="claimed", add your ID
|
|
204
|
+
- Set timeout_at = now + 5 minutes
|
|
205
|
+
- Write file back
|
|
206
|
+
- If file changed between read/write, retry
|
|
207
|
+
|
|
208
|
+
**Completion:**
|
|
209
|
+
When no pending tasks remain, exit cleanly.
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Constraints
|
|
213
|
+
|
|
214
|
+
- **Max Agents:** 5 (Claude Code background task limit)
|
|
215
|
+
- **Claim Timeout:** 5 minutes per task
|
|
216
|
+
- **Auto-Release:** Timed-out claims automatically released
|
|
217
|
+
- **Heartbeat:** Recommended every 60 seconds
|
|
218
|
+
|
|
219
|
+
## Error Handling
|
|
220
|
+
|
|
221
|
+
- **Agent Crash:** Task auto-releases after timeout
|
|
222
|
+
- **State Corruption:** Orchestrator validates and repairs
|
|
223
|
+
- **No Pending Tasks:** Agent exits cleanly
|
|
224
|
+
- **All Agents Idle:** Orchestrator concludes session
|
|
225
|
+
|
|
226
|
+
## Cancellation
|
|
227
|
+
|
|
228
|
+
Use unified cancel command:
|
|
229
|
+
```
|
|
230
|
+
/oh-my-claudecode:cancel
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
This:
|
|
234
|
+
- Stops orchestrator monitoring
|
|
235
|
+
- Signals all background agents to exit
|
|
236
|
+
- Preserves partial progress in swarm-tasks.json
|
|
237
|
+
- Marks session as "cancelled"
|
|
238
|
+
|
|
239
|
+
## Use Cases
|
|
240
|
+
|
|
241
|
+
### Fix All Type Errors
|
|
242
|
+
```
|
|
243
|
+
/swarm 5:executor "fix all TypeScript type errors"
|
|
244
|
+
```
|
|
245
|
+
Spawns 5 executors, each claiming and fixing individual files.
|
|
246
|
+
|
|
247
|
+
### Implement UI Components
|
|
248
|
+
```
|
|
249
|
+
/swarm 3:designer "implement Material-UI styling for all components"
|
|
250
|
+
```
|
|
251
|
+
Spawns 3 designers, each styling different component files.
|
|
252
|
+
|
|
253
|
+
### Security Audit
|
|
254
|
+
```
|
|
255
|
+
/swarm 4:security-reviewer "review all API endpoints for vulnerabilities"
|
|
256
|
+
```
|
|
257
|
+
Spawns 4 security reviewers, each auditing different endpoints.
|
|
258
|
+
|
|
259
|
+
### Documentation Sprint
|
|
260
|
+
```
|
|
261
|
+
/swarm 2:writer "add JSDoc comments to all exported functions"
|
|
262
|
+
```
|
|
263
|
+
Spawns 2 writers, each documenting different modules.
|
|
264
|
+
|
|
265
|
+
## Benefits
|
|
266
|
+
|
|
267
|
+
- **Parallel Execution:** N agents work simultaneously
|
|
268
|
+
- **Auto-Balancing:** Fast agents claim more tasks
|
|
269
|
+
- **Fault Tolerance:** Timeouts prevent deadlocks
|
|
270
|
+
- **Progress Visibility:** Live stats on claimed/done/pending
|
|
271
|
+
- **Scalable:** Works for 10s to 100s of subtasks
|
|
272
|
+
|
|
273
|
+
## Output
|
|
274
|
+
|
|
275
|
+
Report when complete:
|
|
276
|
+
- Total tasks completed
|
|
277
|
+
- Tasks per agent (performance comparison)
|
|
278
|
+
- Total time elapsed
|
|
279
|
+
- Final verification status
|
|
280
|
+
- Summary of changes made
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CostBreakdown } from './types.js';
|
|
2
|
+
export interface CostInput {
|
|
3
|
+
modelName: string;
|
|
4
|
+
inputTokens: number;
|
|
5
|
+
outputTokens: number;
|
|
6
|
+
cacheCreationTokens: number;
|
|
7
|
+
cacheReadTokens: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function calculateCost(input: CostInput): CostBreakdown;
|
|
10
|
+
export declare function formatCost(cost: number): string;
|
|
11
|
+
export declare function getCostColor(cost: number): 'green' | 'yellow' | 'red';
|
|
12
|
+
export declare function estimateDailyCost(tokensPerHour: number, modelName: string): number;
|
|
13
|
+
export declare function estimateMonthlyCost(tokensPerHour: number, modelName: string): number;
|
|
14
|
+
//# sourceMappingURL=cost-estimator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-estimator.d.ts","sourceRoot":"","sources":["../../src/analytics/cost-estimator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,aAAa,EAAE,MAAM,YAAY,CAAC;AAElE,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,CA0B7D;AA8BD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAIrE;AAED,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAKlF;AAED,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEpF"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { PRICING } from './types.js';
|
|
2
|
+
export function calculateCost(input) {
|
|
3
|
+
const pricing = getPricingForModel(input.modelName);
|
|
4
|
+
// Base input cost
|
|
5
|
+
const inputCost = (input.inputTokens / 1_000_000) * pricing.inputPerMillion;
|
|
6
|
+
// Output cost
|
|
7
|
+
const outputCost = (input.outputTokens / 1_000_000) * pricing.outputPerMillion;
|
|
8
|
+
// Cache write cost (25% markup on input price)
|
|
9
|
+
const cacheWriteCost = (input.cacheCreationTokens / 1_000_000) *
|
|
10
|
+
pricing.inputPerMillion * (1 + pricing.cacheWriteMarkup);
|
|
11
|
+
// Cache read cost (90% discount on input price)
|
|
12
|
+
const cacheReadCost = (input.cacheReadTokens / 1_000_000) *
|
|
13
|
+
pricing.inputPerMillion * (1 - pricing.cacheReadDiscount);
|
|
14
|
+
const totalCost = inputCost + outputCost + cacheWriteCost + cacheReadCost;
|
|
15
|
+
return {
|
|
16
|
+
inputCost,
|
|
17
|
+
outputCost,
|
|
18
|
+
cacheWriteCost,
|
|
19
|
+
cacheReadCost,
|
|
20
|
+
totalCost
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function getPricingForModel(modelName) {
|
|
24
|
+
// Normalize model name
|
|
25
|
+
const normalized = normalizeModelName(modelName);
|
|
26
|
+
if (PRICING[normalized]) {
|
|
27
|
+
return PRICING[normalized];
|
|
28
|
+
}
|
|
29
|
+
// Default to Sonnet if unknown
|
|
30
|
+
console.warn(`Unknown model: ${modelName}, defaulting to Sonnet pricing`);
|
|
31
|
+
return PRICING['claude-sonnet-4.5'];
|
|
32
|
+
}
|
|
33
|
+
function normalizeModelName(modelName) {
|
|
34
|
+
// Handle various model name formats
|
|
35
|
+
const lower = modelName.toLowerCase();
|
|
36
|
+
if (lower.includes('haiku'))
|
|
37
|
+
return 'claude-haiku-4';
|
|
38
|
+
if (lower.includes('sonnet'))
|
|
39
|
+
return 'claude-sonnet-4.5';
|
|
40
|
+
if (lower.includes('opus'))
|
|
41
|
+
return 'claude-opus-4.5';
|
|
42
|
+
// Check exact matches
|
|
43
|
+
if (PRICING[modelName])
|
|
44
|
+
return modelName;
|
|
45
|
+
// Default
|
|
46
|
+
return 'claude-sonnet-4.5';
|
|
47
|
+
}
|
|
48
|
+
export function formatCost(cost) {
|
|
49
|
+
if (cost < 0.01) {
|
|
50
|
+
return `$${(cost * 100).toFixed(4)}¢`;
|
|
51
|
+
}
|
|
52
|
+
return `$${cost.toFixed(4)}`;
|
|
53
|
+
}
|
|
54
|
+
export function getCostColor(cost) {
|
|
55
|
+
if (cost < 1.0)
|
|
56
|
+
return 'green';
|
|
57
|
+
if (cost < 5.0)
|
|
58
|
+
return 'yellow';
|
|
59
|
+
return 'red';
|
|
60
|
+
}
|
|
61
|
+
export function estimateDailyCost(tokensPerHour, modelName) {
|
|
62
|
+
const pricing = getPricingForModel(modelName);
|
|
63
|
+
const tokensPerDay = tokensPerHour * 24;
|
|
64
|
+
const costPerDay = (tokensPerDay / 1_000_000) * pricing.inputPerMillion;
|
|
65
|
+
return costPerDay;
|
|
66
|
+
}
|
|
67
|
+
export function estimateMonthlyCost(tokensPerHour, modelName) {
|
|
68
|
+
return estimateDailyCost(tokensPerHour, modelName) * 30;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=cost-estimator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-estimator.js","sourceRoot":"","sources":["../../src/analytics/cost-estimator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CostReport, UsagePattern } from './query-engine.js';
|
|
2
|
+
import { SessionHistory } from './session-types.js';
|
|
3
|
+
export type ExportFormat = 'json' | 'csv';
|
|
4
|
+
export declare function exportCostReport(report: CostReport, format: ExportFormat, outputPath: string): Promise<void>;
|
|
5
|
+
export declare function exportSessionHistory(history: SessionHistory, format: ExportFormat, outputPath: string): Promise<void>;
|
|
6
|
+
export declare function exportUsagePatterns(patterns: UsagePattern, format: ExportFormat, outputPath: string): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/analytics/export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,CAAC;AAE1C,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOlH;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3H;AAED,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOzH"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
export async function exportCostReport(report, format, outputPath) {
|
|
3
|
+
if (format === 'json') {
|
|
4
|
+
await fs.writeFile(outputPath, JSON.stringify(report, null, 2), 'utf-8');
|
|
5
|
+
}
|
|
6
|
+
else {
|
|
7
|
+
const csv = costReportToCSV(report);
|
|
8
|
+
await fs.writeFile(outputPath, csv, 'utf-8');
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export async function exportSessionHistory(history, format, outputPath) {
|
|
12
|
+
if (format === 'json') {
|
|
13
|
+
await fs.writeFile(outputPath, JSON.stringify(history, null, 2), 'utf-8');
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
const csv = sessionHistoryToCSV(history);
|
|
17
|
+
await fs.writeFile(outputPath, csv, 'utf-8');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export async function exportUsagePatterns(patterns, format, outputPath) {
|
|
21
|
+
if (format === 'json') {
|
|
22
|
+
await fs.writeFile(outputPath, JSON.stringify(patterns, null, 2), 'utf-8');
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const csv = usagePatternsToCSV(patterns);
|
|
26
|
+
await fs.writeFile(outputPath, csv, 'utf-8');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function costReportToCSV(report) {
|
|
30
|
+
const lines = [];
|
|
31
|
+
// Header
|
|
32
|
+
lines.push('Type,Name,Cost');
|
|
33
|
+
// By agent
|
|
34
|
+
for (const [agent, cost] of Object.entries(report.byAgent)) {
|
|
35
|
+
lines.push(`Agent,${agent},${cost.toFixed(4)}`);
|
|
36
|
+
}
|
|
37
|
+
// By model
|
|
38
|
+
for (const [model, cost] of Object.entries(report.byModel)) {
|
|
39
|
+
lines.push(`Model,${model},${cost.toFixed(4)}`);
|
|
40
|
+
}
|
|
41
|
+
// By day
|
|
42
|
+
if (report.byDay) {
|
|
43
|
+
for (const [day, cost] of Object.entries(report.byDay)) {
|
|
44
|
+
lines.push(`Day,${day},${cost.toFixed(4)}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Total
|
|
48
|
+
lines.push(`Total,,${report.totalCost.toFixed(4)}`);
|
|
49
|
+
return lines.join('\n');
|
|
50
|
+
}
|
|
51
|
+
function sessionHistoryToCSV(history) {
|
|
52
|
+
const lines = [];
|
|
53
|
+
// Header
|
|
54
|
+
lines.push('SessionID,ProjectPath,StartTime,EndTime,Duration,Status,Tags,Goals,Outcomes');
|
|
55
|
+
// Sessions
|
|
56
|
+
for (const session of history.sessions) {
|
|
57
|
+
const row = [
|
|
58
|
+
session.id,
|
|
59
|
+
session.projectPath,
|
|
60
|
+
session.startTime,
|
|
61
|
+
session.endTime || '',
|
|
62
|
+
session.duration?.toString() || '',
|
|
63
|
+
session.status,
|
|
64
|
+
session.tags.join(';'),
|
|
65
|
+
session.goals.join(';'),
|
|
66
|
+
session.outcomes.join(';')
|
|
67
|
+
];
|
|
68
|
+
lines.push(row.map(escapeCSV).join(','));
|
|
69
|
+
}
|
|
70
|
+
return lines.join('\n');
|
|
71
|
+
}
|
|
72
|
+
function usagePatternsToCSV(patterns) {
|
|
73
|
+
const lines = [];
|
|
74
|
+
// Header
|
|
75
|
+
lines.push('Type,Value,Cost');
|
|
76
|
+
// Peak hours
|
|
77
|
+
lines.push(`PeakHours,${patterns.peakHours.join(';')},`);
|
|
78
|
+
// Most expensive operations
|
|
79
|
+
for (const op of patterns.mostExpensiveOperations) {
|
|
80
|
+
lines.push(`Operation,${op.operation},${op.cost.toFixed(4)}`);
|
|
81
|
+
}
|
|
82
|
+
// Summary stats
|
|
83
|
+
lines.push(`AverageCostPerSession,,${patterns.averageCostPerSession.toFixed(4)}`);
|
|
84
|
+
lines.push(`TotalSessions,${patterns.totalSessions},`);
|
|
85
|
+
return lines.join('\n');
|
|
86
|
+
}
|
|
87
|
+
function escapeCSV(value) {
|
|
88
|
+
if (value.includes(',') || value.includes('"') || value.includes('\n')) {
|
|
89
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
90
|
+
}
|
|
91
|
+
return value;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/analytics/export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics Module
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive token tracking, cost estimation, and session analytics for Claude API usage
|
|
5
|
+
*/
|
|
6
|
+
export * from './types.js';
|
|
7
|
+
export * from './token-tracker.js';
|
|
8
|
+
export * from './cost-estimator.js';
|
|
9
|
+
export * from './session-manager.js';
|
|
10
|
+
export * from './session-types.js';
|
|
11
|
+
export * from './metrics-collector.js';
|
|
12
|
+
export * from './query-engine.js';
|
|
13
|
+
export * from './export.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics Module
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive token tracking, cost estimation, and session analytics for Claude API usage
|
|
5
|
+
*/
|
|
6
|
+
export * from './types.js';
|
|
7
|
+
export * from './token-tracker.js';
|
|
8
|
+
export * from './cost-estimator.js';
|
|
9
|
+
export * from './session-manager.js';
|
|
10
|
+
export * from './session-types.js';
|
|
11
|
+
export * from './metrics-collector.js';
|
|
12
|
+
export * from './query-engine.js';
|
|
13
|
+
export * from './export.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface MetricEvent {
|
|
2
|
+
timestamp: string;
|
|
3
|
+
type: string;
|
|
4
|
+
data: Record<string, any>;
|
|
5
|
+
sessionId?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface MetricQuery {
|
|
8
|
+
type?: string;
|
|
9
|
+
startDate?: string;
|
|
10
|
+
endDate?: string;
|
|
11
|
+
sessionId?: string;
|
|
12
|
+
limit?: number;
|
|
13
|
+
offset?: number;
|
|
14
|
+
}
|
|
15
|
+
export declare class MetricsCollector {
|
|
16
|
+
recordEvent(type: string, data: Record<string, any>, sessionId?: string): Promise<void>;
|
|
17
|
+
query(query: MetricQuery): Promise<MetricEvent[]>;
|
|
18
|
+
aggregate(query: MetricQuery, aggregator: (events: MetricEvent[]) => any): Promise<any>;
|
|
19
|
+
private appendToLog;
|
|
20
|
+
}
|
|
21
|
+
export declare const aggregators: {
|
|
22
|
+
sum: (field: string) => (events: MetricEvent[]) => number;
|
|
23
|
+
avg: (field: string) => (events: MetricEvent[]) => number;
|
|
24
|
+
count: () => (events: MetricEvent[]) => number;
|
|
25
|
+
groupBy: (field: string) => (events: MetricEvent[]) => Record<string, MetricEvent[]>;
|
|
26
|
+
max: (field: string) => (events: MetricEvent[]) => number;
|
|
27
|
+
min: (field: string) => (events: MetricEvent[]) => number;
|
|
28
|
+
};
|
|
29
|
+
export declare function getMetricsCollector(): MetricsCollector;
|
|
30
|
+
//# sourceMappingURL=metrics-collector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics-collector.d.ts","sourceRoot":"","sources":["../../src/analytics/metrics-collector.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,qBAAa,gBAAgB;IACrB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvF,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAoCjD,SAAS,CACb,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,GAAG,GACzC,OAAO,CAAC,GAAG,CAAC;YAKD,WAAW;CAO1B;AAGD,eAAO,MAAM,WAAW;iBACT,MAAM,MAAM,QAAQ,WAAW,EAAE;iBAIjC,MAAM,MAAM,QAAQ,WAAW,EAAE;kBAMhC,QAAQ,WAAW,EAAE;qBAIlB,MAAM,MAAM,QAAQ,WAAW,EAAE;iBAUrC,MAAM,MAAM,QAAQ,WAAW,EAAE;iBAKjC,MAAM,MAAM,QAAQ,WAAW,EAAE;CAI/C,CAAC;AAKF,wBAAgB,mBAAmB,IAAI,gBAAgB,CAKtD"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
const METRICS_LOG_FILE = '.omc/logs/metrics.jsonl';
|
|
4
|
+
export class MetricsCollector {
|
|
5
|
+
async recordEvent(type, data, sessionId) {
|
|
6
|
+
const event = {
|
|
7
|
+
timestamp: new Date().toISOString(),
|
|
8
|
+
type,
|
|
9
|
+
data,
|
|
10
|
+
sessionId
|
|
11
|
+
};
|
|
12
|
+
await this.appendToLog(event);
|
|
13
|
+
}
|
|
14
|
+
async query(query) {
|
|
15
|
+
const logPath = path.resolve(process.cwd(), METRICS_LOG_FILE);
|
|
16
|
+
try {
|
|
17
|
+
const content = await fs.readFile(logPath, 'utf-8');
|
|
18
|
+
const lines = content.trim().split('\n').filter(l => l.length > 0);
|
|
19
|
+
let events = lines.map(line => JSON.parse(line));
|
|
20
|
+
// Apply filters
|
|
21
|
+
if (query.type) {
|
|
22
|
+
events = events.filter(e => e.type === query.type);
|
|
23
|
+
}
|
|
24
|
+
if (query.sessionId) {
|
|
25
|
+
events = events.filter(e => e.sessionId === query.sessionId);
|
|
26
|
+
}
|
|
27
|
+
if (query.startDate) {
|
|
28
|
+
events = events.filter(e => e.timestamp >= query.startDate);
|
|
29
|
+
}
|
|
30
|
+
if (query.endDate) {
|
|
31
|
+
events = events.filter(e => e.timestamp <= query.endDate);
|
|
32
|
+
}
|
|
33
|
+
// Apply pagination
|
|
34
|
+
const offset = query.offset || 0;
|
|
35
|
+
const limit = query.limit || events.length;
|
|
36
|
+
return events.slice(offset, offset + limit);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async aggregate(query, aggregator) {
|
|
43
|
+
const events = await this.query(query);
|
|
44
|
+
return aggregator(events);
|
|
45
|
+
}
|
|
46
|
+
async appendToLog(event) {
|
|
47
|
+
const logPath = path.resolve(process.cwd(), METRICS_LOG_FILE);
|
|
48
|
+
const logDir = path.dirname(logPath);
|
|
49
|
+
await fs.mkdir(logDir, { recursive: true });
|
|
50
|
+
await fs.appendFile(logPath, JSON.stringify(event) + '\n', 'utf-8');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Common aggregators
|
|
54
|
+
export const aggregators = {
|
|
55
|
+
sum: (field) => (events) => {
|
|
56
|
+
return events.reduce((sum, e) => sum + (e.data[field] || 0), 0);
|
|
57
|
+
},
|
|
58
|
+
avg: (field) => (events) => {
|
|
59
|
+
if (events.length === 0)
|
|
60
|
+
return 0;
|
|
61
|
+
const sum = aggregators.sum(field)(events);
|
|
62
|
+
return sum / events.length;
|
|
63
|
+
},
|
|
64
|
+
count: () => (events) => {
|
|
65
|
+
return events.length;
|
|
66
|
+
},
|
|
67
|
+
groupBy: (field) => (events) => {
|
|
68
|
+
const groups = {};
|
|
69
|
+
for (const event of events) {
|
|
70
|
+
const key = event.data[field]?.toString() || 'unknown';
|
|
71
|
+
if (!groups[key])
|
|
72
|
+
groups[key] = [];
|
|
73
|
+
groups[key].push(event);
|
|
74
|
+
}
|
|
75
|
+
return groups;
|
|
76
|
+
},
|
|
77
|
+
max: (field) => (events) => {
|
|
78
|
+
if (events.length === 0)
|
|
79
|
+
return 0;
|
|
80
|
+
return Math.max(...events.map(e => e.data[field] || 0));
|
|
81
|
+
},
|
|
82
|
+
min: (field) => (events) => {
|
|
83
|
+
if (events.length === 0)
|
|
84
|
+
return 0;
|
|
85
|
+
return Math.min(...events.map(e => e.data[field] || 0));
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
// Singleton instance
|
|
89
|
+
let globalCollector = null;
|
|
90
|
+
export function getMetricsCollector() {
|
|
91
|
+
if (!globalCollector) {
|
|
92
|
+
globalCollector = new MetricsCollector();
|
|
93
|
+
}
|
|
94
|
+
return globalCollector;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=metrics-collector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics-collector.js","sourceRoot":"","sources":["../../src/analytics/metrics-collector.ts"],"names":[],"mappings":"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"}
|