aiblueprint-cli 1.4.59 → 1.4.61

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 +16 -36
  2. package/agents-config/agents/action.md +1 -1
  3. package/agents-config/agents/explore-codebase.md +53 -53
  4. package/agents-config/agents/explore-docs.md +50 -69
  5. package/agents-config/agents/websearch.md +36 -40
  6. package/agents-config/claude-config/scripts/.claude/skills/fix-on-my-computer/SKILL.md +81 -0
  7. package/agents-config/claude-config/scripts/CLAUDE.md +10 -4
  8. package/agents-config/claude-config/scripts/bun.lockb +0 -0
  9. package/agents-config/claude-config/scripts/package.json +22 -30
  10. package/agents-config/claude-config/scripts/statusline/CLAUDE.md +37 -155
  11. package/agents-config/claude-config/scripts/statusline/README.md +18 -94
  12. package/agents-config/claude-config/scripts/statusline/defaults.json +13 -10
  13. package/agents-config/claude-config/scripts/statusline/fixtures/mock-transcript.jsonl +4 -4
  14. package/agents-config/claude-config/scripts/statusline/fixtures/test-input.json +4 -4
  15. package/agents-config/claude-config/scripts/statusline/src/commands/interactive-config.ts +403 -0
  16. package/agents-config/claude-config/scripts/statusline/src/index.ts +33 -82
  17. package/agents-config/claude-config/scripts/statusline/src/lib/config-types.ts +7 -1
  18. package/agents-config/claude-config/scripts/statusline/src/lib/formatters.ts +40 -0
  19. package/agents-config/claude-config/scripts/statusline/src/lib/presets.ts +13 -13
  20. package/agents-config/claude-config/scripts/statusline/src/lib/render-pure.ts +24 -5
  21. package/agents-config/claude-config/scripts/statusline/statusline.config.free.json +79 -0
  22. package/agents-config/claude-config/scripts/statusline/statusline.config.json +77 -77
  23. package/agents-config/codex-config/config.toml +9 -0
  24. package/agents-config/codex-config/hooks/command-deny-list.ts +203 -0
  25. package/agents-config/commands/prompts/create-vitejs-app.md +272 -0
  26. package/agents-config/commands/prompts/nextjs-add-prisma-db.md +136 -0
  27. package/agents-config/commands/prompts/nextjs-setup-better-auth.md +173 -0
  28. package/agents-config/commands/prompts/nextjs-setup-project.md +200 -0
  29. package/agents-config/commands/prompts/prompt.md +55 -0
  30. package/agents-config/commands/prompts/saas-challenge-idea.md +135 -0
  31. package/agents-config/commands/prompts/saas-create-architecture.md +242 -0
  32. package/agents-config/commands/prompts/saas-create-headline.md +132 -0
  33. package/agents-config/commands/prompts/saas-create-landing-copywritting.md +267 -0
  34. package/agents-config/commands/prompts/saas-create-legals-docs.md +176 -0
  35. package/agents-config/commands/prompts/saas-create-logos.md +240 -0
  36. package/agents-config/commands/prompts/saas-create-prd.md +195 -0
  37. package/agents-config/commands/prompts/saas-create-tasks.md +240 -0
  38. package/agents-config/commands/prompts/saas-define-pricing.md +293 -0
  39. package/agents-config/commands/prompts/saas-find-domain-name.md +190 -0
  40. package/agents-config/commands/prompts/saas-implement-landing-page.md +257 -0
  41. package/agents-config/commands/prompts/setup-tmux.md +160 -0
  42. package/agents-config/commands/prompts/tools.md +148 -0
  43. package/agents-config/scripts/.claude/skills/fix-on-my-computer/SKILL.md +81 -0
  44. package/agents-config/scripts/CLAUDE.md +37 -0
  45. package/agents-config/scripts/biome.json +37 -0
  46. package/agents-config/scripts/bun.lockb +0 -0
  47. package/agents-config/scripts/package.json +24 -0
  48. package/agents-config/scripts/statusline/CLAUDE.md +87 -0
  49. package/agents-config/scripts/statusline/README.md +117 -0
  50. package/agents-config/scripts/statusline/__tests__/context.test.ts +229 -0
  51. package/agents-config/scripts/statusline/__tests__/formatters.test.ts +108 -0
  52. package/agents-config/scripts/statusline/__tests__/statusline.test.ts +309 -0
  53. package/agents-config/scripts/statusline/defaults.json +82 -0
  54. package/agents-config/scripts/statusline/fixtures/mock-transcript.jsonl +4 -0
  55. package/agents-config/scripts/statusline/fixtures/test-input.json +35 -0
  56. package/agents-config/scripts/statusline/src/commands/interactive-config.ts +403 -0
  57. package/agents-config/scripts/statusline/src/index.ts +141 -0
  58. package/agents-config/scripts/statusline/src/lib/config-types.ts +110 -0
  59. package/agents-config/scripts/statusline/src/lib/config.ts +21 -0
  60. package/agents-config/scripts/statusline/src/lib/context.ts +103 -0
  61. package/agents-config/scripts/statusline/src/lib/formatters.ts +426 -0
  62. package/agents-config/scripts/statusline/src/lib/git.ts +100 -0
  63. package/agents-config/scripts/statusline/src/lib/menu-factories.ts +224 -0
  64. package/agents-config/scripts/statusline/src/lib/presets.ts +177 -0
  65. package/agents-config/scripts/statusline/src/lib/render-pure.ts +516 -0
  66. package/agents-config/scripts/statusline/src/lib/types.ts +36 -0
  67. package/agents-config/scripts/statusline/src/lib/utils.ts +15 -0
  68. package/agents-config/scripts/statusline/statusline.config.free.json +79 -0
  69. package/agents-config/scripts/statusline/statusline.config.json +79 -0
  70. package/agents-config/scripts/statusline/test-with-fixtures.ts +37 -0
  71. package/agents-config/scripts/statusline/test.ts +20 -0
  72. package/agents-config/scripts/statusline/tsconfig.json +27 -0
  73. package/agents-config/scripts/tsconfig.json +27 -0
  74. package/agents-config/skills/{subagent-creator → agents-managers}/SKILL.md +47 -47
  75. package/agents-config/skills/{subagent-creator/references/subagents.md → agents-managers/references/agents.md} +45 -45
  76. package/agents-config/skills/{subagent-creator → agents-managers}/references/context-management.md +20 -20
  77. package/agents-config/skills/{subagent-creator → agents-managers}/references/debugging-agents.md +27 -27
  78. package/agents-config/skills/{subagent-creator → agents-managers}/references/error-handling-and-recovery.md +19 -19
  79. package/agents-config/skills/{subagent-creator → agents-managers}/references/evaluation-and-testing.md +29 -29
  80. package/agents-config/skills/{subagent-creator → agents-managers}/references/orchestration-patterns.md +5 -5
  81. package/agents-config/skills/{subagent-creator/references/writing-subagent-prompts.md → agents-managers/references/writing-agent-prompts.md} +23 -23
  82. package/agents-config/skills/codex-environment/SKILL.md +2 -0
  83. package/agents-config/skills/commit/SKILL.md +2 -0
  84. package/agents-config/skills/create-pr/SKILL.md +2 -0
  85. package/agents-config/skills/environments-manager/SKILL.md +271 -0
  86. package/agents-config/skills/environments-manager/examples/claude/.worktreeinclude +3 -0
  87. package/agents-config/skills/environments-manager/examples/claude/commands/dev.md +5 -0
  88. package/agents-config/skills/environments-manager/examples/claude/commands/lint.md +5 -0
  89. package/agents-config/skills/environments-manager/examples/claude/commands/test.md +5 -0
  90. package/agents-config/skills/environments-manager/examples/claude/commands/typecheck.md +5 -0
  91. package/agents-config/skills/environments-manager/examples/claude/settings.json +24 -0
  92. package/agents-config/skills/environments-manager/examples/codex/environments/environment.toml +29 -0
  93. package/agents-config/skills/environments-manager/examples/cursor/worktrees.json +3 -0
  94. package/agents-config/skills/environments-manager/examples/scripts/claude-worktree-create.sh +96 -0
  95. package/agents-config/skills/environments-manager/examples/scripts/claude-worktree-remove.sh +66 -0
  96. package/agents-config/skills/environments-manager/examples/scripts/dev.sh +15 -0
  97. package/agents-config/skills/environments-manager/examples/scripts/worktree-down.sh +22 -0
  98. package/agents-config/skills/environments-manager/examples/scripts/worktree-up.sh +50 -0
  99. package/agents-config/skills/environments-manager/references/claude.md +156 -0
  100. package/agents-config/skills/environments-manager/references/codex.md +97 -0
  101. package/agents-config/skills/environments-manager/references/cursor.md +88 -0
  102. package/agents-config/skills/fix-pr-comments/SKILL.md +2 -0
  103. package/agents-config/skills/grill-me/SKILL.md +10 -0
  104. package/agents-config/skills/merge/SKILL.md +2 -0
  105. package/agents-config/skills/rules-manager/SKILL.md +191 -0
  106. package/agents-config/skills/rules-manager/references/agents-vs-claude.md +66 -0
  107. package/agents-config/skills/rules-manager/references/examples.md +117 -0
  108. package/agents-config/skills/skill-manager/SKILL.md +101 -0
  109. package/agents-config/skills/skill-manager/references/claude-code.md +81 -0
  110. package/agents-config/skills/skill-manager/references/codex.md +288 -0
  111. package/agents-config/skills/skill-manager/references/cursor.md +125 -0
  112. package/agents-config/skills/skill-manager/references/description-recommandation.md +97 -0
  113. package/agents-config/skills/skill-manager/scripts/inspect-description.ts +743 -0
  114. package/agents-config/skills/ultrathink/SKILL.md +2 -0
  115. package/dist/cli.js +581 -299
  116. package/package.json +1 -1
  117. package/agents-config/claude-config/scripts/statusline/data/.gitignore +0 -8
  118. package/agents-config/claude-config/scripts/statusline/data/.gitkeep +0 -0
  119. package/agents-config/claude-config/scripts/statusline/docs/ARCHITECTURE.md +0 -166
  120. package/agents-config/claude-config/scripts/statusline/src/tests/spend-v2.test.ts +0 -306
  121. package/agents-config/skills/apex/SKILL.md +0 -261
  122. package/agents-config/skills/apex/scripts/setup-templates.sh +0 -100
  123. package/agents-config/skills/apex/scripts/update-progress.sh +0 -80
  124. package/agents-config/skills/apex/steps/step-00-init.md +0 -267
  125. package/agents-config/skills/apex/steps/step-00b-branch.md +0 -126
  126. package/agents-config/skills/apex/steps/step-00b-economy.md +0 -244
  127. package/agents-config/skills/apex/steps/step-00b-interactive.md +0 -153
  128. package/agents-config/skills/apex/steps/step-01-analyze.md +0 -361
  129. package/agents-config/skills/apex/steps/step-02-plan.md +0 -264
  130. package/agents-config/skills/apex/steps/step-03-execute.md +0 -239
  131. package/agents-config/skills/apex/steps/step-04-validate.md +0 -251
  132. package/agents-config/skills/apex/templates/00-context.md +0 -43
  133. package/agents-config/skills/apex/templates/01-analyze.md +0 -10
  134. package/agents-config/skills/apex/templates/02-plan.md +0 -10
  135. package/agents-config/skills/apex/templates/03-execute.md +0 -10
  136. package/agents-config/skills/apex/templates/04-validate.md +0 -10
  137. package/agents-config/skills/apex/templates/README.md +0 -176
  138. package/agents-config/skills/apex/templates/step-complete.md +0 -7
  139. package/agents-config/skills/claude-memory/SKILL.md +0 -293
  140. package/agents-config/skills/claude-memory/references/comprehensive-example.md +0 -175
  141. package/agents-config/skills/claude-memory/references/optimize-guide.md +0 -300
  142. package/agents-config/skills/claude-memory/references/project-patterns.md +0 -334
  143. package/agents-config/skills/claude-memory/references/prompting-techniques.md +0 -411
  144. package/agents-config/skills/claude-memory/references/rules-directory-guide.md +0 -298
  145. package/agents-config/skills/claude-memory/references/section-templates.md +0 -347
  146. package/agents-config/skills/fix-errors/SKILL.md +0 -61
  147. package/agents-config/skills/fix-grammar/SKILL.md +0 -59
  148. package/agents-config/skills/ralph-loop/SKILL.md +0 -117
  149. package/agents-config/skills/ralph-loop/scripts/setup.sh +0 -278
  150. package/agents-config/skills/ralph-loop/steps/step-00-init.md +0 -215
  151. package/agents-config/skills/ralph-loop/steps/step-01-interactive-prd.md +0 -366
  152. package/agents-config/skills/ralph-loop/steps/step-02-create-stories.md +0 -273
  153. package/agents-config/skills/ralph-loop/steps/step-03-finish.md +0 -245
  154. package/agents-config/skills/skill-creator/LICENSE.txt +0 -202
  155. package/agents-config/skills/skill-creator/SKILL.md +0 -421
  156. package/agents-config/skills/skill-creator/package.json +0 -5
  157. package/agents-config/skills/skill-creator/references/output-patterns.md +0 -82
  158. package/agents-config/skills/skill-creator/references/progressive-disclosure-patterns.md +0 -374
  159. package/agents-config/skills/skill-creator/references/prompting-integration.md +0 -363
  160. package/agents-config/skills/skill-creator/references/real-world-examples.md +0 -513
  161. package/agents-config/skills/skill-creator/references/script-patterns.md +0 -385
  162. package/agents-config/skills/skill-creator/references/workflows.md +0 -28
  163. package/agents-config/skills/skill-creator/references/xml-tag-guide.md +0 -606
  164. package/agents-config/skills/skill-creator/scripts/init-skill.ts +0 -214
  165. package/agents-config/skills/skill-creator/scripts/package-skill.ts +0 -146
  166. package/agents-config/skills/skill-creator/scripts/validate.ts +0 -138
  167. package/agents-config/skills/workflow-apex-free/SKILL.md +0 -261
  168. package/agents-config/skills/workflow-apex-free/scripts/setup-templates.sh +0 -100
  169. package/agents-config/skills/workflow-apex-free/scripts/update-progress.sh +0 -80
  170. package/agents-config/skills/workflow-apex-free/steps/step-00-init.md +0 -267
  171. package/agents-config/skills/workflow-apex-free/steps/step-00b-branch.md +0 -126
  172. package/agents-config/skills/workflow-apex-free/steps/step-00b-economy.md +0 -244
  173. package/agents-config/skills/workflow-apex-free/steps/step-00b-interactive.md +0 -153
  174. package/agents-config/skills/workflow-apex-free/steps/step-01-analyze.md +0 -361
  175. package/agents-config/skills/workflow-apex-free/steps/step-02-plan.md +0 -264
  176. package/agents-config/skills/workflow-apex-free/steps/step-03-execute.md +0 -239
  177. package/agents-config/skills/workflow-apex-free/steps/step-04-validate.md +0 -251
  178. package/agents-config/skills/workflow-apex-free/templates/00-context.md +0 -43
  179. package/agents-config/skills/workflow-apex-free/templates/01-analyze.md +0 -10
  180. package/agents-config/skills/workflow-apex-free/templates/02-plan.md +0 -10
  181. package/agents-config/skills/workflow-apex-free/templates/03-execute.md +0 -10
  182. package/agents-config/skills/workflow-apex-free/templates/04-validate.md +0 -10
  183. package/agents-config/skills/workflow-apex-free/templates/README.md +0 -176
  184. package/agents-config/skills/workflow-apex-free/templates/step-complete.md +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiblueprint-cli",
