@tagma/sdk 0.7.4 → 0.7.6

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 (191) hide show
  1. package/README.md +60 -53
  2. package/dist/completions/file-exists.js +1 -1
  3. package/dist/completions/file-exists.js.map +1 -1
  4. package/dist/completions/output-check.d.ts.map +1 -1
  5. package/dist/completions/output-check.js +17 -4
  6. package/dist/completions/output-check.js.map +1 -1
  7. package/dist/config.d.ts +4 -4
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +2 -2
  10. package/dist/config.js.map +1 -1
  11. package/dist/dataflow.d.ts +3 -0
  12. package/dist/dataflow.d.ts.map +1 -0
  13. package/dist/dataflow.js +2 -0
  14. package/dist/dataflow.js.map +1 -0
  15. package/dist/drivers/opencode.d.ts.map +1 -1
  16. package/dist/drivers/opencode.js +23 -71
  17. package/dist/drivers/opencode.js.map +1 -1
  18. package/dist/middlewares/static-context.d.ts.map +1 -1
  19. package/dist/middlewares/static-context.js +1 -2
  20. package/dist/middlewares/static-context.js.map +1 -1
  21. package/dist/pipeline-runner.d.ts.map +1 -1
  22. package/dist/pipeline-runner.js +2 -2
  23. package/dist/pipeline-runner.js.map +1 -1
  24. package/dist/schema.d.ts.map +1 -1
  25. package/dist/schema.js +3 -4
  26. package/dist/schema.js.map +1 -1
  27. package/dist/triggers/file.d.ts.map +1 -1
  28. package/dist/triggers/file.js +1 -2
  29. package/dist/triggers/file.js.map +1 -1
  30. package/dist/triggers/manual.d.ts.map +1 -1
  31. package/dist/triggers/manual.js +1 -2
  32. package/dist/triggers/manual.js.map +1 -1
  33. package/dist/types.d.ts +1 -2
  34. package/dist/types.d.ts.map +1 -1
  35. package/dist/types.js +1 -12
  36. package/dist/types.js.map +1 -1
  37. package/dist/utils-api.d.ts +1 -1
  38. package/dist/utils-api.d.ts.map +1 -1
  39. package/dist/utils-api.js +1 -1
  40. package/dist/utils-api.js.map +1 -1
  41. package/dist/validate-raw.d.ts +4 -4
  42. package/dist/validate-raw.d.ts.map +1 -1
  43. package/dist/validate-raw.js +45 -52
  44. package/dist/validate-raw.js.map +1 -1
  45. package/package.json +11 -24
  46. package/dist/adapters/stdin-approval.d.ts +0 -2
  47. package/dist/adapters/stdin-approval.d.ts.map +0 -1
  48. package/dist/adapters/stdin-approval.js +0 -2
  49. package/dist/adapters/stdin-approval.js.map +0 -1
  50. package/dist/adapters/websocket-approval.d.ts +0 -2
  51. package/dist/adapters/websocket-approval.d.ts.map +0 -1
  52. package/dist/adapters/websocket-approval.js +0 -2
  53. package/dist/adapters/websocket-approval.js.map +0 -1
  54. package/dist/core/dataflow.d.ts +0 -23
  55. package/dist/core/dataflow.d.ts.map +0 -1
  56. package/dist/core/dataflow.js +0 -99
  57. package/dist/core/dataflow.js.map +0 -1
  58. package/dist/core/log-prune.d.ts +0 -16
  59. package/dist/core/log-prune.d.ts.map +0 -1
  60. package/dist/core/log-prune.js +0 -34
  61. package/dist/core/log-prune.js.map +0 -1
  62. package/dist/core/preflight.d.ts +0 -13
  63. package/dist/core/preflight.d.ts.map +0 -1
  64. package/dist/core/preflight.js +0 -61
  65. package/dist/core/preflight.js.map +0 -1
  66. package/dist/core/run-context.d.ts +0 -55
  67. package/dist/core/run-context.d.ts.map +0 -1
  68. package/dist/core/run-context.js +0 -158
  69. package/dist/core/run-context.js.map +0 -1
  70. package/dist/core/run-state.d.ts +0 -25
  71. package/dist/core/run-state.d.ts.map +0 -1
  72. package/dist/core/run-state.js +0 -93
  73. package/dist/core/run-state.js.map +0 -1
  74. package/dist/core/scheduler.d.ts +0 -13
  75. package/dist/core/scheduler.d.ts.map +0 -1
  76. package/dist/core/scheduler.js +0 -35
  77. package/dist/core/scheduler.js.map +0 -1
  78. package/dist/core/task-executor.d.ts +0 -13
  79. package/dist/core/task-executor.d.ts.map +0 -1
  80. package/dist/core/task-executor.js +0 -610
  81. package/dist/core/task-executor.js.map +0 -1
  82. package/dist/core/trigger-errors.d.ts +0 -9
  83. package/dist/core/trigger-errors.d.ts.map +0 -1
  84. package/dist/core/trigger-errors.js +0 -15
  85. package/dist/core/trigger-errors.js.map +0 -1
  86. package/dist/dag.d.ts +0 -45
  87. package/dist/dag.d.ts.map +0 -1
  88. package/dist/dag.js +0 -177
  89. package/dist/dag.js.map +0 -1
  90. package/dist/hooks.d.ts +0 -73
  91. package/dist/hooks.d.ts.map +0 -1
  92. package/dist/hooks.js +0 -106
  93. package/dist/hooks.js.map +0 -1
  94. package/dist/pipeline-definition.d.ts +0 -3
  95. package/dist/pipeline-definition.d.ts.map +0 -1
  96. package/dist/pipeline-definition.js +0 -4
  97. package/dist/pipeline-definition.js.map +0 -1
  98. package/dist/ports.d.ts +0 -196
  99. package/dist/ports.d.ts.map +0 -1
  100. package/dist/ports.js +0 -688
  101. package/dist/ports.js.map +0 -1
  102. package/dist/prompt-doc.d.ts +0 -70
  103. package/dist/prompt-doc.d.ts.map +0 -1
  104. package/dist/prompt-doc.js +0 -154
  105. package/dist/prompt-doc.js.map +0 -1
  106. package/dist/registry.d.ts +0 -3
  107. package/dist/registry.d.ts.map +0 -1
  108. package/dist/registry.js +0 -2
  109. package/dist/registry.js.map +0 -1
  110. package/dist/task-ref.d.ts +0 -55
  111. package/dist/task-ref.d.ts.map +0 -1
  112. package/dist/task-ref.js +0 -103
  113. package/dist/task-ref.js.map +0 -1
  114. package/dist/utils.d.ts +0 -13
  115. package/dist/utils.d.ts.map +0 -1
  116. package/dist/utils.js +0 -177
  117. package/dist/utils.js.map +0 -1
  118. package/src/adapters/stdin-approval.ts +0 -1
  119. package/src/adapters/websocket-approval.ts +0 -1
  120. package/src/approval.ts +0 -9
  121. package/src/bootstrap.ts +0 -55
  122. package/src/completions/exit-code.ts +0 -34
  123. package/src/completions/file-exists.ts +0 -66
  124. package/src/completions/output-check.test.ts +0 -50
  125. package/src/completions/output-check.ts +0 -92
  126. package/src/config-ops.test.ts +0 -70
  127. package/src/config-ops.ts +0 -328
  128. package/src/config.ts +0 -26
  129. package/src/core/dataflow.test.ts +0 -166
  130. package/src/core/dataflow.ts +0 -161
  131. package/src/core/log-prune.test.ts +0 -58
  132. package/src/core/log-prune.ts +0 -43
  133. package/src/core/preflight.test.ts +0 -49
  134. package/src/core/preflight.ts +0 -89
  135. package/src/core/run-context.test.ts +0 -291
  136. package/src/core/run-context.ts +0 -211
  137. package/src/core/run-state.test.ts +0 -98
  138. package/src/core/run-state.ts +0 -122
  139. package/src/core/scheduler.test.ts +0 -83
  140. package/src/core/scheduler.ts +0 -42
  141. package/src/core/task-executor.ts +0 -752
  142. package/src/core/trigger-errors.ts +0 -15
  143. package/src/dag.test.ts +0 -56
  144. package/src/dag.ts +0 -245
  145. package/src/drivers/opencode.ts +0 -410
  146. package/src/engine-ports-mixed.test.ts +0 -182
  147. package/src/engine-ports.test.ts +0 -210
  148. package/src/engine-task-type.test.ts +0 -56
  149. package/src/engine.ts +0 -32
  150. package/src/hooks.ts +0 -193
  151. package/src/index.ts +0 -31
  152. package/src/logger.ts +0 -2
  153. package/src/middlewares/static-context.ts +0 -49
  154. package/src/package-split.test.ts +0 -15
  155. package/src/pipeline-definition.ts +0 -5
  156. package/src/pipeline-runner.test.ts +0 -144
  157. package/src/pipeline-runner.ts +0 -194
  158. package/src/plugin-registry.test.ts +0 -448
  159. package/src/plugins.ts +0 -21
  160. package/src/ports.test.ts +0 -678
  161. package/src/ports.ts +0 -925
  162. package/src/prompt-doc.test.ts +0 -174
  163. package/src/prompt-doc.ts +0 -169
  164. package/src/registry.ts +0 -7
  165. package/src/runner.test.ts +0 -142
  166. package/src/runner.ts +0 -1
  167. package/src/runtime/adapters/stdin-approval.ts +0 -1
  168. package/src/runtime/adapters/websocket-approval.ts +0 -1
  169. package/src/runtime/bun-process-runner.ts +0 -1
  170. package/src/runtime-adapters.test.ts +0 -10
  171. package/src/runtime.ts +0 -12
  172. package/src/schema-ports.test.ts +0 -172
  173. package/src/schema.test.ts +0 -213
  174. package/src/schema.ts +0 -379
  175. package/src/tagma.test.ts +0 -317
  176. package/src/tagma.ts +0 -67
  177. package/src/task-ref.test.ts +0 -401
  178. package/src/task-ref.ts +0 -121
  179. package/src/triggers/file.test.ts +0 -79
  180. package/src/triggers/file.ts +0 -131
  181. package/src/triggers/manual.ts +0 -86
  182. package/src/types.ts +0 -18
  183. package/src/utils-api.ts +0 -8
  184. package/src/utils.test.ts +0 -28
  185. package/src/utils.ts +0 -203
  186. package/src/validate-raw-plugin-types.test.ts +0 -60
  187. package/src/validate-raw-ports.test.ts +0 -136
  188. package/src/validate-raw.ts +0 -852
  189. package/src/yaml-compiler.test.ts +0 -108
  190. package/src/yaml-compiler.ts +0 -110
  191. package/src/yaml.ts +0 -11
