@jamesaphoenix/tx 0.4.3 → 0.4.4

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 (2) hide show
  1. package/README.md +144 -315
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,12 +1,15 @@
1
1
  # tx
2
2
 
3
- **TanStack for AI agents.** Primitives, not frameworks.
3
+ **Primitives, not frameworks.** Headless infrastructure for AI agents.
4
4
 
5
- Headless infrastructure for memory, tasks, and orchestration.
5
+ Memory, tasks, and orchestration — you own the loop.
6
6
 
7
7
  ```bash
8
- npm install -g @jamesaphoenix/tx
9
- tx init
8
+ # CLI (global install)
9
+ npm install -g @jamesaphoenix/tx-cli
10
+
11
+ # Library (project dependency)
12
+ npm install @jamesaphoenix/tx
10
13
  ```
11
14
 
12
15
  ---
@@ -26,7 +29,7 @@ Composable primitives that handle the hard parts. You keep control of the orches
26
29
  │ tx primitives │
27
30
  │ │
28
31
  │ tx ready tx done tx context tx learn │
29
- │ tx claim tx block tx handoff tx sync
32
+ │ tx claim tx block tx sync tx trace
30
33
  │ │
31
34
  └─────────────────────────────────────────────────────────┘
32
35
  ```
@@ -40,16 +43,20 @@ Composable primitives that handle the hard parts. You keep control of the orches
40
43
  Learnings that persist and surface when relevant.
41
44
 
42
45
  ```bash
43
- # Store knowledge (with optional file path)
44
- tx learning:add "Use bcrypt for passwords, not SHA256" --file src/auth/hash.ts
45
- tx learning:add "Redis cache invalidation has race conditions"
46
+ # Store knowledge
47
+ tx learning:add "Use bcrypt for passwords, not SHA256"
48
+ tx learning:add "Redis cache invalidation has race conditions" -c database
49
+
50
+ # Attach learnings to file paths
51
+ tx learn "src/auth/*.ts" "Services must use Effect-TS patterns"
46
52
 
47
53
  # Retrieve via search or task context
48
54
  tx learning:search "authentication"
49
55
  tx context tx-abc123 # Get relevant learnings for a task
56
+ tx recall "src/auth/hash.ts" # Recall learnings for a file
50
57
  ```
51
58
 
52
- Learnings can be tagged with file paths for organization. Hybrid search (BM25 + vector) finds relevant knowledge.
59
+ Hybrid search (BM25 + vector with RRF fusion) finds relevant knowledge.
53
60
 
54
61
  ### Tasks
55
62
 
@@ -70,14 +77,54 @@ Full hierarchy support. Epics contain milestones contain tasks contain subtasks.
70
77
 
71
78
  ### Coordination
72
79
 
73
- Primitives for multi-agent workflows without prescribing the pattern.
80
+ Lease-based claims prevent parallel agents from colliding.
81
+
82
+ ```bash
83
+ tx claim tx-abc123 worker-1 # Claim with 30-min lease
84
+ tx claim tx-abc123 worker-1 --lease 60 # Custom lease duration
85
+ tx claim:renew tx-abc123 worker-1 # Extend lease
86
+ tx claim:release tx-abc123 worker-1 # Release early
87
+ ```
88
+
89
+ ### Attempts
90
+
91
+ Track what approaches have been tried on a task.
74
92
 
75
93
  ```bash
76
- tx claim tx-abc123 # Prevent collisions
77
- tx checkpoint tx-abc123 \
78
- --note "API done, UI next" # Save progress
79
- tx handoff tx-abc123 \
80
- --to reviewer # Transfer with context
94
+ tx try tx-abc123 "Used Redux" --failed "Too complex for this use case"
95
+ tx try tx-abc123 "Used Zustand" --succeeded
96
+ tx attempts tx-abc123 # See all attempts
97
+ ```
98
+
99
+ ### Docs
100
+
101
+ Structured documentation as primitives. YAML-based with versioning, locking, and linking.
102
+
103
+ ```bash
104
+ tx doc add prd auth-system --title "Auth System PRD"
105
+ tx doc render # Generate markdown from YAML
106
+ tx doc lock auth-system # Lock doc (immutable)
107
+ tx doc link auth-prd auth-dd # Link PRD to DD
108
+ tx doc drift # Detect stale docs
109
+ ```
110
+
111
+ ### Invariants
112
+
113
+ Track and verify project invariants across sessions.
114
+
115
+ ```bash
116
+ tx invariant list # List all invariants
117
+ tx invariant show INV-001 # Show details
118
+ tx invariant record INV-001 --passed # Record check result
119
+ tx invariant sync # Sync from CLAUDE.md
120
+ ```
121
+
122
+ ### Cycle Scan
123
+
124
+ Sub-agent swarm scanning for codebase analysis.
125
+
126
+ ```bash
127
+ tx cycle --task-prompt "Review auth" --scan-prompt "Find bugs"
81
128
  ```
82
129
 
83
130
  ---
@@ -94,10 +141,12 @@ done
94
141
  ```
