ultimate-pi 0.9.0 → 0.10.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/.agents/skills/harness-decisions/SKILL.md +17 -13
- package/.agents/skills/harness-plan/SKILL.md +3 -3
- package/.pi/agents/harness/planner.md +8 -4
- package/.pi/extensions/harness-plan-approval.ts +140 -0
- package/.pi/extensions/harness-run-context.ts +29 -8
- package/.pi/extensions/lib/harness-subagents/harness-subagent-policy.ts +11 -1
- package/.pi/extensions/lib/harness-subagents/parent-ask-user-bridge.ts +8 -87
- package/.pi/extensions/lib/harness-subagents/parent-harness-ui-bridge.ts +306 -0
- package/.pi/extensions/lib/harness-subagents/parent-harness-ui-hooks.ts +59 -0
- package/.pi/extensions/lib/harness-subagents/spawn-policy.ts +9 -0
- package/.pi/extensions/lib/harness-subagents/vendored/agent-manager.ts +4 -0
- package/.pi/extensions/lib/harness-subagents/vendored/agent-runner.ts +39 -12
- package/.pi/extensions/lib/harness-subagents/vendored/index.ts +36 -12
- package/.pi/extensions/lib/plan-approval/create-plan.ts +131 -0
- package/.pi/extensions/lib/plan-approval/dialog.ts +207 -0
- package/.pi/extensions/lib/plan-approval/fallback.ts +50 -0
- package/.pi/extensions/lib/plan-approval/format-plan.ts +94 -0
- package/.pi/extensions/lib/plan-approval/render.ts +83 -0
- package/.pi/extensions/lib/plan-approval/schema.ts +39 -0
- package/.pi/extensions/lib/plan-approval/types.ts +32 -0
- package/.pi/extensions/lib/plan-approval/validate.ts +61 -0
- package/.pi/harness/agents.manifest.json +2 -2
- package/.pi/lib/harness-run-context.ts +117 -28
- package/.pi/prompts/harness-plan.md +6 -6
- package/.pi/scripts/harness-verify.mjs +28 -1
- package/CHANGELOG.md +12 -0
- package/package.json +3 -3
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": "1.0.0",
|
|
3
3
|
"package": "ultimate-pi",
|
|
4
|
-
"package_version": "0.
|
|
5
|
-
"generated_at": "2026-05-
|
|
4
|
+
"package_version": "0.9.0",
|
|
5
|
+
"generated_at": "2026-05-17T10:06:28.388Z",
|
|
6
6
|
"agents": {
|
|
7
7
|
"pi-pi/agent-expert": {
|
|
8
8
|
"path": ".pi/agents/pi-pi/agent-expert.md",
|
|
@@ -126,7 +126,11 @@ const PLAN_CANCEL_OPTION =
|
|
|
126
126
|
export interface PlanUserApproval {
|
|
127
127
|
plan_id: string | null;
|
|
128
128
|
approved_at: string;
|
|
129
|
-
source:
|
|
129
|
+
source:
|
|
130
|
+
| "ask_user"
|
|
131
|
+
| "approve_plan"
|
|
132
|
+
| "harness-plan-approval"
|
|
133
|
+
| "noninteractive";
|
|
130
134
|
}
|
|
131
135
|
|
|
132
136
|
/** Persisted on `input` when user invokes a raw `/harness-*` prompt template. */
|
|
@@ -291,32 +295,45 @@ export function indexOfLastPlanCommand(entries: unknown[]): number {
|
|
|
291
295
|
return -1;
|
|
292
296
|
}
|
|
293
297
|
|
|
294
|
-
|
|
298
|
+
type PlanApprovalToolDetails = {
|
|
299
|
+
cancelled?: boolean;
|
|
300
|
+
plan_packet?: PlanPacketLike;
|
|
301
|
+
response?: {
|
|
302
|
+
kind?: string;
|
|
303
|
+
text?: string;
|
|
304
|
+
selections?: string[];
|
|
305
|
+
};
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
function planIdFromApprovalDetails(
|
|
309
|
+
details: PlanApprovalToolDetails | undefined,
|
|
310
|
+
): string | null {
|
|
311
|
+
const fromPacket = details?.plan_packet?.plan_id;
|
|
312
|
+
return typeof fromPacket === "string" && fromPacket.length > 0
|
|
313
|
+
? fromPacket
|
|
314
|
+
: null;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export function parsePlanApprovalFromMessage(msg: {
|
|
295
318
|
toolName?: string;
|
|
296
319
|
details?: unknown;
|
|
297
320
|
content?: { type?: string; text?: string }[];
|
|
298
321
|
}): PlanUserApproval | null {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
response?: {
|
|
304
|
-
kind?: string;
|
|
305
|
-
text?: string;
|
|
306
|
-
selections?: string[];
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
| undefined;
|
|
322
|
+
const toolName = msg.toolName;
|
|
323
|
+
if (toolName !== "ask_user" && toolName !== "approve_plan") return null;
|
|
324
|
+
const source = toolName === "approve_plan" ? "approve_plan" : "ask_user";
|
|
325
|
+
const details = msg.details as PlanApprovalToolDetails | undefined;
|
|
310
326
|
if (details?.cancelled) return null;
|
|
311
327
|
const response = details?.response;
|
|
312
328
|
if (!response) return null;
|
|
329
|
+
const plan_id = planIdFromApprovalDetails(details);
|
|
313
330
|
if (response.kind === "freeform") {
|
|
314
331
|
const text = (response.text ?? "").trim();
|
|
315
332
|
if (/^approve(d)?\b/i.test(text)) {
|
|
316
333
|
return {
|
|
317
|
-
plan_id
|
|
334
|
+
plan_id,
|
|
318
335
|
approved_at: nowIso(),
|
|
319
|
-
source
|
|
336
|
+
source,
|
|
320
337
|
};
|
|
321
338
|
}
|
|
322
339
|
return null;
|
|
@@ -325,14 +342,23 @@ export function parseAskUserApprovalFromMessage(msg: {
|
|
|
325
342
|
if (!selection || PLAN_CANCEL_OPTION.test(selection)) return null;
|
|
326
343
|
if (PLAN_APPROVE_OPTION.test(selection)) {
|
|
327
344
|
return {
|
|
328
|
-
plan_id
|
|
345
|
+
plan_id,
|
|
329
346
|
approved_at: nowIso(),
|
|
330
|
-
source
|
|
347
|
+
source,
|
|
331
348
|
};
|
|
332
349
|
}
|
|
333
350
|
return null;
|
|
334
351
|
}
|
|
335
352
|
|
|
353
|
+
/** @deprecated Use parsePlanApprovalFromMessage */
|
|
354
|
+
export function parseAskUserApprovalFromMessage(msg: {
|
|
355
|
+
toolName?: string;
|
|
356
|
+
details?: unknown;
|
|
357
|
+
content?: { type?: string; text?: string }[];
|
|
358
|
+
}): PlanUserApproval | null {
|
|
359
|
+
return parsePlanApprovalFromMessage(msg);
|
|
360
|
+
}
|
|
361
|
+
|
|
336
362
|
export function getLatestPlanUserApproval(
|
|
337
363
|
entries: unknown[],
|
|
338
364
|
sinceIndex = 0,
|
|
@@ -365,8 +391,8 @@ export function getLatestPlanUserApproval(
|
|
|
365
391
|
if (entry.type !== "message" || entry.message?.role !== "toolResult") {
|
|
366
392
|
continue;
|
|
367
393
|
}
|
|
368
|
-
const
|
|
369
|
-
if (
|
|
394
|
+
const fromTool = parsePlanApprovalFromMessage(entry.message);
|
|
395
|
+
if (fromTool) return fromTool;
|
|
370
396
|
}
|
|
371
397
|
return null;
|
|
372
398
|
}
|
|
@@ -472,7 +498,7 @@ export async function isPlanPhaseAllowedMutation(
|
|
|
472
498
|
allowed: false,
|
|
473
499
|
isScopedPlanWrite: true,
|
|
474
500
|
reason:
|
|
475
|
-
"policy-gate: plan-packet.json write blocked until the user approves via ask_user (present the full plan, then Approve).",
|
|
501
|
+
"policy-gate: plan-packet.json write blocked until the user approves via approve_plan or ask_user (present the full plan, then Approve).",
|
|
476
502
|
};
|
|
477
503
|
}
|
|
478
504
|
if (opts.aborted) {
|
|
@@ -569,11 +595,72 @@ export function userVisiblePromptSlice(prompt: string): string {
|
|
|
569
595
|
|
|
570
596
|
export function hasApprovedPlanSignalFromUserPrompt(prompt: string): boolean {
|
|
571
597
|
const p = userVisiblePromptSlice(prompt).toLowerCase();
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
);
|
|
598
|
+
if (p.includes("user approved") || p.includes("already approved")) {
|
|
599
|
+
return true;
|
|
600
|
+
}
|
|
601
|
+
if (/\bapprove(d)?\s+(this\s+)?plan\b/.test(p)) return true;
|
|
602
|
+
if (p.includes("harness-plan-approval")) return true;
|
|
603
|
+
return false;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/** Detect parent-session ask_user calls that duplicate planner plan approval. */
|
|
607
|
+
export function isPlanApprovalAskUser(input: {
|
|
608
|
+
question?: string;
|
|
609
|
+
options?: unknown[];
|
|
610
|
+
}): boolean {
|
|
611
|
+
const q = String(input.question ?? "").trim();
|
|
612
|
+
const opts = Array.isArray(input.options) ? input.options : [];
|
|
613
|
+
const titles = opts.map((o) => {
|
|
614
|
+
if (typeof o === "string") return o.trim();
|
|
615
|
+
if (o && typeof o === "object" && "title" in o) {
|
|
616
|
+
return String((o as { title?: string }).title ?? "").trim();
|
|
617
|
+
}
|
|
618
|
+
return "";
|
|
619
|
+
});
|
|
620
|
+
const hasPlanOptions =
|
|
621
|
+
titles.some(
|
|
622
|
+
(t) => PLAN_APPROVE_OPTION.test(t) || PLAN_CANCEL_OPTION.test(t),
|
|
623
|
+
) || PLAN_APPROVE_OPTION.test(q);
|
|
624
|
+
if (!hasPlanOptions) return false;
|
|
625
|
+
return /plan|approve/i.test(q);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
export function appendPlanApprovalIfNew(
|
|
629
|
+
appendEntry: (customType: string, data: unknown) => void,
|
|
630
|
+
parentEntries: unknown[],
|
|
631
|
+
approval: PlanUserApproval,
|
|
632
|
+
runCtx: HarnessRunContext | null,
|
|
633
|
+
opts?: { sincePlanCommand?: boolean },
|
|
634
|
+
): boolean {
|
|
635
|
+
const since =
|
|
636
|
+
opts?.sincePlanCommand !== false
|
|
637
|
+
? Math.max(0, indexOfLastPlanCommand(parentEntries))
|
|
638
|
+
: 0;
|
|
639
|
+
if (getLatestPlanUserApproval(parentEntries, since)) {
|
|
640
|
+
return false;
|
|
641
|
+
}
|
|
642
|
+
appendEntry("harness-plan-approval", {
|
|
643
|
+
plan_id: approval.plan_id ?? runCtx?.plan_id ?? null,
|
|
644
|
+
approved_at: approval.approved_at,
|
|
645
|
+
source: approval.source,
|
|
646
|
+
});
|
|
647
|
+
return true;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/** Sync planner subagent approvals into the parent session (deduped). */
|
|
651
|
+
export function syncPlannerApprovalsToParent(
|
|
652
|
+
appendEntry: (customType: string, data: unknown) => void,
|
|
653
|
+
parentEntries: unknown[],
|
|
654
|
+
subEntries: unknown[],
|
|
655
|
+
runCtx: HarnessRunContext | null,
|
|
656
|
+
): number {
|
|
657
|
+
let synced = 0;
|
|
658
|
+
for (const approval of extractPlanApprovalsFromEntries(subEntries)) {
|
|
659
|
+
if (appendPlanApprovalIfNew(appendEntry, parentEntries, approval, runCtx)) {
|
|
660
|
+
synced++;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
return synced;
|
|
577
664
|
}
|
|
578
665
|
|
|
579
666
|
export function isDriftReplanPrompt(prompt: string): boolean {
|
|
@@ -970,7 +1057,9 @@ export interface HarnessPolicyState {
|
|
|
970
1057
|
aborted: boolean;
|
|
971
1058
|
}
|
|
972
1059
|
|
|
973
|
-
export function inferHarnessPhaseFromTurn(
|
|
1060
|
+
export function inferHarnessPhaseFromTurn(
|
|
1061
|
+
entries: unknown[],
|
|
1062
|
+
): HarnessPhase | null {
|
|
974
1063
|
const turn = getLatestHarnessTurn(entries);
|
|
975
1064
|
if (!turn) return null;
|
|
976
1065
|
return HARNESS_COMMAND_PHASE[turn.command] ?? null;
|
|
@@ -1266,8 +1355,8 @@ export function extractPlanApprovalsFromEntries(
|
|
|
1266
1355
|
if (entry.type !== "message" || entry.message?.role !== "toolResult") {
|
|
1267
1356
|
continue;
|
|
1268
1357
|
}
|
|
1269
|
-
const
|
|
1270
|
-
if (
|
|
1358
|
+
const fromTool = parsePlanApprovalFromMessage(entry.message);
|
|
1359
|
+
if (fromTool) out.push(fromTool);
|
|
1271
1360
|
}
|
|
1272
1361
|
return out;
|
|
1273
1362
|
}
|
|
@@ -5,7 +5,7 @@ argument-hint: "\"<task>\" [--risk low|med|high] [--budget <amount>] [--quick]"
|
|
|
5
5
|
|
|
6
6
|
# harness-plan
|
|
7
7
|
|
|
8
|
-
Orchestrator only — spawn `harness/planner` once
|
|
8
|
+
Orchestrator only — spawn `harness/planner` once. The planner runs clarification (`ask_user`), approval (`approve_plan`), and persists the plan (`create_plan`). Do **not** write `plan-packet.json` in this parent session.
|
|
9
9
|
|
|
10
10
|
## Step 0 — Parse arguments
|
|
11
11
|
|
|
@@ -33,7 +33,7 @@ Otherwise use `HarnessSpawnContext` from `[HarnessRunContext]` for greenfield `m
|
|
|
33
33
|
|
|
34
34
|
## Orchestration (required)
|
|
35
35
|
|
|
36
|
-
1. Copy the `HarnessSpawnContext=…` JSON from `[HarnessRunContext]` into the spawn prompt (adjust `risk_level`, `quick`, `mode` from `$ARGUMENTS` if needed).
|
|
36
|
+
1. Copy the `HarnessSpawnContext=…` JSON from `[HarnessRunContext]` into the spawn prompt (adjust `risk_level`, `quick`, `mode` from `$ARGUMENTS` if needed). Do **not** add “call ask_user for approval” in the `Agent` prompt — the planner agent instructions already define `approve_plan` / `create_plan`.
|
|
37
37
|
2. Spawn **once** with **`inherit_context: false`**:
|
|
38
38
|
|
|
39
39
|
```
|
|
@@ -41,15 +41,15 @@ Agent({ subagent_type: "harness/planner", prompt: "<task + HarnessSpawnContext J
|
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
3. `get_subagent_result` — parse final JSON (`status`, `plan_packet`, `human_summary`, `clarification`) via fenced `json` block.
|
|
44
|
-
4. If `status === "ready"` and
|
|
44
|
+
4. If `status === "ready"` and parent `harness-run-context` shows `plan_ready: true` (planner called `create_plan`), confirm `plan_packet_path` exists — do **not** write the file yourself.
|
|
45
45
|
5. If `needs_clarification`, tell the user the planner is waiting — do **not** re-spawn; user should answer in the subagent or re-run `/harness-plan`.
|
|
46
|
-
6. Do **not** call `ask_user` in this parent session
|
|
46
|
+
6. Do **not** call `ask_user`, `approve_plan`, or `create_plan` in this parent session.
|
|
47
47
|
|
|
48
48
|
## Parent rules
|
|
49
49
|
|
|
50
|
-
- Do not mutate project source files
|
|
50
|
+
- Do not mutate project source files in the plan phase.
|
|
51
51
|
- Do not embed `plan_id=` in prompts for policy sync.
|
|
52
|
-
- Optional: `/harness-plan-commit` if
|
|
52
|
+
- Optional recovery: `/harness-plan-commit` only if the planner approved but `create_plan` failed.
|
|
53
53
|
|
|
54
54
|
## Completion
|
|
55
55
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { readFile, access } from "node:fs/promises";
|
|
7
7
|
import { constants } from "node:fs";
|
|
8
|
-
import { join, dirname } from "node:path";
|
|
8
|
+
import { join, dirname, resolve } from "node:path";
|
|
9
9
|
import { fileURLToPath } from "node:url";
|
|
10
10
|
import { spawn } from "node:child_process";
|
|
11
11
|
|
|
@@ -202,6 +202,33 @@ async function main() {
|
|
|
202
202
|
if (!(await fileExists(runCtxLib))) fail("missing lib/harness-run-context.ts");
|
|
203
203
|
ok("lib/harness-run-context.ts");
|
|
204
204
|
|
|
205
|
+
const vendoredIndex = join(
|
|
206
|
+
ROOT,
|
|
207
|
+
".pi",
|
|
208
|
+
"extensions",
|
|
209
|
+
"lib",
|
|
210
|
+
"harness-subagents",
|
|
211
|
+
"vendored",
|
|
212
|
+
"index.ts",
|
|
213
|
+
);
|
|
214
|
+
const vendoredSrc = await readFile(vendoredIndex, "utf-8");
|
|
215
|
+
const runCtxImport = vendoredSrc.match(
|
|
216
|
+
/from ["']([^"']*harness-run-context\.js)["']/,
|
|
217
|
+
);
|
|
218
|
+
if (!runCtxImport) {
|
|
219
|
+
fail("vendored/index.ts must import harness-run-context.js");
|
|
220
|
+
}
|
|
221
|
+
const runCtxImportPath = resolve(
|
|
222
|
+
dirname(vendoredIndex),
|
|
223
|
+
runCtxImport[1].replace(/\.js$/, ".ts"),
|
|
224
|
+
);
|
|
225
|
+
if (runCtxImportPath !== runCtxLib) {
|
|
226
|
+
fail(
|
|
227
|
+
`vendored/index.ts harness-run-context import resolves to ${runCtxImportPath}, expected ${runCtxLib}`,
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
ok("vendored/index.ts harness-run-context import path");
|
|
231
|
+
|
|
205
232
|
const policyGateSrc = await readFile(
|
|
206
233
|
join(ROOT, ".pi", "extensions", "policy-gate.ts"),
|
|
207
234
|
"utf-8",
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ All notable changes to this project are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [v0.10.0] — 2026-05-17
|
|
8
|
+
|
|
9
|
+
### ✨ Features
|
|
10
|
+
|
|
11
|
+
- **Harness plan UX:** scrollable `approve_plan` overlay with `harness-plan-draft` parent transcript; planner-only `create_plan` persists canonical `plan-packet.json` after approval; blocks planner `write`/`edit` for plan files; syncs subagent approvals and dedupes duplicate plan-approval gates.
|
|
12
|
+
|
|
13
|
+
## [v0.9.1] — 2026-05-17
|
|
14
|
+
|
|
15
|
+
### 🐛 Fixes
|
|
16
|
+
|
|
17
|
+
- **npm package:** fix `harness-subagents` vendored import of `harness-run-context` (`../../../../lib`); broken installs failed with `Cannot find module '../../../lib/harness-run-context.js'`.
|
|
18
|
+
|
|
7
19
|
## [v0.9.0] — 2026-05-17
|
|
8
20
|
|
|
9
21
|
### ✨ Features
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ultimate-pi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Ultimate AI coding harness for pi.dev — extensible skills, Obsidian wiki knowledge layer, compressed context, deterministic output",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"@earendil-works/pi-coding-agent": "*"
|
|
74
74
|
},
|
|
75
75
|
"scripts": {
|
|
76
|
-
"check:ts": "tsc --noEmit --target ES2023 --lib ES2023 --moduleResolution nodenext --module nodenext --skipLibCheck .pi/extensions/00-ultimate-pi-system-prompt.ts .pi/lib/harness-run-context.ts .pi/lib/harness-ui-state.ts .pi/extensions/harness-run-context.ts .pi/extensions/lib/harness-vcc-settings.ts .pi/extensions/dotenv-loader.ts .pi/extensions/lib/posthog-node.d.ts .pi/extensions/lib/harness-posthog.ts .pi/extensions/lib/harness-paths.ts .pi/extensions/pi-model-router-harness.ts .pi/extensions/provider-payload-sanitize.ts .pi/extensions/harness-telemetry.ts .pi/extensions/harness-ask-user.ts .pi/extensions/lib/ask-user/schema.ts .pi/extensions/lib/ask-user/types.ts .pi/extensions/lib/ask-user/validate.ts .pi/extensions/lib/ask-user/dialog.ts .pi/extensions/lib/ask-user/fallback.ts .pi/extensions/lib/ask-user/render.ts .pi/extensions/trace-recorder.ts .pi/extensions/observation-bus.ts .pi/extensions/drift-monitor.ts .pi/extensions/policy-gate.ts .pi/extensions/budget-guard.ts .pi/extensions/debate-orchestrator.ts .pi/extensions/harness-live-widget.ts .pi/extensions/sentrux-rules-sync.ts .pi/extensions/custom-header.ts .pi/extensions/lib/harness-subagents/agent-loader.ts .pi/extensions/lib/harness-subagents/agent-parser.ts .pi/extensions/lib/harness-subagents/agent-manifest.ts .pi/extensions/lib/harness-subagents/blackboard.ts .pi/extensions/lib/harness-subagents/blackboard-tool.ts .pi/extensions/lib/harness-subagents/spawn-policy.ts .pi/extensions/lib/harness-subagents/types-blackboard.ts .pi/extensions/harness-web-tools.ts .pi/extensions/harness-web-guard.ts .pi/extensions/lib/harness-web/run-cli.ts",
|
|
76
|
+
"check:ts": "tsc --noEmit --target ES2023 --lib ES2023 --moduleResolution nodenext --module nodenext --skipLibCheck .pi/extensions/00-ultimate-pi-system-prompt.ts .pi/lib/harness-run-context.ts .pi/lib/harness-ui-state.ts .pi/extensions/harness-run-context.ts .pi/extensions/lib/harness-vcc-settings.ts .pi/extensions/dotenv-loader.ts .pi/extensions/lib/posthog-node.d.ts .pi/extensions/lib/harness-posthog.ts .pi/extensions/lib/harness-paths.ts .pi/extensions/pi-model-router-harness.ts .pi/extensions/provider-payload-sanitize.ts .pi/extensions/harness-telemetry.ts .pi/extensions/harness-ask-user.ts .pi/extensions/harness-plan-approval.ts .pi/extensions/lib/ask-user/schema.ts .pi/extensions/lib/ask-user/types.ts .pi/extensions/lib/ask-user/validate.ts .pi/extensions/lib/ask-user/dialog.ts .pi/extensions/lib/ask-user/fallback.ts .pi/extensions/lib/ask-user/render.ts .pi/extensions/lib/plan-approval/types.ts .pi/extensions/lib/plan-approval/schema.ts .pi/extensions/lib/plan-approval/validate.ts .pi/extensions/lib/plan-approval/format-plan.ts .pi/extensions/lib/plan-approval/dialog.ts .pi/extensions/lib/plan-approval/fallback.ts .pi/extensions/lib/plan-approval/render.ts .pi/extensions/lib/plan-approval/create-plan.ts .pi/extensions/lib/harness-subagents/parent-harness-ui-bridge.ts .pi/extensions/lib/harness-subagents/parent-harness-ui-hooks.ts .pi/extensions/lib/harness-subagents/parent-ask-user-bridge.ts .pi/extensions/trace-recorder.ts .pi/extensions/observation-bus.ts .pi/extensions/drift-monitor.ts .pi/extensions/policy-gate.ts .pi/extensions/budget-guard.ts .pi/extensions/debate-orchestrator.ts .pi/extensions/harness-live-widget.ts .pi/extensions/sentrux-rules-sync.ts .pi/extensions/custom-header.ts .pi/extensions/lib/harness-subagents/agent-loader.ts .pi/extensions/lib/harness-subagents/agent-parser.ts .pi/extensions/lib/harness-subagents/agent-manifest.ts .pi/extensions/lib/harness-subagents/blackboard.ts .pi/extensions/lib/harness-subagents/blackboard-tool.ts .pi/extensions/lib/harness-subagents/spawn-policy.ts .pi/extensions/lib/harness-subagents/types-blackboard.ts .pi/extensions/harness-web-tools.ts .pi/extensions/harness-web-guard.ts .pi/extensions/lib/harness-web/run-cli.ts",
|
|
77
77
|
"vendor:sync-router": "bash .pi/scripts/vendor-sync-pi-model-router.sh",
|
|
78
78
|
"vendor:sync-vcc": "bash .pi/scripts/vendor-sync-pi-vcc.sh",
|
|
79
79
|
"release": "bash .pi/scripts/release.sh",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"format": "biome format --write",
|
|
83
83
|
"format:check": "biome format",
|
|
84
84
|
"prepare": "lefthook install",
|
|
85
|
-
"test": "node --test test/harness-verify.test.mjs test/harness-ask-user.test.mjs test/harness-subagents-loader.test.mjs test/sentrux-rules-sync.test.mjs test/harness-budget-guard.test.mjs && npx -y tsx --test test/harness-vcc-settings.test.ts test/harness-plan-phase-policy.test.mjs test/harness-subagent-policy.test.mjs test/harness-turn-routing.test.mjs",
|
|
85
|
+
"test": "node --test test/harness-verify.test.mjs test/harness-ask-user.test.mjs test/harness-subagents-loader.test.mjs test/harness-subagents-import-path.test.mjs test/sentrux-rules-sync.test.mjs test/harness-budget-guard.test.mjs && npx -y tsx --test test/harness-vcc-settings.test.ts test/harness-plan-phase-policy.test.mjs test/harness-subagent-policy.test.mjs test/harness-turn-routing.test.mjs test/plan-approval-format.test.mjs test/plan-approval-sync.test.mjs test/plan-create-plan.test.mjs",
|
|
86
86
|
"test:vcc": "npx -y tsx --test vendor/pi-vcc/tests/*.test.ts",
|
|
87
87
|
"harness:sentrux-bootstrap": "node .pi/scripts/harness-sentrux-bootstrap.mjs",
|
|
88
88
|
"harness:sentrux-sync": "node .pi/scripts/sentrux-rules-sync.mjs --force",
|