@autonome-research/thread-phase-cli 3.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 thread-phase contributors
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 ADDED
@@ -0,0 +1,67 @@
1
+ # @autonome-research/thread-phase-cli
2
+
3
+ The CLI and auto-loader for [thread-phase](https://github.com/Code4me2/thread-phase). Discovers extensions under `./.thread-phase/{triggers,adapters,pipelines}/` and runs registered pipelines.
4
+
5
+ ```sh
6
+ npm install -g @autonome-research/thread-phase-cli @autonome-research/thread-phase
7
+ ```
8
+
9
+ ## Commands
10
+
11
+ ```sh
12
+ thread-phase list # show registered extensions
13
+ thread-phase list --verbose # …plus structural details per entry
14
+ thread-phase run <pipeline-name> # invoke a pipeline once and exit
15
+ thread-phase run <name> --input ... # override defaultInput (JSON literal, @file, or -)
16
+ thread-phase serve # start all triggered pipelines (SIGINT/SIGTERM to stop)
17
+ thread-phase serve --health-port N # …with a /health endpoint on port N
18
+ ```
19
+
20
+ `run` replaces `npx tsx pipelines/foo.ts` once the pipeline is registered. `serve` is the systemd-unit / docker-container case — one long-running process per project hosting every triggered pipeline.
21
+
22
+ ### `run --input`
23
+
24
+ Three forms for supplying input that overrides the pipeline's `defaultInput`:
25
+
26
+ ```sh
27
+ thread-phase run digest --input '{"date":"2026-05-20"}' # inline JSON
28
+ thread-phase run digest --input @./payload.json # read JSON from file
29
+ echo '{"date":"2026-05-20"}' | thread-phase run digest --input - # read from stdin
30
+ ```
31
+
32
+ Invalid JSON or unreadable files exit 1 with a clear stderr message.
33
+
34
+ ### `serve --health-port`
35
+
36
+ Opt-in health endpoint backed by `node:http`. While the serve loop is running it returns `200 {"status":"ok"}`. Once a shutdown signal arrives but pipelines are still draining it returns `503 {"status":"shutting_down"}`. The server stops listening when serve fully exits. Useful for k8s liveness/readiness probes or load-balancer drain checks.
37
+
38
+ ## Extension layout
39
+
40
+ ```
41
+ your-project/
42
+ .thread-phase/
43
+ triggers/<name>.ts a Trigger registered via api.registerTrigger
44
+ adapters/<name>.ts an AgentAdapter registered via api.registerAdapter
45
+ pipelines/<name>.ts a Pipeline registered via api.registerPipeline
46
+ ```
47
+
48
+ Each file's default export is `(api: ThreadPhaseAPI) => void`. See [`EXTENDING.md`](../../EXTENDING.md) for the full contract, three-tier discovery (loose file → folder → package.json manifest), and copy-paste templates.
49
+
50
+ ## Programmatic API
51
+
52
+ ```ts
53
+ import { Registry, loadExtensions, runCli } from '@autonome-research/thread-phase-cli';
54
+
55
+ const registry = new Registry();
56
+ await loadExtensions(registry, { cwd: process.cwd() });
57
+
58
+ const pipelines = registry.listPipelines();
59
+ // or invoke the full CLI dispatch:
60
+ const code = await runCli({ args: ['run', 'morning-digest'] });
61
+ ```
62
+
63
+ Useful for embedding the loader inside a larger runtime (a job queue worker, a Temporal activity, a custom server).
64
+
65
+ ## Stability
66
+
67
+ Versions are locked across the thread-phase monorepo. CLI 2.x.x ships against thread-phase 2.x.x.
package/dist/bin.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * thread-phase bin entry.
4
+ *
5
+ * Tiny shim: parse argv, delegate to runCli, exit with its code.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;;GAIG"}
package/dist/bin.js ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * thread-phase bin entry.
4
+ *
5
+ * Tiny shim: parse argv, delegate to runCli, exit with its code.
6
+ */
7
+ import { runCli } from './cli.js';
8
+ const code = await runCli({ args: process.argv.slice(2) });
9
+ process.exit(code);
10
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC3D,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * CLI subcommand dispatcher.
3
+ *
4
+ * Three subcommands:
5
+ * - `run <name>` execute a registered pipeline once, exit
6
+ * - `serve` start all triggered pipelines, run continuously
7
+ * - `list` print everything in the registry, grouped by kind
8
+ *
9
+ * All commands first call `loadExtensions(...)` against `${cwd}/.thread-phase/`,
10
+ * then dispatch against the populated registry.
11
+ */
12
+ export interface RunCliOptions {
13
+ /** Project root. Default: process.cwd(). */
14
+ cwd?: string;
15
+ /** argv excluding `node` and bin script path. */
16
+ args: string[];
17
+ /** Output stream for human-facing logs. Default: process.stdout. */
18
+ stdout?: NodeJS.WritableStream;
19
+ /** Error stream. Default: process.stderr. */
20
+ stderr?: NodeJS.WritableStream;
21
+ /**
22
+ * Input stream used when `run --input -` reads JSON from stdin. Optional;
23
+ * defaults to `process.stdin`. Exposed for testability.
24
+ */
25
+ stdin?: NodeJS.ReadableStream;
26
+ /**
27
+ * Optional AbortSignal that, when aborted, initiates the same shutdown
28
+ * path as SIGINT/SIGTERM for `serve`. Exposed for testability.
29
+ */
30
+ abortSignal?: AbortSignal;
31
+ }
32
+ export declare function runCli(options: RunCliOptions): Promise<number>;
33
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAoBH,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAqCpE"}
package/dist/cli.js ADDED
@@ -0,0 +1,336 @@
1
+ /**
2
+ * CLI subcommand dispatcher.
3
+ *
4
+ * Three subcommands:
5
+ * - `run <name>` execute a registered pipeline once, exit
6
+ * - `serve` start all triggered pipelines, run continuously
7
+ * - `list` print everything in the registry, grouped by kind
8
+ *
9
+ * All commands first call `loadExtensions(...)` against `${cwd}/.thread-phase/`,
10
+ * then dispatch against the populated registry.
11
+ */
12
+ import { PipelineCache, runPipeline } from '@autonome-research/thread-phase';
13
+ import { runTrigger } from '@autonome-research/thread-phase/triggers';
14
+ import { readFileSync } from 'node:fs';
15
+ import { createServer } from 'node:http';
16
+ import { Registry } from './registry.js';
17
+ import { loadExtensions } from './loader.js';
18
+ export async function runCli(options) {
19
+ const cwd = options.cwd ?? process.cwd();
20
+ const stdout = options.stdout ?? process.stdout;
21
+ const stderr = options.stderr ?? process.stderr;
22
+ const stdin = options.stdin ?? process.stdin;
23
+ const args = options.args;
24
+ if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
25
+ printHelp(stdout);
26
+ return 0;
27
+ }
28
+ const subcommand = args[0];
29
+ const rest = args.slice(1);
30
+ const registry = new Registry();
31
+ await loadExtensions(registry, {
32
+ cwd,
33
+ log: (msg) => stderr.write(`${msg}\n`),
34
+ });
35
+ switch (subcommand) {
36
+ case 'run':
37
+ return cmdRun(registry, rest, { stdout, stderr, stdin });
38
+ case 'serve':
39
+ return cmdServe(registry, rest, {
40
+ stdout,
41
+ stderr,
42
+ abortSignal: options.abortSignal,
43
+ });
44
+ case 'list':
45
+ return cmdList(registry, rest, { stdout });
46
+ default:
47
+ stderr.write(`unknown subcommand: ${subcommand}\n`);
48
+ printHelp(stderr);
49
+ return 1;
50
+ }
51
+ }
52
+ function printHelp(out) {
53
+ out.write(`thread-phase — automation workflow runner
54
+
55
+ Usage:
56
+ thread-phase run <pipeline-name>
57
+ thread-phase serve
58
+ thread-phase list
59
+
60
+ Discovers extensions from ./.thread-phase/{triggers,adapters,pipelines}/.
61
+
62
+ Commands:
63
+ run Execute a registered pipeline once and exit.
64
+ serve Start all triggered pipelines and run continuously (SIGINT/SIGTERM to stop).
65
+ list Print the registry: triggers, adapters, pipelines.
66
+ `);
67
+ }
68
+ async function cmdRun(registry, args, io) {
69
+ // Find the first positional (pipeline name), and an optional --input value.
70
+ let name;
71
+ let inputArg;
72
+ for (let i = 0; i < args.length; i++) {
73
+ const a = args[i];
74
+ if (a === undefined)
75
+ continue;
76
+ if (a === '--input') {
77
+ inputArg = args[++i];
78
+ continue;
79
+ }
80
+ if (a.startsWith('--input=')) {
81
+ inputArg = a.slice('--input='.length);
82
+ continue;
83
+ }
84
+ if (name === undefined)
85
+ name = a;
86
+ }
87
+ if (!name) {
88
+ io.stderr.write('usage: thread-phase run <pipeline-name> [--input <json|@file|->]\n');
89
+ return 1;
90
+ }
91
+ const spec = registry.getPipeline(name);
92
+ if (!spec) {
93
+ io.stderr.write(`no pipeline registered with name "${name}"\n`);
94
+ const available = registry.listPipelines().map((p) => p.name);
95
+ if (available.length > 0) {
96
+ io.stderr.write(`available: ${available.join(', ')}\n`);
97
+ }
98
+ return 1;
99
+ }
100
+ let input = spec.defaultInput;
101
+ if (inputArg !== undefined) {
102
+ try {
103
+ input = await resolveInput(inputArg, io.stdin);
104
+ }
105
+ catch (err) {
106
+ io.stderr.write(`invalid --input: ${err.message}\n`);
107
+ return 1;
108
+ }
109
+ }
110
+ const event = {
111
+ id: 1,
112
+ occurredAt: new Date().toISOString(),
113
+ input,
114
+ };
115
+ const { phases, ctx } = materializePipeline(spec, input, event);
116
+ io.stdout.write(`[run] ${name}\n`);
117
+ let hadError = false;
118
+ for await (const ev of runPipeline(phases, ctx)) {
119
+ io.stdout.write(`${JSON.stringify(ev)}\n`);
120
+ if (ev.type === 'error')
121
+ hadError = true;
122
+ }
123
+ return hadError ? 1 : 0;
124
+ }
125
+ /**
126
+ * Resolve a `--input` flag value into a parsed JSON value.
127
+ *
128
+ * - `-` → read all of stdin, parse as JSON
129
+ * - `@path` → read file at path, parse as JSON
130
+ * - otherwise → parse the literal arg as JSON
131
+ *
132
+ * Throws `Error` with a human-readable message on parse / IO failure.
133
+ */
134
+ async function resolveInput(arg, stdin) {
135
+ let raw;
136
+ if (arg === '-') {
137
+ raw = await readAll(stdin);
138
+ }
139
+ else if (arg.startsWith('@')) {
140
+ const path = arg.slice(1);
141
+ try {
142
+ raw = readFileSync(path, 'utf8');
143
+ }
144
+ catch (err) {
145
+ throw new Error(`could not read file ${path}: ${err.message}`);
146
+ }
147
+ }
148
+ else {
149
+ raw = arg;
150
+ }
151
+ try {
152
+ return JSON.parse(raw);
153
+ }
154
+ catch (err) {
155
+ throw new Error(`not valid JSON (${err.message})`);
156
+ }
157
+ }
158
+ async function readAll(stream) {
159
+ const chunks = [];
160
+ for await (const chunk of stream) {
161
+ chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
162
+ }
163
+ return Buffer.concat(chunks).toString('utf8');
164
+ }
165
+ async function cmdServe(registry, args, io) {
166
+ // Parse flags: --health-port <n> | --health-port=<n>
167
+ let healthPort;
168
+ for (let i = 0; i < args.length; i++) {
169
+ const a = args[i];
170
+ if (a === undefined)
171
+ continue;
172
+ if (a === '--health-port') {
173
+ const v = args[++i];
174
+ const n = Number(v);
175
+ if (!Number.isFinite(n) || n <= 0) {
176
+ io.stderr.write(`invalid --health-port: ${v}\n`);
177
+ return 1;
178
+ }
179
+ healthPort = n;
180
+ continue;
181
+ }
182
+ if (a.startsWith('--health-port=')) {
183
+ const v = a.slice('--health-port='.length);
184
+ const n = Number(v);
185
+ if (!Number.isFinite(n) || n <= 0) {
186
+ io.stderr.write(`invalid --health-port: ${v}\n`);
187
+ return 1;
188
+ }
189
+ healthPort = n;
190
+ continue;
191
+ }
192
+ }
193
+ const pipelines = registry
194
+ .listPipelines()
195
+ .filter((p) => p.trigger !== undefined);
196
+ if (pipelines.length === 0) {
197
+ io.stderr.write('no triggered pipelines registered — nothing for `serve` to do\n');
198
+ return 1;
199
+ }
200
+ const handles = [];
201
+ for (const meta of pipelines) {
202
+ const spec = registry.getPipeline(meta.name);
203
+ const trigger = registry.getTrigger(spec.trigger);
204
+ if (!trigger) {
205
+ io.stderr.write(`pipeline "${meta.name}" references trigger "${spec.trigger}" which is not registered — skipping\n`);
206
+ continue;
207
+ }
208
+ io.stdout.write(`[serve] ${meta.name} ← ${spec.trigger}\n`);
209
+ const handle = runTrigger(trigger, (input, event) => materializePipeline(spec, input, event), {
210
+ pipelineName: meta.name,
211
+ onStart: (event) => io.stdout.write(`[start] ${meta.name} event=${event.id} at=${event.occurredAt}\n`),
212
+ onComplete: (event) => io.stdout.write(`[done] ${meta.name} event=${event.id}\n`),
213
+ onError: (event, err) => io.stderr.write(`[err] ${meta.name} event=${event.id}: ${err.message}\n`),
214
+ });
215
+ handles.push({ name: meta.name, stop: handle.stop, done: handle.done });
216
+ }
217
+ if (handles.length === 0) {
218
+ return 1;
219
+ }
220
+ // Optional health-check HTTP server. Returns 200/`ok` while running,
221
+ // 503/`shutting_down` once stop() has begun.
222
+ let healthServer;
223
+ let serving = true;
224
+ if (healthPort !== undefined) {
225
+ healthServer = createServer((_req, res) => {
226
+ if (serving) {
227
+ res.statusCode = 200;
228
+ res.setHeader('content-type', 'application/json');
229
+ res.end(JSON.stringify({ status: 'ok' }));
230
+ }
231
+ else {
232
+ res.statusCode = 503;
233
+ res.setHeader('content-type', 'application/json');
234
+ res.end(JSON.stringify({ status: 'shutting_down' }));
235
+ }
236
+ });
237
+ await new Promise((resolve, reject) => {
238
+ healthServer.once('error', reject);
239
+ healthServer.listen(healthPort, '127.0.0.1', () => resolve());
240
+ });
241
+ io.stdout.write(`[serve] health endpoint http://127.0.0.1:${healthPort}/\n`);
242
+ }
243
+ let shuttingDown = false;
244
+ const shutdown = async (signal) => {
245
+ if (shuttingDown)
246
+ return;
247
+ shuttingDown = true;
248
+ serving = false;
249
+ io.stdout.write(`\n[serve] ${signal} received, shutting down…\n`);
250
+ await Promise.all(handles.map((h) => h.stop()));
251
+ };
252
+ const onSigint = () => void shutdown('SIGINT');
253
+ const onSigterm = () => void shutdown('SIGTERM');
254
+ process.on('SIGINT', onSigint);
255
+ process.on('SIGTERM', onSigterm);
256
+ const onAbort = () => void shutdown('abort');
257
+ io.abortSignal?.addEventListener('abort', onAbort);
258
+ try {
259
+ await Promise.all(handles.map((h) => h.done));
260
+ }
261
+ finally {
262
+ process.off('SIGINT', onSigint);
263
+ process.off('SIGTERM', onSigterm);
264
+ io.abortSignal?.removeEventListener('abort', onAbort);
265
+ if (healthServer) {
266
+ await new Promise((resolve) => healthServer.close(() => resolve()));
267
+ }
268
+ }
269
+ io.stdout.write('[serve] all pipelines exited\n');
270
+ return 0;
271
+ }
272
+ function cmdList(registry, args, io) {
273
+ const verbose = args.includes('--verbose') || args.includes('-v');
274
+ const triggers = registry.listTriggers();
275
+ const adapters = registry.listAdapters();
276
+ const pipelines = registry.listPipelines();
277
+ io.stdout.write(`triggers (${triggers.length}):\n`);
278
+ for (const t of triggers) {
279
+ io.stdout.write(` ${t.name} (${t.source})\n`);
280
+ if (verbose) {
281
+ const inst = registry.getTrigger(t.name);
282
+ const className = inst ? inst.constructor.name : 'unknown';
283
+ io.stdout.write(` source: ${t.source}\n`);
284
+ io.stdout.write(` class: ${className}\n`);
285
+ }
286
+ }
287
+ io.stdout.write(`\nadapters (${adapters.length}):\n`);
288
+ for (const a of adapters) {
289
+ io.stdout.write(` ${a.name} id=${a.id} (${a.source})\n`);
290
+ if (verbose) {
291
+ const inst = registry.getAdapter(a.name);
292
+ const caps = inst?.capabilities
293
+ ? JSON.stringify(inst.capabilities)
294
+ : '<none>';
295
+ io.stdout.write(` id: ${a.id}\n`);
296
+ io.stdout.write(` source: ${a.source}\n`);
297
+ io.stdout.write(` capabilities: ${caps}\n`);
298
+ }
299
+ }
300
+ io.stdout.write(`\npipelines (${pipelines.length}):\n`);
301
+ for (const p of pipelines) {
302
+ const trigger = p.trigger ? ` trigger=${p.trigger}` : ' one-shot';
303
+ const desc = p.description ? ` — ${p.description}` : '';
304
+ io.stdout.write(` ${p.name}${trigger}${desc} (${p.source})\n`);
305
+ if (verbose) {
306
+ const spec = registry.getPipeline(p.name);
307
+ io.stdout.write(` source: ${p.source}\n`);
308
+ io.stdout.write(` description: ${p.description ?? '<none>'}\n`);
309
+ io.stdout.write(` trigger: ${p.trigger ?? '<one-shot>'}\n`);
310
+ const phasesKind = spec && typeof spec.phases === 'function' ? 'factory' : 'array';
311
+ const ctxKind = spec && typeof spec.ctx === 'function' ? 'factory' : 'literal';
312
+ io.stdout.write(` phases: ${phasesKind}\n`);
313
+ io.stdout.write(` ctx: ${ctxKind}\n`);
314
+ const di = spec && 'defaultInput' in spec && spec.defaultInput !== undefined
315
+ ? JSON.stringify(spec.defaultInput)
316
+ : '<none>';
317
+ io.stdout.write(` defaultInput: ${di}\n`);
318
+ }
319
+ }
320
+ return 0;
321
+ }
322
+ // ---------------------------------------------------------------------------
323
+ function materializePipeline(spec, input, event) {
324
+ const phases = typeof spec.phases === 'function'
325
+ ? spec.phases(input, event)
326
+ : spec.phases;
327
+ const ctx = typeof spec.ctx === 'function'
328
+ ? spec.ctx(input, event)
329
+ : spec.ctx;
330
+ // Ensure ctx has a fresh cache if the user didn't supply one.
331
+ if (!ctx.cache) {
332
+ ctx.cache = new PipelineCache();
333
+ }
334
+ return { phases, ctx };
335
+ }
336
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAK7E,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAMtE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AAEtD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAwB7C,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAsB;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAChD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC;IAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAE1B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAClE,SAAS,CAAC,MAAM,CAAC,CAAC;QAClB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAE3B,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;IAChC,MAAM,cAAc,CAAC,QAAQ,EAAE;QAC7B,GAAG;QACH,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC;KACvC,CAAC,CAAC;IAEH,QAAQ,UAAU,EAAE,CAAC;QACnB,KAAK,KAAK;YACR,OAAO,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3D,KAAK,OAAO;YACV,OAAO,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE;gBAC9B,MAAM;gBACN,MAAM;gBACN,WAAW,EAAE,OAAO,CAAC,WAAW;aACjC,CAAC,CAAC;QACL,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7C;YACE,MAAM,CAAC,KAAK,CAAC,uBAAuB,UAAU,IAAI,CAAC,CAAC;YACpD,SAAS,CAAC,MAAM,CAAC,CAAC;YAClB,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,GAA0B;IAC3C,GAAG,CAAC,KAAK,CAAC;;;;;;;;;;;;;CAaX,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,MAAM,CACnB,QAAkB,EAClB,IAAc,EACd,EAIC;IAED,4EAA4E;IAC5E,IAAI,IAAwB,CAAC;IAC7B,IAAI,QAA4B,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,KAAK,SAAS;YAAE,SAAS;QAC9B,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACpB,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACrB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7B,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YACtC,SAAS;QACX,CAAC;QACD,IAAI,IAAI,KAAK,SAAS;YAAE,IAAI,GAAG,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,oEAAoE,CAAC,CAAC;QACtF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,IAAI,KAAK,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC9D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,KAAK,GAAY,IAAI,CAAC,YAAY,CAAC;IACvC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,EAAE,CAAC,MAAM,CAAC,KAAK,CACb,oBAAqB,GAAa,CAAC,OAAO,IAAI,CAC/C,CAAC;YACF,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAA0B;QACnC,EAAE,EAAE,CAAC;QACL,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,KAAK;KACN,CAAC;IACF,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAEhE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC;IACnC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,KAAK,EAAE,MAAM,EAAE,IAAI,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;QAChD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO;YAAE,QAAQ,GAAG,IAAI,CAAC;IAC3C,CAAC;IACD,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,YAAY,CACzB,GAAW,EACX,KAA4B;IAE5B,IAAI,GAAW,CAAC;IAChB,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;QAChB,GAAG,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;SAAM,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,CAAC;YACH,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;SAAM,CAAC;QACN,GAAG,GAAG,GAAG,CAAC;IACZ,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,mBAAoB,GAAa,CAAC,OAAO,GAAG,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,MAA6B;IAClD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC;AAED,KAAK,UAAU,QAAQ,CACrB,QAAkB,EAClB,IAAc,EACd,EAIC;IAED,qDAAqD;IACrD,IAAI,UAA8B,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,KAAK,SAAS;YAAE,SAAS;QAC9B,IAAI,CAAC,KAAK,eAAe,EAAE,CAAC;YAC1B,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACpB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC;gBACjD,OAAO,CAAC,CAAC;YACX,CAAC;YACD,UAAU,GAAG,CAAC,CAAC;YACf,SAAS;QACX,CAAC;QACD,IAAI,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YAC3C,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC;gBACjD,OAAO,CAAC,CAAC;YACX,CAAC;YACD,UAAU,GAAG,CAAC,CAAC;YACf,SAAS;QACX,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,QAAQ;SACvB,aAAa,EAAE;SACf,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC;IAE1C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,EAAE,CAAC,MAAM,CAAC,KAAK,CACb,iEAAiE,CAClE,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,OAAO,GAA4E,EAAE,CAAC;IAC5F,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,OAAQ,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,EAAE,CAAC,MAAM,CAAC,KAAK,CACb,aAAa,IAAI,CAAC,IAAI,yBAAyB,IAAI,CAAC,OAAO,wCAAwC,CACpG,CAAC;YACF,SAAS;QACX,CAAC;QAED,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;QAE5D,MAAM,MAAM,GAAG,UAAU,CACvB,OAA2B,EAC3B,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,EACzD;YACE,YAAY,EAAE,IAAI,CAAC,IAAI;YACvB,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,EAAE,CAAC,MAAM,CAAC,KAAK,CACb,WAAW,IAAI,CAAC,IAAI,UAAU,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC,UAAU,IAAI,CAClE;YACH,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CACpB,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,IAAI,UAAU,KAAK,CAAC,EAAE,IAAI,CAAC;YAC7D,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CACtB,EAAE,CAAC,MAAM,CAAC,KAAK,CACb,WAAW,IAAI,CAAC,IAAI,UAAU,KAAK,CAAC,EAAE,KAAK,GAAG,CAAC,OAAO,IAAI,CAC3D;SACJ,CACF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,qEAAqE;IACrE,6CAA6C;IAC7C,IAAI,YAAgC,CAAC;IACrC,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,YAAY,GAAG,YAAY,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YACxC,IAAI,OAAO,EAAE,CAAC;gBACZ,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;gBACrB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;gBAClD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;gBACrB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;gBAClD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;YACvD,CAAC;QACH,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,YAAa,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACpC,YAAa,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,4CAA4C,UAAU,KAAK,CAAC,CAAC;IAC/E,CAAC;IAED,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAiB,EAAE;QACvD,IAAI,YAAY;YAAE,OAAO;QACzB,YAAY,GAAG,IAAI,CAAC;QACpB,OAAO,GAAG,KAAK,CAAC;QAChB,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,MAAM,6BAA6B,CAAC,CAAC;QAClE,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7C,EAAE,CAAC,WAAW,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAEnD,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAClC,EAAE,CAAC,WAAW,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACtD,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,YAAa,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;IACD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAClD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,OAAO,CACd,QAAkB,EAClB,IAAc,EACd,EAAqC;IAErC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC;IACzC,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,EAAE,CAAC;IAE3C,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,QAAQ,CAAC,MAAM,MAAM,CAAC,CAAC;IACpD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;QAChD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAC3D,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,SAAS,IAAI,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IACD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,QAAQ,CAAC,MAAM,MAAM,CAAC,CAAC;IACtD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;QAC5D,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,IAAI,EAAE,YAAY;gBAC7B,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC;gBACnC,CAAC,CAAC,QAAQ,CAAC;YACb,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YAC/C,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;YACnD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,IAAI,IAAI,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IACD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,SAAS,CAAC,MAAM,MAAM,CAAC,CAAC;IACxD,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;QACpE,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,OAAO,GAAG,IAAI,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;QACjE,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC1C,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;YACnD,EAAE,CAAC,MAAM,CAAC,KAAK,CACb,qBAAqB,CAAC,CAAC,WAAW,IAAI,QAAQ,IAAI,CACnD,CAAC;YACF,EAAE,CAAC,MAAM,CAAC,KAAK,CACb,qBAAqB,CAAC,CAAC,OAAO,IAAI,YAAY,IAAI,CACnD,CAAC;YACF,MAAM,UAAU,GACd,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;YAClE,MAAM,OAAO,GACX,IAAI,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;YACjE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,UAAU,IAAI,CAAC,CAAC;YACrD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,OAAO,IAAI,CAAC,CAAC;YAClD,MAAM,EAAE,GACN,IAAI,IAAI,cAAc,IAAI,IAAI,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;gBAC/D,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC;gBACnC,CAAC,CAAC,QAAQ,CAAC;YACf,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,OAAO,CAAC,CAAC;AACX,CAAC;AAED,8EAA8E;AAE9E,SAAS,mBAAmB,CAC1B,IAAgC,EAChC,KAAa,EACb,KAA2B;IAE3B,MAAM,MAAM,GACV,OAAO,IAAI,CAAC,MAAM,KAAK,UAAU;QAC/B,CAAC,CAAE,IAAI,CAAC,MAA6E,CACjF,KAAK,EACL,KAAK,CACN;QACH,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;IAElB,MAAM,GAAG,GACP,OAAO,IAAI,CAAC,GAAG,KAAK,UAAU;QAC5B,CAAC,CAAE,IAAI,CAAC,GAAoD,CAAC,KAAK,EAAE,KAAK,CAAC;QAC1E,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IAEf,8DAA8D;IAC9D,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACd,GAAgC,CAAC,KAAK,GAAG,IAAI,aAAa,EAAE,CAAC;IAChE,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACzB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Public API for @autonome-research/thread-phase-cli.
3
+ *
4
+ * Most users only need the `thread-phase` bin and the `ThreadPhaseAPI`
5
+ * type for their extension files. Programmatic embedding of the loader
6
+ * + registry is also supported.
7
+ */
8
+ export type { ThreadPhaseAPI, PipelineSpec, ExtensionRegisterFn, } from './types.js';
9
+ export { Registry } from './registry.js';
10
+ export { loadExtensions, EXTENSION_KINDS, type LoadOptions, type LoadResult, type ExtensionKind, } from './loader.js';
11
+ export { runCli, type RunCliOptions } from './cli.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EACV,cAAc,EACd,YAAY,EACZ,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,cAAc,EACd,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,aAAa,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Public API for @autonome-research/thread-phase-cli.
3
+ *
4
+ * Most users only need the `thread-phase` bin and the `ThreadPhaseAPI`
5
+ * type for their extension files. Programmatic embedding of the loader
6
+ * + registry is also supported.
7
+ */
8
+ export { Registry } from './registry.js';
9
+ export { loadExtensions, EXTENSION_KINDS, } from './loader.js';
10
+ export { runCli } from './cli.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,cAAc,EACd,eAAe,GAIhB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,MAAM,EAAsB,MAAM,UAAU,CAAC"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Extension loader — scans `.thread-phase/` and registers what it finds.
3
+ *
4
+ * Three discovery tiers, in order of complexity:
5
+ *
6
+ * 1. Loose `.ts` / `.js` file
7
+ * .thread-phase/triggers/cron-15m.ts
8
+ * The default export is `(api) => void`.
9
+ *
10
+ * 2. Folder with `index.ts` / `index.js`
11
+ * .thread-phase/triggers/my-webhook/index.ts
12
+ * Same contract; useful when the extension needs sibling files.
13
+ *
14
+ * 3. Folder with `package.json` carrying a `thread-phase.extensions` field
15
+ * .thread-phase/triggers/with-deps/package.json
16
+ * ```json
17
+ * { "name": "with-deps", "thread-phase": { "extensions": ["./index.ts"] } }
18
+ * ```
19
+ * Use this when the extension needs its own npm deps installed via
20
+ * an npm workspace inside `.thread-phase/`.
21
+ *
22
+ * Per-extension errors don't fail the whole load. The loader logs the
23
+ * failing file's path and continues. Use `--strict` (later) to opt in
24
+ * to fail-fast.
25
+ *
26
+ * TypeScript files are loaded via `tsx`'s programmatic API, so the CLI
27
+ * itself runs as compiled JS but user extensions stay in `.ts`.
28
+ */
29
+ import type { Registry } from './registry.js';
30
+ /** Kinds of extensions the loader discovers. Order matters: triggers and adapters before pipelines, so pipeline bindings can resolve. */
31
+ export declare const EXTENSION_KINDS: readonly ["triggers", "adapters", "pipelines"];
32
+ export type ExtensionKind = (typeof EXTENSION_KINDS)[number];
33
+ export interface LoadOptions {
34
+ /** Project root containing `.thread-phase/`. Default: `process.cwd()`. */
35
+ cwd?: string;
36
+ /** Stop on first error. Default: false (per-file isolation). */
37
+ strict?: boolean;
38
+ /** Log function. Default: console.error (stderr). */
39
+ log?: (message: string) => void;
40
+ }
41
+ export interface LoadResult {
42
+ /** Paths loaded successfully. */
43
+ loaded: string[];
44
+ /** Errors keyed by path. */
45
+ errors: Array<{
46
+ path: string;
47
+ error: Error;
48
+ }>;
49
+ }
50
+ export declare function loadExtensions(registry: Registry, options?: LoadOptions): Promise<LoadResult>;
51
+ export declare function discoverExtensionPaths(kindDir: string): string[];
52
+ /**
53
+ * Normalize the namespace object returned by a dynamic `import()`.
54
+ *
55
+ * Native ESM dynamic imports produce `{ default: <user-default> }`. When tsx
56
+ * transpiles to CJS (because the nearest package.json has no `"type":
57
+ * "module"`), Node wraps the CJS `module.exports` under `default`, so the
58
+ * user's `export default fn` ends up at `mod.default.default`. This helper
59
+ * unwraps that inner default so callers always see a single canonical
60
+ * `{ default?: T }` shape.
61
+ *
62
+ * Split from `loadModule` so the normalization can be unit-tested without
63
+ * depending on Node's module-resolver semantics (which the test runner can
64
+ * intercept).
65
+ */
66
+ export declare function normalizeModuleShape<T>(mod: {
67
+ default?: T | {
68
+ default?: T;
69
+ };
70
+ }): {
71
+ default?: T;
72
+ };
73
+ /**
74
+ * Import a module by URL and normalize its shape via `normalizeModuleShape`.
75
+ * Callers always see `{ default?: T }` regardless of whether the source was
76
+ * loaded as native ESM or CJS-transpiled.
77
+ */
78
+ export declare function loadModule<T>(url: string): Promise<{
79
+ default?: T;
80
+ }>;
81
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAgB9C,yIAAyI;AACzI,eAAO,MAAM,eAAe,gDAAiD,CAAC;AAC9E,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,0EAA0E;IAC1E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qDAAqD;IACrD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,UAAU;IACzB,iCAAiC;IACjC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,4BAA4B;IAC5B,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;CAC/C;AAID,wBAAsB,cAAc,CAClC,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,CA8BrB;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CA8ChE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,GAAG,EAAE;IAC3C,OAAO,CAAC,EAAE,CAAC,GAAG;QAAE,OAAO,CAAC,EAAE,CAAC,CAAA;KAAE,CAAC;CAC/B,GAAG;IAAE,OAAO,CAAC,EAAE,CAAC,CAAA;CAAE,CAOlB;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC,CAQzE"}
package/dist/loader.js ADDED
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Extension loader — scans `.thread-phase/` and registers what it finds.
3
+ *
4
+ * Three discovery tiers, in order of complexity:
5
+ *
6
+ * 1. Loose `.ts` / `.js` file
7
+ * .thread-phase/triggers/cron-15m.ts
8
+ * The default export is `(api) => void`.
9
+ *
10
+ * 2. Folder with `index.ts` / `index.js`
11
+ * .thread-phase/triggers/my-webhook/index.ts
12
+ * Same contract; useful when the extension needs sibling files.
13
+ *
14
+ * 3. Folder with `package.json` carrying a `thread-phase.extensions` field
15
+ * .thread-phase/triggers/with-deps/package.json
16
+ * ```json
17
+ * { "name": "with-deps", "thread-phase": { "extensions": ["./index.ts"] } }
18
+ * ```
19
+ * Use this when the extension needs its own npm deps installed via
20
+ * an npm workspace inside `.thread-phase/`.
21
+ *
22
+ * Per-extension errors don't fail the whole load. The loader logs the
23
+ * failing file's path and continues. Use `--strict` (later) to opt in
24
+ * to fail-fast.
25
+ *
26
+ * TypeScript files are loaded via `tsx`'s programmatic API, so the CLI
27
+ * itself runs as compiled JS but user extensions stay in `.ts`.
28
+ */
29
+ import { existsSync, readdirSync, statSync, readFileSync } from 'node:fs';
30
+ import { join, resolve } from 'node:path';
31
+ import { pathToFileURL } from 'node:url';
32
+ import { register } from 'tsx/esm/api';
33
+ /**
34
+ * Lazily install the tsx ESM hook once per process. Subsequent imports of
35
+ * `.ts` files go through plain `import()` without per-file namespacing,
36
+ * which lets transitive imports (e.g. `@autonome-research/thread-phase`)
37
+ * resolve normally.
38
+ */
39
+ let tsxHookInstalled = false;
40
+ function ensureTsxHook() {
41
+ if (tsxHookInstalled)
42
+ return;
43
+ register();
44
+ tsxHookInstalled = true;
45
+ }
46
+ /** Kinds of extensions the loader discovers. Order matters: triggers and adapters before pipelines, so pipeline bindings can resolve. */
47
+ export const EXTENSION_KINDS = ['triggers', 'adapters', 'pipelines'];
48
+ const PKG_FIELD = 'thread-phase';
49
+ export async function loadExtensions(registry, options = {}) {
50
+ const cwd = options.cwd ?? process.cwd();
51
+ const log = options.log ?? ((m) => console.error(m));
52
+ const root = join(cwd, '.thread-phase');
53
+ const result = { loaded: [], errors: [] };
54
+ if (!existsSync(root)) {
55
+ return result; // no extensions; nothing to load (not an error)
56
+ }
57
+ for (const kind of EXTENSION_KINDS) {
58
+ const kindDir = join(root, kind);
59
+ if (!existsSync(kindDir))
60
+ continue;
61
+ const paths = discoverExtensionPaths(kindDir);
62
+ for (const path of paths) {
63
+ try {
64
+ await loadOne(path, registry);
65
+ result.loaded.push(path);
66
+ }
67
+ catch (err) {
68
+ const error = err instanceof Error ? err : new Error(String(err));
69
+ result.errors.push({ path, error });
70
+ if (options.strict)
71
+ throw error;
72
+ log(`[thread-phase] failed to load ${path}: ${error.message}`);
73
+ }
74
+ }
75
+ }
76
+ return result;
77
+ }
78
+ export function discoverExtensionPaths(kindDir) {
79
+ const entries = readdirSync(kindDir).sort();
80
+ const paths = [];
81
+ for (const entry of entries) {
82
+ const full = join(kindDir, entry);
83
+ const st = statSync(full);
84
+ // Tier 1: loose .ts / .js
85
+ if (st.isFile() && (entry.endsWith('.ts') || entry.endsWith('.js'))) {
86
+ paths.push(full);
87
+ continue;
88
+ }
89
+ if (!st.isDirectory())
90
+ continue;
91
+ // Tier 3: package.json with `thread-phase.extensions`
92
+ const pkgPath = join(full, 'package.json');
93
+ if (existsSync(pkgPath)) {
94
+ try {
95
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
96
+ const declared = pkg[PKG_FIELD]?.extensions;
97
+ if (Array.isArray(declared)) {
98
+ for (const rel of declared) {
99
+ paths.push(resolve(full, rel));
100
+ }
101
+ continue;
102
+ }
103
+ }
104
+ catch {
105
+ // Fall through to tier 2 if package.json is malformed.
106
+ }
107
+ }
108
+ // Tier 2: folder with index.ts / index.js
109
+ const indexTs = join(full, 'index.ts');
110
+ const indexJs = join(full, 'index.js');
111
+ if (existsSync(indexTs)) {
112
+ paths.push(indexTs);
113
+ }
114
+ else if (existsSync(indexJs)) {
115
+ paths.push(indexJs);
116
+ }
117
+ }
118
+ return paths;
119
+ }
120
+ /**
121
+ * Normalize the namespace object returned by a dynamic `import()`.
122
+ *
123
+ * Native ESM dynamic imports produce `{ default: <user-default> }`. When tsx
124
+ * transpiles to CJS (because the nearest package.json has no `"type":
125
+ * "module"`), Node wraps the CJS `module.exports` under `default`, so the
126
+ * user's `export default fn` ends up at `mod.default.default`. This helper
127
+ * unwraps that inner default so callers always see a single canonical
128
+ * `{ default?: T }` shape.
129
+ *
130
+ * Split from `loadModule` so the normalization can be unit-tested without
131
+ * depending on Node's module-resolver semantics (which the test runner can
132
+ * intercept).
133
+ */
134
+ export function normalizeModuleShape(mod) {
135
+ const top = mod.default;
136
+ if (top !== null && typeof top === 'object' && 'default' in top) {
137
+ // CJS-transpiled shape: unwrap the inner default.
138
+ return { default: top.default };
139
+ }
140
+ return { default: top };
141
+ }
142
+ /**
143
+ * Import a module by URL and normalize its shape via `normalizeModuleShape`.
144
+ * Callers always see `{ default?: T }` regardless of whether the source was
145
+ * loaded as native ESM or CJS-transpiled.
146
+ */
147
+ export async function loadModule(url) {
148
+ if (url.endsWith('.ts'))
149
+ ensureTsxHook();
150
+ const mod = (await import(url));
151
+ return normalizeModuleShape(mod);
152
+ }
153
+ async function loadOne(path, registry) {
154
+ const url = pathToFileURL(path).href;
155
+ const mod = await loadModule(url);
156
+ const registerFn = mod.default;
157
+ if (typeof registerFn !== 'function') {
158
+ throw new Error(`extension at ${path} has no default export of shape (api) => void`);
159
+ }
160
+ registry.currentSource = path;
161
+ try {
162
+ await registerFn(registry);
163
+ }
164
+ finally {
165
+ registry.currentSource = '<unknown>';
166
+ }
167
+ }
168
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Concrete registry implementing `ThreadPhaseAPI`.
3
+ *
4
+ * Backed by plain Maps keyed by name. Holds no per-kind type — registered
5
+ * adapters/triggers/pipelines come back as `unknown`-typed values, and
6
+ * the CLI/loader narrows when invoking them. This keeps the registry
7
+ * simple at the cost of some casts at use sites.
8
+ *
9
+ * Name collisions throw with the location of the prior registration so
10
+ * the user can spot the duplicate quickly.
11
+ */
12
+ import type { AgentAdapterMeta, AgentRunResult } from '@autonome-research/thread-phase/agents';
13
+ import type { BasePipelineContext } from '@autonome-research/thread-phase';
14
+ import type { Trigger } from '@autonome-research/thread-phase/triggers';
15
+ import type { PipelineSpec, ThreadPhaseAPI } from './types.js';
16
+ export declare class Registry implements ThreadPhaseAPI {
17
+ private readonly triggers;
18
+ private readonly adapters;
19
+ private readonly pipelines;
20
+ /**
21
+ * Source path attributed to the next register call. Set by the loader
22
+ * before invoking the extension's default export, cleared after.
23
+ */
24
+ currentSource: string;
25
+ registerTrigger<TInput>(name: string, trigger: Trigger<TInput>): void;
26
+ registerAdapter<TConfig, TResult extends AgentRunResult = AgentRunResult>(name: string, adapter: AgentAdapterMeta<TConfig, TResult>): void;
27
+ registerPipeline<TCtx extends BasePipelineContext, TInput = unknown>(name: string, spec: PipelineSpec<TCtx, TInput>): void;
28
+ getTrigger(name: string): Trigger<unknown> | undefined;
29
+ getAdapter(name: string): AgentAdapterMeta<unknown, AgentRunResult> | undefined;
30
+ getPipeline(name: string): PipelineSpec<BasePipelineContext, unknown> | undefined;
31
+ listTriggers(): Array<{
32
+ name: string;
33
+ source: string;
34
+ }>;
35
+ listAdapters(): Array<{
36
+ name: string;
37
+ id: string;
38
+ source: string;
39
+ }>;
40
+ listPipelines(): Array<{
41
+ name: string;
42
+ trigger?: string;
43
+ description?: string;
44
+ source: string;
45
+ }>;
46
+ }
47
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACf,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0CAA0C,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAO/D,qBAAa,QAAS,YAAW,cAAc;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmD;IAC5E,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4E;IACrG,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6E;IAEvG;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAe;IAEpC,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI;IAarE,eAAe,CAAC,OAAO,EAAE,OAAO,SAAS,cAAc,GAAG,cAAc,EACtE,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,GAC1C,IAAI;IAaP,gBAAgB,CAAC,IAAI,SAAS,mBAAmB,EAAE,MAAM,GAAG,OAAO,EACjE,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,GAC/B,IAAI;IAeP,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,SAAS;IAItD,UAAU,CACR,IAAI,EAAE,MAAM,GACX,gBAAgB,CAAC,OAAO,EAAE,cAAc,CAAC,GAAG,SAAS;IAIxD,WAAW,CACT,IAAI,EAAE,MAAM,GACX,YAAY,CAAC,mBAAmB,EAAE,OAAO,CAAC,GAAG,SAAS;IAIzD,YAAY,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAOvD,YAAY,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAQnE,aAAa,IAAI,KAAK,CAAC;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CAQH"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Concrete registry implementing `ThreadPhaseAPI`.
3
+ *
4
+ * Backed by plain Maps keyed by name. Holds no per-kind type — registered
5
+ * adapters/triggers/pipelines come back as `unknown`-typed values, and
6
+ * the CLI/loader narrows when invoking them. This keeps the registry
7
+ * simple at the cost of some casts at use sites.
8
+ *
9
+ * Name collisions throw with the location of the prior registration so
10
+ * the user can spot the duplicate quickly.
11
+ */
12
+ export class Registry {
13
+ triggers = new Map();
14
+ adapters = new Map();
15
+ pipelines = new Map();
16
+ /**
17
+ * Source path attributed to the next register call. Set by the loader
18
+ * before invoking the extension's default export, cleared after.
19
+ */
20
+ currentSource = '<unknown>';
21
+ registerTrigger(name, trigger) {
22
+ const existing = this.triggers.get(name);
23
+ if (existing) {
24
+ throw new Error(`duplicate trigger "${name}" registered from ${this.currentSource} (already registered from ${existing.source})`);
25
+ }
26
+ this.triggers.set(name, {
27
+ value: trigger,
28
+ source: this.currentSource,
29
+ });
30
+ }
31
+ registerAdapter(name, adapter) {
32
+ const existing = this.adapters.get(name);
33
+ if (existing) {
34
+ throw new Error(`duplicate adapter "${name}" registered from ${this.currentSource} (already registered from ${existing.source})`);
35
+ }
36
+ this.adapters.set(name, {
37
+ value: adapter,
38
+ source: this.currentSource,
39
+ });
40
+ }
41
+ registerPipeline(name, spec) {
42
+ const existing = this.pipelines.get(name);
43
+ if (existing) {
44
+ throw new Error(`duplicate pipeline "${name}" registered from ${this.currentSource} (already registered from ${existing.source})`);
45
+ }
46
+ this.pipelines.set(name, {
47
+ value: spec,
48
+ source: this.currentSource,
49
+ });
50
+ }
51
+ // --- inspection ---------------------------------------------------------
52
+ getTrigger(name) {
53
+ return this.triggers.get(name)?.value;
54
+ }
55
+ getAdapter(name) {
56
+ return this.adapters.get(name)?.value;
57
+ }
58
+ getPipeline(name) {
59
+ return this.pipelines.get(name)?.value;
60
+ }
61
+ listTriggers() {
62
+ return Array.from(this.triggers.entries()).map(([name, r]) => ({
63
+ name,
64
+ source: r.source,
65
+ }));
66
+ }
67
+ listAdapters() {
68
+ return Array.from(this.adapters.entries()).map(([name, r]) => ({
69
+ name,
70
+ id: r.value.id,
71
+ source: r.source,
72
+ }));
73
+ }
74
+ listPipelines() {
75
+ return Array.from(this.pipelines.entries()).map(([name, r]) => ({
76
+ name,
77
+ trigger: r.value.trigger,
78
+ description: r.value.description,
79
+ source: r.source,
80
+ }));
81
+ }
82
+ }
83
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Extension contract for the thread-phase CLI auto-loader.
3
+ *
4
+ * Every extension is a TypeScript file (or folder, see loader.ts) whose
5
+ * default export is a function `(api: ThreadPhaseAPI) => void` that
6
+ * calls `api.register{Trigger,Adapter,Pipeline}` to add itself to the
7
+ * project's registry.
8
+ *
9
+ * Patterns are NOT auto-loaded. They are reusable factory functions
10
+ * the user imports directly into their pipeline files. The CLI does
11
+ * not gate access to them.
12
+ */
13
+ import type { AgentAdapterMeta, AgentRunResult } from '@autonome-research/thread-phase/agents';
14
+ import type { BasePipelineContext, Phase } from '@autonome-research/thread-phase';
15
+ import type { Trigger, TriggerEvent } from '@autonome-research/thread-phase/triggers';
16
+ /**
17
+ * One registered pipeline. Either:
18
+ *
19
+ * - **Triggered:** bind to a registered trigger by name. `serve` will
20
+ * run this pipeline on every event from that trigger. `run <name>`
21
+ * invokes it once with default input (the user-supplied default, or
22
+ * `undefined` if absent).
23
+ *
24
+ * - **One-shot:** no trigger binding. Only invokable via `run <name>`.
25
+ *
26
+ * `phases` and `ctx` accept either a literal value or a factory that
27
+ * receives the trigger input + event. The factory form is required when
28
+ * ctx needs the input baked in.
29
+ */
30
+ export interface PipelineSpec<TCtx extends BasePipelineContext = BasePipelineContext, TInput = unknown> {
31
+ /** Phases to run, or a factory that builds them per invocation. */
32
+ phases: ReadonlyArray<Phase<TCtx>> | ((input: TInput, event: TriggerEvent<TInput>) => ReadonlyArray<Phase<TCtx>>);
33
+ /** Initial ctx, or a factory that builds it per invocation. */
34
+ ctx: TCtx | ((input: TInput, event: TriggerEvent<TInput>) => TCtx);
35
+ /** Name of a registered trigger to bind to. Optional. */
36
+ trigger?: string;
37
+ /** Default input used when `run <name>` is invoked without a trigger event. */
38
+ defaultInput?: TInput;
39
+ /** Free-form description for `list`. */
40
+ description?: string;
41
+ }
42
+ /**
43
+ * The registration API injected into every extension's default export.
44
+ *
45
+ * Registrations live for the lifetime of one CLI invocation. The CLI
46
+ * scans, loads, registers everything, then dispatches `run` / `serve` /
47
+ * `list` against the populated registry.
48
+ *
49
+ * Name collisions are an error — the loader will reject the second
50
+ * registration with a clear message naming both files. Use the file
51
+ * path as the de facto namespace for now.
52
+ */
53
+ export interface ThreadPhaseAPI {
54
+ /** Register a Trigger by name. */
55
+ registerTrigger<TInput>(name: string, trigger: Trigger<TInput>): void;
56
+ /** Register an AgentAdapter (with its metadata) by name. */
57
+ registerAdapter<TConfig, TResult extends AgentRunResult = AgentRunResult>(name: string, adapter: AgentAdapterMeta<TConfig, TResult>): void;
58
+ /** Register a Pipeline by name. */
59
+ registerPipeline<TCtx extends BasePipelineContext, TInput = unknown>(name: string, spec: PipelineSpec<TCtx, TInput>): void;
60
+ /**
61
+ * Look up a registered pipeline by name. Use inside `subPipeline`'s
62
+ * lazy resolver so registration order between extensions doesn't matter:
63
+ * the lookup runs at dispatch time, not load time.
64
+ */
65
+ getPipeline(name: string): PipelineSpec<BasePipelineContext, unknown> | undefined;
66
+ /** Look up a registered adapter by name. */
67
+ getAdapter(name: string): AgentAdapterMeta<unknown, AgentRunResult> | undefined;
68
+ /** Look up a registered trigger by name. */
69
+ getTrigger(name: string): Trigger<unknown> | undefined;
70
+ }
71
+ /** Extension default export: `(api) => void`. */
72
+ export type ExtensionRegisterFn = (api: ThreadPhaseAPI) => void | Promise<void>;
73
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACf,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EACV,mBAAmB,EACnB,KAAK,EACN,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAEtF;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,YAAY,CAC3B,IAAI,SAAS,mBAAmB,GAAG,mBAAmB,EACtD,MAAM,GAAG,OAAO;IAEhB,mEAAmE;IACnE,MAAM,EACF,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAC1B,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjF,+DAA+D;IAC/D,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IACnE,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC7B,kCAAkC;IAClC,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACtE,4DAA4D;IAC5D,eAAe,CAAC,OAAO,EAAE,OAAO,SAAS,cAAc,GAAG,cAAc,EACtE,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,GAC1C,IAAI,CAAC;IACR,mCAAmC;IACnC,gBAAgB,CAAC,IAAI,SAAS,mBAAmB,EAAE,MAAM,GAAG,OAAO,EACjE,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,GAC/B,IAAI,CAAC;IAER;;;;OAIG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC,mBAAmB,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAClF,4CAA4C;IAC5C,UAAU,CACR,IAAI,EAAE,MAAM,GACX,gBAAgB,CAAC,OAAO,EAAE,cAAc,CAAC,GAAG,SAAS,CAAC;IACzD,4CAA4C;IAC5C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;CACxD;AAED,iDAAiD;AACjD,MAAM,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Extension contract for the thread-phase CLI auto-loader.
3
+ *
4
+ * Every extension is a TypeScript file (or folder, see loader.ts) whose
5
+ * default export is a function `(api: ThreadPhaseAPI) => void` that
6
+ * calls `api.register{Trigger,Adapter,Pipeline}` to add itself to the
7
+ * project's registry.
8
+ *
9
+ * Patterns are NOT auto-loaded. They are reusable factory functions
10
+ * the user imports directly into their pipeline files. The CLI does
11
+ * not gate access to them.
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@autonome-research/thread-phase-cli",
3
+ "version": "3.0.0",
4
+ "description": "CLI and auto-loader for thread-phase — discovers extensions under .thread-phase/ and runs registered pipelines. Installing this gets the full runtime (core + adapters).",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": "./dist/index.js"
11
+ },
12
+ "bin": {
13
+ "thread-phase": "./dist/bin.js"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc -p tsconfig.json && node -e \"require('fs').chmodSync('./dist/bin.js', 0o755)\"",
22
+ "test": "vitest run",
23
+ "test:watch": "vitest",
24
+ "typecheck": "tsc --noEmit"
25
+ },
26
+ "dependencies": {
27
+ "@autonome-research/thread-phase": "^3.0.0",
28
+ "@autonome-research/thread-phase-agents": "^3.0.0",
29
+ "tsx": "^4.19.0"
30
+ },
31
+ "devDependencies": {
32
+ "@autonome-research/thread-phase": "*",
33
+ "@autonome-research/thread-phase-agents": "*",
34
+ "@types/node": "^22.0.0",
35
+ "typescript": "^5.6.0",
36
+ "vitest": "^2.1.0"
37
+ },
38
+ "engines": {
39
+ "node": ">=20"
40
+ },
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "git+https://github.com/Code4me2/thread-phase.git",
44
+ "directory": "packages/thread-phase-cli"
45
+ }
46
+ }