@jamesaphoenix/tx 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/create-tx.d.ts +147 -0
- package/dist/create-tx.d.ts.map +1 -0
- package/dist/create-tx.js +102 -0
- package/dist/create-tx.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -16
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/package.json +35 -35
- package/LICENSE +0 -21
- package/README.md +0 -125
- package/dist/cli.js +0 -868
- package/dist/cli.js.map +0 -1
- package/dist/db.js +0 -70
- package/dist/db.js.map +0 -1
- package/dist/errors.js +0 -22
- package/dist/errors.js.map +0 -1
- package/dist/id.js +0 -19
- package/dist/id.js.map +0 -1
- package/dist/layer.js +0 -20
- package/dist/layer.js.map +0 -1
- package/dist/mcp/server.js +0 -453
- package/dist/mcp/server.js.map +0 -1
- package/dist/repo/dep-repo.js +0 -104
- package/dist/repo/dep-repo.js.map +0 -1
- package/dist/repo/task-repo.js +0 -140
- package/dist/repo/task-repo.js.map +0 -1
- package/dist/schema.js +0 -37
- package/dist/schema.js.map +0 -1
- package/dist/schemas/sync.js +0 -55
- package/dist/schemas/sync.js.map +0 -1
- package/dist/services/dep-service.js +0 -34
- package/dist/services/dep-service.js.map +0 -1
- package/dist/services/hierarchy-service.js +0 -66
- package/dist/services/hierarchy-service.js.map +0 -1
- package/dist/services/ready-service.js +0 -70
- package/dist/services/ready-service.js.map +0 -1
- package/dist/services/score-service.js +0 -82
- package/dist/services/score-service.js.map +0 -1
- package/dist/services/sync-service.js +0 -244
- package/dist/services/sync-service.js.map +0 -1
- package/dist/services/task-service.js +0 -201
- package/dist/services/task-service.js.map +0 -1
- package/migrations/001_initial.sql +0 -57
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createTx - Factory function to create a configured tx client
|
|
3
|
+
*
|
|
4
|
+
* This module provides the main entry point for SDK consumers who want
|
|
5
|
+
* to customize tx behavior, such as providing a custom retriever.
|
|
6
|
+
*
|
|
7
|
+
* @example Basic usage
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { createTx } from "@jamesaphoenix/tx";
|
|
10
|
+
*
|
|
11
|
+
* const tx = createTx();
|
|
12
|
+
* const ready = await tx.run(tasks.getReady({ limit: 5 }));
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* @example Custom retriever
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { createTx, RetrieverService } from "@jamesaphoenix/tx";
|
|
18
|
+
* import { Effect, Layer } from "effect";
|
|
19
|
+
*
|
|
20
|
+
* const myRetriever = Layer.succeed(RetrieverService, {
|
|
21
|
+
* search: (query, options) => Effect.gen(function* () {
|
|
22
|
+
* return yield* pineconeQuery(query);
|
|
23
|
+
* }),
|
|
24
|
+
* isAvailable: () => Effect.succeed(true)
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* const tx = createTx({ retriever: myRetriever });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
import { Effect, Exit, Layer } from "effect";
|
|
31
|
+
import { RetrieverService } from "@tx/core";
|
|
32
|
+
/**
|
|
33
|
+
* Options for configuring createTx().
|
|
34
|
+
*
|
|
35
|
+
* All options are optional - defaults provide a fully functional tx instance.
|
|
36
|
+
*/
|
|
37
|
+
export interface CreateTxOptions {
|
|
38
|
+
/**
|
|
39
|
+
* Path to SQLite database file.
|
|
40
|
+
* @default ".tx/tasks.db"
|
|
41
|
+
*/
|
|
42
|
+
readonly dbPath?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Custom retriever layer to use instead of the default BM25+vector hybrid.
|
|
45
|
+
*
|
|
46
|
+
* When provided, this layer replaces RetrieverServiceLive entirely.
|
|
47
|
+
* The layer must satisfy the RetrieverService interface.
|
|
48
|
+
*
|
|
49
|
+
* @example Pinecone retriever
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const myRetriever = Layer.succeed(RetrieverService, {
|
|
52
|
+
* search: (query, options) => Effect.gen(function* () {
|
|
53
|
+
* const results = yield* pineconeQuery(query);
|
|
54
|
+
* return results.map(toLearningWithScore);
|
|
55
|
+
* }),
|
|
56
|
+
* isAvailable: () => Effect.succeed(true)
|
|
57
|
+
* });
|
|
58
|
+
*
|
|
59
|
+
* const tx = createTx({ retriever: myRetriever });
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
readonly retriever?: Layer.Layer<RetrieverService>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The tx client returned by createTx().
|
|
66
|
+
*
|
|
67
|
+
* Provides methods to run Effects against the configured layer
|
|
68
|
+
* and access commonly-used services directly.
|
|
69
|
+
*/
|
|
70
|
+
export interface TxClient {
|
|
71
|
+
/**
|
|
72
|
+
* Run an Effect against the configured tx layer.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* const ready = await tx.run(
|
|
77
|
+
* Effect.gen(function* () {
|
|
78
|
+
* const tasks = yield* TaskService;
|
|
79
|
+
* return yield* tasks.getReady({ limit: 5 });
|
|
80
|
+
* })
|
|
81
|
+
* );
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
readonly run: <A, E>(effect: Effect.Effect<A, E, never>) => Promise<A>;
|
|
85
|
+
/**
|
|
86
|
+
* Run an Effect and return an Exit (success or failure).
|
|
87
|
+
* Useful when you need to handle errors programmatically.
|
|
88
|
+
*/
|
|
89
|
+
readonly runExit: <A, E>(effect: Effect.Effect<A, E, never>) => Promise<Exit.Exit<A, unknown>>;
|
|
90
|
+
/**
|
|
91
|
+
* The composed Layer for advanced use cases.
|
|
92
|
+
* Can be used with Effect.provide() directly.
|
|
93
|
+
*/
|
|
94
|
+
readonly layer: Layer.Layer<any, any, any>;
|
|
95
|
+
/**
|
|
96
|
+
* Clean up resources (close database, etc.).
|
|
97
|
+
* Call this when done using the client.
|
|
98
|
+
*/
|
|
99
|
+
readonly close: () => Promise<void>;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Create a tx client with optional configuration.
|
|
103
|
+
*
|
|
104
|
+
* This is the main entry point for SDK consumers who want to:
|
|
105
|
+
* - Use a custom database path
|
|
106
|
+
* - Provide a custom retriever (Pinecone, Weaviate, etc.)
|
|
107
|
+
*
|
|
108
|
+
* @param options - Configuration options (all optional)
|
|
109
|
+
* @returns A TxClient for running Effects against the configured layer
|
|
110
|
+
*
|
|
111
|
+
* @example Basic usage (defaults)
|
|
112
|
+
* ```typescript
|
|
113
|
+
* const tx = createTx();
|
|
114
|
+
*
|
|
115
|
+
* const ready = await tx.run(
|
|
116
|
+
* Effect.gen(function* () {
|
|
117
|
+
* const tasks = yield* TaskService;
|
|
118
|
+
* return yield* tasks.getReady({ limit: 5 });
|
|
119
|
+
* })
|
|
120
|
+
* );
|
|
121
|
+
*
|
|
122
|
+
* await tx.close();
|
|
123
|
+
* ```
|
|
124
|
+
*
|
|
125
|
+
* @example Custom retriever
|
|
126
|
+
* ```typescript
|
|
127
|
+
* import { createTx, RetrieverService } from "@jamesaphoenix/tx";
|
|
128
|
+
* import { Effect, Layer } from "effect";
|
|
129
|
+
*
|
|
130
|
+
* const pineconeRetriever = Layer.succeed(RetrieverService, {
|
|
131
|
+
* search: (query, options) => Effect.gen(function* () {
|
|
132
|
+
* // Your Pinecone/Weaviate/Chroma implementation
|
|
133
|
+
* const results = yield* queryExternalVectorDB(query, options);
|
|
134
|
+
* return results;
|
|
135
|
+
* }),
|
|
136
|
+
* isAvailable: () => Effect.succeed(true)
|
|
137
|
+
* });
|
|
138
|
+
*
|
|
139
|
+
* const tx = createTx({
|
|
140
|
+
* dbPath: "./my-app/.tx/tasks.db",
|
|
141
|
+
* retriever: pineconeRetriever
|
|
142
|
+
* });
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
export declare const createTx: (options?: CreateTxOptions) => TxClient;
|
|
146
|
+
export { RetrieverService } from "@tx/core";
|
|
147
|
+
//# sourceMappingURL=create-tx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-tx.d.ts","sourceRoot":"","sources":["../src/create-tx.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAkB,MAAM,QAAQ,CAAA;AAC5D,OAAO,EAEL,gBAAgB,EACjB,MAAM,UAAU,CAAA;AAEjB;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IAExB;;;;;;;;;;;;;;;;;;OAkBG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAA;CACnD;AAED;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IAEtE;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAA;IAE9F;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IAE1C;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,eAAO,MAAM,QAAQ,GAAI,UAAS,eAAoB,KAAG,QAiCxD,CAAA;AAGD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createTx - Factory function to create a configured tx client
|
|
3
|
+
*
|
|
4
|
+
* This module provides the main entry point for SDK consumers who want
|
|
5
|
+
* to customize tx behavior, such as providing a custom retriever.
|
|
6
|
+
*
|
|
7
|
+
* @example Basic usage
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { createTx } from "@jamesaphoenix/tx";
|
|
10
|
+
*
|
|
11
|
+
* const tx = createTx();
|
|
12
|
+
* const ready = await tx.run(tasks.getReady({ limit: 5 }));
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* @example Custom retriever
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { createTx, RetrieverService } from "@jamesaphoenix/tx";
|
|
18
|
+
* import { Effect, Layer } from "effect";
|
|
19
|
+
*
|
|
20
|
+
* const myRetriever = Layer.succeed(RetrieverService, {
|
|
21
|
+
* search: (query, options) => Effect.gen(function* () {
|
|
22
|
+
* return yield* pineconeQuery(query);
|
|
23
|
+
* }),
|
|
24
|
+
* isAvailable: () => Effect.succeed(true)
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* const tx = createTx({ retriever: myRetriever });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
import { Layer, ManagedRuntime } from "effect";
|
|
31
|
+
import { makeAppLayer } from "@tx/core";
|
|
32
|
+
/**
|
|
33
|
+
* Create a tx client with optional configuration.
|
|
34
|
+
*
|
|
35
|
+
* This is the main entry point for SDK consumers who want to:
|
|
36
|
+
* - Use a custom database path
|
|
37
|
+
* - Provide a custom retriever (Pinecone, Weaviate, etc.)
|
|
38
|
+
*
|
|
39
|
+
* @param options - Configuration options (all optional)
|
|
40
|
+
* @returns A TxClient for running Effects against the configured layer
|
|
41
|
+
*
|
|
42
|
+
* @example Basic usage (defaults)
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const tx = createTx();
|
|
45
|
+
*
|
|
46
|
+
* const ready = await tx.run(
|
|
47
|
+
* Effect.gen(function* () {
|
|
48
|
+
* const tasks = yield* TaskService;
|
|
49
|
+
* return yield* tasks.getReady({ limit: 5 });
|
|
50
|
+
* })
|
|
51
|
+
* );
|
|
52
|
+
*
|
|
53
|
+
* await tx.close();
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @example Custom retriever
|
|
57
|
+
* ```typescript
|
|
58
|
+
* import { createTx, RetrieverService } from "@jamesaphoenix/tx";
|
|
59
|
+
* import { Effect, Layer } from "effect";
|
|
60
|
+
*
|
|
61
|
+
* const pineconeRetriever = Layer.succeed(RetrieverService, {
|
|
62
|
+
* search: (query, options) => Effect.gen(function* () {
|
|
63
|
+
* // Your Pinecone/Weaviate/Chroma implementation
|
|
64
|
+
* const results = yield* queryExternalVectorDB(query, options);
|
|
65
|
+
* return results;
|
|
66
|
+
* }),
|
|
67
|
+
* isAvailable: () => Effect.succeed(true)
|
|
68
|
+
* });
|
|
69
|
+
*
|
|
70
|
+
* const tx = createTx({
|
|
71
|
+
* dbPath: "./my-app/.tx/tasks.db",
|
|
72
|
+
* retriever: pineconeRetriever
|
|
73
|
+
* });
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export const createTx = (options = {}) => {
|
|
77
|
+
const { dbPath = ".tx/tasks.db", retriever } = options;
|
|
78
|
+
// Build the base app layer
|
|
79
|
+
const baseLayer = makeAppLayer(dbPath);
|
|
80
|
+
// If custom retriever provided, merge it on top to override the default
|
|
81
|
+
// Layer.provideMerge gives priority to the first layer for overlapping services
|
|
82
|
+
const appLayer = retriever
|
|
83
|
+
? Layer.provideMerge(retriever, baseLayer)
|
|
84
|
+
: baseLayer;
|
|
85
|
+
// Create a managed runtime that handles resource lifecycle
|
|
86
|
+
const managedRuntime = ManagedRuntime.make(appLayer);
|
|
87
|
+
return {
|
|
88
|
+
run: async (effect) => {
|
|
89
|
+
return managedRuntime.runPromise(effect);
|
|
90
|
+
},
|
|
91
|
+
runExit: async (effect) => {
|
|
92
|
+
return managedRuntime.runPromiseExit(effect);
|
|
93
|
+
},
|
|
94
|
+
layer: appLayer,
|
|
95
|
+
close: async () => {
|
|
96
|
+
await managedRuntime.dispose();
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
// Re-export RetrieverService for custom retriever implementations
|
|
101
|
+
export { RetrieverService } from "@tx/core";
|
|
102
|
+
//# sourceMappingURL=create-tx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-tx.js","sourceRoot":"","sources":["../src/create-tx.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAgB,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAC5D,OAAO,EACL,YAAY,EAEb,MAAM,UAAU,CAAA;AA6EjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,UAA2B,EAAE,EAAY,EAAE;IAClE,MAAM,EACJ,MAAM,GAAG,cAAc,EACvB,SAAS,EACV,GAAG,OAAO,CAAA;IAEX,2BAA2B;IAC3B,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;IAEtC,wEAAwE;IACxE,gFAAgF;IAChF,MAAM,QAAQ,GAAG,SAAS;QACxB,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC;QAC1C,CAAC,CAAC,SAAS,CAAA;IAEb,2DAA2D;IAC3D,MAAM,cAAc,GAAG,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAEpD,OAAO;QACL,GAAG,EAAE,KAAK,EAAQ,MAAkC,EAAc,EAAE;YAClE,OAAO,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;QAC1C,CAAC;QAED,OAAO,EAAE,KAAK,EAAQ,MAAkC,EAAkC,EAAE;YAC1F,OAAO,cAAc,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;QAC9C,CAAC;QAED,KAAK,EAAE,QAAQ;QAEf,KAAK,EAAE,KAAK,IAAmB,EAAE;YAC/B,MAAM,cAAc,CAAC,OAAO,EAAE,CAAA;QAChC,CAAC;KACF,CAAA;AACH,CAAC,CAAA;AAED,kEAAkE;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jamesaphoenix/tx - TanStack for AI agents
|
|
3
|
+
*
|
|
4
|
+
* Headless primitives for memory, tasks, and orchestration.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { TaskService, LearningService, makeAppLayer } from "@jamesaphoenix/tx";
|
|
9
|
+
* import { Effect } from "effect";
|
|
10
|
+
*
|
|
11
|
+
* const program = Effect.gen(function* () {
|
|
12
|
+
* const tasks = yield* TaskService;
|
|
13
|
+
* const ready = yield* tasks.getReady({ limit: 5 });
|
|
14
|
+
* return ready;
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @example Custom Retriever
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { createTx, RetrieverService } from "@jamesaphoenix/tx";
|
|
21
|
+
* import { Effect, Layer } from "effect";
|
|
22
|
+
*
|
|
23
|
+
* // Custom Pinecone retriever
|
|
24
|
+
* const myRetriever = Layer.succeed(RetrieverService, {
|
|
25
|
+
* search: (query, options) => Effect.gen(function* () {
|
|
26
|
+
* const results = yield* pineconeQuery(query);
|
|
27
|
+
* return results.map(toLearningWithScore);
|
|
28
|
+
* }),
|
|
29
|
+
* isAvailable: () => Effect.succeed(true)
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* const tx = createTx({
|
|
33
|
+
* retriever: myRetriever // optional override
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export * from "@tx/core";
|
|
38
|
+
export { createTx, type CreateTxOptions, type TxClient } from "./create-tx.js";
|
|
39
|
+
export type { TaskStatus, TaskId, Task, TaskWithDeps, TaskTree, TaskDependency, CreateTaskInput, UpdateTaskInput, TaskFilter, LearningSourceType, LearningId, Learning, LearningWithScore, CreateLearningInput, UpdateLearningInput, LearningQuery, ContextOptions, ContextResult, RetrievalOptions, AttemptOutcome, AttemptId, Attempt, CreateAttemptInput, RunId, RunStatus, Run, CreateRunInput, UpdateRunInput, AnchorId, AnchorType, AnchorStatus, Anchor, CreateAnchorInput, EdgeId, NodeType, EdgeType, Edge, CreateEdgeInput, } from "@tx/types";
|
|
40
|
+
export { TASK_STATUSES, VALID_TRANSITIONS, LEARNING_SOURCE_TYPES, ATTEMPT_OUTCOMES, RUN_STATUSES, ANCHOR_TYPES, ANCHOR_STATUSES, NODE_TYPES, EDGE_TYPES, } from "@tx/types";
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,cAAc,UAAU,CAAC;AAGzB,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG/E,YAAY,EAEV,UAAU,EACV,MAAM,EACN,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,eAAe,EACf,eAAe,EACf,UAAU,EAEV,kBAAkB,EAClB,UAAU,EACV,QAAQ,EACR,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,aAAa,EACb,gBAAgB,EAEhB,cAAc,EACd,SAAS,EACT,OAAO,EACP,kBAAkB,EAElB,KAAK,EACL,SAAS,EACT,GAAG,EACH,cAAc,EACd,cAAc,EAEd,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,MAAM,EACN,iBAAiB,EAEjB,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,eAAe,GAChB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,UAAU,EACV,UAAU,GACX,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @jamesaphoenix/tx - TanStack for AI agents
|
|
3
|
+
*
|
|
4
|
+
* Headless primitives for memory, tasks, and orchestration.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { TaskService, LearningService, makeAppLayer } from "@jamesaphoenix/tx";
|
|
9
|
+
* import { Effect } from "effect";
|
|
10
|
+
*
|
|
11
|
+
* const program = Effect.gen(function* () {
|
|
12
|
+
* const tasks = yield* TaskService;
|
|
13
|
+
* const ready = yield* tasks.getReady({ limit: 5 });
|
|
14
|
+
* return ready;
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @example Custom Retriever
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { createTx, RetrieverService } from "@jamesaphoenix/tx";
|
|
21
|
+
* import { Effect, Layer } from "effect";
|
|
22
|
+
*
|
|
23
|
+
* // Custom Pinecone retriever
|
|
24
|
+
* const myRetriever = Layer.succeed(RetrieverService, {
|
|
25
|
+
* search: (query, options) => Effect.gen(function* () {
|
|
26
|
+
* const results = yield* pineconeQuery(query);
|
|
27
|
+
* return results.map(toLearningWithScore);
|
|
28
|
+
* }),
|
|
29
|
+
* isAvailable: () => Effect.succeed(true)
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* const tx = createTx({
|
|
33
|
+
* retriever: myRetriever // optional override
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
// Re-export everything from @tx/core
|
|
38
|
+
export * from "@tx/core";
|
|
39
|
+
// Export createTx and related types
|
|
40
|
+
export { createTx } from "./create-tx.js";
|
|
41
|
+
// Re-export constants from types
|
|
42
|
+
export { TASK_STATUSES, VALID_TRANSITIONS, LEARNING_SOURCE_TYPES, ATTEMPT_OUTCOMES, RUN_STATUSES, ANCHOR_TYPES, ANCHOR_STATUSES, NODE_TYPES, EDGE_TYPES, } from "@tx/types";
|
|
17
43
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,qCAAqC;AACrC,cAAc,UAAU,CAAC;AAEzB,oCAAoC;AACpC,OAAO,EAAE,QAAQ,EAAuC,MAAM,gBAAgB,CAAC;AAkD/E,iCAAiC;AACjC,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,UAAU,EACV,UAAU,GACX,MAAM,WAAW,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-only exports for @jamesaphoenix/tx
|
|
3
|
+
*
|
|
4
|
+
* Use this for type-only imports when you don't need runtime code.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import type { Task, Learning } from "@jamesaphoenix/tx/types";
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export * from "@tx/types";
|
|
12
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,WAAW,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-only exports for @jamesaphoenix/tx
|
|
3
|
+
*
|
|
4
|
+
* Use this for type-only imports when you don't need runtime code.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import type { Task, Learning } from "@jamesaphoenix/tx/types";
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export * from "@tx/types";
|
|
12
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,WAAW,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,16 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jamesaphoenix/tx",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "TanStack for AI agents - headless primitives for memory, tasks, and orchestration",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"tx": "./dist/cli.js"
|
|
8
|
-
},
|
|
9
6
|
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./types": {
|
|
14
|
+
"types": "./dist/types.d.ts",
|
|
15
|
+
"import": "./dist/types.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
10
18
|
"files": [
|
|
11
|
-
"dist"
|
|
12
|
-
"migrations"
|
|
19
|
+
"dist"
|
|
13
20
|
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc -b",
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"prepublishOnly": "npm run build"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@tx/core": "*",
|
|
28
|
+
"@tx/types": "*"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"better-sqlite3": "^11.0.0",
|
|
32
|
+
"effect": "^3.0.0"
|
|
33
|
+
},
|
|
34
|
+
"peerDependenciesMeta": {
|
|
35
|
+
"better-sqlite3": {
|
|
36
|
+
"optional": false
|
|
37
|
+
}
|
|
38
|
+
},
|
|
14
39
|
"repository": {
|
|
15
40
|
"type": "git",
|
|
16
41
|
"url": "https://github.com/jamesaphoenix/tx.git"
|
|
@@ -18,35 +43,10 @@
|
|
|
18
43
|
"keywords": [
|
|
19
44
|
"task-management",
|
|
20
45
|
"ai-agents",
|
|
21
|
-
"cli",
|
|
22
46
|
"effect-ts",
|
|
23
|
-
"mcp"
|
|
47
|
+
"mcp",
|
|
48
|
+
"orchestration"
|
|
24
49
|
],
|
|
25
50
|
"author": "James Phoenix",
|
|
26
|
-
"license": "MIT"
|
|
27
|
-
"scripts": {
|
|
28
|
-
"build": "tsc",
|
|
29
|
-
"dev": "tsx src/cli.ts",
|
|
30
|
-
"test": "vitest --run",
|
|
31
|
-
"test:watch": "vitest",
|
|
32
|
-
"validate": "npm run build && npm test && npm link"
|
|
33
|
-
},
|
|
34
|
-
"dependencies": {
|
|
35
|
-
"@effect/cli": "^0.73.1",
|
|
36
|
-
"@effect/platform": "^0.94.2",
|
|
37
|
-
"@effect/platform-node": "^0.104.1",
|
|
38
|
-
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
39
|
-
"better-sqlite3": "^11.7.0",
|
|
40
|
-
"effect": "^3.19.15"
|
|
41
|
-
},
|
|
42
|
-
"devDependencies": {
|
|
43
|
-
"@types/better-sqlite3": "^7.6.12",
|
|
44
|
-
"@types/node": "^22.10.0",
|
|
45
|
-
"tsx": "^4.19.0",
|
|
46
|
-
"typescript": "^5.7.0",
|
|
47
|
-
"vitest": "^3.0.0"
|
|
48
|
-
},
|
|
49
|
-
"engines": {
|
|
50
|
-
"node": ">=20"
|
|
51
|
-
}
|
|
51
|
+
"license": "MIT"
|
|
52
52
|
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 James Phoenix
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
package/README.md
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
# tx
|
|
2
|
-
|
|
3
|
-
A lean task management system for AI agents and humans, built with Effect-TS.
|
|
4
|
-
|
|
5
|
-
## Why
|
|
6
|
-
|
|
7
|
-
AI coding agents lose context across sessions. Markdown plans go stale, git issue trackers are designed for humans, and session-scoped todo lists vanish when the conversation ends.
|
|
8
|
-
|
|
9
|
-
**tx** gives agents a persistent, queryable, dependency-aware task store that works across sessions and can be programmatically manipulated through CLI, MCP, or TypeScript API.
|
|
10
|
-
|
|
11
|
-
## Core Ideas
|
|
12
|
-
|
|
13
|
-
- **Persistent** -- Tasks survive across agent sessions and machine restarts via SQLite
|
|
14
|
-
- **Fast** -- Sub-100ms queries for common operations (list, ready, get)
|
|
15
|
-
- **Dependency-aware** -- Explicit blocking relationships so agents never work on blocked tasks
|
|
16
|
-
- **Ready detection** -- `tx ready` returns the highest-priority unblocked tasks, sorted by score
|
|
17
|
-
- **Hierarchical** -- Flexible N-level nesting (epics, milestones, tasks, subtasks)
|
|
18
|
-
- **Multi-interface** -- CLI for humans, MCP server for Claude Code, TypeScript API for custom agents
|
|
19
|
-
- **Minimal** -- Single dependency (SQLite), no external services required for core features
|
|
20
|
-
- **LLM-optional** -- Core commands work without an API key; LLM features (dedupe, compact, reprioritize) use Claude when available
|
|
21
|
-
|
|
22
|
-
## How It Works
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
tx add "Implement authentication" --score 800
|
|
26
|
-
tx add "Design auth schema" --parent tx-a1b2c3
|
|
27
|
-
tx block tx-d4e5f6 tx-a1b2c3
|
|
28
|
-
tx ready # returns highest-priority unblocked tasks
|
|
29
|
-
tx done tx-a1b2c3 # completes task, unblocks dependents
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Agents query `tx ready` to pick up work, create subtasks as they decompose problems, and mark tasks done to unblock the next piece of work. Humans review, reprioritize, and add context.
|
|
33
|
-
|
|
34
|
-
## Architecture
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
CLI / MCP Server / TypeScript API
|
|
38
|
-
|
|
|
39
|
-
Service Layer (Effect-TS)
|
|
40
|
-
TaskService, ReadyService, ScoreService, HierarchyService
|
|
41
|
-
|
|
|
42
|
-
Repository Layer
|
|
43
|
-
TaskRepository, DependencyRepository
|
|
44
|
-
|
|
|
45
|
-
SQLite (better-sqlite3, WAL mode)
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
All business logic uses Effect-TS for typed errors, service composition, and layer-based dependency injection. Two layer configurations:
|
|
49
|
-
|
|
50
|
-
- **AppMinimalLive** -- No LLM, used by CLI core commands, MCP server, Agent SDK
|
|
51
|
-
- **AppLive** -- Includes LLM, used by dedupe/compact/reprioritize
|
|
52
|
-
|
|
53
|
-
## Status Lifecycle
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
backlog -> ready -> planning -> active -> blocked -> review -> human_needs_to_review -> done
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
A task is **ready** when its status is workable and all blockers have status `done`.
|
|
60
|
-
|
|
61
|
-
## Interfaces
|
|
62
|
-
|
|
63
|
-
| Interface | Consumer | Protocol |
|
|
64
|
-
|-----------|----------|----------|
|
|
65
|
-
| CLI (`tx`) | Humans, scripts | stdin/stdout (text or JSON) |
|
|
66
|
-
| MCP Server | Claude Code | JSON-RPC over stdio |
|
|
67
|
-
| TypeScript API | Custom agents | Effect types |
|
|
68
|
-
| Agent SDK | Anthropic SDK | Tool definitions |
|
|
69
|
-
|
|
70
|
-
## LLM Features (optional)
|
|
71
|
-
|
|
72
|
-
These commands require `ANTHROPIC_API_KEY`:
|
|
73
|
-
|
|
74
|
-
- **`tx dedupe`** -- Find and merge semantically duplicate tasks
|
|
75
|
-
- **`tx compact`** -- Summarize completed tasks, extract learnings, export to CLAUDE.md
|
|
76
|
-
- **`tx reprioritize`** -- LLM recalculates scores based on context
|
|
77
|
-
|
|
78
|
-
## RALPH Loop — Autonomous Development
|
|
79
|
-
|
|
80
|
-
tx uses an adapted [RALPH loop](https://ghuntley.com/ralph) for autonomous development. Fresh agent instances are spawned per task — memory persists through files (CLAUDE.md, git, `.tx/tasks.db`), not conversation history.
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
./scripts/ralph.sh # Run until all tasks done
|
|
84
|
-
./scripts/ralph.sh --max 10 # Run at most 10 iterations
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
The orchestrator picks the highest-priority task from `tx ready`, dispatches it to a specialized agent, and loops until all work is complete.
|
|
88
|
-
|
|
89
|
-
### Specialized Agents
|
|
90
|
-
|
|
91
|
-
Agents are defined as markdown files in `.claude/agents/`:
|
|
92
|
-
|
|
93
|
-
| Agent | Role |
|
|
94
|
-
|-------|------|
|
|
95
|
-
| `tx-planner` | Research codebase, create implementation plan, decompose into subtasks |
|
|
96
|
-
| `tx-implementer` | Write Effect-TS code for a single task, following doctrine |
|
|
97
|
-
| `tx-reviewer` | Review code changes against all 7 doctrine rules |
|
|
98
|
-
| `tx-tester` | Write integration tests with SHA256 deterministic fixtures |
|
|
99
|
-
| `tx-decomposer` | Break large tasks into atomic subtasks for single iterations |
|
|
100
|
-
|
|
101
|
-
Agents can also be used programmatically via the [Claude Agent SDK](https://docs.anthropic.com/en/docs/agent-sdk).
|
|
102
|
-
|
|
103
|
-
## Project Structure
|
|
104
|
-
|
|
105
|
-
```
|
|
106
|
-
tx/
|
|
107
|
-
├── CLAUDE.md # Doctrine, PRDs, design docs
|
|
108
|
-
├── .claude/
|
|
109
|
-
│ └── agents/ # Specialized agent definitions
|
|
110
|
-
│ ├── tx-planner.md
|
|
111
|
-
│ ├── tx-implementer.md
|
|
112
|
-
│ ├── tx-reviewer.md
|
|
113
|
-
│ ├── tx-tester.md
|
|
114
|
-
│ └── tx-decomposer.md
|
|
115
|
-
├── scripts/
|
|
116
|
-
│ └── ralph.sh # RALPH loop orchestrator
|
|
117
|
-
├── docs/
|
|
118
|
-
│ ├── prd/ # Product Requirements Documents
|
|
119
|
-
│ └── design/ # Design Documents
|
|
120
|
-
└── src/ # Implementation
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
## License
|
|
124
|
-
|
|
125
|
-
MIT
|