3
- "version": "1.4.59",
3
+ "version": "1.4.61",
4
4
  "description": "AIBlueprint CLI for setting up AI coding configurations",
5
5
  "author": "AIBlueprint",
6
6
  "license": "MIT",
@@ -1,8 +0,0 @@
1
- # Ignore all data files
2
- *.db
3
- *.json
4
-
5
- # But keep this .gitignore
6
- !.gitignore
7
-
8
- last_payload.txt
@@ -1,166 +0,0 @@
1
- # Statusline Architecture - Session & Period Tracking
2
-
3
- ## Concepts Fondamentaux
4
-
5
- ### Session Claude Code
6
-
7
- Une **session** est créée chaque fois qu'on ouvre un chat avec Claude Code.
8
-
9
- Caractéristiques:
10
- - **ID unique**: `session_id` (UUID)
11
- - **Coût cumulatif**: Le coût total de la session qui AUGMENTE au fil du temps
12
- - **Persistance**: Une session peut durer des heures/jours
13
- - **Commande /clear**: Efface la conversation mais GARDE la même session
14
- - **Le coût ne reset jamais**: Si une session a coûté $10, puis on fait /clear, le coût reste $10 et continue d'augmenter
15
-
16
- ```
17
- Session "abc-123"
18
- ├── Début: $0
19
- ├── Après 1h: $5
20
- ├── /clear (conversation effacée)
21
- ├── Après 2h: $12 (coût continue d'augmenter)
22
- ├── Fermeture terminal
23
- ├── Réouverture (même session)
24
- └── Après 3h: $18 (toujours cumulatif)
25
- ```
26
-
27
- ### Période (5 heures)
28
-
29
- Une **période** est une fenêtre de 5 heures pour le rate limiting d'Anthropic.
30
-
31
- Caractéristiques:
32
- - **resets_at**: Timestamp de fin de période (ex: "2025-12-09T10:00:00.000Z")
33
- - **Durée fixe**: 5 heures
34
- - **Indépendant des sessions**: Les sessions peuvent traverser plusieurs périodes
35
-
36
- ```
37
- Période A (05:00-10:00) Période B (10:00-15:00)
38
- ├────────────────────┤ ├────────────────────┤
39
- Session 1: +$5 Session 1: +$3 (continue)
40
- Session 2: +$8 Session 3: +$10 (nouvelle)
41
- ───────────── ─────────────
42
- Total: $13 Total: $13
43
- ```
44
-
45
- ## Le Problème Actuel
46
-
47
- ### Bug: Double Comptage
48
-
49
- Quand on calcule le coût d'une période en sommant les coûts totaux des sessions:
50
-
51
- ```
52
- Session X: coût total = $24
53
- Session X: last_resets_at = période actuelle
54
-
55
- getCurrentPeriodCost() retourne $24 ❌ FAUX!
56
- ```
57
-
58
- Mais si la session X avait déjà $10 AVANT cette période:
59
- - Coût réel de cette période = $24 - $10 = $14
60
- - On affiche $24 au lieu de $14 = **double comptage**
61
-
62
- ### Scénario Réel
63
-
64
- ```
65
- 1. Période A: Session X coûte $10, on compte $10 ✓
66
- 2. Période B commence
67
- 3. Session X continue, coût monte à $24
68
- 4. On calcule période B: on voit session X = $24
69
- 5. On affiche $24 pour période B ❌
70
- 6. Mais on avait déjà compté $10 en période A!
71
- 7. Total affiché: $10 + $24 = $34
72
- 8. Total réel: $24
73
- ```
74
-
75
- ## Solution: Tracking des Deltas par Session
76
-
77
- ### Nouvelle Structure de Données
78
-
79
- On doit tracker pour chaque session:
80
- - Combien on a DÉJÀ compté
81
- - Dans quelle période on l'a compté
82
-
83
- ```sql
84
- -- Table: sessions
85
- session_id TEXT PRIMARY KEY
86
- total_cost REAL -- Coût total actuel de la session
87
- cwd TEXT
88
- date TEXT
89
- duration_ms INTEGER
90
- lines_added INTEGER
91
- lines_removed INTEGER
92
-
93
- -- Table: session_period_tracking
94
- session_id TEXT
95
- period_id TEXT -- resets_at normalisé
96
- counted_cost REAL -- Combien on a compté pour cette période
97
- last_update INTEGER -- Timestamp
98
- PRIMARY KEY (session_id, period_id)
99
-
100
- -- Table: periods
101
- period_id TEXT PRIMARY KEY -- resets_at normalisé
102
- total_cost REAL -- Somme des deltas de toutes les sessions
103
- utilization INTEGER
104
- date TEXT
105
- ```
106
-
107
- ### Algorithme Correct
108
-
109
- ```
110
- Quand saveSession(session_id, new_cost, current_period):
111
- 1. Chercher session dans DB
112
- 2. Si existe:
113
- old_cost = session.total_cost
114
- delta = new_cost - old_cost
115
- Sinon:
116
- delta = new_cost
117
-
118
- 3. Chercher tracking pour (session_id, current_period)
119
- 4. Si existe:
120
- // Déjà compté dans cette période, calculer le vrai delta
121
- already_counted = tracking.counted_cost
122
- period_delta = delta // Le delta depuis la dernière update
123
- Sinon:
124
- // Nouvelle session dans cette période
125
- period_delta = delta
126
-
127
- 5. Mettre à jour:
128
- - session.total_cost = new_cost
129
- - tracking.counted_cost += period_delta
130
- - period.total_cost += period_delta
131
- ```
132
-
133
- ### Exemple Concret
134
-
135
- ```
136
- Session X traverse 2 périodes:
137
-
138
- Période A:
139
- - Session X: $0 → $10
140
- - tracking(X, A).counted_cost = $10
141
- - period(A).total_cost = $10
142
-
143
- Période B:
144
- - Session X: $10 → $24
145
- - delta = $24 - $10 = $14
146
- - tracking(X, B).counted_cost = $14
147
- - period(B).total_cost = $14
148
-
149
- Calcul période B:
150
- - On lit period(B).total_cost = $14 ✓ CORRECT!
151
- ```
152
-
153
- ## Avantages SQLite
154
-
155
- 1. **Transactions ACID**: Pas de corruption de données
156
- 2. **Requêtes complexes**: Agrégations, joins faciles
157
- 3. **Index**: Performance pour les lookups par session_id
158
- 4. **Single file**: Toujours portable
159
- 5. **Intégrité référentielle**: FK entre tables
160
-
161
- ## Migration
162
-
163
- 1. Créer nouveau fichier `statusline.db`
164
- 2. Migrer données existantes de spend.json et daily-usage.json
165
- 3. Recalculer les period_costs correctement
166
- 4. Supprimer les anciens fichiers JSON
@@ -1,306 +0,0 @@
1
- import { Database } from "bun:sqlite";
2
- import { afterEach, beforeEach, describe, expect, test } from "bun:test";
3
- import { existsSync, rmSync } from "node:fs";
4
- import { join } from "node:path";
5
-
6
- const TEST_DB_PATH = join(import.meta.dir, "..", "..", "data", "test.db");
7
-
8
- describe("SQLite Delta Tracking", () => {
9
- let db: Database;
10
-
11
- beforeEach(() => {
12
- if (existsSync(TEST_DB_PATH)) {
13
- rmSync(TEST_DB_PATH);
14
- }
15
-
16
- db = new Database(TEST_DB_PATH);
17
-
18
- db.run(`
19
- CREATE TABLE sessions (
20
- session_id TEXT PRIMARY KEY,
21
- total_cost REAL NOT NULL DEFAULT 0,
22
- cwd TEXT NOT NULL,
23
- date TEXT NOT NULL,
24
- duration_ms INTEGER NOT NULL DEFAULT 0,
25
- lines_added INTEGER NOT NULL DEFAULT 0,
26
- lines_removed INTEGER NOT NULL DEFAULT 0,
27
- last_resets_at TEXT
28
- )
29
- `);
30
-
31
- db.run(`
32
- CREATE TABLE session_period_tracking (
33
- session_id TEXT NOT NULL,
34
- period_id TEXT NOT NULL,
35
- counted_cost REAL NOT NULL DEFAULT 0,
36
- last_session_cost REAL NOT NULL DEFAULT 0,
37
- PRIMARY KEY (session_id, period_id)
38
- )
39
- `);
40
-
41
- db.run(`
42
- CREATE TABLE periods (
43
- period_id TEXT PRIMARY KEY,
44
- total_cost REAL NOT NULL DEFAULT 0,
45
- utilization INTEGER NOT NULL DEFAULT 0,
46
- date TEXT NOT NULL
47
- )
48
- `);
49
- });
50
-
51
- afterEach(() => {
52
- db.close();
53
- if (existsSync(TEST_DB_PATH)) {
54
- rmSync(TEST_DB_PATH);
55
- }
56
- });
57
-
58
- test("New session: full cost added to period", () => {
59
- const sessionId = "session-1";
60
- const periodId = "2025-12-09T10:00:00.000Z";
61
- const sessionCost = 10.0;
62
-
63
- db.run(
64
- "INSERT INTO sessions (session_id, total_cost, cwd, date, last_resets_at) VALUES (?, ?, ?, ?, ?)",
65
- [sessionId, sessionCost, "/test", "2025-12-09", periodId],
66
- );
67
-
68
- db.run(
69
- "INSERT INTO session_period_tracking (session_id, period_id, counted_cost, last_session_cost) VALUES (?, ?, ?, ?)",
70
- [sessionId, periodId, sessionCost, sessionCost],
71
- );
72
-
73
- db.run(
74
- "INSERT INTO periods (period_id, total_cost, utilization, date) VALUES (?, ?, ?, ?)",
75
- [periodId, sessionCost, 0, "2025-12-09"],
76
- );
77
-
78
- const period = db
79
- .query<{ total_cost: number }, [string]>(
80
- "SELECT total_cost FROM periods WHERE period_id = ?",
81
- )
82
- .get(periodId);
83
-
84
- expect(period?.total_cost).toBe(10.0);
85
- });
86
-
87
- test("Continued session: only delta added to period", () => {
88
- const sessionId = "session-1";
89
- const periodId = "2025-12-09T10:00:00.000Z";
90
-
91
- db.run(
92
- "INSERT INTO sessions (session_id, total_cost, cwd, date, last_resets_at) VALUES (?, ?, ?, ?, ?)",
93
- [sessionId, 10.0, "/test", "2025-12-09", periodId],
94
- );
95
-
96
- db.run(
97
- "INSERT INTO session_period_tracking (session_id, period_id, counted_cost, last_session_cost) VALUES (?, ?, ?, ?)",
98
- [sessionId, periodId, 10.0, 10.0],
99
- );
100
-
101
- db.run(
102
- "INSERT INTO periods (period_id, total_cost, utilization, date) VALUES (?, ?, ?, ?)",
103
- [periodId, 10.0, 0, "2025-12-09"],
104
- );
105
-
106
- const newSessionCost = 24.0;
107
- const delta = newSessionCost - 10.0;
108
-
109
- db.run("UPDATE sessions SET total_cost = ? WHERE session_id = ?", [
110
- newSessionCost,
111
- sessionId,
112
- ]);
113
-
114
- const tracking = db
115
- .query<
116
- { counted_cost: number; last_session_cost: number },
117
- [string, string]
118
- >(
119
- "SELECT counted_cost, last_session_cost FROM session_period_tracking WHERE session_id = ? AND period_id = ?",
120
- )
121
- .get(sessionId, periodId);
122
-
123
- const newCountedCost = (tracking?.counted_cost ?? 0) + delta;
124
-
125
- db.run(
126
- "UPDATE session_period_tracking SET counted_cost = ?, last_session_cost = ? WHERE session_id = ? AND period_id = ?",
127
- [newCountedCost, newSessionCost, sessionId, periodId],
128
- );
129
-
130
- db.run(
131
- "UPDATE periods SET total_cost = total_cost + ? WHERE period_id = ?",
132
- [delta, periodId],
133
- );
134
-
135
- const period = db
136
- .query<{ total_cost: number }, [string]>(
137
- "SELECT total_cost FROM periods WHERE period_id = ?",
138
- )
139
- .get(periodId);
140
- const updatedTracking = db
141
- .query<{ counted_cost: number }, [string, string]>(
142
- "SELECT counted_cost FROM session_period_tracking WHERE session_id = ? AND period_id = ?",
143
- )
144
- .get(sessionId, periodId);
145
-
146
- expect(period?.total_cost).toBe(24.0);
147
- expect(updatedTracking?.counted_cost).toBe(24.0);
148
- });
149
-
150
- test("Session spanning periods: only new delta in new period", () => {
151
- const sessionId = "session-1";
152
- const periodA = "2025-12-09T05:00:00.000Z";
153
- const periodB = "2025-12-09T10:00:00.000Z";
154
-
155
- db.run(
156
- "INSERT INTO sessions (session_id, total_cost, cwd, date, last_resets_at) VALUES (?, ?, ?, ?, ?)",
157
- [sessionId, 10.0, "/test", "2025-12-09", periodA],
158
- );
159
-
160
- db.run(
161
- "INSERT INTO session_period_tracking (session_id, period_id, counted_cost, last_session_cost) VALUES (?, ?, ?, ?)",
162
- [sessionId, periodA, 10.0, 10.0],
163
- );
164
-
165
- db.run(
166
- "INSERT INTO periods (period_id, total_cost, utilization, date) VALUES (?, ?, ?, ?)",
167
- [periodA, 10.0, 0, "2025-12-09"],
168
- );
169
-
170
- const newSessionCost = 24.0;
171
- const session = db
172
- .query<{ total_cost: number }, [string]>(
173
- "SELECT total_cost FROM sessions WHERE session_id = ?",
174
- )
175
- .get(sessionId);
176
- const delta = newSessionCost - (session?.total_cost ?? 0);
177
-
178
- db.run(
179
- "UPDATE sessions SET total_cost = ?, last_resets_at = ? WHERE session_id = ?",
180
- [newSessionCost, periodB, sessionId],
181
- );
182
-
183
- db.run(
184
- "INSERT INTO session_period_tracking (session_id, period_id, counted_cost, last_session_cost) VALUES (?, ?, ?, ?)",
185
- [sessionId, periodB, delta, newSessionCost],
186
- );
187
-
188
- db.run(
189
- "INSERT OR IGNORE INTO periods (period_id, total_cost, utilization, date) VALUES (?, ?, ?, ?)",
190
- [periodB, 0, 0, "2025-12-09"],
191
- );
192
- db.run(
193
- "UPDATE periods SET total_cost = total_cost + ? WHERE period_id = ?",
194
- [delta, periodB],
195
- );
196
-
197
- const periodACost = db
198
- .query<{ total_cost: number }, [string]>(
199
- "SELECT total_cost FROM periods WHERE period_id = ?",
200
- )
201
- .get(periodA);
202
- const periodBCost = db
203
- .query<{ total_cost: number }, [string]>(
204
- "SELECT total_cost FROM periods WHERE period_id = ?",
205
- )
206
- .get(periodB);
207
- const trackingA = db
208
- .query<{ counted_cost: number }, [string, string]>(
209
- "SELECT counted_cost FROM session_period_tracking WHERE session_id = ? AND period_id = ?",
210
- )
211
- .get(sessionId, periodA);
212
- const trackingB = db
213
- .query<{ counted_cost: number }, [string, string]>(
214
- "SELECT counted_cost FROM session_period_tracking WHERE session_id = ? AND period_id = ?",
215
- )
216
- .get(sessionId, periodB);
217
-
218
- expect(periodACost?.total_cost).toBe(10.0);
219
- expect(periodBCost?.total_cost).toBe(14.0);
220
- expect(trackingA?.counted_cost).toBe(10.0);
221
- expect(trackingB?.counted_cost).toBe(14.0);
222
-
223
- expect(
224
- (periodACost?.total_cost ?? 0) + (periodBCost?.total_cost ?? 0),
225
- ).toBe(24.0);
226
- });
227
-
228
- test("Multiple sessions in same period: costs sum correctly", () => {
229
- const periodId = "2025-12-09T10:00:00.000Z";
230
-
231
- db.run(
232
- "INSERT INTO periods (period_id, total_cost, utilization, date) VALUES (?, ?, ?, ?)",
233
- [periodId, 0, 0, "2025-12-09"],
234
- );
235
-
236
- const sessions = [
237
- { id: "session-1", cost: 10.0 },
238
- { id: "session-2", cost: 15.0 },
239
- { id: "session-3", cost: 8.0 },
240
- ];
241
-
242
- for (const session of sessions) {
243
- db.run(
244
- "INSERT INTO sessions (session_id, total_cost, cwd, date, last_resets_at) VALUES (?, ?, ?, ?, ?)",
245
- [session.id, session.cost, "/test", "2025-12-09", periodId],
246
- );
247
-
248
- db.run(
249
- "INSERT INTO session_period_tracking (session_id, period_id, counted_cost, last_session_cost) VALUES (?, ?, ?, ?)",
250
- [session.id, periodId, session.cost, session.cost],
251
- );
252
-
253
- db.run(
254
- "UPDATE periods SET total_cost = total_cost + ? WHERE period_id = ?",
255
- [session.cost, periodId],
256
- );
257
- }
258
-
259
- const period = db
260
- .query<{ total_cost: number }, [string]>(
261
- "SELECT total_cost FROM periods WHERE period_id = ?",
262
- )
263
- .get(periodId);
264
-
265
- expect(period?.total_cost).toBe(33.0);
266
- });
267
-
268
- test("No double counting: continuing old session after restart", () => {
269
- const sessionId = "session-1";
270
- const periodId = "2025-12-09T10:00:00.000Z";
271
-
272
- db.run(
273
- "INSERT INTO sessions (session_id, total_cost, cwd, date, last_resets_at) VALUES (?, ?, ?, ?, ?)",
274
- [sessionId, 10.0, "/test", "2025-12-09", periodId],
275
- );
276
-
277
- db.run(
278
- "INSERT INTO session_period_tracking (session_id, period_id, counted_cost, last_session_cost) VALUES (?, ?, ?, ?)",
279
- [sessionId, periodId, 10.0, 10.0],
280
- );
281
-
282
- db.run(
283
- "INSERT INTO periods (period_id, total_cost, utilization, date) VALUES (?, ?, ?, ?)",
284
- [periodId, 10.0, 0, "2025-12-09"],
285
- );
286
-
287
- const tracking = db
288
- .query<{ last_session_cost: number }, [string, string]>(
289
- "SELECT last_session_cost FROM session_period_tracking WHERE session_id = ? AND period_id = ?",
290
- )
291
- .get(sessionId, periodId);
292
-
293
- const currentSessionCost = 10.0;
294
- const delta = currentSessionCost - (tracking?.last_session_cost ?? 0);
295
-
296
- expect(delta).toBe(0);
297
-
298
- const period = db
299
- .query<{ total_cost: number }, [string]>(
300
- "SELECT total_cost FROM periods WHERE period_id = ?",
301
- )
302
- .get(periodId);
303
-
304
- expect(period?.total_cost).toBe(10.0);
305
- });
306
- });