@jamesaphoenix/tx-test-utils 0.5.1 → 0.5.2

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 CHANGED
@@ -9,6 +9,14 @@ npm install -g @jamesaphoenix/tx-cli
9
9
  tx init
10
10
  ```
11
11
 
12
+ Agent onboarding (optional, both supported):
13
+
14
+ ```bash
15
+ tx init --claude # CLAUDE.md + .claude/skills
16
+ tx init --codex # AGENTS.md + .codex/agents
17
+ tx init --claude --codex # scaffold both
18
+ ```
19
+
12
20
  ---
13
21
 
14
22
  ## The Problem
@@ -132,18 +140,20 @@ We ship **example loops**, not **the loop**:
132
140
 
133
141
  ```bash
134
142
  # Simple: one agent, one task
143
+ AGENT_CMD=${AGENT_CMD:-codex} # or: claude
135
144
  while task=$(tx ready --limit 1 --json | jq -r '.[0].id'); do
136
- claude "Work on task $task, then run: tx done $task"
145
+ "$AGENT_CMD" "Work on task $task, then run: tx done $task"
137
146
  done
138
147
  ```
139
148
 
140
149
  ```bash
141
150
  # Parallel: N agents with claims
151
+ AGENT_CMD=${AGENT_CMD:-codex} # or: claude
142
152
  for i in {1..5}; do
143
153
  (while task=$(tx ready --json --limit 1 | jq -r '.[0].id // empty'); do
144
154
  [ -z "$task" ] && break
145
155
  tx claim "$task" "worker-$i" || continue
146
- claude "Complete $task" && tx done "$task"
156
+ "$AGENT_CMD" "Complete $task" && tx done "$task"
147
157
  done) &
148
158
  done
149
159
  wait
@@ -151,9 +161,10 @@ wait
151
161
 
152
162
  ```bash
153
163
  # Human-in-loop: agent proposes, human approves
164
+ AGENT_CMD=${AGENT_CMD:-codex} # or: claude
154
165
  task=$(tx ready --json --limit 1 | jq -r '.[0].id')
155
- claude "Plan implementation for $task" > plan.md
156
- read -p "Approve? [y/n] " && claude "Execute plan.md"
166
+ "$AGENT_CMD" "Plan implementation for $task" > plan.md
167
+ read -p "Approve? [y/n] " && "$AGENT_CMD" "Execute plan.md"
157
168
  tx done $task
158
169
  ```
159
170
 
@@ -326,6 +337,7 @@ Local SQLite for speed. JSONL for git sync. Branch your knowledge with your code
326
337
 