@@ -1,144 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { mkdtempSync, rmSync } from 'node:fs';
3
- import { tmpdir } from 'node:os';
4
- import { join } from 'node:path';
5
- import { bootstrapBuiltins } from './bootstrap';
6
- import { PipelineRunner } from './pipeline-runner';
7
- import { PluginRegistry } from './registry';
8
- import type { PipelineConfig, TagmaRuntime, TaskResult } from './types';
9
-
10
- function makeDir(): string {
11
- return mkdtempSync(join(tmpdir(), 'tagma-pipeline-runner-'));
12
- }
13
-
14
- function bindingsPipeline(dir: string): PipelineConfig {
15
- return {
16
- name: 'runner-snapshot',
17
- tracks: [
18
- {
19
- id: 't',
20
- name: 'T',
21
- tasks: [
22
- {
23
- id: 'up',
24
- name: 'up',
25
- command: 'emit-city',
26
- outputs: { city: { type: 'string' } },
27
- },
28
- {
29
- id: 'down',
30
- name: 'down',
31
- depends_on: ['up'],
32
- command: 'echo-city "{{inputs.city}}"',
33
- inputs: { city: { from: 't.up.outputs.city', type: 'string', required: true } },
34
- },
35
- ],
36
- },
37
- ],
38
- };
39
- }
40
-
41
- function taskResult(stdout: string): TaskResult {
42
- return {
43
- exitCode: 0,
44
- stdout,
45
- stderr: '',
46
- stdoutPath: null,
47
- stderrPath: null,
48
- stdoutBytes: stdout.length,
49
- stderrBytes: 0,
50
- durationMs: 1,
51
- sessionId: null,
52
- normalizedOutput: null,
53
- failureKind: null,
54
- };
55
- }
56
-
57
- function fakeRuntime(): TagmaRuntime {
58
- return {
59
- async runCommand(command) {
60
- return command.startsWith('emit-city')
61
- ? taskResult('{"city":"Shanghai"}\n')
62
- : taskResult('Shanghai\n');
63
- },
64
- async runSpawn() {
65
- throw new Error('runSpawn should not be called');
66
- },
67
- async ensureDir() {
68
- /* no-op */
69
- },
70
- async fileExists() {
71
- return false;
72
- },
73
- async *watch() {
74
- /* no-op */
75
- },
76
- logStore: {
77
- openRunLog({ runId }) {
78
- return {
79
- path: `mem://${runId}/pipeline.log`,
80
- dir: `mem://${runId}`,
81
- append() {
82
- /* memory sink */
83
- },
84
- close() {
85
- /* memory sink */
86
- },
87
- };
88
- },
89
- taskOutputPath({ runId, taskId, stream }) {
90
- return `mem://${runId}/${taskId}.${stream}`;
91
- },
92
- logsDir() {
93
- return 'mem://logs';
94
- },
95
- },
96
- now: () => new Date('2026-04-26T00:00:00.000Z'),
97
- sleep: () => Promise.resolve(),
98
- };
99
- }
100
-
101
- async function run(config: PipelineConfig, dir: string): Promise<PipelineRunner> {
102
- const registry = new PluginRegistry();
103
- bootstrapBuiltins(registry);
104
- const runner = new PipelineRunner(config, dir, {
105
- registry,
106
- runtime: fakeRuntime(),
107
- skipPluginLoading: true,
108
- });
109
-
110
- const result = await runner.start();
111
- expect(result.success).toBe(true);
112
- return runner;
113
- }
114
-
115
- describe('PipelineRunner task snapshot', () => {
116
- test('getTasks reflects task_update inputs and outputs', async () => {
117
- const dir = makeDir();
118
- try {
119
- const runner = await run(bindingsPipeline(dir), dir);
120
-
121
- const tasks = runner.getTasks();
122
- const up = tasks.get('t.up');
123
- const down = tasks.get('t.down');
124
- expect(up?.outputs).toEqual({ city: 'Shanghai' });
125
- expect(down?.inputs).toEqual({ city: 'Shanghai' });
126
- } finally {
127
- rmSync(dir, { recursive: true, force: true });
128
- }
129
- });
130
-
131
- test('getTasks folds streamed task logs into the task snapshot', async () => {
132
- const dir = makeDir();
133
- try {
134
- const runner = await run(bindingsPipeline(dir), dir);
135
-
136
- const tasks = runner.getTasks();
137
- const up = tasks.get('t.up');
138
- expect(up?.logs.length).toBeGreaterThan(0);
139
- expect(up?.totalLogCount).toBeGreaterThan(0);
140
- } finally {
141
- rmSync(dir, { recursive: true, force: true });
142
- }
143
- });
144
- });
@@ -1,194 +0,0 @@
1
- // ═══ PipelineRunner ═══
2
- //
3
- // Wraps runPipeline in a lifecycle object suited for multi-pipeline
4
- // management in sidecar / Tauri IPC scenarios. Each instance controls
5
- // one pipeline run.
6
- //
7
- // The runner forwards wire-shape `RunEventPayload` values to its
8
- // subscribers — identical to what the editor server broadcasts over SSE —
9
- // so sidecar hosts don't need to know anything about the engine's
10
- // internal TaskState.
11
- //
12
- // Typical sidecar usage:
13
- //
14
- // const runners = new Map<string, PipelineRunner>();
15
- //
16
- // const runner = new PipelineRunner(config, workDir, { registry });
17
- // runner.subscribe(event => ipcEmit('run_event', event));
18
- // runner.start();
19
- // runners.set(runner.instanceId, runner);
20
- //
21
- // // Later, from IPC:
22
- // runners.get(id)?.abort();
23
-
24
- import { runPipeline } from './engine';
25
- import type { EngineResult, RunPipelineOptions } from './engine';
26
- import { TASK_LOG_CAP, type PipelineConfig, type RunEventPayload, type RunTaskState } from './types';
27
- import { generateRunId } from './utils';
28
-
29
- export type { EngineResult };
30
-
31
- export type PipelineRunnerStatus = 'idle' | 'running' | 'done' | 'aborted';
32
- export type PipelineRunnerOptions = Omit<RunPipelineOptions, 'signal' | 'onEvent'>;
33
-
34
- export class PipelineRunner {
35
- /**
36
- * Stable ID assigned before start() — safe to use as a Map key before
37
- * the engine-assigned runId becomes available.
38
- */
39
- readonly instanceId: string;
40
-
41
- /**
42
- * The runId generated by the engine. Set when the first `run_start`
43
- * event arrives on the forwarded event stream. null until then.
44
- */
45
- private _runId: string | null = null;
46
- private _status: PipelineRunnerStatus = 'idle';
47
- private _result: Promise<EngineResult> | null = null;
48
- private _abortController = new AbortController();
49
- private _handlers = new Set<(event: RunEventPayload) => void>();
50
- /**
51
- * Wire-shape task mirror, kept in sync with `run_start` / `task_update`
52
- * events. Exposed through `getTasks()`. Hosts see the same wire
53
- * projection the editor client sees, so there is exactly one task-state
54
- * vocabulary across IPC boundaries.
55
- */
56
- private _tasks = new Map<string, RunTaskState>();
57
-
58
- constructor(
59
- private readonly config: PipelineConfig,
60
- private readonly workDir: string,
61
- private readonly opts: PipelineRunnerOptions,
62
- ) {
63
- this.instanceId = generateRunId();
64
- }
65
-
66
- get runId(): string | null {
67
- return this._runId;
68
- }
69
- get status(): PipelineRunnerStatus {
70
- return this._status;
71
- }
72
-
73
- /**
74
- * Start the pipeline. Calling start() more than once returns the same Promise.
75
- */
76
- start(): Promise<EngineResult> {
77
- if (this._result) return this._result;
78
-
79
- // Guard: if abort() was called before start(), the signal is already
80
- // aborted. Create a fresh controller so the pipeline doesn't terminate
81
- // immediately. If users truly want pre-abort semantics, they call
82
- // abort() after start().
83
- if (this._abortController.signal.aborted) {
84
- this._abortController = new AbortController();
85
- this._status = 'idle';
86
- }
87
-
88
- this._status = 'running';
89
- this._result = runPipeline(this.config, this.workDir, {
90
- ...this.opts,
91
- signal: this._abortController.signal,
92
- onEvent: (event) => {
93
- this._applyEvent(event);
94
- for (const h of this._handlers) h(event);
95
- },
96
- })
97
- .then((result) => {
98
- if (this._status === 'running') this._status = 'done';
99
- return result;
100
- })
101
- .catch((err) => {
102
- this._status = 'aborted';
103
- throw err;
104
- });
105
-
106
- return this._result;
107
- }
108
-
109
- private _applyEvent(event: RunEventPayload): void {
110
- switch (event.type) {
111
- case 'run_start':
112
- this._runId = event.runId;
113
- this._tasks.clear();
114
- for (const t of event.tasks) this._tasks.set(t.taskId, { ...t });
115
- return;
116
- case 'task_update': {
117
- const prev = this._tasks.get(event.taskId);
118
- if (!prev) return;
119
- const pick = <T>(incoming: T | undefined, previous: T): T =>
120
- incoming !== undefined ? incoming : previous;
121
- this._tasks.set(event.taskId, {
122
- ...prev,
123
- status: event.status,
124
- startedAt: pick(event.startedAt, prev.startedAt),
125
- finishedAt: pick(event.finishedAt, prev.finishedAt),
126
- durationMs: pick(event.durationMs, prev.durationMs),
127
- exitCode: pick(event.exitCode, prev.exitCode),
128
- stdout: pick(event.stdout, prev.stdout),
129
- stderr: pick(event.stderr, prev.stderr),
130
- stdoutPath: pick(event.stdoutPath, prev.stdoutPath),
131
- stderrPath: pick(event.stderrPath, prev.stderrPath),
132
- stdoutBytes: pick(event.stdoutBytes, prev.stdoutBytes),
133
- stderrBytes: pick(event.stderrBytes, prev.stderrBytes),
134
- sessionId: pick(event.sessionId, prev.sessionId),
135
- normalizedOutput: pick(event.normalizedOutput, prev.normalizedOutput),
136
- outputs: pick(event.outputs, prev.outputs),
137
- inputs: pick(event.inputs, prev.inputs),
138
- resolvedDriver: pick(event.resolvedDriver, prev.resolvedDriver),
139
- resolvedModel: pick(event.resolvedModel, prev.resolvedModel),
140
- resolvedPermissions: pick(event.resolvedPermissions, prev.resolvedPermissions),
141
- });
142
- return;
143
- }
144
- case 'task_log': {
145
- if (event.taskId === null) return;
146
- const prev = this._tasks.get(event.taskId);
147
- if (!prev) return;
148
- const logs = [
149
- ...prev.logs,
150
- { level: event.level, timestamp: event.timestamp, text: event.text },
151
- ];
152
- this._tasks.set(event.taskId, {
153
- ...prev,
154
- logs: logs.slice(-TASK_LOG_CAP),
155
- totalLogCount: prev.totalLogCount + 1,
156
- });
157
- return;
158
- }
159
- case 'run_end':
160
- this._status = this._abortController.signal.aborted ? 'aborted' : 'done';
161
- return;
162
- default:
163
- return;
164
- }
165
- }
166
-
167
- /**
168
- * Cancel the running pipeline. Safe to call multiple times or before start().
169
- */
170
- abort(reason?: string): void {
171
- this._status = 'aborted';
172
- this._abortController.abort(reason);
173
- }
174
-
175
- /**
176
- * Live snapshot of wire-shape task states. Populated from the first
177
- * `run_start` event onward. Returns an empty map before the run starts.
178
- */
179
- getTasks(): ReadonlyMap<string, RunTaskState> {
180
- const copy = new Map<string, RunTaskState>();
181
- for (const [id, t] of this._tasks) copy.set(id, { ...t });
182
- return copy;
183
- }
184
-
185
- /**
186
- * Subscribe to run events. Returns an unsubscribe function. Events are
187
- * emitted synchronously in the engine's event loop, so keep handlers
188
- * non-blocking (e.g. queue to IPC, do not await inside).
189
- */
190
- subscribe(handler: (event: RunEventPayload) => void): () => void {
191
- this._handlers.add(handler);
192
- return () => this._handlers.delete(handler);
193
- }
194
- }