95
142
 
96
143
  ```bash
97
- # Parallel: N agents pulling from queue
144
+ # Parallel: N agents with claims
98
145
  for i in {1..5}; do
99
- (while task=$(tx claim --next); do
100
- claude "Complete $task" && tx done $task
146
+ (while task=$(tx ready --json --limit 1 | jq -r '.[0].id // empty'); do
147
+ [ -z "$task" ] && break
148
+ tx claim "$task" "worker-$i" || continue
149
+ claude "Complete $task" && tx done "$task"
101
150
  done) &
102
151
  done
103
152
  wait
@@ -105,7 +154,7 @@ wait
105
154
 
106
155
  ```bash
107
156
  # Human-in-loop: agent proposes, human approves
108
- task=$(tx ready --limit 1)
157
+ task=$(tx ready --json --limit 1 | jq -r '.[0].id')
109
158
  claude "Plan implementation for $task" > plan.md
110
159
  read -p "Approve? [y/n] " && claude "Execute plan.md"
111
160
  tx done $task
@@ -115,13 +164,43 @@ tx done $task
115
164
 
116
165
  ---
117
166
 
167
+ ## TypeScript SDK
168
+
169
+ This package (`@jamesaphoenix/tx`) is the library entry point. It re-exports everything from `@jamesaphoenix/tx-core` plus convenience helpers.
170
+
171
+ ```typescript
172
+ import { TaskService, LearningService, makeAppLayer } from "@jamesaphoenix/tx";
173
+ import { Effect } from "effect";
174
+
175
+ const program = Effect.gen(function* () {
176
+ const tasks = yield* TaskService;
177
+ const ready = yield* tasks.getReady({ limit: 5 });
178
+ return ready;
179
+ });
180
+
181
+ // Run with the default layer (SQLite-backed)
182
+ const layer = makeAppLayer(".tx/tasks.db");
183
+ await Effect.runPromise(program.pipe(Effect.provide(layer)));
184
+ ```
185
+
186
+ For a Promise-based HTTP client, use the Agent SDK:
187
+
188
+ ```typescript
189
+ import { TxClient } from "@jamesaphoenix/tx-agent-sdk";
190
+
191
+ const tx = new TxClient({ apiUrl: "http://localhost:3456" });
192
+ const ready = await tx.tasks.ready({ limit: 10 });
193
+ ```
194
+
195
+ ---
196
+
118
197
  ## Why tx?
119
198
 
120
199
  | | Native Tasks | CLAUDE.md | tx |
121
200
  |---|---|---|---|
122
201
  | **Persistence** | Session-scoped | File grows forever | Git-native, branch-aware |
123
- | **Multi-agent** | Collisions | Manual coordination | Claim, block, handoff |
124
- | **Knowledge** | Lost each session | Static dump | Graph RAG, contextual retrieval |
202
+ | **Multi-agent** | Collisions | Manual coordination | Claim with lease expiry |
203
+ | **Knowledge** | Lost each session | Static dump | Hybrid search, contextual retrieval |
125
204
  | **Orchestration** | None | None | Primitives for any pattern |
126
205
 
127
206
  ---
@@ -136,249 +215,17 @@ tx done $task
136
215
 
137
216
  ---
138
217
 