327
338
  - **[txdocs.dev](https://txdocs.dev)**: Documentation
328
339
  - **[CLAUDE.md](CLAUDE.md)**: Doctrine and quick reference
340
+ - **[AGENTS.md](AGENTS.md)**: Codex onboarding and quick reference
329
341
  - **[docs/](docs/)**: PRDs and Design Docs
330
342
 
331
343
  ---
@@ -0,0 +1,36 @@
1
+ /**
2
+ * better-sqlite3 adapter for Vitest compatibility
3
+ *
4
+ * Wraps better-sqlite3 to match the SqliteDatabase interface used by @tx/core.
5
+ * This allows tests to use Vitest (with proper parallelization) while production
6
+ * uses bun:sqlite.
7
+ *
8
+ * The SqliteDatabase interface abstracts away the implementation, so this adapter
9
+ * makes better-sqlite3 compatible with the existing code.
10
+ */
11
+ import type { SqliteDatabase } from "@jamesaphoenix/tx-core";
12
+ type BetterSqlite3Database = {
13
+ prepare(sql: string): {
14
+ run(...params: unknown[]): {
15
+ lastInsertRowid: number | bigint;
16
+ changes: number;
17
+ };
18
+ get(...params: unknown[]): unknown;
19
+ all(...params: unknown[]): unknown[];
20
+ };
21
+ exec(sql: string): void;
22
+ close(): void;
23
+ pragma(key: string, value?: unknown): unknown;
24
+ transaction<T>(fn: () => T): () => T;
25
+ };
26
+ /**
27
+ * Wrap a better-sqlite3 Database to match SqliteDatabase interface
28
+ */
29
+ export declare function wrapBetterSqlite3(db: BetterSqlite3Database): SqliteDatabase;
30
+ /**
31
+ * Create an in-memory better-sqlite3 database wrapped as SqliteDatabase
32
+ * with migrations applied.
33
+ */
34
+ export declare function createBetterSqlite3Database(): Promise<SqliteDatabase>;
35
+ export {};
36
+ //# sourceMappingURL=better-sqlite3-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"better-sqlite3-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/better-sqlite3-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAoC,MAAM,wBAAwB,CAAA;AAG9F,KAAK,qBAAqB,GAAG;IAC3B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG;QACpB,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG;YAAE,eAAe,EAAE,MAAM,GAAG,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;QAChF,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAA;QAClC,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAA;KACrC,CAAA;IACD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,KAAK,IAAI,IAAI,CAAA;IACb,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;IAC7C,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,CAAA;CACrC,CAAA;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,qBAAqB,GAAG,cAAc,CA8C3E;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,cAAc,CAAC,CAe3E"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * better-sqlite3 adapter for Vitest compatibility
3
+ *
4
+ * Wraps better-sqlite3 to match the SqliteDatabase interface used by @tx/core.
5
+ * This allows tests to use Vitest (with proper parallelization) while production
6
+ * uses bun:sqlite.
7
+ *
8
+ * The SqliteDatabase interface abstracts away the implementation, so this adapter
9
+ * makes better-sqlite3 compatible with the existing code.
10
+ */
11
+ /**
12
+ * Wrap a better-sqlite3 Database to match SqliteDatabase interface
13
+ */
14
+ export function wrapBetterSqlite3(db) {
15
+ return {
16
+ prepare(sql) {
17
+ const stmt = db.prepare(sql);
18
+ return {
19
+ run(...params) {
20
+ const result = stmt.run(...params);
21
+ return {
22
+ lastInsertRowid: result.lastInsertRowid ?? 0,
23
+ changes: result.changes ?? 0
24
+ };
25
+ },
26
+ get(...params) {
27
+ return stmt.get(...params) ?? null;
28
+ },
29
+ all(...params) {
30
+ return stmt.all(...params);
31
+ }
32
+ };
33
+ },
34
+ run(sql, ...params) {
35
+ // Handle PRAGMA statements — better-sqlite3 uses .pragma("key = value") as a single string
36
+ const trimmed = sql.trim();
37
+ if (trimmed.toUpperCase().startsWith("PRAGMA")) {
38
+ // Strip the "PRAGMA " prefix and pass the rest directly to .pragma()
39
+ const pragmaArg = trimmed.slice(6).trim();
40
+ db.pragma(pragmaArg);
41
+ return { lastInsertRowid: 0, changes: 0 };
42
+ }
43
+ // Regular SQL statements
44
+ const result = db.prepare(sql).run(...params);
45
+ return {
46
+ lastInsertRowid: result.lastInsertRowid ?? 0,
47
+ changes: result.changes ?? 0
48
+ };
49
+ },
50
+ exec(sql) {
51
+ db.exec(sql);
52
+ },
53
+ close() {
54
+ db.close();
55
+ },
56
+ transaction(fn) {
57
+ return db.transaction(fn);
58
+ }
59
+ };
60
+ }
61
+ /**
62
+ * Create an in-memory better-sqlite3 database wrapped as SqliteDatabase
63
+ * with migrations applied.
64
+ */
65
+ export async function createBetterSqlite3Database() {
66
+ // Dynamic import to avoid requiring better-sqlite3 at module load time
67
+ // (only needed when running tests with Vitest)
68
+ const Database = (await import("better-sqlite3")).default;
69
+ const { applyMigrations } = await import("@jamesaphoenix/tx-core");
70
+ const db = new Database(":memory:");
71
+ db.pragma("journal_mode = WAL");
72
+ db.pragma("foreign_keys = ON");
73
+ db.pragma("busy_timeout = 5000");
74
+ const wrapped = wrapBetterSqlite3(db);
75
+ applyMigrations(wrapped);
76
+ return wrapped;
77
+ }
78
+ //# sourceMappingURL=better-sqlite3-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"better-sqlite3-adapter.js","sourceRoot":"","sources":["../../src/adapters/better-sqlite3-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiBH;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAyB;IACzD,OAAO;QACL,OAAO,CAAc,GAAW;YAC9B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC5B,OAAO;gBACL,GAAG,CAAC,GAAG,MAAiB;oBACtB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAA0D,CAAA;oBAC3F,OAAO;wBACL,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,CAAC;wBAC5C,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,CAAC;qBAC7B,CAAA;gBACH,CAAC;gBACD,GAAG,CAAC,GAAG,MAAiB;oBACtB,OAAQ,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAO,IAAI,IAAI,CAAA;gBAC3C,CAAC;gBACD,GAAG,CAAC,GAAG,MAAiB;oBACtB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAQ,CAAA;gBACnC,CAAC;aACF,CAAA;QACH,CAAC;QACD,GAAG,CAAC,GAAW,EAAE,GAAG,MAAiB;YACnC,2FAA2F;YAC3F,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;YAC1B,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC/C,qEAAqE;gBACrE,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;gBACzC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;gBACpB,OAAO,EAAE,eAAe,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;YAC3C,CAAC;YACD,yBAAyB;YACzB,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAA0D,CAAA;YACtG,OAAO;gBACL,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,CAAC;gBAC5C,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,CAAC;aAC7B,CAAA;QACH,CAAC;QACD,IAAI,CAAC,GAAW;YACd,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACd,CAAC;QACD,KAAK;YACH,EAAE,CAAC,KAAK,EAAE,CAAA;QACZ,CAAC;QACD,WAAW,CAAI,EAAW;YACxB,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;QAC3B,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B;IAC/C,uEAAuE;IACvE,+CAA+C;IAC/C,MAAM,QAAQ,GAAG,CAAC,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAA;IACzD,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAA;IAElE,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAA;IACnC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAA;IAC/B,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAA;IAC9B,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAA;IAEhC,MAAM,OAAO,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAA;IACrC,eAAe,CAAC,OAAO,CAAC,CAAA;IAExB,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -56,7 +56,7 @@ export interface SharedTestLayer<L> {
56
56
  * ```
57
57
  */
58
58
  export declare const createSharedTestLayer: () => Promise<{
59
- layer: Layer.Layer<import("@jamesaphoenix/tx-core").MigrationService | import("@jamesaphoenix/tx-core").SqliteClient | import("@jamesaphoenix/tx-core").TaskRepository | import("@jamesaphoenix/tx-core").DependencyRepository | import("@jamesaphoenix/tx-core").LearningRepository | import("@jamesaphoenix/tx-core").FileLearningRepository | import("@jamesaphoenix/tx-core").AttemptRepository | import("@jamesaphoenix/tx-core").RunRepository | import("@jamesaphoenix/tx-core").AnchorRepository | import("@jamesaphoenix/tx-core").EdgeRepository | import("@jamesaphoenix/tx-core").DeduplicationRepository | import("@jamesaphoenix/tx-core").CandidateRepository | import("@jamesaphoenix/tx-core").TrackedProjectRepository | import("@jamesaphoenix/tx-core").WorkerRepository | import("@jamesaphoenix/tx-core").ClaimRepository | import("@jamesaphoenix/tx-core").OrchestratorStateRepository | import("@jamesaphoenix/tx-core").TaskService | import("@jamesaphoenix/tx-core").DependencyService | import("@jamesaphoenix/tx-core").ReadyService | import("@jamesaphoenix/tx-core").HierarchyService | import("@jamesaphoenix/tx-core").EdgeService | import("@jamesaphoenix/tx-core").GraphExpansionService | import("@jamesaphoenix/tx-core").FeedbackTrackerService | import("@jamesaphoenix/tx-core").DiversifierService | import("@jamesaphoenix/tx-core").RetrieverService | import("@jamesaphoenix/tx-core").LearningService | import("@jamesaphoenix/tx-core").FileLearningService | import("@jamesaphoenix/tx-core").AttemptService | import("@jamesaphoenix/tx-core").AnchorVerificationService | import("@jamesaphoenix/tx-core").AnchorService | import("@jamesaphoenix/tx-core").DeduplicationService | import("@jamesaphoenix/tx-core").SyncService | import("@jamesaphoenix/tx-core").SwarmVerificationService | import("@jamesaphoenix/tx-core").PromotionService | import("@jamesaphoenix/tx-core").WorkerService | import("@jamesaphoenix/tx-core").ClaimService | import("@jamesaphoenix/tx-core").OrchestratorService | import("@jamesaphoenix/tx-core").DaemonService | import("@jamesaphoenix/tx-core").TracingService | import("@jamesaphoenix/tx-core").CompactionRepository | import("@jamesaphoenix/tx-core").CompactionService | import("@jamesaphoenix/tx-core").ValidationService | import("@jamesaphoenix/tx-core").MessageRepository | import("@jamesaphoenix/tx-core").MessageService | import("@jamesaphoenix/tx-core").DocRepository | import("@jamesaphoenix/tx-core").DocService, import("@jamesaphoenix/tx-core").DatabaseError, never>;
59
+ layer: Layer.Layer<import("@jamesaphoenix/tx-core").EdgeRepository | import("@jamesaphoenix/tx-core").SqliteClient | import("@jamesaphoenix/tx-core").TaskService | import("@jamesaphoenix/tx-core").TaskRepository | import("@jamesaphoenix/tx-core").DependencyRepository | import("@jamesaphoenix/tx-core").DependencyService | import("@jamesaphoenix/tx-core").ReadyService | import("@jamesaphoenix/tx-core").HierarchyService | import("@jamesaphoenix/tx-core").LearningService | import("@jamesaphoenix/tx-core").LearningRepository | import("@jamesaphoenix/tx-core").RetrieverService | import("@jamesaphoenix/tx-core").FileLearningService | import("@jamesaphoenix/tx-core").FileLearningRepository | import("@jamesaphoenix/tx-core").AttemptService | import("@jamesaphoenix/tx-core").AttemptRepository | import("@jamesaphoenix/tx-core").AnchorService | import("@jamesaphoenix/tx-core").AnchorRepository | import("@jamesaphoenix/tx-core").DeduplicationService | import("@jamesaphoenix/tx-core").DeduplicationRepository | import("@jamesaphoenix/tx-core").RunRepository | import("@jamesaphoenix/tx-core").CandidateRepository | import("@jamesaphoenix/tx-core").TrackedProjectRepository | import("@jamesaphoenix/tx-core").WorkerRepository | import("@jamesaphoenix/tx-core").ClaimRepository | import("@jamesaphoenix/tx-core").OrchestratorStateRepository | import("@jamesaphoenix/tx-core").CompactionRepository | import("@jamesaphoenix/tx-core").MessageRepository | import("@jamesaphoenix/tx-core").DocRepository | import("@jamesaphoenix/tx-core").DiversifierService | import("@jamesaphoenix/tx-core").GraphExpansionService | import("@jamesaphoenix/tx-core").FeedbackTrackerService | import("@jamesaphoenix/tx-core").EdgeService | import("@jamesaphoenix/tx-core").SyncService | import("@jamesaphoenix/tx-core").AnchorVerificationService | import("@jamesaphoenix/tx-core").SwarmVerificationService | import("@jamesaphoenix/tx-core").PromotionService | import("@jamesaphoenix/tx-core").WorkerService | import("@jamesaphoenix/tx-core").ClaimService | import("@jamesaphoenix/tx-core").OrchestratorService | import("@jamesaphoenix/tx-core").DaemonService | import("@jamesaphoenix/tx-core").TracingService | import("@jamesaphoenix/tx-core").CompactionService | import("@jamesaphoenix/tx-core").ValidationService | import("@jamesaphoenix/tx-core").MessageService | import("@jamesaphoenix/tx-core").DocService | import("@jamesaphoenix/tx-core").MigrationService, import("@jamesaphoenix/tx-core").DatabaseError, never>;
60
60
  reset: () => Promise<void>;
61
61
  close: () => Promise<void>;
62
62
  getDb: () => Database;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jamesaphoenix/tx-test-utils",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "Test utilities, factories, fixtures, and helpers for tx monorepo",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",