@cad0p/pi-steering 0.1.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/CHANGELOG.md +36 -0
- package/LICENSE +29 -0
- package/README.md +920 -0
- package/dist/__test-helpers__.d.ts +95 -0
- package/dist/__test-helpers__.d.ts.map +1 -0
- package/dist/__test-helpers__.js +174 -0
- package/dist/__test-helpers__.js.map +1 -0
- package/dist/bin/pi-steering.d.ts +9 -0
- package/dist/bin/pi-steering.d.ts.map +1 -0
- package/dist/bin/pi-steering.js +506 -0
- package/dist/bin/pi-steering.js.map +1 -0
- package/dist/compat.d.ts +50 -0
- package/dist/compat.d.ts.map +1 -0
- package/dist/compat.js +180 -0
- package/dist/compat.js.map +1 -0
- package/dist/defaults.d.ts +61 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +106 -0
- package/dist/defaults.js.map +1 -0
- package/dist/define-config.d.ts +235 -0
- package/dist/define-config.d.ts.map +1 -0
- package/dist/define-config.js +118 -0
- package/dist/define-config.js.map +1 -0
- package/dist/define-predicate.d.ts +49 -0
- package/dist/define-predicate.d.ts.map +1 -0
- package/dist/define-predicate.js +35 -0
- package/dist/define-predicate.js.map +1 -0
- package/dist/evaluator-internals/context.d.ts +186 -0
- package/dist/evaluator-internals/context.d.ts.map +1 -0
- package/dist/evaluator-internals/context.js +219 -0
- package/dist/evaluator-internals/context.js.map +1 -0
- package/dist/evaluator-internals/override.d.ts +19 -0
- package/dist/evaluator-internals/override.d.ts.map +1 -0
- package/dist/evaluator-internals/override.js +79 -0
- package/dist/evaluator-internals/override.js.map +1 -0
- package/dist/evaluator-internals/predicates.d.ts +152 -0
- package/dist/evaluator-internals/predicates.d.ts.map +1 -0
- package/dist/evaluator-internals/predicates.js +849 -0
- package/dist/evaluator-internals/predicates.js.map +1 -0
- package/dist/evaluator-internals/speculative-synthesis.d.ts +102 -0
- package/dist/evaluator-internals/speculative-synthesis.d.ts.map +1 -0
- package/dist/evaluator-internals/speculative-synthesis.js +101 -0
- package/dist/evaluator-internals/speculative-synthesis.js.map +1 -0
- package/dist/evaluator.d.ts +101 -0
- package/dist/evaluator.d.ts.map +1 -0
- package/dist/evaluator.js +714 -0
- package/dist/evaluator.js.map +1 -0
- package/dist/helpers/walker-unknown-cwd-reason.d.ts +68 -0
- package/dist/helpers/walker-unknown-cwd-reason.d.ts.map +1 -0
- package/dist/helpers/walker-unknown-cwd-reason.js +73 -0
- package/dist/helpers/walker-unknown-cwd-reason.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/drop-unused-observers.d.ts +43 -0
- package/dist/internal/drop-unused-observers.d.ts.map +1 -0
- package/dist/internal/drop-unused-observers.js +50 -0
- package/dist/internal/drop-unused-observers.js.map +1 -0
- package/dist/internal/finalize-plugin-state.d.ts +22 -0
- package/dist/internal/finalize-plugin-state.d.ts.map +1 -0
- package/dist/internal/finalize-plugin-state.js +14 -0
- package/dist/internal/finalize-plugin-state.js.map +1 -0
- package/dist/internal/merge-observers.d.ts +30 -0
- package/dist/internal/merge-observers.d.ts.map +1 -0
- package/dist/internal/merge-observers.js +27 -0
- package/dist/internal/merge-observers.js.map +1 -0
- package/dist/internal/pattern-utils.d.ts +33 -0
- package/dist/internal/pattern-utils.d.ts.map +1 -0
- package/dist/internal/pattern-utils.js +20 -0
- package/dist/internal/pattern-utils.js.map +1 -0
- package/dist/internal/ref-text.d.ts +11 -0
- package/dist/internal/ref-text.d.ts.map +1 -0
- package/dist/internal/ref-text.js +15 -0
- package/dist/internal/ref-text.js.map +1 -0
- package/dist/internal/session-runtime.d.ts +44 -0
- package/dist/internal/session-runtime.d.ts.map +1 -0
- package/dist/internal/session-runtime.js +143 -0
- package/dist/internal/session-runtime.js.map +1 -0
- package/dist/internal/watch-matcher.d.ts +56 -0
- package/dist/internal/watch-matcher.d.ts.map +1 -0
- package/dist/internal/watch-matcher.js +179 -0
- package/dist/internal/watch-matcher.js.map +1 -0
- package/dist/loader.d.ts +97 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +527 -0
- package/dist/loader.js.map +1 -0
- package/dist/observer-dispatcher.d.ts +69 -0
- package/dist/observer-dispatcher.d.ts.map +1 -0
- package/dist/observer-dispatcher.js +184 -0
- package/dist/observer-dispatcher.js.map +1 -0
- package/dist/plugin-merger.d.ts +175 -0
- package/dist/plugin-merger.d.ts.map +1 -0
- package/dist/plugin-merger.js +450 -0
- package/dist/plugin-merger.js.map +1 -0
- package/dist/plugins/git/branch-tracker.d.ts +85 -0
- package/dist/plugins/git/branch-tracker.d.ts.map +1 -0
- package/dist/plugins/git/branch-tracker.js +181 -0
- package/dist/plugins/git/branch-tracker.js.map +1 -0
- package/dist/plugins/git/cwd-extensions.d.ts +10 -0
- package/dist/plugins/git/cwd-extensions.d.ts.map +1 -0
- package/dist/plugins/git/cwd-extensions.js +155 -0
- package/dist/plugins/git/cwd-extensions.js.map +1 -0
- package/dist/plugins/git/git-ops.d.ts +89 -0
- package/dist/plugins/git/git-ops.d.ts.map +1 -0
- package/dist/plugins/git/git-ops.js +107 -0
- package/dist/plugins/git/git-ops.js.map +1 -0
- package/dist/plugins/git/index.d.ts +225 -0
- package/dist/plugins/git/index.d.ts.map +1 -0
- package/dist/plugins/git/index.js +52 -0
- package/dist/plugins/git/index.js.map +1 -0
- package/dist/plugins/git/predicates.d.ts +312 -0
- package/dist/plugins/git/predicates.d.ts.map +1 -0
- package/dist/plugins/git/predicates.js +580 -0
- package/dist/plugins/git/predicates.js.map +1 -0
- package/dist/plugins/git/rules.d.ts +209 -0
- package/dist/plugins/git/rules.d.ts.map +1 -0
- package/dist/plugins/git/rules.js +267 -0
- package/dist/plugins/git/rules.js.map +1 -0
- package/dist/schema.d.ts +1799 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +4 -0
- package/dist/schema.js.map +1 -0
- package/dist/testing/index.d.ts +621 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +747 -0
- package/dist/testing/index.js.map +1 -0
- package/examples/README.md +83 -0
- package/examples/combined-git-discipline/README.md +52 -0
- package/examples/combined-git-discipline/node_modules/.bin/pi-steering +43 -0
- package/examples/combined-git-discipline/package.json +18 -0
- package/examples/combined-git-discipline/steering.json +27 -0
- package/examples/combined-git-discipline/steering.test.ts +42 -0
- package/examples/combined-git-discipline/steering.ts +64 -0
- package/examples/combined-git-discipline/tsconfig.json +7 -0
- package/examples/draft-prs-only/README.md +42 -0
- package/examples/draft-prs-only/node_modules/.bin/pi-steering +43 -0
- package/examples/draft-prs-only/package.json +18 -0
- package/examples/draft-prs-only/steering.json +12 -0
- package/examples/draft-prs-only/steering.test.ts +48 -0
- package/examples/draft-prs-only/steering.ts +36 -0
- package/examples/draft-prs-only/tsconfig.json +7 -0
- package/examples/dynamic-reason-runtime-cwd/README.md +148 -0
- package/examples/dynamic-reason-runtime-cwd/node_modules/.bin/pi-steering +43 -0
- package/examples/dynamic-reason-runtime-cwd/package.json +18 -0
- package/examples/dynamic-reason-runtime-cwd/steering.test.ts +130 -0
- package/examples/dynamic-reason-runtime-cwd/steering.ts +82 -0
- package/examples/dynamic-reason-runtime-cwd/tsconfig.json +7 -0
- package/examples/force-push-strict/README.md +75 -0
- package/examples/force-push-strict/node_modules/.bin/pi-steering +43 -0
- package/examples/force-push-strict/package.json +18 -0
- package/examples/force-push-strict/steering.json +12 -0
- package/examples/force-push-strict/steering.test.ts +51 -0
- package/examples/force-push-strict/steering.ts +54 -0
- package/examples/force-push-strict/tsconfig.json +7 -0
- package/examples/no-amend/README.md +52 -0
- package/examples/no-amend/node_modules/.bin/pi-steering +43 -0
- package/examples/no-amend/package.json +18 -0
- package/examples/no-amend/steering.cwd-scoped.json +12 -0
- package/examples/no-amend/steering.json +11 -0
- package/examples/no-amend/steering.test.ts +49 -0
- package/examples/no-amend/steering.ts +38 -0
- package/examples/no-amend/tsconfig.json +7 -0
- package/examples/work-item-plugin/README.md +103 -0
- package/examples/work-item-plugin/node_modules/.bin/pi-steering +43 -0
- package/examples/work-item-plugin/package.json +19 -0
- package/examples/work-item-plugin/src/index.test.ts +168 -0
- package/examples/work-item-plugin/src/index.ts +122 -0
- package/examples/work-item-plugin/src/observers/npm-test-tracker.test.ts +95 -0
- package/examples/work-item-plugin/src/observers/npm-test-tracker.ts +88 -0
- package/examples/work-item-plugin/src/observers/retest-required-tracker.test.ts +81 -0
- package/examples/work-item-plugin/src/observers/retest-required-tracker.ts +81 -0
- package/examples/work-item-plugin/src/predicates/work-item-format.test.ts +157 -0
- package/examples/work-item-plugin/src/predicates/work-item-format.ts +99 -0
- package/examples/work-item-plugin/src/rules/commit-description-check.test.ts +107 -0
- package/examples/work-item-plugin/src/rules/commit-description-check.ts +83 -0
- package/examples/work-item-plugin/src/rules/commit-requires-work-item.test.ts +79 -0
- package/examples/work-item-plugin/src/rules/commit-requires-work-item.ts +56 -0
- package/examples/work-item-plugin/src/rules/push-requires-tests.test.ts +245 -0
- package/examples/work-item-plugin/src/rules/push-requires-tests.ts +62 -0
- package/examples/work-item-plugin/tsconfig.json +8 -0
- package/package.json +88 -0
- package/skills/steering-authoring/SKILL.md +102 -0
- package/src/INVARIANTS.md +116 -0
- package/src/__test-helpers__.ts +243 -0
- package/src/bin/pi-steering.test.ts +920 -0
- package/src/bin/pi-steering.ts +584 -0
- package/src/compat.test.ts +431 -0
- package/src/compat.ts +282 -0
- package/src/defaults.test.ts +585 -0
- package/src/defaults.ts +148 -0
- package/src/define-config.test.ts +888 -0
- package/src/define-config.ts +375 -0
- package/src/define-predicate.test.ts +70 -0
- package/src/define-predicate.ts +57 -0
- package/src/evaluator-internals/context.ts +290 -0
- package/src/evaluator-internals/override.test.ts +99 -0
- package/src/evaluator-internals/override.ts +83 -0
- package/src/evaluator-internals/predicates.ts +1037 -0
- package/src/evaluator-internals/speculative-synthesis.test.ts +411 -0
- package/src/evaluator-internals/speculative-synthesis.ts +199 -0
- package/src/evaluator.test.ts +6296 -0
- package/src/evaluator.ts +1106 -0
- package/src/factory-time-load.test.ts +630 -0
- package/src/helpers/walker-unknown-cwd-reason.test.ts +73 -0
- package/src/helpers/walker-unknown-cwd-reason.ts +83 -0
- package/src/index.test.ts +836 -0
- package/src/index.ts +229 -0
- package/src/internal/drop-unused-observers.test.ts +141 -0
- package/src/internal/drop-unused-observers.ts +81 -0
- package/src/internal/finalize-plugin-state.ts +43 -0
- package/src/internal/merge-observers.ts +51 -0
- package/src/internal/pattern-utils.test.ts +52 -0
- package/src/internal/pattern-utils.ts +38 -0
- package/src/internal/ref-text.test.ts +54 -0
- package/src/internal/ref-text.ts +17 -0
- package/src/internal/session-runtime.test.ts +629 -0
- package/src/internal/session-runtime.ts +201 -0
- package/src/internal/watch-matcher.test.ts +326 -0
- package/src/internal/watch-matcher.ts +200 -0
- package/src/jsdoc-propagation.test.ts +277 -0
- package/src/loader.test.ts +1098 -0
- package/src/loader.ts +581 -0
- package/src/not-block-onunknown.test.ts +554 -0
- package/src/observer-dispatcher.test.ts +939 -0
- package/src/observer-dispatcher.ts +290 -0
- package/src/per-predicate-typing.test.ts +361 -0
- package/src/plugin-merger.test.ts +790 -0
- package/src/plugin-merger.ts +598 -0
- package/src/plugins/git/README.md +485 -0
- package/src/plugins/git/branch-tracker.test.ts +281 -0
- package/src/plugins/git/branch-tracker.ts +187 -0
- package/src/plugins/git/cwd-extensions.test.ts +230 -0
- package/src/plugins/git/cwd-extensions.ts +160 -0
- package/src/plugins/git/git-ops.test.ts +397 -0
- package/src/plugins/git/git-ops.ts +173 -0
- package/src/plugins/git/index.ts +253 -0
- package/src/plugins/git/integration.test.ts +705 -0
- package/src/plugins/git/predicates.test.ts +1401 -0
- package/src/plugins/git/predicates.ts +693 -0
- package/src/plugins/git/rules.test.ts +1001 -0
- package/src/plugins/git/rules.ts +307 -0
- package/src/schema.test.ts +259 -0
- package/src/schema.ts +1963 -0
- package/src/testing/index.test.ts +1696 -0
- package/src/testing/index.ts +1472 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Part of pi-steering.
|
|
3
|
+
import { createAppendEntry, createFindEntries, createSessionEntryCache, } from "./evaluator-internals/context.js";
|
|
4
|
+
import { mergeObserversUserFirst } from "./internal/merge-observers.js";
|
|
5
|
+
import { extractRefTextsForBash, matchesWatch, } from "./internal/watch-matcher.js";
|
|
6
|
+
import { validateName } from "./plugin-merger.js";
|
|
7
|
+
// Re-export the shared filter contract so existing consumers that
|
|
8
|
+
// imported `matchesWatch` from this module (most notably the testing
|
|
9
|
+
// harness's `testObserver`) don't need to switch imports. The source
|
|
10
|
+
// of truth lives in `./internal/watch-matcher.ts`; this re-export
|
|
11
|
+
// keeps the public surface stable.
|
|
12
|
+
export { matchesWatch } from "./internal/watch-matcher.js";
|
|
13
|
+
/**
|
|
14
|
+
* Construct an {@link ObserverDispatcher}.
|
|
15
|
+
*
|
|
16
|
+
* Arguments:
|
|
17
|
+
* - `resolved` — merged plugin state from {@link resolvePlugins}.
|
|
18
|
+
* Source of plugin-shipped observers and the
|
|
19
|
+
* registry used by the evaluator at the same
|
|
20
|
+
* level.
|
|
21
|
+
* - `userObservers` — the user's `config.observers` list (already
|
|
22
|
+
* deduped at the loader level in Phase 2). User
|
|
23
|
+
* observers fire BEFORE plugin observers on the
|
|
24
|
+
* same event; within each group, registration
|
|
25
|
+
* order decides.
|
|
26
|
+
* - `host` — narrow surface exposing pi's `exec` +
|
|
27
|
+
* `appendEntry`. Passed straight through to the
|
|
28
|
+
* per-event observer context.
|
|
29
|
+
*/
|
|
30
|
+
export function buildObserverDispatcher(resolved, userObservers, host) {
|
|
31
|
+
// S3 defense-in-depth: validate user-authored observer names so a
|
|
32
|
+
// malformed name surfaces with the same `(user config)` label as
|
|
33
|
+
// production diagnostics. Production routes through
|
|
34
|
+
// `runMergerPipeline`'s `invalid-name` diagnostic; this throw
|
|
35
|
+
// covers direct-caller paths (unit tests, SDK embedders).
|
|
36
|
+
// See ./INVARIANTS.md for the S/E tag glossary.
|
|
37
|
+
for (const o of userObservers) {
|
|
38
|
+
const d = validateName("observer", o.name, "user config");
|
|
39
|
+
if (d !== undefined)
|
|
40
|
+
throw new Error(`[pi-steering] ${d.message}`);
|
|
41
|
+
}
|
|
42
|
+
// Merge user and plugin observers; duplicates of observer.name are
|
|
43
|
+
// deduped here by first-registered (user takes precedence over a
|
|
44
|
+
// plugin observer of the same name — matches the "user overrides
|
|
45
|
+
// plugin by declaring their own" pattern the rule list uses). Shared
|
|
46
|
+
// with the evaluator's speculative-synthesis reverse-index via
|
|
47
|
+
// `mergeObserversUserFirst` so both callers see the same final list.
|
|
48
|
+
const merged = mergeObserversUserFirst(userObservers, resolved.observers);
|
|
49
|
+
return {
|
|
50
|
+
dispatch: (event, ctx, agentLoopIndex) => dispatchEvent(event, ctx, agentLoopIndex, merged, host),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Dispatch
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
async function dispatchEvent(event, ctx, agentLoopIndex, observers, host) {
|
|
57
|
+
// Top-level fail-open wrap. Per-observer throws are already
|
|
58
|
+
// isolated in the inner loop; this outer wrap exists so a throw in
|
|
59
|
+
// the dispatch SCAFFOLDING (e.g. a session-JSONL read blowing up
|
|
60
|
+
// inside `createFindEntries`, or an unexpected shape on the
|
|
61
|
+
// incoming event) is logged rather than propagating back into pi's
|
|
62
|
+
// `tool_result` hook. Observers are best-effort state recorders —
|
|
63
|
+
// a broken engine should not take down the tool_result pipeline.
|
|
64
|
+
try {
|
|
65
|
+
await dispatchEventInner(event, ctx, agentLoopIndex, observers, host);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
console.warn(`[pi-steering] observer dispatcher threw: ${formatError(err)}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function dispatchEventInner(event, ctx, agentLoopIndex, observers, host) {
|
|
72
|
+
// Shared per-event session-entry cache: findEntries + appendEntry
|
|
73
|
+
// share it so an earlier observer's appendEntry invalidates the
|
|
74
|
+
// cached read for that customType, and a later observer's
|
|
75
|
+
// findEntries(customType) sees the fresh write (S2/E1). Without the
|
|
76
|
+
// shared cache, observer A appending "description-read" + observer
|
|
77
|
+
// B reading "description-read" on the same event would see a stale
|
|
78
|
+
// pre-write snapshot.
|
|
79
|
+
const entryCache = createSessionEntryCache();
|
|
80
|
+
const findEntries = createFindEntries(ctx, entryCache);
|
|
81
|
+
// Shared appendEntry: auto-tags writes with `_agentLoopIndex` so
|
|
82
|
+
// `when.happened: { in: "agent_loop" }` can filter by agent-loop
|
|
83
|
+
// scope. Safe to hoist out of the loop: the wrapper is stateless.
|
|
84
|
+
const appendEntry = createAppendEntry(host, agentLoopIndex, entryCache);
|
|
85
|
+
// Hoist the per-event projections out of the loop so N observers
|
|
86
|
+
// each get the identical event shape + exit code without paying N
|
|
87
|
+
// copies of the same work.
|
|
88
|
+
const exitCode = extractExitCode(event);
|
|
89
|
+
const schemaEvent = toSchemaEvent(event, exitCode);
|
|
90
|
+
// Wrapper-aware command-ref cache (ADR §12). Populated lazily on the
|
|
91
|
+
// first observer whose watch filter references `inputMatches.command`
|
|
92
|
+
// against a bash event; reused across subsequent observers on the
|
|
93
|
+
// same event so `sh -c '…'` / `sudo …` are parsed at most once per
|
|
94
|
+
// dispatch regardless of how many observers share the filter shape.
|
|
95
|
+
// `null` encodes "extraction attempted but failed (parse error or
|
|
96
|
+
// non-bash event)" so we don't retry per observer.
|
|
97
|
+
let refTextsCache;
|
|
98
|
+
const getRefTexts = () => {
|
|
99
|
+
if (refTextsCache !== undefined)
|
|
100
|
+
return refTextsCache;
|
|
101
|
+
refTextsCache = extractRefTextsForBash(schemaEvent);
|
|
102
|
+
return refTextsCache;
|
|
103
|
+
};
|
|
104
|
+
for (const observer of observers) {
|
|
105
|
+
if (!matchesWatch(observer.watch, schemaEvent, getRefTexts))
|
|
106
|
+
continue;
|
|
107
|
+
// Each observer gets its own ctx so appendEntry writes attribute
|
|
108
|
+
// cleanly. `exec` is intentionally absent — observers are recording
|
|
109
|
+
// hooks, not shell-out points.
|
|
110
|
+
const observerCtx = {
|
|
111
|
+
cwd: ctx.cwd,
|
|
112
|
+
agentLoopIndex,
|
|
113
|
+
appendEntry,
|
|
114
|
+
findEntries,
|
|
115
|
+
};
|
|
116
|
+
try {
|
|
117
|
+
const result = observer.onResult(schemaEvent, observerCtx);
|
|
118
|
+
if (result instanceof Promise) {
|
|
119
|
+
await result;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
// One observer's bug must not poison the rest. Log with the
|
|
124
|
+
// observer name so the operator can locate + disable it.
|
|
125
|
+
console.warn(`[pi-steering] observer "${observer.name}" threw: ${formatError(err)}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// Schema event projection
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
/**
|
|
133
|
+
* Extract an exit code from a pi tool_result event. Only bash events
|
|
134
|
+
* carry one (via `details.exitCode`). Other tool results lack a
|
|
135
|
+
* meaningful numeric code; we return `undefined` and let the watch
|
|
136
|
+
* filter's `exitCode` check decide.
|
|
137
|
+
*/
|
|
138
|
+
function extractExitCode(event) {
|
|
139
|
+
if (event.toolName !== "bash")
|
|
140
|
+
return undefined;
|
|
141
|
+
const details = event.details;
|
|
142
|
+
if (!details || typeof details.exitCode !== "number")
|
|
143
|
+
return undefined;
|
|
144
|
+
return details.exitCode;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Project pi's concrete `ToolResultEvent` onto the schema's minimal
|
|
148
|
+
* {@link SchemaToolResultEvent}. Observers are typed against the schema
|
|
149
|
+
* shape — they don't depend on pi's internal tool details unions. The
|
|
150
|
+
* fields we fill:
|
|
151
|
+
*
|
|
152
|
+
* - `toolName` + `input` — direct.
|
|
153
|
+
* - `output` — pi's `content` (TextContent/ImageContent
|
|
154
|
+
* array) passed through unchanged. Observer
|
|
155
|
+
* handlers cast to the shape they expect.
|
|
156
|
+
* - `exitCode` — passed in precomputed by the caller
|
|
157
|
+
* (so the extraction runs once per event,
|
|
158
|
+
* not once per matching observer); bash
|
|
159
|
+
* events only, others leave it `undefined`.
|
|
160
|
+
*/
|
|
161
|
+
function toSchemaEvent(event, exitCode) {
|
|
162
|
+
const out = {
|
|
163
|
+
toolName: event.toolName,
|
|
164
|
+
input: event.input,
|
|
165
|
+
output: event.content,
|
|
166
|
+
};
|
|
167
|
+
if (exitCode !== undefined)
|
|
168
|
+
out.exitCode = exitCode;
|
|
169
|
+
return out;
|
|
170
|
+
}
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
// Error formatting
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
function formatError(err) {
|
|
175
|
+
if (err instanceof Error)
|
|
176
|
+
return `${err.message}\n${err.stack ?? ""}`;
|
|
177
|
+
try {
|
|
178
|
+
return JSON.stringify(err);
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
return String(err);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=observer-dispatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer-dispatcher.js","sourceRoot":"","sources":["../src/observer-dispatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin merger — flatten a list of plugins + a SteeringConfig into a
|
|
3
|
+
* single `ResolvedPluginState` the evaluator and observer dispatcher can
|
|
4
|
+
* drive off directly.
|
|
5
|
+
*
|
|
6
|
+
* Per the accepted ADR ("Design → Plugin schema" and "Precedence:
|
|
7
|
+
* first-wins everywhere"):
|
|
8
|
+
*
|
|
9
|
+
* - predicates / rules / observers — first-registered wins on name
|
|
10
|
+
* collision; later entries logged as WARNings.
|
|
11
|
+
* - trackers — HARD ERROR on name collision (two plugins claiming the
|
|
12
|
+
* same state dimension is always a bug, not a soft-override).
|
|
13
|
+
* - trackerExtensions — later plugins can layer modifiers onto an
|
|
14
|
+
* existing tracker under a `(tracker, basename)` slot. Multiple
|
|
15
|
+
* entries under the same slot are preserved in registration order.
|
|
16
|
+
* Extensions targeting an unregistered tracker are warned about and
|
|
17
|
+
* ignored.
|
|
18
|
+
* - config.disabledRules / config.disabledPlugins — filter rules and
|
|
19
|
+
* whole plugins by name. Disabled entries are surfaced via
|
|
20
|
+
* `console.info` breadcrumbs (NOT diagnostics, since disabling is
|
|
21
|
+
* by-design behavior). `config.disableDefaults` is the caller's
|
|
22
|
+
* problem:
|
|
23
|
+
* the caller chooses whether to include DEFAULT_PLUGINS in the input
|
|
24
|
+
* list (handled upstream by the extension runtime).
|
|
25
|
+
*
|
|
26
|
+
* The composed trackers map returned here is what the runtime passes to
|
|
27
|
+
* `walk()`; the raw `trackers` map from individual plugins is kept on
|
|
28
|
+
* the result as well for introspection / tests.
|
|
29
|
+
*/
|
|
30
|
+
import type { Modifier, Tracker } from "@cad0p/unbash-walker";
|
|
31
|
+
import type { Observer, Plugin, PredicateHandler, Rule, SteeringConfig, SteeringDiagnostic } from "./schema.ts";
|
|
32
|
+
/**
|
|
33
|
+
* Single source of truth for the `tracker-name-collision` diagnostic
|
|
34
|
+
* message. Both `loader.ts:detectTrackerNameCollisions` and
|
|
35
|
+
* `plugin-merger.ts:resolvePlugins` call this so the wording stays in
|
|
36
|
+
* lock-step.
|
|
37
|
+
*/
|
|
38
|
+
export declare function formatTrackerNameCollisionMessage(firstRegisteredPlugin: string, secondRegisteredPlugin: string, trackerName: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* S3: validate a rule / plugin / observer name at load time. Names
|
|
41
|
+
* flow into user-visible strings — the `[steering:<name>@<source>]`
|
|
42
|
+
* block-reason tag shown to the LLM, the `@<source>` tag in warning
|
|
43
|
+
* logs, override-comment target matching, `disabledRules` /
|
|
44
|
+
* `disabledPlugins` config references. Names containing whitespace,
|
|
45
|
+
* control characters, `]`, or newlines let a malicious (or careless)
|
|
46
|
+
* config author forge block reasons that deceive the agent:
|
|
47
|
+
*
|
|
48
|
+
* name: "phony] ALL CLEAR [real"
|
|
49
|
+
* → reason: "[steering:phony] ALL CLEAR [real@user] ..."
|
|
50
|
+
*
|
|
51
|
+
* Returns an error-class `SteeringDiagnostic` with `kind:
|
|
52
|
+
* "invalid-name"` when the name is malformed; `undefined` when the
|
|
53
|
+
* name passes. Callers in the diagnostic-aggregation flow
|
|
54
|
+
* (`resolvePlugins`) push the returned diagnostic onto their local
|
|
55
|
+
* stream so the strict-mode runtime sees it alongside other
|
|
56
|
+
* error-class diagnostics. Direct callers outside the aggregation
|
|
57
|
+
* flow (`buildEvaluator`, `buildObserverDispatcher`) translate the
|
|
58
|
+
* returned diagnostic into a thrown `Error` at build time so the
|
|
59
|
+
* malformed name short-circuits the user-config wiring before the
|
|
60
|
+
* first tool_call.
|
|
61
|
+
*
|
|
62
|
+
* The validation kind is plumbed through to the message so the
|
|
63
|
+
* author knows exactly which of their objects is at fault (`rule
|
|
64
|
+
* name`, `plugin name`, `observer name`).
|
|
65
|
+
*/
|
|
66
|
+
export declare function validateName(kind: "rule" | "plugin" | "observer", value: unknown, context?: string): SteeringDiagnostic | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Validate the `name` field on every user-config rule and observer.
|
|
69
|
+
* Plugin-shipped rule / observer / plugin names are validated inside
|
|
70
|
+
* {@link resolvePlugins}; user-config rules and observers reach
|
|
71
|
+
* {@link validateName} only at factory time (via
|
|
72
|
+
* `buildEvaluator` / `buildObserverDispatcher`'s build-time throw).
|
|
73
|
+
*
|
|
74
|
+
* The CLI's `pi-steering list` pre-flight surface uses this helper
|
|
75
|
+
* to flag the same class of malformed names BEFORE the user hits a
|
|
76
|
+
* thrown error from the bridge factory — otherwise a config with a
|
|
77
|
+
* malformed user-config rule name renders as a valid listing on
|
|
78
|
+
* stdout, then production refuses to start on the same config.
|
|
79
|
+
*
|
|
80
|
+
* Operates on the raw user-authored `layers` array — NOT on the
|
|
81
|
+
* post-merge `SteeringConfig`. The merged config can include
|
|
82
|
+
* default rules injected by `buildConfig` (when `disableDefaults`
|
|
83
|
+
* is false); validating those would attribute package-controlled
|
|
84
|
+
* names to a `(user config)` source, which is a misnomer. Default
|
|
85
|
+
* rule names ship in `DEFAULT_RULES` and are package-controlled —
|
|
86
|
+
* they don't pass through this validator.
|
|
87
|
+
*
|
|
88
|
+
* Note: `layer.observers` covers user-authored observers only.
|
|
89
|
+
* Plugin-shipped observers live under `layer.plugins[].observers`
|
|
90
|
+
* and are validated by {@link resolvePlugins}.
|
|
91
|
+
*/
|
|
92
|
+
export declare function validateUserConfigNames(layers: readonly SteeringConfig[]): SteeringDiagnostic[];
|
|
93
|
+
/**
|
|
94
|
+
* Fully-resolved plugin state: the evaluator + observer dispatcher drive
|
|
95
|
+
* off this shape. All maps / arrays are freshly built and safe for the
|
|
96
|
+
* caller to stash on the extension closure.
|
|
97
|
+
*/
|
|
98
|
+
export interface ResolvedPluginState {
|
|
99
|
+
/** Plugin-registered predicate handlers, keyed by `when.<key>`. */
|
|
100
|
+
predicates: Record<string, PredicateHandler>;
|
|
101
|
+
/** Observers in registration order, deduped by name. */
|
|
102
|
+
observers: Observer[];
|
|
103
|
+
/**
|
|
104
|
+
* Plugin-declared trackers (NOT yet composed with trackerExtensions).
|
|
105
|
+
* Exposed for introspection and tests; the runtime should use
|
|
106
|
+
* {@link composedTrackers} when calling {@link walk}.
|
|
107
|
+
*/
|
|
108
|
+
trackers: Record<string, Tracker<unknown>>;
|
|
109
|
+
/**
|
|
110
|
+
* Modifiers layered on by `trackerExtensions`, keyed by
|
|
111
|
+
* `[trackerName][basename]`. Multiple modifiers under one slot are
|
|
112
|
+
* appended in registration order. Consumers typically use
|
|
113
|
+
* {@link composedTrackers} instead.
|
|
114
|
+
*/
|
|
115
|
+
trackerModifiers: Record<string, Record<string, Modifier<unknown>[]>>;
|
|
116
|
+
/**
|
|
117
|
+
* Trackers after applying {@link trackerModifiers} on top of each
|
|
118
|
+
* plugin's own `modifiers` map. This is the map that gets passed to
|
|
119
|
+
* unbash-walker's `walk()` at evaluation time.
|
|
120
|
+
*/
|
|
121
|
+
composedTrackers: Record<string, Tracker<unknown>>;
|
|
122
|
+
/** Plugin-shipped rules in registration order, deduped by name. */
|
|
123
|
+
rules: Rule[];
|
|
124
|
+
/**
|
|
125
|
+
* Rule-name → plugin-name mapping for every rule surviving in
|
|
126
|
+
* {@link rules}. Consumed by the evaluator to source-tag block
|
|
127
|
+
* reasons as `[steering:<rule>@<plugin>] …`. User-defined rules
|
|
128
|
+
* (`SteeringConfig.rules`) are NOT in this map — the evaluator
|
|
129
|
+
* defaults to `@user` for anything missing.
|
|
130
|
+
*/
|
|
131
|
+
rulePluginOwners: Record<string, string>;
|
|
132
|
+
/**
|
|
133
|
+
* Diagnostics observed while resolving plugins. Includes both
|
|
134
|
+
* non-fatal collisions (warning class) and reserved-name violations
|
|
135
|
+
* that the runtime escalates to a thrown error regardless of
|
|
136
|
+
* strict-mode settings.
|
|
137
|
+
*/
|
|
138
|
+
diagnostics: SteeringDiagnostic[];
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Merge a list of plugins together, applying the config's `disabledRules` /
|
|
142
|
+
* `disabledPlugins` filters along the way.
|
|
143
|
+
*
|
|
144
|
+
* The caller is responsible for composing the plugin list — including
|
|
145
|
+
* whether to prepend DEFAULT_PLUGINS. This function does not consult
|
|
146
|
+
* `config.disableDefaults`; that decision sits one layer up in the
|
|
147
|
+
* extension runtime.
|
|
148
|
+
*
|
|
149
|
+
* Collision semantics per the ADR:
|
|
150
|
+
* - predicate / observer / plugin-shipped-rule name collision — first
|
|
151
|
+
* wins, recorded as a warning-class diagnostic.
|
|
152
|
+
* - tracker name collision — recorded as an error-class diagnostic.
|
|
153
|
+
* The loader-side `buildConfig` (`detectTrackerNameCollisions`)
|
|
154
|
+
* records this same kind for callers going through the standard
|
|
155
|
+
* pipeline; this in-merger check covers direct `resolvePlugins`
|
|
156
|
+
* callers (testing, external embed) that bypass `buildConfig`.
|
|
157
|
+
* Direct callers should check `result.diagnostics.some(d => d.type === "error")`
|
|
158
|
+
* before using the resolved state — same contract as `loadHarness`.
|
|
159
|
+
* - reserved tracker name (`events`) and reserved predicate keys
|
|
160
|
+
* (operator/modifier surface) — recorded as error-class
|
|
161
|
+
* diagnostics; the runtime escalates to a thrown error regardless
|
|
162
|
+
* of strict-mode settings.
|
|
163
|
+
* - trackerExtension targeting an unregistered tracker — recorded
|
|
164
|
+
* as a warning-class diagnostic, extension ignored.
|
|
165
|
+
*
|
|
166
|
+
* `knownBuiltinTrackers` lists tracker names the caller guarantees are
|
|
167
|
+
* injected at a later wiring stage (e.g. the evaluator's built-in
|
|
168
|
+
* `cwd` tracker). Extensions targeting these names are KEPT in
|
|
169
|
+
* `trackerModifiers` (so the caller can compose them onto the built-in
|
|
170
|
+
* tracker) without emitting an orphan warning. Omitted / empty list
|
|
171
|
+
* means "no built-ins" — every extension must target a
|
|
172
|
+
* plugin-registered tracker.
|
|
173
|
+
*/
|
|
174
|
+
export declare function resolvePlugins(plugins: readonly Plugin[], config: SteeringConfig, knownBuiltinTrackers?: readonly string[]): ResolvedPluginState;
|
|
175
|
+
//# sourceMappingURL=plugin-merger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-merger.d.ts","sourceRoot":"","sources":["../src/plugin-merger.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAK9D,OAAO,KAAK,EACV,QAAQ,EAER,MAAM,EACN,gBAAgB,EAGhB,IAAI,EACJ,cAAc,EACd,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAMrB;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAC/C,qBAAqB,EAAE,MAAM,EAC7B,sBAAsB,EAAE,MAAM,EAC9B,WAAW,EAAE,MAAM,GAClB,MAAM,CAOR;AAqBD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,EACpC,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,MAAM,GACf,kBAAkB,GAAG,SAAS,CAehC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,cAAc,EAAE,GAChC,kBAAkB,EAAE,CAatB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAE7C,wDAAwD;IACxD,SAAS,EAAE,QAAQ,EAAE,CAAC;IAEtB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAE3C;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAEtE;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAEnD,mEAAmE;IACnE,KAAK,EAAE,IAAI,EAAE,CAAC;IAEd;;;;;;OAMG;IACH,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEzC;;;;;OAKG;IACH,WAAW,EAAE,kBAAkB,EAAE,CAAC;CACnC;AAuDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,MAAM,EAAE,cAAc,EACtB,oBAAoB,GAAE,SAAS,MAAM,EAAO,GAC3C,mBAAmB,CA6QrB"}
|