139
- ## Non-Goals
140
-
141
- - **Not an agent framework.** You bring your own orchestration.
142
- - **Not a hosted memory product.** Local-first, your data stays yours.
143
- - **Not a prompt library.** Primitives, not templates.
144
- - **Not a replacement for your issue tracker.** (Unless you want it to be.)
145
-
146
- ---
147
-
148
- ## Three Systems
149
-
150
- ### 1. Knowledge System
151
-
152
- **Working today:**
153
- - Learnings stored with file path tags
154
- - Basic hybrid search (BM25 + vector)
155
- - Retrieval by task ID via `tx context`
156
-
157
- ```bash
158
- tx learning:add "Use bcrypt for passwords" --file src/auth/hash.ts
159
- tx learning:search "authentication"
160
- tx context tx-abc123 # Get learnings relevant to a task
161
- ```
162
-
163
- **Research in progress:**
164
- - Symbol anchoring (AST-based code references, not just file paths)
165
- - Knowledge graph expansion (automatic relationship discovery)
166
- - Auto-invalidation when code changes
167
-
168
- ### 2. Task System
169
-
170
- **Working today:**
171
- - N-level hierarchy (epics → tasks → subtasks)
172
- - Explicit dependencies with cycle detection
173
- - Priority scoring
174
- - Claim/release with lease expiry
175
-
176
- ```
177
- Epic: "User Authentication"
178
- ├── Task: "Design schema" ✓ done
179
- ├── Task: "Implement service" ● ready (unblocked)
180
- │ └── blocks: "Write tests", "Add endpoints"
181
- └── Task: "Write tests" ○ blocked
182
- ```
183
-
184
- **Research in progress:**
185
- - LLM-based reprioritization
186
- - Automatic task decomposition
187
-
188
- ### 3. Worker System
189
-
190
- **Working today:**
191
- - `runWorker()` with execute/captureIO hooks
192
- - Lease-based claims (prevents collisions)
193
- - Automatic lease renewal
194
- - Coordinator reconciliation (dead worker recovery)
195
-
196
- ```typescript
197
- runWorker({
198
- execute: async (task, ctx) => {
199
- await ctx.renewLease() // For long tasks
200
- return { success: true }
201
- }
202
- })
203
- ```
204
-
205
- **Research in progress:**
206
- - Daemon watching `~/.claude/projects/**/*.jsonl`
207
- - Automatic learning extraction from sessions
208
- - Confidence scoring for auto-promotion
209
-
210
- ---
211
-
212
- ## Worker Orchestration (TypeScript SDK)
213
-
214
- For programmatic control, the TypeScript SDK provides `runWorker()` — a headless worker that executes tasks using your hooks.
215
-
216
- ### Two Hooks. That's It.
217
-
218
- ```typescript
219
- import { runWorker } from "@jamesaphoenix/tx-core"
220
-
221
- runWorker({
222
- name: "my-worker",
223
- execute: async (task, ctx) => {
224
- // YOUR LOGIC HERE
225
- console.log(`Working on: ${task.title}`)
226
-
227
- // Use ctx.renewLease() for long tasks
228
- await ctx.renewLease()
229
-
230
- // Return success or failure
231
- return { success: true, output: "Done!" }
232
- },
233
- captureIO: (runId, task) => ({
234
- transcriptPath: `.tx/runs/${runId}.jsonl`,
235
- stderrPath: `.tx/runs/${runId}.stderr`
236
- })
237
- })
238
- ```
239
-
240
- | Hook | Required | Purpose |
241
- |------|----------|---------|
242
- | `execute` | Yes | Your task execution logic |
243
- | `captureIO` | No | Paths for transcript/stderr/stdout capture |
244
-
245
- ### WorkerContext
246
-
247
- The `ctx` object provides tx primitives:
248
-
249
- ```typescript
250
- interface WorkerContext {
251
- workerId: string // This worker's ID
252
- runId: string // Unique ID for this execution
253
- renewLease: () => Promise<void> // Extend lease for long tasks
254
- log: (message: string) => void // Log with worker prefix
255
- state: Record<string, unknown> // Mutable state within task
256
- }
257
- ```
258
-
259
- ### Custom Context
218
+ ## Packages
260
219
 
