@yagni-app/code 0.2.1 → 0.3.1
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/dist/cli.d.ts +30 -0
- package/dist/cli.js +147 -3
- package/dist/connectClaudeCode.d.ts +77 -0
- package/dist/connectClaudeCode.js +228 -0
- package/dist/connectCodex.d.ts +75 -0
- package/dist/connectCodex.js +201 -0
- package/dist/doctor.d.ts +1 -1
- package/dist/doctor.js +1 -1
- package/dist/extension/advisor.d.ts +4 -4
- package/dist/extension/advisor.js +6 -7
- package/dist/extension/approvedPrefixes.d.ts +103 -0
- package/dist/extension/approvedPrefixes.js +282 -0
- package/dist/extension/askAdvisorTool.d.ts +20 -5
- package/dist/extension/askAdvisorTool.js +126 -20
- package/dist/extension/askYagniTool.d.ts +23 -0
- package/dist/extension/askYagniTool.js +91 -2
- package/dist/extension/branding.d.ts +34 -3
- package/dist/extension/branding.js +114 -13
- package/dist/extension/chipEditor.d.ts +30 -9
- package/dist/extension/chipEditor.js +173 -59
- package/dist/extension/claudeRules.d.ts +0 -2
- package/dist/extension/claudeRules.js +0 -8
- package/dist/extension/cmux/dispatcher.d.ts +25 -0
- package/dist/extension/cmux/dispatcher.js +266 -0
- package/dist/extension/cmux/hooks.d.ts +12 -0
- package/dist/extension/cmux/hooks.js +192 -0
- package/dist/extension/cmux/index.d.ts +3 -0
- package/dist/extension/cmux/index.js +155 -0
- package/dist/extension/cmux/naming.d.ts +5 -0
- package/dist/extension/cmux/naming.js +23 -0
- package/dist/extension/cmux/state.d.ts +33 -0
- package/dist/extension/cmux/state.js +142 -0
- package/dist/extension/config.d.ts +44 -1
- package/dist/extension/config.js +37 -4
- package/dist/extension/costHud.d.ts +16 -22
- package/dist/extension/costHud.js +8 -47
- package/dist/extension/crashReport.js +1 -3
- package/dist/extension/execPolicy.d.ts +135 -0
- package/dist/extension/execPolicy.js +936 -0
- package/dist/extension/flywheel.d.ts +44 -0
- package/dist/extension/flywheel.js +53 -0
- package/dist/extension/footer.d.ts +118 -0
- package/dist/extension/footer.js +308 -0
- package/dist/extension/guardian.d.ts +139 -0
- package/dist/extension/guardian.js +237 -0
- package/dist/extension/index.d.ts +35 -7
- package/dist/extension/index.js +338 -33
- package/dist/extension/mineBeat.d.ts +95 -0
- package/dist/extension/mineBeat.js +193 -0
- package/dist/extension/permission.d.ts +124 -10
- package/dist/extension/permission.js +603 -52
- package/dist/extension/pipeline/childRegistry.d.ts +41 -0
- package/dist/extension/pipeline/childRegistry.js +118 -0
- package/dist/extension/pipeline/finish.js +5 -1
- package/dist/extension/pipeline/goCommand.d.ts +1 -1
- package/dist/extension/pipeline/goCommand.js +40 -9
- package/dist/extension/pipeline/goStatusCommands.d.ts +10 -0
- package/dist/extension/pipeline/goStatusCommands.js +61 -1
- package/dist/extension/pipeline/personas.js +26 -1
- package/dist/extension/pipeline/resilience.d.ts +2 -1
- package/dist/extension/pipeline/resilience.js +21 -2
- package/dist/extension/pipeline/runRegistry.d.ts +23 -1
- package/dist/extension/pipeline/runRegistry.js +57 -1
- package/dist/extension/pipeline/runner.js +4 -0
- package/dist/extension/pipeline/verify.d.ts +4 -0
- package/dist/extension/pipeline/verify.js +48 -26
- package/dist/extension/recordDecisionTool.d.ts +8 -0
- package/dist/extension/recordDecisionTool.js +24 -0
- package/dist/extension/redact.d.ts +20 -0
- package/dist/extension/redact.js +64 -0
- package/dist/extension/rerouteNotice.d.ts +3 -4
- package/dist/extension/rerouteNotice.js +20 -11
- package/dist/extension/subagentRender.d.ts +129 -0
- package/dist/extension/subagentRender.js +441 -0
- package/dist/extension/subagents.d.ts +11 -8
- package/dist/extension/subagents.js +162 -37
- package/dist/extension/ticketTools.d.ts +37 -0
- package/dist/extension/ticketTools.js +117 -0
- package/dist/extension/todos.d.ts +28 -1
- package/dist/extension/todos.js +76 -1
- package/dist/extension/tokenProvider.js +46 -5
- package/dist/extension/ultra.d.ts +27 -0
- package/dist/extension/ultra.js +76 -0
- package/dist/launch.d.ts +7 -0
- package/dist/launch.js +24 -12
- package/dist/login.d.ts +4 -2
- package/dist/login.js +19 -4
- package/dist/padding.d.ts +22 -0
- package/dist/padding.js +25 -0
- package/dist/promptEnrichment.d.ts +40 -0
- package/dist/promptEnrichment.js +85 -0
- package/dist/signalForward.d.ts +60 -0
- package/dist/signalForward.js +130 -0
- package/dist/token.d.ts +25 -0
- package/dist/token.js +45 -0
- package/package.json +6 -5
- package/dist/extension/boostCommand.d.ts +0 -144
- package/dist/extension/boostCommand.js +0 -263
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Guardian — LLM auto-review of prompt-band bash commands (YAG-504).
|
|
3
|
+
*
|
|
4
|
+
* Pure half: verdict types, state tracking, circuit breaker, JSON parsing.
|
|
5
|
+
* I/O half: reviewCommand spawns a locked-down child pi (same runStage seam
|
|
6
|
+
* the advisor uses) on the efficient tier with read-only tools and a risk
|
|
7
|
+
* policy persona. The child returns a JSON verdict; the gate acts on it.
|
|
8
|
+
*
|
|
9
|
+
* Same pure/IO split as advisor.ts (decideConsult pure, askAdvisorTool I/O)
|
|
10
|
+
* and permission.ts (decideGate pure, registerPermissionGate I/O), for the
|
|
11
|
+
* same reason: the rules are what need exhaustive tests, and they must not
|
|
12
|
+
* require a child process to exercise.
|
|
13
|
+
*
|
|
14
|
+
* Trigger: the exec policy classifies a bash command as "prompt" (not clearly
|
|
15
|
+
* safe, not clearly forbidden). The Guardian reviews it instead of interrupting
|
|
16
|
+
* the user. On allow, the command runs. On ask (YAG-510), the user arbitrates:
|
|
17
|
+
* the gate shows the Guardian's question-rationale and the user approves or
|
|
18
|
+
* declines. On deny, the agent sees the rationale and is told to find a safer
|
|
19
|
+
* alternative or ask the user. On timeout/error, auto mode falls back to an
|
|
20
|
+
* ask when a UI exists, else fails closed; review mode falls back to the
|
|
21
|
+
* ordinary user confirm.
|
|
22
|
+
*
|
|
23
|
+
* Circuit breaker: 3 consecutive denials within one user prompt → escalation
|
|
24
|
+
* (ask the user once) or, headless, interruption. Denial streaks reset on
|
|
25
|
+
* `before_agent_start`, which fires once per USER PROMPT (not per LLM turn).
|
|
26
|
+
* An `ask` outcome leaves the streak untouched — neither a denial nor an
|
|
27
|
+
* exoneration — so an ask-preferring model cannot disarm the breaker by
|
|
28
|
+
* alternating deny/ask.
|
|
29
|
+
*/
|
|
30
|
+
import { runStage as defaultRunStage } from "./pipeline/runner.js";
|
|
31
|
+
export const DEFAULT_GUARDIAN_LIMITS = {
|
|
32
|
+
maxReviews: 120,
|
|
33
|
+
maxConsecutiveDenials: 3,
|
|
34
|
+
timeoutMs: 15_000,
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Resolve Guardian limits from the environment. `YAGNI_GUARDIAN_MAX_REVIEWS`
|
|
38
|
+
* overrides the sliding-window review cap; anything non-numeric or < 1 falls
|
|
39
|
+
* back to the default (a bad value must never zero out the cap and lock the
|
|
40
|
+
* session).
|
|
41
|
+
*/
|
|
42
|
+
export function resolveGuardianLimits(env = process.env) {
|
|
43
|
+
const raw = env.YAGNI_GUARDIAN_MAX_REVIEWS?.trim();
|
|
44
|
+
const parsed = raw ? Number.parseInt(raw, 10) : NaN;
|
|
45
|
+
const maxReviews = Number.isFinite(parsed) && parsed >= 1 ? parsed : DEFAULT_GUARDIAN_LIMITS.maxReviews;
|
|
46
|
+
return { ...DEFAULT_GUARDIAN_LIMITS, maxReviews };
|
|
47
|
+
}
|
|
48
|
+
/** The model tier the Guardian runs on. Configurable via YAGNI_GUARDIAN_TIER. */
|
|
49
|
+
export const GUARDIAN_MODEL_TIER = "efficient";
|
|
50
|
+
/** Read-only tools — the Guardian can read files for context but cannot write or execute. */
|
|
51
|
+
export const GUARDIAN_TOOLS = ["read"];
|
|
52
|
+
// --- State ---
|
|
53
|
+
/**
|
|
54
|
+
* The review-cap window. `reviews` counts consults inside a SLIDING window
|
|
55
|
+
* rather than for the session's lifetime: a 24/7 session (a fleet operator's
|
|
56
|
+
* always-on terminal) must regain review capacity as old consults age out,
|
|
57
|
+
* not hard-block forever after the first N. The cap is a cost/runaway bound,
|
|
58
|
+
* not a safety bound — safety is the verdicts themselves.
|
|
59
|
+
*/
|
|
60
|
+
export const GUARDIAN_REVIEW_WINDOW_MS = 60 * 60_000;
|
|
61
|
+
export function makeGuardianState(now = Date.now) {
|
|
62
|
+
const reviewTimes = [];
|
|
63
|
+
let consecutiveDenials = 0;
|
|
64
|
+
const prune = () => {
|
|
65
|
+
const cutoff = now() - GUARDIAN_REVIEW_WINDOW_MS;
|
|
66
|
+
while (reviewTimes.length > 0 && reviewTimes[0] <= cutoff)
|
|
67
|
+
reviewTimes.shift();
|
|
68
|
+
};
|
|
69
|
+
const snapshot = () => ({
|
|
70
|
+
reviews: reviewTimes.length,
|
|
71
|
+
consecutiveDenials,
|
|
72
|
+
});
|
|
73
|
+
return {
|
|
74
|
+
read: () => {
|
|
75
|
+
prune();
|
|
76
|
+
return snapshot();
|
|
77
|
+
},
|
|
78
|
+
recordReview(outcome) {
|
|
79
|
+
prune();
|
|
80
|
+
reviewTimes.push(now());
|
|
81
|
+
if (outcome === "deny") {
|
|
82
|
+
consecutiveDenials += 1;
|
|
83
|
+
}
|
|
84
|
+
else if (outcome === "allow") {
|
|
85
|
+
consecutiveDenials = 0;
|
|
86
|
+
}
|
|
87
|
+
// "ask" leaves the denial streak UNCHANGED: it is neither a denial nor
|
|
88
|
+
// an exoneration. If it reset the streak, deny/ask/deny/ask would never
|
|
89
|
+
// trip the breaker (round-2 review blocker).
|
|
90
|
+
return snapshot();
|
|
91
|
+
},
|
|
92
|
+
resetTurn() {
|
|
93
|
+
consecutiveDenials = 0;
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export function checkCircuitBreaker(state, limits) {
|
|
98
|
+
if (state.consecutiveDenials >= limits.maxConsecutiveDenials) {
|
|
99
|
+
return {
|
|
100
|
+
tripped: true,
|
|
101
|
+
reason: `Guardian denied ${state.consecutiveDenials} consecutive actions this turn. Pausing for human review.`,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return { tripped: false };
|
|
105
|
+
}
|
|
106
|
+
// --- Verdict parsing (fail closed on malformed) ---
|
|
107
|
+
export function parseVerdict(raw) {
|
|
108
|
+
try {
|
|
109
|
+
// Efficient-tier models may wrap JSON in markdown fences despite
|
|
110
|
+
// instructions to output raw JSON. Extract the first {...} block.
|
|
111
|
+
const jsonMatch = raw.match(/\{[\s\S]*\}/);
|
|
112
|
+
const jsonStr = jsonMatch ? jsonMatch[0] : raw;
|
|
113
|
+
const parsed = JSON.parse(jsonStr);
|
|
114
|
+
const outcome = parsed?.outcome;
|
|
115
|
+
if (outcome !== "allow" && outcome !== "ask" && outcome !== "deny")
|
|
116
|
+
return null;
|
|
117
|
+
const riskLevel = parsed.riskLevel;
|
|
118
|
+
const validLevels = ["low", "medium", "high", "critical"];
|
|
119
|
+
return {
|
|
120
|
+
outcome,
|
|
121
|
+
riskLevel: typeof riskLevel === "string" && validLevels.includes(riskLevel)
|
|
122
|
+
? riskLevel
|
|
123
|
+
: "medium",
|
|
124
|
+
rationale: typeof parsed.rationale === "string" && parsed.rationale.trim().length > 0
|
|
125
|
+
? parsed.rationale.trim()
|
|
126
|
+
: "No rationale provided.",
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// --- /cost subtotal ---
|
|
134
|
+
export function formatGuardianSubtotal(state, limits) {
|
|
135
|
+
if (state.reviews === 0)
|
|
136
|
+
return "";
|
|
137
|
+
const plural = state.reviews === 1 ? "review" : "reviews";
|
|
138
|
+
return `Guardian: ${state.reviews} ${plural}.`;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The synthetic stage a Guardian consult runs as. Borrows the `plan` StageId
|
|
142
|
+
* (same pattern as the advisor) so it doesn't ripple into feed/reducers. The
|
|
143
|
+
* agent name selects the guardian persona from PERSONA_BODIES.
|
|
144
|
+
*/
|
|
145
|
+
export function guardianStage(modelTier = GUARDIAN_MODEL_TIER) {
|
|
146
|
+
return {
|
|
147
|
+
id: "plan",
|
|
148
|
+
agent: "guardian",
|
|
149
|
+
model: modelTier,
|
|
150
|
+
tools: GUARDIAN_TOOLS,
|
|
151
|
+
taskTemplate: "{ticket}",
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Run a Guardian consult: spawn a locked-down child pi with the risk policy
|
|
156
|
+
* persona and the command as the task. Parse the JSON verdict from the output.
|
|
157
|
+
* Returns { verdict, cost } on success, { verdict: null, error, cost } on failure.
|
|
158
|
+
*/
|
|
159
|
+
export async function reviewCommand(command, deps) {
|
|
160
|
+
const runStage = deps.runStage ?? defaultRunStage;
|
|
161
|
+
const stage = guardianStage(deps.modelTier);
|
|
162
|
+
// Build the abort signal with the Guardian timeout (injectable — the gate
|
|
163
|
+
// threads guardianLimits.timeoutMs through).
|
|
164
|
+
const timeoutMs = deps.timeoutMs ?? DEFAULT_GUARDIAN_LIMITS.timeoutMs;
|
|
165
|
+
const controller = new AbortController();
|
|
166
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
167
|
+
timer.unref?.();
|
|
168
|
+
// Chain with the caller's signal if present.
|
|
169
|
+
if (deps.signal) {
|
|
170
|
+
if (deps.signal.aborted)
|
|
171
|
+
controller.abort();
|
|
172
|
+
else
|
|
173
|
+
deps.signal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
const justificationLine = deps.execJustification
|
|
177
|
+
? `\n\nWhy this command was routed to you (static policy): ${deps.execJustification}`
|
|
178
|
+
: "";
|
|
179
|
+
const result = await runStage(stage, { ticket: `Review this shell command for safety. Output only the JSON verdict.${justificationLine}\n\nCommand:\n${command}` }, {
|
|
180
|
+
cwd: deps.cwd,
|
|
181
|
+
signal: controller.signal,
|
|
182
|
+
callerLabel: "guardian",
|
|
183
|
+
});
|
|
184
|
+
const cost = result.usage?.cost ?? 0;
|
|
185
|
+
const output = result.finalOutput.trim();
|
|
186
|
+
// An aborted child often RESOLVES with empty/partial output instead of
|
|
187
|
+
// throwing (observed live: ESC → 433ms "empty"). Any result produced
|
|
188
|
+
// while the caller's signal is aborted is an abort, not an outage — the
|
|
189
|
+
// gate must not warn or fall back to an ask on it.
|
|
190
|
+
if (deps.signal?.aborted) {
|
|
191
|
+
return { verdict: null, error: "aborted", cost };
|
|
192
|
+
}
|
|
193
|
+
if (!output) {
|
|
194
|
+
return { verdict: null, error: "empty", cost };
|
|
195
|
+
}
|
|
196
|
+
const verdict = parseVerdict(output);
|
|
197
|
+
if (!verdict) {
|
|
198
|
+
return { verdict: null, error: "malformed", cost };
|
|
199
|
+
}
|
|
200
|
+
return { verdict, cost };
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
// Distinguish the caller aborting (user hit ESC — must NOT be treated as
|
|
204
|
+
// an outage, or the fallback ask would pop a dialog on an aborted turn),
|
|
205
|
+
// our own timeout, and real network/process errors.
|
|
206
|
+
if (deps.signal?.aborted) {
|
|
207
|
+
return { verdict: null, error: "aborted", cost: 0 };
|
|
208
|
+
}
|
|
209
|
+
if (controller.signal.aborted) {
|
|
210
|
+
return { verdict: null, error: "timeout", cost: 0 };
|
|
211
|
+
}
|
|
212
|
+
return { verdict: null, error: "network", cost: 0 };
|
|
213
|
+
}
|
|
214
|
+
finally {
|
|
215
|
+
clearTimeout(timer);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Create a sanitized diagnostic event. Never includes the raw command text
|
|
220
|
+
* (could contain secrets). YAGNI_DEBUG=1 adds rationale and a command hash.
|
|
221
|
+
*/
|
|
222
|
+
export function buildDiagnosticEvent(outcome, opts) {
|
|
223
|
+
const ev = {
|
|
224
|
+
event: "guardian_review",
|
|
225
|
+
outcome,
|
|
226
|
+
...(opts.durationMs !== undefined ? { durationMs: opts.durationMs } : {}),
|
|
227
|
+
...(opts.tier !== undefined ? { tier: opts.tier } : {}),
|
|
228
|
+
};
|
|
229
|
+
if (opts.debug) {
|
|
230
|
+
if (opts.rationale)
|
|
231
|
+
ev.rationale = opts.rationale;
|
|
232
|
+
if (opts.commandHash)
|
|
233
|
+
ev.commandHash = opts.commandHash;
|
|
234
|
+
}
|
|
235
|
+
return ev;
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=guardian.js.map
|
|
@@ -4,7 +4,8 @@ import { runInitPass as defaultRunInitPass } from "./initPass.js";
|
|
|
4
4
|
import { fetchMcpServers as defaultFetchMcpServers } from "./mcpTools.js";
|
|
5
5
|
import { type FlushOutcome, type SpoolClientOpts } from "./spool.js";
|
|
6
6
|
import { type TokenProvider } from "./tokenProvider.js";
|
|
7
|
-
import { type
|
|
7
|
+
import { type CatalogResult, type ContextBrief } from "./config.js";
|
|
8
|
+
import { maybeOfferMiningBeat as defaultMaybeOfferMiningBeat, type MineBeatMarkers } from "./mineBeat.js";
|
|
8
9
|
/**
|
|
9
10
|
* YAGNI Code extension entry point.
|
|
10
11
|
*
|
|
@@ -31,12 +32,26 @@ export interface RegisterYagniDeps {
|
|
|
31
32
|
baseUrl: string;
|
|
32
33
|
getToken: () => string | undefined;
|
|
33
34
|
fetchImpl?: typeof fetch;
|
|
34
|
-
}) => Promise<
|
|
35
|
+
}) => Promise<CatalogResult>;
|
|
35
36
|
fetchContextBrief?: (opts: {
|
|
36
37
|
baseUrl: string;
|
|
37
38
|
getToken: () => string | undefined;
|
|
38
39
|
fetchImpl?: typeof fetch;
|
|
40
|
+
repo?: string;
|
|
39
41
|
}) => Promise<ContextBrief | null>;
|
|
42
|
+
/**
|
|
43
|
+
* The session repo (`owner/name`), resolved from the origin remote before
|
|
44
|
+
* the boot brief fetch so `/context` can carry `repoDecisionCount` for the
|
|
45
|
+
* mining beat. Injectable (no git in tests); undefined outside a repo.
|
|
46
|
+
*/
|
|
47
|
+
resolveRepoFullName?: (cwd: string) => string | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* The opt-in seeding beat itself (Run 7). Injectable so tests assert it
|
|
50
|
+
* fires only on a startup with an explicitly-zero repo ledger.
|
|
51
|
+
*/
|
|
52
|
+
offerMiningBeat?: typeof defaultMaybeOfferMiningBeat;
|
|
53
|
+
/** The beat's once-per-repo marker store. Injectable (no disk in tests). */
|
|
54
|
+
mineBeatMarkers?: MineBeatMarkers;
|
|
40
55
|
/**
|
|
41
56
|
* Workspace MCP server list seam (YAG-446). The default hits
|
|
42
57
|
* `/api/yagni-code/mcp/servers` and is fail-soft: older backends and
|
|
@@ -63,6 +78,12 @@ export interface RegisterYagniDeps {
|
|
|
63
78
|
tokenProvider?: TokenProvider;
|
|
64
79
|
/** The spool flush (R4 write half), injectable so tests never touch disk. */
|
|
65
80
|
flushSpool?: (opts: SpoolClientOpts) => Promise<FlushOutcome>;
|
|
81
|
+
/**
|
|
82
|
+
* Non-fatal auth-event reporter (YAG-500 Fix E). Defaults to
|
|
83
|
+
* `makeCrashReporter` gated on `!evalMode`; inject a spy in tests to assert
|
|
84
|
+
* the report is fired with `context: "auth-failure"` and the refresh outcome.
|
|
85
|
+
*/
|
|
86
|
+
authReporter?: (error: unknown, context?: string) => Promise<void>;
|
|
66
87
|
env?: NodeJS.ProcessEnv;
|
|
67
88
|
}
|
|
68
89
|
/**
|
|
@@ -97,8 +118,11 @@ export declare function parseSpendResponse(data: unknown): SpendResponse | null;
|
|
|
97
118
|
export declare function registerYagni(pi: ExtensionAPI, deps?: RegisterYagniDeps): Promise<void>;
|
|
98
119
|
export default function (pi: ExtensionAPI): Promise<void>;
|
|
99
120
|
export { makeAskYagniTool } from "./askYagniTool.js";
|
|
121
|
+
export { makeFileTicketTool, makeUpdateTicketStatusTool } from "./ticketTools.js";
|
|
100
122
|
export { makeAskAdvisorTool, registerAdviseCommand } from "./askAdvisorTool.js";
|
|
101
123
|
export { ADVISOR_TIER, DEFAULT_ADVISOR_LIMITS, decideConsult, formatAdvisorSubtotal, makeAdvisorState, } from "./advisor.js";
|
|
124
|
+
export { DEFAULT_GUARDIAN_LIMITS, GUARDIAN_MODEL_TIER, formatGuardianSubtotal, makeGuardianState, resolveGuardianLimits, reviewCommand, } from "./guardian.js";
|
|
125
|
+
export type { GuardianOutcome, GuardianVerdict, GuardianState, GuardianStateHandle, GuardianLimits, ReviewResult, ReviewCommandDeps, } from "./guardian.js";
|
|
102
126
|
export type { Citation, MakeAskYagniToolOptions } from "./askYagniTool.js";
|
|
103
127
|
export { makeReviewBusinessMatchTool } from "./reviewTool.js";
|
|
104
128
|
export type { MakeReviewToolOptions } from "./reviewTool.js";
|
|
@@ -113,9 +137,11 @@ export type { RecordDecisionParams } from "./recordDecisionTool.js";
|
|
|
113
137
|
export { runInitPass, runTeamSetup, registerTeamSetupCommand, isFreshWorkspace, readRepoIntake, draftEngineering, summarizeDraft, FRESH_BRIEF_MIN_CHARS, } from "./initPass.js";
|
|
114
138
|
export type { RunInitPassDeps, InitPassOutcome, RunTeamSetupDeps, TeamSetupOutcome, RepoIntake, RepoIntakeFs, EngineeringDraft, DraftTeam, } from "./initPass.js";
|
|
115
139
|
export { isInitDone, markInitDone, initDoneMarkerFile, _setInitDoneHomeForTest } from "./initDone.js";
|
|
116
|
-
export { brandSystemPrompt, YAGNI_IDENTITY, YAGNI_IDENTITY_DRIVER, BRAND_NAME } from "./branding.js";
|
|
140
|
+
export { brandSystemPrompt, YAGNI_IDENTITY, YAGNI_IDENTITY_DRIVER, YAGNI_IDENTITY_ULTRA, BRAND_NAME } from "./branding.js";
|
|
141
|
+
export { createUltraHolder, registerUltraCommand } from "./ultra.js";
|
|
142
|
+
export type { UltraHolder } from "./ultra.js";
|
|
117
143
|
export { attributionHeaders, isDriverCaller, fetchCatalog, getToken, getWorkspaceId, resolveBaseUrl, sanitizeCallerSegment, } from "./config.js";
|
|
118
|
-
export type { FetchCatalogOptions, ModelEntry } from "./config.js";
|
|
144
|
+
export type { CatalogResult, FetchCatalogOptions, ModelEntry } from "./config.js";
|
|
119
145
|
export { buildYagniProvider } from "./provider.js";
|
|
120
146
|
export { registerGoCommand } from "./pipeline/goCommand.js";
|
|
121
147
|
export type { RegisterGoDeps } from "./pipeline/goCommand.js";
|
|
@@ -130,11 +156,13 @@ export type { VerifyCommand, VerifyOutcome } from "./pipeline/verify.js";
|
|
|
130
156
|
export { blindStages, reportOnlyStages, makeGroundedVsBlindEval, formatComparisonReport } from "./pipeline/eval.js";
|
|
131
157
|
export type { ComparisonReport, LaneFit, LaneOutcome } from "./pipeline/eval.js";
|
|
132
158
|
export { registerGoCompareCommand } from "./pipeline/goCompareCommand.js";
|
|
133
|
-
export { registerSubagents, makeSubagentTool, discoverSubagents, parseAgentMarkdown, buildSubagentStage, formatAgentList, mapModelTier, SUBAGENT_TOOL_NAME, GENERAL_AGENT_NAME, MAX_PARALLEL_SUBAGENTS, DEFAULT_SUBAGENT_TOOLS, } from "./subagents.js";
|
|
159
|
+
export { registerSubagents, makeSubagentTool, discoverSubagents, parseAgentMarkdown, buildSubagentStage, formatAgentList, mapModelTier, SUBAGENT_TOOL_NAME, GENERAL_AGENT_NAME, MAX_PARALLEL_SUBAGENTS, MAX_PARALLEL_SUBAGENTS_ULTRA, DEFAULT_SUBAGENT_TOOLS, } from "./subagents.js";
|
|
134
160
|
export type { SubagentDef, SubagentSource } from "./subagents.js";
|
|
135
|
-
export { registerTodos, makeTodoTool, normalizeTodos, reconstructTodos, renderTodoWidget, formatTodoList, todoSummary, TODO_TOOL_NAME, MAX_TODOS, } from "./todos.js";
|
|
161
|
+
export { registerTodos, makeTodoTool, normalizeTodos, reconstructTodos, renderTodoWidget, formatTodoList, formatTodoReminder, shouldRemindTodos, todoSummary, TODO_TOOL_NAME, TODO_REMINDER_TURNS, MAX_TODOS, } from "./todos.js";
|
|
136
162
|
export type { TodoItem, TodoStatus, TodoTheme } from "./todos.js";
|
|
137
|
-
export { decideGate, registerPermissionGate, filterStalePlanContext, DEFAULT_PERMISSION_POLICY, PLAN_CONTEXT_TYPE, PLAN_CONTEXT_MESSAGE, } from "./permission.js";
|
|
163
|
+
export { decideGate, registerPermissionGate, filterStaleModeContext, filterStalePlanContext, buildModeContextMessage, DEFAULT_PERMISSION_POLICY, MODE_CONTEXT_TYPE, PLAN_CONTEXT_TYPE, PLAN_CONTEXT_MESSAGE, } from "./permission.js";
|
|
164
|
+
export { classifyCommand, DEFAULT_EXEC_POLICY, } from "./execPolicy.js";
|
|
165
|
+
export type { ExecDecision, ExecPolicy, PrefixRule, ExecClassification, } from "./execPolicy.js";
|
|
138
166
|
export type { PermissionMode, PermissionPolicy, GateDecision, RegisterPermissionDeps, BlessRememberInfo, } from "./permission.js";
|
|
139
167
|
export { makeBlessStore, blessPath } from "./bless.js";
|
|
140
168
|
export type { BlessStore, BlessRule } from "./bless.js";
|