@db-lyon/flowkit 0.13.0 → 0.14.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/README.md +387 -386
- package/dist/.tsbuildinfo +1 -1
- package/dist/guard/index.d.ts +7 -0
- package/dist/guard/index.d.ts.map +1 -0
- package/dist/guard/index.js +5 -0
- package/dist/guard/index.js.map +1 -0
- package/dist/guard/pipeline.d.ts +22 -0
- package/dist/guard/pipeline.d.ts.map +1 -0
- package/dist/guard/pipeline.js +45 -0
- package/dist/guard/pipeline.js.map +1 -0
- package/dist/guard/registry.d.ts +20 -0
- package/dist/guard/registry.d.ts.map +1 -0
- package/dist/guard/registry.js +33 -0
- package/dist/guard/registry.js.map +1 -0
- package/dist/guard/task-guards.d.ts +89 -0
- package/dist/guard/task-guards.d.ts.map +1 -0
- package/dist/guard/task-guards.js +83 -0
- package/dist/guard/task-guards.js.map +1 -0
- package/dist/guard/types.d.ts +49 -0
- package/dist/guard/types.d.ts.map +1 -0
- package/dist/guard/types.js +38 -0
- package/dist/guard/types.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/docs/ai-agents.md +368 -368
- package/docs/api-reference.md +568 -458
- package/docs/configuration.md +347 -347
- package/docs/custom-tasks.md +258 -258
- package/docs/guards.md +133 -0
- package/package.json +54 -53
- package/dist/flow/references.d.ts +0 -39
- package/dist/flow/references.d.ts.map +0 -1
- package/dist/flow/references.js +0 -102
- package/dist/flow/references.js.map +0 -1
package/dist/.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/index.ts","../src/logger.ts","../src/references.ts","../src/config/deep-merge.ts","../src/config/index.ts","../src/config/loader.ts","../src/config/schema.ts","../src/dag/index.ts","../src/dag/resolver.ts","../src/flow/index.ts","../src/flow/runner.ts","../src/task/agent-prompt-task.ts","../src/task/agent-task.ts","../src/task/base-task.ts","../src/task/concurrency.ts","../src/task/index.ts","../src/task/json-schema.ts","../src/task/llm-provider.ts","../src/task/llm-runner.ts","../src/task/redact.ts","../src/task/registry.ts","../src/task/shell-task.ts","../src/task/shell-termination.ts","../src/task/task-resolution.ts","../src/task/token-ledger.ts"],"version":"5.9.3"}
|
|
1
|
+
{"root":["../src/index.ts","../src/logger.ts","../src/references.ts","../src/config/deep-merge.ts","../src/config/index.ts","../src/config/loader.ts","../src/config/schema.ts","../src/dag/index.ts","../src/dag/resolver.ts","../src/flow/index.ts","../src/flow/runner.ts","../src/guard/index.ts","../src/guard/pipeline.ts","../src/guard/registry.ts","../src/guard/task-guards.ts","../src/guard/types.ts","../src/task/agent-prompt-task.ts","../src/task/agent-task.ts","../src/task/base-task.ts","../src/task/concurrency.ts","../src/task/index.ts","../src/task/json-schema.ts","../src/task/llm-provider.ts","../src/task/llm-runner.ts","../src/task/redact.ts","../src/task/registry.ts","../src/task/shell-task.ts","../src/task/shell-termination.ts","../src/task/task-resolution.ts","../src/task/token-ledger.ts"],"version":"5.9.3"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { GuardRegistry } from './registry.js';
|
|
2
|
+
export { runGuarded } from './pipeline.js';
|
|
3
|
+
export { discoverTaskGuards } from './task-guards.js';
|
|
4
|
+
export type { DiscoverTaskGuardsOptions, GuardScope, GuardTaskFailure, } from './task-guards.js';
|
|
5
|
+
export { guardContextBase, lazy } from './types.js';
|
|
6
|
+
export type { Guard, GuardContext } from './types.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/guard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,YAAY,EACV,yBAAyB,EACzB,UAAU,EACV,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACpD,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/guard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAMtD,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { GuardRegistry } from './registry.js';
|
|
2
|
+
import type { GuardContext } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Run one host operation through a guard pipeline.
|
|
5
|
+
*
|
|
6
|
+
* Applicability resolves once, up front, so `before` and `after` see the same
|
|
7
|
+
* set of guards even if a guard's own side effects would change what
|
|
8
|
+
* `appliesTo` answers (a source-control guard that checks a file out makes it
|
|
9
|
+
* writable, and must still get its `after` half).
|
|
10
|
+
*
|
|
11
|
+
* `before` runs in registration order and any throw denies the operation:
|
|
12
|
+
* `invoke` never happens and the error propagates unchanged, so the host's own
|
|
13
|
+
* error type survives. `after` runs in reverse order, innermost guard first,
|
|
14
|
+
* so a guard's two halves nest rather than interleave. An `after` hook that
|
|
15
|
+
* returns a value replaces the result for every remaining hook and the caller;
|
|
16
|
+
* returning nothing leaves it alone.
|
|
17
|
+
*
|
|
18
|
+
* With an empty registry this is exactly `invoke()`, so it is always safe to
|
|
19
|
+
* install on a seam before any guard exists.
|
|
20
|
+
*/
|
|
21
|
+
export declare function runGuarded<Ctx extends GuardContext, TResult>(ctx: Ctx, registry: GuardRegistry<Ctx, TResult>, invoke: () => Promise<TResult>): Promise<TResult>;
|
|
22
|
+
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/guard/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAS,YAAY,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,UAAU,CAAC,GAAG,SAAS,YAAY,EAAE,OAAO,EAChE,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,EACrC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAC7B,OAAO,CAAC,OAAO,CAAC,CAyBlB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run one host operation through a guard pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Applicability resolves once, up front, so `before` and `after` see the same
|
|
5
|
+
* set of guards even if a guard's own side effects would change what
|
|
6
|
+
* `appliesTo` answers (a source-control guard that checks a file out makes it
|
|
7
|
+
* writable, and must still get its `after` half).
|
|
8
|
+
*
|
|
9
|
+
* `before` runs in registration order and any throw denies the operation:
|
|
10
|
+
* `invoke` never happens and the error propagates unchanged, so the host's own
|
|
11
|
+
* error type survives. `after` runs in reverse order, innermost guard first,
|
|
12
|
+
* so a guard's two halves nest rather than interleave. An `after` hook that
|
|
13
|
+
* returns a value replaces the result for every remaining hook and the caller;
|
|
14
|
+
* returning nothing leaves it alone.
|
|
15
|
+
*
|
|
16
|
+
* With an empty registry this is exactly `invoke()`, so it is always safe to
|
|
17
|
+
* install on a seam before any guard exists.
|
|
18
|
+
*/
|
|
19
|
+
export async function runGuarded(ctx, registry, invoke) {
|
|
20
|
+
if (registry.size === 0)
|
|
21
|
+
return invoke();
|
|
22
|
+
const applicable = [];
|
|
23
|
+
for (const g of registry.list()) {
|
|
24
|
+
if (!g.appliesTo || (await g.appliesTo(ctx)))
|
|
25
|
+
applicable.push(g);
|
|
26
|
+
}
|
|
27
|
+
for (const g of applicable) {
|
|
28
|
+
if (g.before)
|
|
29
|
+
await g.before(ctx);
|
|
30
|
+
}
|
|
31
|
+
// `await` widens a generic TResult to Awaited<TResult>, which an `after`
|
|
32
|
+
// hook's replacement value is not assignable to. The invoke contract already
|
|
33
|
+
// fixes the type, so pin it back.
|
|
34
|
+
let result = (await invoke());
|
|
35
|
+
for (let i = applicable.length - 1; i >= 0; i--) {
|
|
36
|
+
const after = applicable[i].after;
|
|
37
|
+
if (!after)
|
|
38
|
+
continue;
|
|
39
|
+
const replaced = await after(ctx, result);
|
|
40
|
+
if (replaced !== undefined)
|
|
41
|
+
result = replaced;
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/guard/pipeline.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAQ,EACR,QAAqC,EACrC,MAA8B;IAE9B,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,MAAM,EAAE,CAAC;IAEzC,MAAM,UAAU,GAA0B,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QAChC,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,MAAM;YAAE,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,yEAAyE;IACzE,6EAA6E;IAC7E,kCAAkC;IAClC,IAAI,MAAM,GAAG,CAAC,MAAM,MAAM,EAAE,CAAY,CAAC;IAEzC,KAAK,IAAI,CAAC,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC1C,IAAI,QAAQ,KAAK,SAAS;YAAE,MAAM,GAAG,QAAmB,CAAC;IAC3D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Guard, GuardContext } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* An ordered set of guards.
|
|
4
|
+
*
|
|
5
|
+
* Order is recomputed on every registration rather than at read time, so the
|
|
6
|
+
* sequence a caller observes never depends on when it asked. Ties on `order`
|
|
7
|
+
* break by name, so a registry built from an unordered source (a directory
|
|
8
|
+
* listing, a task registry) still runs its guards deterministically.
|
|
9
|
+
*/
|
|
10
|
+
export declare class GuardRegistry<Ctx extends GuardContext = GuardContext, TResult = unknown> {
|
|
11
|
+
private guards;
|
|
12
|
+
register(guard: Guard<Ctx, TResult>): this;
|
|
13
|
+
/** Register several at once, in whatever order they arrive. */
|
|
14
|
+
registerAll(guards: Iterable<Guard<Ctx, TResult>>): this;
|
|
15
|
+
list(): readonly Guard<Ctx, TResult>[];
|
|
16
|
+
/** Registered guard names, in run order. For startup logging. */
|
|
17
|
+
names(): string[];
|
|
18
|
+
get size(): number;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/guard/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;;;;GAOG;AACH,qBAAa,aAAa,CAAC,GAAG,SAAS,YAAY,GAAG,YAAY,EAAE,OAAO,GAAG,OAAO;IACnF,OAAO,CAAC,MAAM,CAA6B;IAE3C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI;IAM1C,+DAA+D;IAC/D,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI;IAKxD,IAAI,IAAI,SAAS,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE;IAItC,iEAAiE;IACjE,KAAK,IAAI,MAAM,EAAE;IAIjB,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An ordered set of guards.
|
|
3
|
+
*
|
|
4
|
+
* Order is recomputed on every registration rather than at read time, so the
|
|
5
|
+
* sequence a caller observes never depends on when it asked. Ties on `order`
|
|
6
|
+
* break by name, so a registry built from an unordered source (a directory
|
|
7
|
+
* listing, a task registry) still runs its guards deterministically.
|
|
8
|
+
*/
|
|
9
|
+
export class GuardRegistry {
|
|
10
|
+
guards = [];
|
|
11
|
+
register(guard) {
|
|
12
|
+
this.guards.push(guard);
|
|
13
|
+
this.guards.sort((a, b) => (a.order ?? 0) - (b.order ?? 0) || a.name.localeCompare(b.name));
|
|
14
|
+
return this;
|
|
15
|
+
}
|
|
16
|
+
/** Register several at once, in whatever order they arrive. */
|
|
17
|
+
registerAll(guards) {
|
|
18
|
+
for (const g of guards)
|
|
19
|
+
this.register(g);
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
list() {
|
|
23
|
+
return this.guards;
|
|
24
|
+
}
|
|
25
|
+
/** Registered guard names, in run order. For startup logging. */
|
|
26
|
+
names() {
|
|
27
|
+
return this.guards.map((g) => g.name);
|
|
28
|
+
}
|
|
29
|
+
get size() {
|
|
30
|
+
return this.guards.length;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/guard/registry.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,OAAO,aAAa;IAChB,MAAM,GAA0B,EAAE,CAAC;IAE3C,QAAQ,CAAC,KAA0B;QACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5F,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+DAA+D;IAC/D,WAAW,CAAC,MAAqC;QAC/C,KAAK,MAAM,CAAC,IAAI,MAAM;YAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,iEAAiE;IACjE,KAAK;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,CAAC;CACF"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task-backed guards: turn registered tasks into pipeline guards by name.
|
|
3
|
+
*
|
|
4
|
+
* A host that already loads tasks from config or from plugins gets guards for
|
|
5
|
+
* free. Declaring a task named `guard.<name>.<phase>` registers it as a guard;
|
|
6
|
+
* no separate activation concept, manifest key, or loader is needed, because
|
|
7
|
+
* the task registry is already the list of everything the host was given.
|
|
8
|
+
*
|
|
9
|
+
* `<phase>` is `before` or `after`, optionally suffixed with a scope the host
|
|
10
|
+
* declared:
|
|
11
|
+
*
|
|
12
|
+
* guard.audit.after runs after every operation
|
|
13
|
+
* guard.p4.beforeWrite runs before an operation the `write` scope claims
|
|
14
|
+
*
|
|
15
|
+
* A `before` guard denies the operation by returning `success: false` or by
|
|
16
|
+
* throwing. An `after` guard observes the result: it cannot replace it (a task
|
|
17
|
+
* returns a `TaskResult`, not the host's result type) and a failure is reported
|
|
18
|
+
* through `onAfterFailure` rather than failing an operation that already
|
|
19
|
+
* happened.
|
|
20
|
+
*/
|
|
21
|
+
import type { TaskContext } from '../task/base-task.js';
|
|
22
|
+
import type { TaskRegistry } from '../task/registry.js';
|
|
23
|
+
import type { Logger } from '../logger.js';
|
|
24
|
+
import type { Guard, GuardContext } from './types.js';
|
|
25
|
+
/** Predicate deciding whether a scoped guard participates in an operation. */
|
|
26
|
+
export type GuardScope<Ctx extends GuardContext> = (ctx: Ctx) => boolean | Promise<boolean>;
|
|
27
|
+
/** Passed to the host's error factories so it can shape its own message. */
|
|
28
|
+
export interface GuardTaskFailure<Ctx extends GuardContext> {
|
|
29
|
+
/** The guard's bare name: `p4` for `guard.p4.beforeWrite`. */
|
|
30
|
+
readonly guard: string;
|
|
31
|
+
/** The full phase as declared: `beforeWrite`. */
|
|
32
|
+
readonly phase: string;
|
|
33
|
+
/** The task name the guard was discovered from. */
|
|
34
|
+
readonly taskName: string;
|
|
35
|
+
readonly ctx: Ctx;
|
|
36
|
+
/** Why it failed: the task's own error, or the exception it threw. */
|
|
37
|
+
readonly reason: string;
|
|
38
|
+
/** Present when the guard task threw rather than returning `success: false`. */
|
|
39
|
+
readonly cause?: Error;
|
|
40
|
+
}
|
|
41
|
+
export interface DiscoverTaskGuardsOptions<Ctx extends GuardContext, TResult = unknown> {
|
|
42
|
+
/**
|
|
43
|
+
* Named scope predicates. A task named `guard.x.beforeWrite` resolves against
|
|
44
|
+
* the `write` key (the suffix's first letter is lowercased). An unknown scope
|
|
45
|
+
* is an error at discovery time, not a guard that silently runs on
|
|
46
|
+
* everything.
|
|
47
|
+
*/
|
|
48
|
+
scopes?: Record<string, GuardScope<Ctx>>;
|
|
49
|
+
/**
|
|
50
|
+
* Build the task context for one guard invocation. Called per operation, so
|
|
51
|
+
* the host can bind the guard to whatever the operation belongs to rather
|
|
52
|
+
* than to a single ambient target.
|
|
53
|
+
*/
|
|
54
|
+
contextFor(ctx: Ctx): TaskContext;
|
|
55
|
+
/**
|
|
56
|
+
* Build the options handed to the guard task. `result` is present only for
|
|
57
|
+
* `after` guards.
|
|
58
|
+
*/
|
|
59
|
+
optionsFor(ctx: Ctx, result?: TResult): Record<string, unknown>;
|
|
60
|
+
/**
|
|
61
|
+
* Error thrown when a `before` guard denies.
|
|
62
|
+
*
|
|
63
|
+
* This covers a guard task that throws as well as one that returns
|
|
64
|
+
* `success: false`, because `BaseTask.run` turns an exception into a failed
|
|
65
|
+
* result. A guard that crashes therefore denies the operation rather than
|
|
66
|
+
* waving it through, which is the safe direction for the thing standing
|
|
67
|
+
* between a caller and a mutation. Default: a plain `Error`.
|
|
68
|
+
*/
|
|
69
|
+
onDeny?(info: GuardTaskFailure<Ctx>): Error;
|
|
70
|
+
/**
|
|
71
|
+
* Error thrown when the guard task cannot be constructed at all: an
|
|
72
|
+
* unresolvable class path, a module that fails to import. Distinct from a
|
|
73
|
+
* denial, because nothing about the operation was actually evaluated.
|
|
74
|
+
* Default: a plain `Error`.
|
|
75
|
+
*/
|
|
76
|
+
onError?(info: GuardTaskFailure<Ctx>): Error;
|
|
77
|
+
/** Called when an `after` guard reports failure. Default: log at debug. */
|
|
78
|
+
onAfterFailure?(info: GuardTaskFailure<Ctx>): void;
|
|
79
|
+
logger?: Logger;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Build a `Guard` for every `guard.<name>.<phase>` task in `registry`.
|
|
83
|
+
*
|
|
84
|
+
* Throws if a task names a scope the host did not declare, so a typo in a
|
|
85
|
+
* plugin's task name surfaces at startup instead of becoming a guard that runs
|
|
86
|
+
* on every operation.
|
|
87
|
+
*/
|
|
88
|
+
export declare function discoverTaskGuards<Ctx extends GuardContext, TResult = unknown>(registry: TaskRegistry, options: DiscoverTaskGuardsOptions<Ctx, TResult>): Guard<Ctx, TResult>[];
|
|
89
|
+
//# sourceMappingURL=task-guards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-guards.d.ts","sourceRoot":"","sources":["../../src/guard/task-guards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAKtD,8EAA8E;AAC9E,MAAM,MAAM,UAAU,CAAC,GAAG,SAAS,YAAY,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAE5F,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB,CAAC,GAAG,SAAS,YAAY;IACxD,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAClB,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB,CAAC,GAAG,SAAS,YAAY,EAAE,OAAO,GAAG,OAAO;IACpF;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACzC;;;;OAIG;IACH,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,WAAW,CAAC;IAClC;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChE;;;;;;;;OAQG;IACH,MAAM,CAAC,CAAC,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC5C;;;;;OAKG;IACH,OAAO,CAAC,CAAC,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC7C,2EAA2E;IAC3E,cAAc,CAAC,CAAC,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAOD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,SAAS,YAAY,EAAE,OAAO,GAAG,OAAO,EAC5E,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,yBAAyB,CAAC,GAAG,EAAE,OAAO,CAAC,GAC/C,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CA4EvB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { noopLogger } from '../logger.js';
|
|
2
|
+
/** `guard.<name>.<before|after><Scope?>` */
|
|
3
|
+
const GUARD_TASK_RE = /^guard\.(.+)\.(before|after)([A-Za-z][A-Za-z0-9]*)?$/;
|
|
4
|
+
/** Turn `beforeWrite` into the `write` scope key. */
|
|
5
|
+
function scopeKey(suffix) {
|
|
6
|
+
return suffix.charAt(0).toLowerCase() + suffix.slice(1);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Build a `Guard` for every `guard.<name>.<phase>` task in `registry`.
|
|
10
|
+
*
|
|
11
|
+
* Throws if a task names a scope the host did not declare, so a typo in a
|
|
12
|
+
* plugin's task name surfaces at startup instead of becoming a guard that runs
|
|
13
|
+
* on every operation.
|
|
14
|
+
*/
|
|
15
|
+
export function discoverTaskGuards(registry, options) {
|
|
16
|
+
const log = options.logger ?? noopLogger;
|
|
17
|
+
const scopes = options.scopes ?? {};
|
|
18
|
+
const guards = [];
|
|
19
|
+
for (const taskName of registry.listRegistered()) {
|
|
20
|
+
const match = GUARD_TASK_RE.exec(taskName);
|
|
21
|
+
if (!match)
|
|
22
|
+
continue;
|
|
23
|
+
const [, name, phase, suffix] = match;
|
|
24
|
+
const fullPhase = `${phase}${suffix ?? ''}`;
|
|
25
|
+
let appliesTo;
|
|
26
|
+
if (suffix) {
|
|
27
|
+
const key = scopeKey(suffix);
|
|
28
|
+
appliesTo = scopes[key];
|
|
29
|
+
if (!appliesTo) {
|
|
30
|
+
const known = Object.keys(scopes);
|
|
31
|
+
throw new Error(`Task '${taskName}' declares guard scope '${key}', which is not registered. ` +
|
|
32
|
+
(known.length ? `Known scopes: ${known.join(', ')}.` : 'No scopes are registered.'));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const fail = (ctx, reason, cause) => ({
|
|
36
|
+
guard: name,
|
|
37
|
+
phase: fullPhase,
|
|
38
|
+
taskName,
|
|
39
|
+
ctx,
|
|
40
|
+
reason,
|
|
41
|
+
cause,
|
|
42
|
+
});
|
|
43
|
+
const runTask = async (ctx, result) => {
|
|
44
|
+
try {
|
|
45
|
+
const task = await registry.create(taskName, options.contextFor(ctx), options.optionsFor(ctx, result));
|
|
46
|
+
return await task.run();
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
const cause = e instanceof Error ? e : new Error(String(e));
|
|
50
|
+
const info = fail(ctx, cause.message, cause);
|
|
51
|
+
throw options.onError?.(info) ?? new Error(`guard '${name}' errored: ${cause.message}`);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const guard = { name: `${name}.${fullPhase}`, appliesTo };
|
|
55
|
+
if (phase === 'before') {
|
|
56
|
+
guard.before = async (ctx) => {
|
|
57
|
+
const r = await runTask(ctx);
|
|
58
|
+
if (!r.success) {
|
|
59
|
+
const reason = r.error?.message ?? `denied by guard '${name}'`;
|
|
60
|
+
const info = fail(ctx, reason, r.error);
|
|
61
|
+
throw options.onDeny?.(info) ?? new Error(`blocked by guard '${name}': ${reason}`);
|
|
62
|
+
}
|
|
63
|
+
log.debug(`guard '${name}' allowed the operation`);
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
guard.after = async (ctx, result) => {
|
|
68
|
+
const r = await runTask(ctx, result);
|
|
69
|
+
if (r.success)
|
|
70
|
+
return;
|
|
71
|
+
const reason = r.error?.message ?? 'unknown failure';
|
|
72
|
+
const info = fail(ctx, reason, r.error);
|
|
73
|
+
if (options.onAfterFailure)
|
|
74
|
+
options.onAfterFailure(info);
|
|
75
|
+
else
|
|
76
|
+
log.debug(`after-guard '${name}' reported failure: ${reason}`);
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
guards.push(guard);
|
|
80
|
+
}
|
|
81
|
+
return guards;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=task-guards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-guards.js","sourceRoot":"","sources":["../../src/guard/task-guards.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guards - a before/after pipeline around an arbitrary host operation.
|
|
3
|
+
*
|
|
4
|
+
* A guard sits on a seam the host already has (an RPC call, a write, a command
|
|
5
|
+
* dispatch) and may veto it, act on it, or observe its result. The pipeline
|
|
6
|
+
* knows nothing about what any guard does: access policy, source control,
|
|
7
|
+
* audit, rate limiting and approval gating are all just guards.
|
|
8
|
+
*
|
|
9
|
+
* Guards are generic over the host's per-call context. Flowkit requires only a
|
|
10
|
+
* `meta` scratch map; everything else (method name, params, connection handles,
|
|
11
|
+
* lazily computed enrichment) belongs to the host's own context type.
|
|
12
|
+
*
|
|
13
|
+
* These are distinct from `FlowRunnerHooks`, which fire around flow steps.
|
|
14
|
+
* A guard wraps one host operation and can deny it; a hook observes a step.
|
|
15
|
+
*/
|
|
16
|
+
/** The minimum a host context must provide. Extend it with whatever the host needs. */
|
|
17
|
+
export interface GuardContext {
|
|
18
|
+
/** Scratch space shared across guards for the life of one operation. */
|
|
19
|
+
readonly meta: Map<string, unknown>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A guard on the pipeline. Every hook is optional; a guard with neither
|
|
23
|
+
* `before` nor `after` is inert but still legal (useful while wiring one up).
|
|
24
|
+
*/
|
|
25
|
+
export interface Guard<Ctx extends GuardContext = GuardContext, TResult = unknown> {
|
|
26
|
+
/** Stable identifier, used for logging and to break ordering ties. */
|
|
27
|
+
readonly name: string;
|
|
28
|
+
/** Lower runs first in `before` and last in `after`. Default 0. */
|
|
29
|
+
readonly order?: number;
|
|
30
|
+
/** Whether this guard participates in a given operation. Default: always. */
|
|
31
|
+
appliesTo?(ctx: Ctx): boolean | Promise<boolean>;
|
|
32
|
+
/** Runs before the operation. Throw to DENY it; side effects are allowed. */
|
|
33
|
+
before?(ctx: Ctx): Promise<void>;
|
|
34
|
+
/** Runs after a successful operation. Return a value to replace the result. */
|
|
35
|
+
after?(ctx: Ctx, result: TResult): Promise<TResult | void>;
|
|
36
|
+
}
|
|
37
|
+
/** Create the base context fields. Spread the result into the host's own context object. */
|
|
38
|
+
export declare function guardContextBase(): GuardContext;
|
|
39
|
+
/**
|
|
40
|
+
* Wrap a pure computation so it runs at most once per operation, caching into
|
|
41
|
+
* the context's `meta` map under `key`.
|
|
42
|
+
*
|
|
43
|
+
* Guard contexts commonly carry enrichment that is expensive to compute and
|
|
44
|
+
* that most guards never look at (which files a call touches, who the caller
|
|
45
|
+
* is). Deferring it means a guard that ignores the enrichment pays nothing,
|
|
46
|
+
* and a pipeline of guards that all consult it pays once.
|
|
47
|
+
*/
|
|
48
|
+
export declare function lazy<T>(ctx: GuardContext, key: string, compute: () => T): () => T;
|
|
49
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/guard/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,uFAAuF;AACvF,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,WAAW,KAAK,CAAC,GAAG,SAAS,YAAY,GAAG,YAAY,EAAE,OAAO,GAAG,OAAO;IAC/E,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,SAAS,CAAC,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,6EAA6E;IAC7E,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,+EAA+E;IAC/E,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CAC5D;AAED,4FAA4F;AAC5F,wBAAgB,gBAAgB,IAAI,YAAY,CAE/C;AAED;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,CAOjF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guards - a before/after pipeline around an arbitrary host operation.
|
|
3
|
+
*
|
|
4
|
+
* A guard sits on a seam the host already has (an RPC call, a write, a command
|
|
5
|
+
* dispatch) and may veto it, act on it, or observe its result. The pipeline
|
|
6
|
+
* knows nothing about what any guard does: access policy, source control,
|
|
7
|
+
* audit, rate limiting and approval gating are all just guards.
|
|
8
|
+
*
|
|
9
|
+
* Guards are generic over the host's per-call context. Flowkit requires only a
|
|
10
|
+
* `meta` scratch map; everything else (method name, params, connection handles,
|
|
11
|
+
* lazily computed enrichment) belongs to the host's own context type.
|
|
12
|
+
*
|
|
13
|
+
* These are distinct from `FlowRunnerHooks`, which fire around flow steps.
|
|
14
|
+
* A guard wraps one host operation and can deny it; a hook observes a step.
|
|
15
|
+
*/
|
|
16
|
+
/** Create the base context fields. Spread the result into the host's own context object. */
|
|
17
|
+
export function guardContextBase() {
|
|
18
|
+
return { meta: new Map() };
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Wrap a pure computation so it runs at most once per operation, caching into
|
|
22
|
+
* the context's `meta` map under `key`.
|
|
23
|
+
*
|
|
24
|
+
* Guard contexts commonly carry enrichment that is expensive to compute and
|
|
25
|
+
* that most guards never look at (which files a call touches, who the caller
|
|
26
|
+
* is). Deferring it means a guard that ignores the enrichment pays nothing,
|
|
27
|
+
* and a pipeline of guards that all consult it pays once.
|
|
28
|
+
*/
|
|
29
|
+
export function lazy(ctx, key, compute) {
|
|
30
|
+
return () => {
|
|
31
|
+
if (ctx.meta.has(key))
|
|
32
|
+
return ctx.meta.get(key);
|
|
33
|
+
const value = compute();
|
|
34
|
+
ctx.meta.set(key, value);
|
|
35
|
+
return value;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/guard/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAyBH,4FAA4F;AAC5F,MAAM,UAAU,gBAAgB;IAC9B,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,EAAmB,EAAE,CAAC;AAC9C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,IAAI,CAAI,GAAiB,EAAE,GAAW,EAAE,OAAgB;IACtE,OAAO,GAAG,EAAE;QACV,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAM,CAAC;QACrD,MAAM,KAAK,GAAG,OAAO,EAAE,CAAC;QACxB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -24,6 +24,12 @@ export { redact, truncate, preview } from './task/redact.js';
|
|
|
24
24
|
export type { LLMProvider, LLMCompletionRequest, LLMCompletionResponse, LLMMessage, LLMRole, LLMToolCall, LLMToolDefinition, LLMToolChoice, LLMToolHandler, } from './task/llm-provider.js';
|
|
25
25
|
export { FlowRunner } from './flow/runner.js';
|
|
26
26
|
export type { FlowRunOptions, FlowStepResult, FlowRunResult, FlowRunnerHooks, FlowRunnerConfig, PlanStep, HookPhase, HookError, RollbackResult, } from './flow/runner.js';
|
|
27
|
+
export { GuardRegistry } from './guard/registry.js';
|
|
28
|
+
export { runGuarded } from './guard/pipeline.js';
|
|
29
|
+
export { discoverTaskGuards } from './guard/task-guards.js';
|
|
30
|
+
export type { DiscoverTaskGuardsOptions, GuardScope, GuardTaskFailure, } from './guard/task-guards.js';
|
|
31
|
+
export { guardContextBase, lazy } from './guard/types.js';
|
|
32
|
+
export type { Guard, GuardContext } from './guard/types.js';
|
|
27
33
|
export { resolveReferences } from './references.js';
|
|
28
34
|
export type { ReferenceableStep, ReferenceContext } from './references.js';
|
|
29
35
|
export { topologicalSort, CircularDependencyError, MissingDependencyError, } from './dag/resolver.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,WAAW,EACX,cAAc,EACd,QAAQ,EACR,cAAc,EACd,SAAS,EACT,WAAW,EACX,eAAe,EACf,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC7E,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAG1E,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EACL,aAAa,EACb,cAAc,EACd,eAAe,EACf,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACnE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,GACf,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC7D,YAAY,EACV,WAAW,EACX,oBAAoB,EACpB,qBAAqB,EACrB,UAAU,EACV,OAAO,EACP,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,cAAc,GACf,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EACV,cAAc,EACd,cAAc,EACd,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,SAAS,EACT,SAAS,EACT,cAAc,GACf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAG3E,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAGjD,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,11 @@ export { createLedger, chargeLedger, ledgerExhausted, exhaustedLimit, } from './
|
|
|
15
15
|
export { redact, truncate, preview } from './task/redact.js';
|
|
16
16
|
// Flow
|
|
17
17
|
export { FlowRunner } from './flow/runner.js';
|
|
18
|
+
// Guard — before/after pipeline around a host operation
|
|
19
|
+
export { GuardRegistry } from './guard/registry.js';
|
|
20
|
+
export { runGuarded } from './guard/pipeline.js';
|
|
21
|
+
export { discoverTaskGuards } from './guard/task-guards.js';
|
|
22
|
+
export { guardContextBase, lazy } from './guard/types.js';
|
|
18
23
|
// References — shared by the task and flow layers
|
|
19
24
|
export { resolveReferences } from './references.js';
|
|
20
25
|
// DAG
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,SAAS;AACT,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAW5B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAG7E,OAAO;AACP,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EACL,aAAa,EACb,cAAc,EACd,eAAe,EACf,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,GACf,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAa7D,OAAO;AACP,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAY9C,kDAAkD;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGpD,MAAM;AACN,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,SAAS;AACT,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAW5B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAG7E,OAAO;AACP,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EACL,aAAa,EACb,cAAc,EACd,eAAe,EACf,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,GACf,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAa7D,OAAO;AACP,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAY9C,wDAAwD;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAM5D,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAG1D,kDAAkD;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGpD,MAAM;AACN,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
|