@tagma/sdk 0.4.1 → 0.4.3
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 +21 -0
- package/dist/adapters/stdin-approval.d.ts +6 -0
- package/dist/adapters/stdin-approval.d.ts.map +1 -0
- package/dist/adapters/stdin-approval.js +90 -0
- package/dist/adapters/stdin-approval.js.map +1 -0
- package/dist/adapters/websocket-approval.d.ts +28 -0
- package/dist/adapters/websocket-approval.d.ts.map +1 -0
- package/dist/adapters/websocket-approval.js +145 -0
- package/dist/adapters/websocket-approval.js.map +1 -0
- package/dist/approval.d.ts +13 -0
- package/dist/approval.d.ts.map +1 -0
- package/dist/approval.js +91 -0
- package/dist/approval.js.map +1 -0
- package/dist/bootstrap.d.ts +2 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +30 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/completions/exit-code.d.ts +3 -0
- package/dist/completions/exit-code.d.ts.map +1 -0
- package/dist/completions/exit-code.js +25 -0
- package/dist/completions/exit-code.js.map +1 -0
- package/dist/completions/file-exists.d.ts +3 -0
- package/dist/completions/file-exists.d.ts.map +1 -0
- package/dist/completions/file-exists.js +58 -0
- package/dist/completions/file-exists.js.map +1 -0
- package/dist/completions/output-check.d.ts +3 -0
- package/dist/completions/output-check.d.ts.map +1 -0
- package/dist/completions/output-check.js +81 -0
- package/dist/completions/output-check.js.map +1 -0
- package/dist/config-ops.d.ts +55 -0
- package/dist/config-ops.d.ts.map +1 -0
- package/dist/config-ops.js +258 -0
- package/dist/config-ops.js.map +1 -0
- package/dist/dag.d.ts +46 -0
- package/dist/dag.d.ts.map +1 -0
- package/dist/dag.js +193 -0
- package/dist/dag.js.map +1 -0
- package/dist/drivers/claude-code.d.ts +3 -0
- package/dist/drivers/claude-code.d.ts.map +1 -0
- package/dist/drivers/claude-code.js +210 -0
- package/dist/drivers/claude-code.js.map +1 -0
- package/dist/engine.d.ts +89 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +815 -0
- package/dist/engine.js.map +1 -0
- package/dist/hooks.d.ts +73 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +103 -0
- package/dist/hooks.js.map +1 -0
- package/dist/logger.d.ts +61 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +151 -0
- package/dist/logger.js.map +1 -0
- package/dist/middlewares/static-context.d.ts +3 -0
- package/dist/middlewares/static-context.d.ts.map +1 -0
- package/dist/middlewares/static-context.js +36 -0
- package/dist/middlewares/static-context.js.map +1 -0
- package/dist/pipeline-runner.d.ts +50 -0
- package/dist/pipeline-runner.d.ts.map +1 -0
- package/dist/pipeline-runner.js +139 -0
- package/dist/pipeline-runner.js.map +1 -0
- package/dist/registry.d.ts +43 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +182 -0
- package/dist/registry.js.map +1 -0
- package/dist/runner.d.ts +19 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +364 -0
- package/dist/runner.js.map +1 -0
- package/dist/schema.d.ts +27 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +373 -0
- package/dist/schema.js.map +1 -0
- package/dist/sdk.d.ts +27 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +33 -0
- package/dist/sdk.js.map +1 -0
- package/dist/templates.d.ts +20 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +93 -0
- package/dist/templates.js.map +1 -0
- package/dist/triggers/file.d.ts +3 -0
- package/dist/triggers/file.d.ts.map +1 -0
- package/dist/triggers/file.js +123 -0
- package/dist/triggers/file.js.map +1 -0
- package/dist/triggers/manual.d.ts +3 -0
- package/dist/triggers/manual.d.ts.map +1 -0
- package/dist/triggers/manual.js +73 -0
- package/dist/triggers/manual.js.map +1 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +14 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +138 -0
- package/dist/utils.js.map +1 -0
- package/dist/validate-raw.d.ts +26 -0
- package/dist/validate-raw.d.ts.map +1 -0
- package/dist/validate-raw.js +260 -0
- package/dist/validate-raw.js.map +1 -0
- package/package.json +26 -17
- package/src/adapters/websocket-approval.ts +20 -4
- package/src/approval.ts +5 -3
- package/src/registry.ts +214 -214
- package/scripts/preinstall.js +0 -38
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// ═══ PipelineRunner ═══
|
|
2
|
+
//
|
|
3
|
+
// Wraps runPipeline in a lifecycle object suited for multi-pipeline management
|
|
4
|
+
// in sidecar / Tauri IPC scenarios. Each instance controls one pipeline run.
|
|
5
|
+
//
|
|
6
|
+
// Typical sidecar usage:
|
|
7
|
+
//
|
|
8
|
+
// const runners = new Map<string, PipelineRunner>();
|
|
9
|
+
//
|
|
10
|
+
// const runner = new PipelineRunner(config, workDir);
|
|
11
|
+
// runner.subscribe(event => ipcEmit('pipeline_event', event));
|
|
12
|
+
// runner.start();
|
|
13
|
+
// runners.set(runner.instanceId, runner);
|
|
14
|
+
//
|
|
15
|
+
// // Later, from IPC:
|
|
16
|
+
// runners.get(id)?.abort();
|
|
17
|
+
import { runPipeline } from './engine';
|
|
18
|
+
import { generateRunId } from './utils';
|
|
19
|
+
export class PipelineRunner {
|
|
20
|
+
config;
|
|
21
|
+
workDir;
|
|
22
|
+
opts;
|
|
23
|
+
/**
|
|
24
|
+
* Stable ID assigned before start() — safe to use as a Map key in the sidecar
|
|
25
|
+
* before the engine-assigned runId becomes available.
|
|
26
|
+
*/
|
|
27
|
+
instanceId;
|
|
28
|
+
/**
|
|
29
|
+
* The runId generated by the engine. Available after the first 'pipeline_start'
|
|
30
|
+
* event fires (i.e. effectively immediately after start() is called).
|
|
31
|
+
* null until then.
|
|
32
|
+
*/
|
|
33
|
+
_runId = null;
|
|
34
|
+
_status = 'idle';
|
|
35
|
+
_result = null;
|
|
36
|
+
_abortController = new AbortController();
|
|
37
|
+
_handlers = new Set();
|
|
38
|
+
_states = null;
|
|
39
|
+
_statesMirror = new Map();
|
|
40
|
+
constructor(config, workDir, opts = {}) {
|
|
41
|
+
this.config = config;
|
|
42
|
+
this.workDir = workDir;
|
|
43
|
+
this.opts = opts;
|
|
44
|
+
this.instanceId = generateRunId();
|
|
45
|
+
}
|
|
46
|
+
get runId() { return this._runId; }
|
|
47
|
+
get status() { return this._status; }
|
|
48
|
+
/**
|
|
49
|
+
* Start the pipeline. Calling start() more than once returns the same Promise.
|
|
50
|
+
*/
|
|
51
|
+
start() {
|
|
52
|
+
if (this._result)
|
|
53
|
+
return this._result;
|
|
54
|
+
// Guard: if abort() was called before start(), the signal is already
|
|
55
|
+
// aborted. Create a fresh controller so the pipeline doesn't terminate
|
|
56
|
+
// immediately. If users truly want pre-abort semantics, they call
|
|
57
|
+
// abort() after start().
|
|
58
|
+
if (this._abortController.signal.aborted) {
|
|
59
|
+
this._abortController = new AbortController();
|
|
60
|
+
this._status = 'idle';
|
|
61
|
+
}
|
|
62
|
+
this._status = 'running';
|
|
63
|
+
this._result = runPipeline(this.config, this.workDir, {
|
|
64
|
+
...this.opts,
|
|
65
|
+
signal: this._abortController.signal,
|
|
66
|
+
onEvent: (event) => {
|
|
67
|
+
if (event.type === 'pipeline_start') {
|
|
68
|
+
this._runId = event.runId;
|
|
69
|
+
// Initialize the live mirror with the full initial state snapshot
|
|
70
|
+
for (const [id, state] of event.states) {
|
|
71
|
+
this._statesMirror.set(id, { ...state });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (event.type === 'task_status_change') {
|
|
75
|
+
// Keep the mirror up to date so getStates() works during the run
|
|
76
|
+
this._statesMirror.set(event.taskId, event.state);
|
|
77
|
+
}
|
|
78
|
+
if (event.type === 'pipeline_end') {
|
|
79
|
+
this._status = this._abortController.signal.aborted ? 'aborted' : 'done';
|
|
80
|
+
}
|
|
81
|
+
for (const h of this._handlers)
|
|
82
|
+
h(event);
|
|
83
|
+
},
|
|
84
|
+
}).then(result => {
|
|
85
|
+
this._states = result.states;
|
|
86
|
+
if (this._status === 'running')
|
|
87
|
+
this._status = 'done';
|
|
88
|
+
return result;
|
|
89
|
+
}).catch(err => {
|
|
90
|
+
this._status = 'aborted';
|
|
91
|
+
throw err;
|
|
92
|
+
});
|
|
93
|
+
return this._result;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Cancel the running pipeline. Safe to call multiple times or before start().
|
|
97
|
+
*/
|
|
98
|
+
abort(reason) {
|
|
99
|
+
this._status = 'aborted';
|
|
100
|
+
this._abortController.abort(reason);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Live snapshot of task states. Available from the first pipeline_start event onward
|
|
104
|
+
* (i.e. as soon as start() is called) and remains accessible after the run completes.
|
|
105
|
+
* Returns null only if the pipeline has never started.
|
|
106
|
+
*/
|
|
107
|
+
getStates() {
|
|
108
|
+
if (this._states)
|
|
109
|
+
return snapshotStates(this._states);
|
|
110
|
+
if (this._statesMirror.size > 0)
|
|
111
|
+
return snapshotStates(this._statesMirror);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Subscribe to pipeline/task events. Returns an unsubscribe function.
|
|
116
|
+
* Events are emitted synchronously in the engine's event loop, so keep
|
|
117
|
+
* handlers non-blocking (e.g. queue to IPC, do not await inside).
|
|
118
|
+
*/
|
|
119
|
+
subscribe(handler) {
|
|
120
|
+
this._handlers.add(handler);
|
|
121
|
+
return () => this._handlers.delete(handler);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** Deep-copy a states map so callers cannot mutate SDK internals. */
|
|
125
|
+
function snapshotStates(src) {
|
|
126
|
+
const copy = new Map();
|
|
127
|
+
for (const [id, s] of src) {
|
|
128
|
+
copy.set(id, {
|
|
129
|
+
config: { ...s.config },
|
|
130
|
+
trackConfig: { ...s.trackConfig },
|
|
131
|
+
status: s.status,
|
|
132
|
+
result: s.result ? { ...s.result } : null,
|
|
133
|
+
startedAt: s.startedAt,
|
|
134
|
+
finishedAt: s.finishedAt,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
return copy;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=pipeline-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-runner.js","sourceRoot":"","sources":["../src/pipeline-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { PluginCategory, DriverPlugin, TriggerPlugin, CompletionPlugin, MiddlewarePlugin, PluginManifest } from './types';
|
|
2
|
+
type PluginType = DriverPlugin | TriggerPlugin | CompletionPlugin | MiddlewarePlugin;
|
|
3
|
+
export type RegisterResult = 'registered' | 'replaced' | 'unchanged';
|
|
4
|
+
/**
|
|
5
|
+
* Register a plugin under (category, type). Returns:
|
|
6
|
+
* - 'registered' on first registration
|
|
7
|
+
* - 'replaced' when an existing entry was overwritten with a different handler
|
|
8
|
+
* - 'unchanged' when the same handler instance was already present
|
|
9
|
+
*
|
|
10
|
+
* Throws if `category` is unknown, `type` is empty, or `handler` violates the
|
|
11
|
+
* minimum interface contract for the category.
|
|
12
|
+
*/
|
|
13
|
+
export declare function registerPlugin<T extends PluginType>(category: PluginCategory, type: string, handler: T): RegisterResult;
|
|
14
|
+
/**
|
|
15
|
+
* Remove a plugin from the in-process registry. Returns true if a plugin
|
|
16
|
+
* was actually removed. Note: ESM module caching is not affected, so
|
|
17
|
+
* re-importing the same file after unregister will yield the cached module —
|
|
18
|
+
* callers wanting a fresh load must restart the host process.
|
|
19
|
+
*/
|
|
20
|
+
export declare function unregisterPlugin(category: PluginCategory, type: string): boolean;
|
|
21
|
+
export declare function getHandler<T extends PluginType>(category: PluginCategory, type: string): T;
|
|
22
|
+
export declare function hasHandler(category: PluginCategory, type: string): boolean;
|
|
23
|
+
export declare const PLUGIN_NAME_RE: RegExp;
|
|
24
|
+
export declare function isValidPluginName(name: unknown): name is string;
|
|
25
|
+
/**
|
|
26
|
+
* Parse and validate the `tagmaPlugin` field of a `package.json` blob.
|
|
27
|
+
*
|
|
28
|
+
* Returns the strongly-typed manifest if the field is present and
|
|
29
|
+
* well-formed (`category` is one of the four known categories and `type`
|
|
30
|
+
* is a non-empty string). Returns `null` if the field is absent — that
|
|
31
|
+
* is the host's signal that the package is a library, not a plugin.
|
|
32
|
+
*
|
|
33
|
+
* Throws if the field is present but malformed: that's a packaging bug
|
|
34
|
+
* the plugin author should hear about loudly, not a silent skip.
|
|
35
|
+
*
|
|
36
|
+
* Hosts use this during auto-discovery to decide whether to load a
|
|
37
|
+
* package as a plugin without having to dynamically `import()` it.
|
|
38
|
+
*/
|
|
39
|
+
export declare function readPluginManifest(pkgJson: unknown): PluginManifest | null;
|
|
40
|
+
export declare function loadPlugins(pluginNames: readonly string[]): Promise<void>;
|
|
41
|
+
export declare function listRegistered(category: PluginCategory): string[];
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAAE,YAAY,EAAE,aAAa,EAC3C,gBAAgB,EAAE,gBAAgB,EAAE,cAAc,EACnD,MAAM,SAAS,CAAC;AAEjB,KAAK,UAAU,GAAG,YAAY,GAAG,aAAa,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AAsFrF,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,UAAU,GAAG,WAAW,CAAC;AAErE;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,UAAU,EACjD,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GACjD,cAAc,CAchB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAGhF;AAED,wBAAgB,UAAU,CAAC,CAAC,SAAS,UAAU,EAC7C,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GACrC,CAAC,CASH;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1E;AAKD,eAAO,MAAM,cAAc,QAA4D,CAAC;AAExF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,MAAM,CAE/D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAmB1E;AAED,wBAAsB,WAAW,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB/E;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,EAAE,CAEjE"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
const VALID_CATEGORIES = new Set([
|
|
2
|
+
'drivers', 'triggers', 'completions', 'middlewares',
|
|
3
|
+
]);
|
|
4
|
+
const registries = {
|
|
5
|
+
drivers: new Map(),
|
|
6
|
+
triggers: new Map(),
|
|
7
|
+
completions: new Map(),
|
|
8
|
+
middlewares: new Map(),
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Minimal contract enforcement so a malformed plugin fails fast at
|
|
12
|
+
* registration time rather than crashing the engine mid-run.
|
|
13
|
+
*
|
|
14
|
+
* For drivers we materialize `capabilities` and assert each field is a
|
|
15
|
+
* boolean — otherwise a plugin author can write
|
|
16
|
+
* get capabilities() { throw new Error('boom') }
|
|
17
|
+
* and pass the basic typeof check, then crash preflight when the engine
|
|
18
|
+
* touches `driver.capabilities.sessionResume`. (R8)
|
|
19
|
+
*/
|
|
20
|
+
function validateContract(category, handler) {
|
|
21
|
+
if (!handler || typeof handler !== 'object') {
|
|
22
|
+
throw new Error(`Plugin handler for category "${category}" must be an object`);
|
|
23
|
+
}
|
|
24
|
+
const h = handler;
|
|
25
|
+
if (typeof h.name !== 'string' || h.name.length === 0) {
|
|
26
|
+
throw new Error(`Plugin handler for category "${category}" must declare a non-empty "name"`);
|
|
27
|
+
}
|
|
28
|
+
switch (category) {
|
|
29
|
+
case 'drivers': {
|
|
30
|
+
if (typeof h.buildCommand !== 'function') {
|
|
31
|
+
throw new Error(`drivers plugin "${h.name}" must export buildCommand()`);
|
|
32
|
+
}
|
|
33
|
+
// Materialize capabilities — this triggers any throwing getter NOW
|
|
34
|
+
// instead of during preflight.
|
|
35
|
+
let caps;
|
|
36
|
+
try {
|
|
37
|
+
caps = h.capabilities;
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
throw new Error(`drivers plugin "${h.name}" capabilities accessor threw: ` +
|
|
41
|
+
(err instanceof Error ? err.message : String(err)));
|
|
42
|
+
}
|
|
43
|
+
if (!caps || typeof caps !== 'object') {
|
|
44
|
+
throw new Error(`drivers plugin "${h.name}" must declare capabilities object`);
|
|
45
|
+
}
|
|
46
|
+
const c = caps;
|
|
47
|
+
for (const field of ['sessionResume', 'systemPrompt', 'outputFormat']) {
|
|
48
|
+
if (typeof c[field] !== 'boolean') {
|
|
49
|
+
throw new Error(`drivers plugin "${h.name}".capabilities.${field} must be a boolean (got ${typeof c[field]})`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Optional methods, but if present must be functions.
|
|
53
|
+
for (const opt of ['parseResult', 'resolveModel', 'resolveTools']) {
|
|
54
|
+
if (h[opt] !== undefined && typeof h[opt] !== 'function') {
|
|
55
|
+
throw new Error(`drivers plugin "${h.name}".${opt} must be a function or undefined`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
case 'triggers':
|
|
61
|
+
if (typeof h.watch !== 'function') {
|
|
62
|
+
throw new Error(`triggers plugin "${h.name}" must export watch()`);
|
|
63
|
+
}
|
|
64
|
+
break;
|
|
65
|
+
case 'completions':
|
|
66
|
+
if (typeof h.check !== 'function') {
|
|
67
|
+
throw new Error(`completions plugin "${h.name}" must export check()`);
|
|
68
|
+
}
|
|
69
|
+
break;
|
|
70
|
+
case 'middlewares':
|
|
71
|
+
if (typeof h.enhance !== 'function') {
|
|
72
|
+
throw new Error(`middlewares plugin "${h.name}" must export enhance()`);
|
|
73
|
+
}
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Register a plugin under (category, type). Returns:
|
|
79
|
+
* - 'registered' on first registration
|
|
80
|
+
* - 'replaced' when an existing entry was overwritten with a different handler
|
|
81
|
+
* - 'unchanged' when the same handler instance was already present
|
|
82
|
+
*
|
|
83
|
+
* Throws if `category` is unknown, `type` is empty, or `handler` violates the
|
|
84
|
+
* minimum interface contract for the category.
|
|
85
|
+
*/
|
|
86
|
+
export function registerPlugin(category, type, handler) {
|
|
87
|
+
if (!VALID_CATEGORIES.has(category)) {
|
|
88
|
+
throw new Error(`Unknown plugin category "${category}"`);
|
|
89
|
+
}
|
|
90
|
+
if (typeof type !== 'string' || type.length === 0) {
|
|
91
|
+
throw new Error(`Plugin type must be a non-empty string (category="${category}")`);
|
|
92
|
+
}
|
|
93
|
+
validateContract(category, handler);
|
|
94
|
+
const registry = registries[category];
|
|
95
|
+
const existing = registry.get(type);
|
|
96
|
+
if (existing === handler)
|
|
97
|
+
return 'unchanged';
|
|
98
|
+
const wasReplaced = existing !== undefined;
|
|
99
|
+
registry.set(type, handler);
|
|
100
|
+
return wasReplaced ? 'replaced' : 'registered';
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Remove a plugin from the in-process registry. Returns true if a plugin
|
|
104
|
+
* was actually removed. Note: ESM module caching is not affected, so
|
|
105
|
+
* re-importing the same file after unregister will yield the cached module —
|
|
106
|
+
* callers wanting a fresh load must restart the host process.
|
|
107
|
+
*/
|
|
108
|
+
export function unregisterPlugin(category, type) {
|
|
109
|
+
if (!VALID_CATEGORIES.has(category))
|
|
110
|
+
return false;
|
|
111
|
+
return registries[category].delete(type);
|
|
112
|
+
}
|
|
113
|
+
export function getHandler(category, type) {
|
|
114
|
+
const handler = registries[category].get(type);
|
|
115
|
+
if (!handler) {
|
|
116
|
+
throw new Error(`${category} type "${type}" not registered.\n` +
|
|
117
|
+
`Install the plugin: bun add @tagma/${category.replace(/s$/, '')}-${type}`);
|
|
118
|
+
}
|
|
119
|
+
return handler;
|
|
120
|
+
}
|
|
121
|
+
export function hasHandler(category, type) {
|
|
122
|
+
return registries[category].has(type);
|
|
123
|
+
}
|
|
124
|
+
// Plugin name must be a scoped npm package or a tagma-prefixed package.
|
|
125
|
+
// Reject absolute/relative paths and suspicious patterns to prevent
|
|
126
|
+
// arbitrary code execution via crafted YAML configs.
|
|
127
|
+
export const PLUGIN_NAME_RE = /^(@[a-z0-9-]+\/[a-z0-9._-]+|tagma-plugin-[a-z0-9._-]+)$/;
|
|
128
|
+
export function isValidPluginName(name) {
|
|
129
|
+
return typeof name === 'string' && PLUGIN_NAME_RE.test(name);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Parse and validate the `tagmaPlugin` field of a `package.json` blob.
|
|
133
|
+
*
|
|
134
|
+
* Returns the strongly-typed manifest if the field is present and
|
|
135
|
+
* well-formed (`category` is one of the four known categories and `type`
|
|
136
|
+
* is a non-empty string). Returns `null` if the field is absent — that
|
|
137
|
+
* is the host's signal that the package is a library, not a plugin.
|
|
138
|
+
*
|
|
139
|
+
* Throws if the field is present but malformed: that's a packaging bug
|
|
140
|
+
* the plugin author should hear about loudly, not a silent skip.
|
|
141
|
+
*
|
|
142
|
+
* Hosts use this during auto-discovery to decide whether to load a
|
|
143
|
+
* package as a plugin without having to dynamically `import()` it.
|
|
144
|
+
*/
|
|
145
|
+
export function readPluginManifest(pkgJson) {
|
|
146
|
+
if (!pkgJson || typeof pkgJson !== 'object')
|
|
147
|
+
return null;
|
|
148
|
+
const raw = pkgJson.tagmaPlugin;
|
|
149
|
+
if (raw === undefined)
|
|
150
|
+
return null;
|
|
151
|
+
if (!raw || typeof raw !== 'object') {
|
|
152
|
+
throw new Error('tagmaPlugin field must be an object with { category, type }');
|
|
153
|
+
}
|
|
154
|
+
const m = raw;
|
|
155
|
+
const category = m.category;
|
|
156
|
+
const type = m.type;
|
|
157
|
+
if (typeof category !== 'string' || !VALID_CATEGORIES.has(category)) {
|
|
158
|
+
throw new Error(`tagmaPlugin.category must be one of ${[...VALID_CATEGORIES].join(', ')}, got ${JSON.stringify(category)}`);
|
|
159
|
+
}
|
|
160
|
+
if (typeof type !== 'string' || type.length === 0) {
|
|
161
|
+
throw new Error(`tagmaPlugin.type must be a non-empty string, got ${JSON.stringify(type)}`);
|
|
162
|
+
}
|
|
163
|
+
return { category: category, type };
|
|
164
|
+
}
|
|
165
|
+
export async function loadPlugins(pluginNames) {
|
|
166
|
+
for (const name of pluginNames) {
|
|
167
|
+
if (!isValidPluginName(name)) {
|
|
168
|
+
throw new Error(`Plugin "${name}" rejected: plugin names must be scoped npm packages ` +
|
|
169
|
+
`(e.g. @tagma/trigger-xyz) or tagma-plugin-* packages. ` +
|
|
170
|
+
`Relative/absolute paths are not allowed.`);
|
|
171
|
+
}
|
|
172
|
+
const mod = await import(name);
|
|
173
|
+
if (!mod.pluginCategory || !mod.pluginType || !mod.default) {
|
|
174
|
+
throw new Error(`Plugin "${name}" must export pluginCategory, pluginType, and default`);
|
|
175
|
+
}
|
|
176
|
+
registerPlugin(mod.pluginCategory, mod.pluginType, mod.default);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
export function listRegistered(category) {
|
|
180
|
+
return [...registries[category].keys()];
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/runner.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { SpawnSpec, DriverPlugin, TaskResult } from './types';
|
|
2
|
+
export interface RunOptions {
|
|
3
|
+
readonly timeoutMs?: number;
|
|
4
|
+
readonly signal?: AbortSignal;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* R2: Validate a SpawnSpec returned by a third-party driver. Returns null on
|
|
8
|
+
* success or a human-readable error message describing the first violation.
|
|
9
|
+
*
|
|
10
|
+
* Catching this here is critical: an undetected bad spec ends up calling
|
|
11
|
+
* Bun.spawn with garbage and the resulting TypeError leaks into engine
|
|
12
|
+
* processTask's catch block as "Cannot read properties of undefined". By
|
|
13
|
+
* validating here we surface a clear "Driver X returned invalid args" message
|
|
14
|
+
* instead, and short-circuit before holding any process resources.
|
|
15
|
+
*/
|
|
16
|
+
export declare function validateSpawnSpec(spec: unknown, driverName: string): string | null;
|
|
17
|
+
export declare function runSpawn(spec: SpawnSpec, driver: DriverPlugin | null, opts?: RunOptions): Promise<TaskResult>;
|
|
18
|
+
export declare function runCommand(command: string, cwd: string, opts?: RunOptions): Promise<TaskResult>;
|
|
19
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAc,MAAM,SAAS,CAAC;AA+B/E,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAsFD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoClF;AAED,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,YAAY,GAAG,IAAI,EAC3B,IAAI,GAAE,UAAe,GACpB,OAAO,CAAC,UAAU,CAAC,CAmNrB;AAED,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,UAAe,GACpB,OAAO,CAAC,UAAU,CAAC,CAMrB"}
|