pi-daddy 0.21.1 → 0.22.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 +20 -1
- package/README.md +12 -7
- package/contracts/ledger/v3/fixtures/capability-decision.json +3 -4
- package/contracts/ledger/v3/fixtures/check-receipt.json +3 -4
- package/contracts/ledger/v3/fixtures/child-lifecycle.json +3 -4
- package/contracts/ledger/v3/fixtures/workflow-fact.json +3 -4
- package/contracts/ledger/v3/fixtures/workspace-lease.json +3 -4
- package/contracts/ledger/v3/ledger-event.schema.json +38 -13
- package/dist/check-runner.d.ts.map +1 -1
- package/dist/check-runner.js +161 -149
- package/dist/check-runner.js.map +1 -1
- package/dist/correlation.d.ts +15 -4
- package/dist/correlation.d.ts.map +1 -1
- package/dist/correlation.js +40 -2
- package/dist/correlation.js.map +1 -1
- package/dist/delegation-approval.d.ts +2 -2
- package/dist/delegation-approval.d.ts.map +1 -1
- package/dist/delegation-approval.js +2 -0
- package/dist/delegation-approval.js.map +1 -1
- package/dist/finalization.d.ts +15 -0
- package/dist/finalization.d.ts.map +1 -0
- package/dist/finalization.js +65 -0
- package/dist/finalization.js.map +1 -0
- package/dist/git-identity.d.ts.map +1 -1
- package/dist/git-identity.js +18 -15
- package/dist/git-identity.js.map +1 -1
- package/dist/grant-store.d.ts +13 -0
- package/dist/grant-store.d.ts.map +1 -1
- package/dist/grant-store.js +48 -25
- package/dist/grant-store.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +2 -6
- package/dist/init.js.map +1 -1
- package/dist/model-preflight.d.ts +8 -0
- package/dist/model-preflight.d.ts.map +1 -0
- package/dist/model-preflight.js +20 -0
- package/dist/model-preflight.js.map +1 -0
- package/dist/refusals.d.ts +1 -1
- package/dist/refusals.d.ts.map +1 -1
- package/dist/refusals.js +2 -0
- package/dist/refusals.js.map +1 -1
- package/dist/run-herdr.d.ts.map +1 -1
- package/dist/run-herdr.js +6 -5
- package/dist/run-herdr.js.map +1 -1
- package/extensions/chain-plan.ts +16 -0
- package/extensions/correlation-shape.ts +39 -0
- package/extensions/delegate-chain.ts +9 -14
- package/extensions/delegation.ts +2 -24
- package/extensions/execute-child.ts +8 -1
- package/extensions/grant-store-refusal.ts +36 -0
- package/extensions/grants.ts +6 -0
- package/extensions/run-delegation.ts +21 -2
- package/extensions/session.ts +15 -5
- package/extensions/stored-grant-session.ts +33 -0
- package/package.json +3 -1
- package/src/check-runner.ts +56 -44
- package/src/correlation.ts +55 -6
- package/src/delegation-approval.ts +4 -2
- package/src/finalization.ts +79 -0
- package/src/git-identity.ts +20 -16
- package/src/grant-store.ts +55 -25
- package/src/init.ts +5 -5
- package/src/model-preflight.ts +32 -0
- package/src/refusals.ts +2 -0
- package/src/run-herdr.ts +6 -4
package/src/init.ts
CHANGED
|
@@ -26,6 +26,7 @@ import { mkdir, open, rm, writeFile } from "node:fs/promises";
|
|
|
26
26
|
import { join } from "node:path";
|
|
27
27
|
import { agentCapability, workspaceCapability } from "./capabilities.ts";
|
|
28
28
|
import { ceilingForDefinition } from "./definitions.ts";
|
|
29
|
+
import { runWithFinalizers } from "./finalization.ts";
|
|
29
30
|
import { ALWAYS_LIVE, assertGrantIsWritable, isLiveByDefault, renderGrantEnv, type GrantEnvSkill } from "./grant-env.ts";
|
|
30
31
|
import { PI_BUILTIN_TOOLS } from "./pi-tools.ts";
|
|
31
32
|
import type { Capability } from "./resolve.ts";
|
|
@@ -332,11 +333,10 @@ async function createUnlessPresent(path: string, content: string, outcome: InitO
|
|
|
332
333
|
try {
|
|
333
334
|
await mkdir(join(path, ".."), { recursive: true });
|
|
334
335
|
const handle = await open(path, "wx");
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}
|
|
336
|
+
await runWithFinalizers(
|
|
337
|
+
() => handle.writeFile(content, "utf8"),
|
|
338
|
+
[{ label: "new-file handle cleanup failed", run: () => handle.close() }],
|
|
339
|
+
);
|
|
340
340
|
outcome.written.push(path);
|
|
341
341
|
} catch (error) {
|
|
342
342
|
if ((error as { code?: string }).code === "EEXIST") outcome.kept.push(path);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { refusal, type StructuredRefusal } from "./refusals.ts";
|
|
2
|
+
|
|
3
|
+
export const ENV_ALLOW_UNRESOLVED_MODELS = "PI_GRANTS_ALLOW_UNRESOLVED_MODELS";
|
|
4
|
+
|
|
5
|
+
export interface ModelCatalogue {
|
|
6
|
+
find(provider: string, modelId: string): unknown;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** Resolve an explicit provider/id against pi's own session catalogue without probing credentials or network. */
|
|
10
|
+
export function preflightModel(
|
|
11
|
+
model: string | undefined,
|
|
12
|
+
catalogue: ModelCatalogue,
|
|
13
|
+
cache: Map<string, boolean>,
|
|
14
|
+
allowUnresolved: boolean,
|
|
15
|
+
): StructuredRefusal | undefined {
|
|
16
|
+
if (model === undefined || allowUnresolved) return undefined;
|
|
17
|
+
const slash = model.indexOf("/");
|
|
18
|
+
const provider = slash > 0 ? model.slice(0, slash) : "";
|
|
19
|
+
const id = slash > 0 ? model.slice(slash + 1) : "";
|
|
20
|
+
let resolved = cache.get(model);
|
|
21
|
+
if (resolved === undefined) {
|
|
22
|
+
resolved = provider.length > 0 && id.length > 0 && catalogue.find(provider, id) !== undefined;
|
|
23
|
+
cache.set(model, resolved);
|
|
24
|
+
}
|
|
25
|
+
if (resolved) return undefined;
|
|
26
|
+
return refusal(
|
|
27
|
+
"MODEL_UNRESOLVED",
|
|
28
|
+
`grants: model ${model || "(empty)"} is not in pi's session catalogue; use provider/id from /model, ` +
|
|
29
|
+
`or set ${ENV_ALLOW_UNRESOLVED_MODELS}=1 to let pi attempt custom resolution`,
|
|
30
|
+
{ model: model || "(empty)" },
|
|
31
|
+
);
|
|
32
|
+
}
|
package/src/refusals.ts
CHANGED
|
@@ -11,6 +11,8 @@ export const REFUSAL_CODES = [
|
|
|
11
11
|
"DEPTH_EXCEEDED",
|
|
12
12
|
"FANOUT_EXCEEDED",
|
|
13
13
|
"EXECUTOR_UNAVAILABLE",
|
|
14
|
+
"MODEL_UNRESOLVED",
|
|
15
|
+
"GRANT_STORE_INVALID",
|
|
14
16
|
// Execution-phase outcomes. Without these, an external controller could distinguish a policy refusal
|
|
15
17
|
// from an internal error but not a lost writer lease from a user pressing stop (R-103).
|
|
16
18
|
"CHILD_TIMED_OUT",
|
package/src/run-herdr.ts
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import { rm } from "node:fs/promises";
|
|
25
|
+
import { runWithFinalizers } from "./finalization.ts";
|
|
25
26
|
import type { ChildRunResult } from "./run-child.ts";
|
|
26
27
|
import { DEFAULT_MAX_OUTPUT_BYTES, DEFAULT_TIMEOUT_MS } from "./run-child.ts";
|
|
27
28
|
import { MAX_OPEN_PANES, markPaneSettled, trackPane, trimOpenPanes, untrackPane } from "./pane-reaper.ts";
|
|
@@ -293,7 +294,7 @@ export async function runHerdrPane(request: HerdrRunRequest): Promise<ChildRunRe
|
|
|
293
294
|
// early `return` from a failed start or prompt — leaves it false, so `cleanup` closes the tab.
|
|
294
295
|
let settledCleanly = false;
|
|
295
296
|
|
|
296
|
-
|
|
297
|
+
return runWithFinalizers(async () => {
|
|
297
298
|
const started = await startAgent(exec, agentName, paneId, effectiveArgs, deadline);
|
|
298
299
|
if (started.error) return { ...empty, spawnError: `herdr agent start failed: ${started.error}` };
|
|
299
300
|
|
|
@@ -352,9 +353,10 @@ export async function runHerdrPane(request: HerdrRunRequest): Promise<ChildRunRe
|
|
|
352
353
|
timedOut: false,
|
|
353
354
|
aborted: false,
|
|
354
355
|
};
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
|
|
356
|
+
}, [{
|
|
357
|
+
label: "herdr pane finalizer failed",
|
|
358
|
+
run: () => cleanup(settledCleanly),
|
|
359
|
+
}]);
|
|
358
360
|
}
|
|
359
361
|
|
|
360
362
|
/**
|