261
- Pass your own primitives via generics:
262
-
263
- ```typescript
264
- interface MyContext {
265
- llm: AnthropicClient
266
- db: Database
267
- }
268
-
269
- runWorker<MyContext>({
270
- context: {
271
- llm: new Anthropic(),
272
- db: myDatabase
273
- },
274
- execute: async (task, ctx) => {
275
- // ctx.llm and ctx.db available here
276
- const response = await ctx.llm.messages.create(...)
277
- return { success: true }
278
- }
279
- })
280
- ```
281
-
282
- ### Claims and Leases
283
-
284
- Workers use a lease-based system to prevent collisions:
285
-
286
- ```
287
- Worker A claims task → Lease expires in 30 min → Renew or lose it
288
- Worker B tries to claim same task → Rejected (already claimed)
289
- Worker A dies → Lease expires → Coordinator reclaims task
290
- ```
291
-
292
- Key points:
293
- - **Claims are atomic** — only one worker can claim a task
294
- - **Leases expire** — prevents stuck tasks from dead workers
295
- - **Auto-renewal** — `runWorker()` renews automatically; use `ctx.renewLease()` for extra-long tasks
296
- - **Coordinator reconciles** — dead workers detected, orphaned tasks recovered
297
-
298
- ### Example Worker Loops
299
-
300
- #### Basic: One Worker
301
-
302
- ```typescript
303
- import { Effect, Layer } from "effect"
304
- import { runWorker, makeMinimalLayer, SqliteClientLive } from "@jamesaphoenix/tx-core"
305
-
306
- const layer = makeMinimalLayer.pipe(
307
- Layer.provide(SqliteClientLive(".tx/tasks.db"))
308
- )
309
-
310
- Effect.runPromise(
311
- runWorker({
312
- execute: async (task, ctx) => {
313
- ctx.log(`Processing: ${task.title}`)
314
- // ... your logic
315
- return { success: true }
316
- }
317
- }).pipe(Effect.provide(layer))
318
- )
319
- ```
320
-
321
- #### With Claude Code
322
-
323
- ```typescript
324
- import { spawn } from "child_process"
325
-
326
- runWorker({
327
- execute: async (task, ctx) => {
328
- return new Promise((resolve) => {
329
- const proc = spawn("claude", [
330
- "--print",
331
- `Work on task ${task.id}: ${task.title}`
332
- ])
333
-
334
- proc.on("close", (code) => {
335
- resolve({
336
- success: code === 0,
337
- error: code !== 0 ? `Exit code ${code}` : undefined
338
- })
339
- })
340
- })
341
- }
342
- })
343
- ```
344
-
345
- #### Parallel Workers
346
-
347
- ```typescript
348
- // Start N workers (each in its own process or fiber)
349
- for (let i = 0; i < 5; i++) {
350
- Effect.fork(
351
- runWorker({
352
- name: `worker-${i}`,
353
- execute: async (task, ctx) => {
354
- // Workers automatically coordinate via claims
355
- return { success: true }
356
- }
357
- })
358
- )
359
- }
360
- ```
361
-
362
- #### Long-Running Tasks
363
-
364
- ```typescript
365
- runWorker({
366
- execute: async (task, ctx) => {
367
- for (let step = 0; step < 100; step++) {
368
- // Periodic lease renewal for tasks > 30 min
369
- if (step % 10 === 0) {
370
- await ctx.renewLease()
371
- }
372
-
373
- // Track progress in mutable state
374
- ctx.state.progress = step
375
-
376
- await doExpensiveWork(step)
377
- }
378
- return { success: true }
379
- }
380
- })
381
- ```
220
+ | Package | Description |
221
+ |---------|-------------|
222
+ | [`@jamesaphoenix/tx`](https://www.npmjs.com/package/@jamesaphoenix/tx) | Library entry point (this package) |
223
+ | [`@jamesaphoenix/tx-cli`](https://www.npmjs.com/package/@jamesaphoenix/tx-cli) | CLI binary (`tx` command) |
224
+ | [`@jamesaphoenix/tx-core`](https://www.npmjs.com/package/@jamesaphoenix/tx-core) | Core services (Effect-TS) |
225
+ | [`@jamesaphoenix/tx-types`](https://www.npmjs.com/package/@jamesaphoenix/tx-types) | Shared type definitions |
226
+ | [`@jamesaphoenix/tx-agent-sdk`](https://www.npmjs.com/package/@jamesaphoenix/tx-agent-sdk) | Promise-based HTTP client |
227
+ | [`@jamesaphoenix/tx-mcp-server`](https://www.npmjs.com/package/@jamesaphoenix/tx-mcp-server) | MCP server (42 tools) |
228
+ | [`@jamesaphoenix/tx-api-server`](https://www.npmjs.com/package/@jamesaphoenix/tx-api-server) | REST API server |
382
229
 
383
230
  ---
384
231
 
@@ -386,8 +233,8 @@ runWorker({
386
233
 
387
234
  | Interface | Use Case |
388
235
  |-----------|----------|
389
- | **CLI** | Scripts, terminal workflows, RALPH loops |
390
- | **MCP Server** | Claude Code integration (16 tools) |
236
+ | **CLI** | Scripts, terminal workflows, agent loops |
237
+ | **MCP Server** | Claude Code integration (42 tools) |
391
238
  | **REST API** | Custom dashboards, external integrations |
392
239
  | **TypeScript SDK** | Programmatic access from your agents |
393
240
  | **Dashboard** | Visual monitoring and management |
@@ -398,25 +245,46 @@ runWorker({
398
245
 
399
246
  ```bash
400
247
  # Tasks
401
- tx add <title> # Create
402
- tx ready # List unblocked
403
- tx done <id> # Complete
248
+ tx add <title> # Create task
249
+ tx list # List all tasks
250
+ tx ready # List unblocked tasks
251
+ tx show <id> # View details
252
+ tx update <id> # Update task fields
253
+ tx done <id> # Complete task
254
+ tx delete <id> # Delete task
404
255
  tx block <id> <blocker> # Add dependency
405
256
  tx tree <id> # Show hierarchy
406
257
 
407
- # Memory
408
- tx learning:add <content> # Store
409
- tx learning:search <query> # Find
258
+ # Context & Learnings
259
+ tx learning:add <content> # Store knowledge
260
+ tx learning:search <query> # Search learnings
410
261
  tx context <task-id> # Contextual retrieval
262
+ tx learn <path> <note> # Attach to file
263
+ tx recall [path] # Query by file
411
264
 
412
265
  # Coordination
413
- tx claim <id> # Prevent collisions
414
- tx handoff <id> --to <agent>
415
- tx checkpoint <id> --note "..."
266
+ tx claim <id> <worker> # Lease-based claim
267
+ tx claim:renew <id> <worker> # Extend lease
268
+ tx claim:release <id> <worker> # Release early
269
+ tx try <id> <approach> # Record attempt
270
+
271
+ # Docs & Invariants
272
+ tx doc add <type> <slug> # Create doc
273
+ tx doc render # Generate markdown
274
+ tx invariant list # List invariants
275
+ tx invariant sync # Sync from CLAUDE.md
416
276
 
417
277
  # Sync
418
278
  tx sync export # SQLite → JSONL (git-friendly)
419
279
  tx sync import # JSONL → SQLite
280
+ tx sync claude --team <name> # Push to Claude Code team
281
+
282
+ # Traces & Utilities
283
+ tx cycle # Sub-agent swarm scan
284
+ tx trace list # Recent runs
285
+ tx stats # Queue metrics
286
+ tx doctor # System diagnostics
287
+ tx dashboard # Launch dashboard
420
288
  ```
421
289
 
422
290
  ---
@@ -428,53 +296,14 @@ tx sync import # JSONL → SQLite
428
296
  ├── tasks.db # SQLite (gitignored)
429
297
  ├── tasks.jsonl # Git-tracked
430
298
  ├── learnings.jsonl # Git-tracked
431
- └── runs.jsonl # Git-tracked
299
+ ├── runs.jsonl # Git-tracked
300
+ └── docs/ # YAML doc sources
432
301
  ```
433
302
 
434
303
  Local SQLite for speed. JSONL for git sync. Branch your knowledge with your code.
435
304
 
436
305
  ---
437
306
 
438
- ## Status
439
-
440
- **Shipping now (concrete, tested):**
441
- - Core task primitives: add, ready, done, block, claim, handoff
442
- - Dependency management with cycle detection
443
- - Worker orchestration via `runWorker()` with claims/leases
444
- - Learnings with file path tagging
445
- - Hybrid search (BM25 + vector)
446
- - CLI (20+ commands), MCP server (16 tools)
447
- - 389+ tests
448
-
449
- **Research in progress (not yet stable):**
450
- - Symbol anchoring (AST-based code references)
451
- - Knowledge graph expansion
452
- - Auto-invalidation when code changes
453
- - Daemon-based learning extraction
454
- - LLM reprioritization
455
-
456
- ---
457
-
458
- ## Documentation
459
-
460
- - **[CLAUDE.md](CLAUDE.md)**: Doctrine and quick reference
461
- - **[docs/](docs/)**: Full documentation (17 PRDs, 17 Design Docs)
462
-
463
- ### Docs Site
464
-
465
- Run the documentation site locally:
466
-
467
- ```bash
468
- cd apps/docs
469
- npm run dev # Development server at http://localhost:3000
470
- npm run build # Production build
471
- npm run start # Serve production build
472
- ```
473
-
474
- The docs site is built with [Fumadocs](https://fumadocs.vercel.app/) and Next.js, featuring full-text search, syntax highlighting, and automatic navigation from the markdown files in `docs/`.
475
-
476
- ---
477
-
478
307
  ## License
479
308
 
480
309
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jamesaphoenix/tx",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "TanStack for AI agents - headless primitives for memory, tasks, and orchestration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",