pi.lock 0.0.0-stage → 0.1.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.
Files changed (49) hide show
  1. package/README.md +91 -2
  2. package/dist/bridge.d.ts +7 -0
  3. package/dist/bridge.js +18 -0
  4. package/dist/bridge.js.map +1 -0
  5. package/dist/cli.d.ts +2 -0
  6. package/dist/cli.js +82 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands.d.ts +1 -0
  9. package/dist/commands.js +114 -0
  10. package/dist/commands.js.map +1 -0
  11. package/dist/common.d.ts +17 -0
  12. package/dist/common.js +87 -0
  13. package/dist/common.js.map +1 -0
  14. package/dist/definition.d.ts +32 -0
  15. package/dist/definition.js +384 -0
  16. package/dist/definition.js.map +1 -0
  17. package/dist/index.d.ts +5 -0
  18. package/dist/index.js +5 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/init.d.ts +6 -0
  21. package/dist/init.js +39 -0
  22. package/dist/init.js.map +1 -0
  23. package/dist/loader.d.ts +48 -0
  24. package/dist/loader.js +141 -0
  25. package/dist/loader.js.map +1 -0
  26. package/dist/lock.d.ts +17 -0
  27. package/dist/lock.js +93 -0
  28. package/dist/lock.js.map +1 -0
  29. package/dist/mcp.d.ts +8 -0
  30. package/dist/mcp.js +113 -0
  31. package/dist/mcp.js.map +1 -0
  32. package/dist/model.d.ts +14 -0
  33. package/dist/model.js +78 -0
  34. package/dist/model.js.map +1 -0
  35. package/dist/runtime.d.ts +37 -0
  36. package/dist/runtime.js +266 -0
  37. package/dist/runtime.js.map +1 -0
  38. package/docs/acceptance.md +54 -0
  39. package/docs/acceptance.tap +178 -0
  40. package/docs/architecture.md +47 -0
  41. package/examples/demo/.pi/SYSTEM.md +1 -0
  42. package/examples/demo/.pi/extensions/demo.ts +13 -0
  43. package/examples/demo/.pi/models.json +26 -0
  44. package/examples/demo/.pi/prompts/hello.md +4 -0
  45. package/examples/demo/.pi/settings.json +15 -0
  46. package/examples/demo/.pi/skills/explain/SKILL.md +5 -0
  47. package/examples/demo/pi.lock +473 -0
  48. package/npm-shrinkwrap.json +1880 -0
  49. package/package.json +46 -4
package/dist/loader.js ADDED
@@ -0,0 +1,141 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { basename, dirname, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { createJiti } from "jiti";
5
+ import { createEventBus, createExtensionRuntime, createCodemodeExtension, createToolSearchExtension, createSyntheticSourceInfo, parseFrontmatter } from "@earendil-works/pi-coding-agent";
6
+ import { explicitExtensionLoader, internalModule } from "./bridge.js";
7
+ import { fail } from "./common.js";
8
+ import { prepareMcp } from "./mcp.js";
9
+ export class LockedResourceLoader {
10
+ root;
11
+ workspace;
12
+ definition;
13
+ env;
14
+ expectedMcp;
15
+ extensions;
16
+ themes = [];
17
+ mcp;
18
+ constructor(root, workspace, definition, env = process.env, expectedMcp) {
19
+ this.root = root;
20
+ this.workspace = workspace;
21
+ this.definition = definition;
22
+ this.env = env;
23
+ this.expectedMcp = expectedMcp;
24
+ }
25
+ async reload() {
26
+ try {
27
+ await this.load();
28
+ }
29
+ catch (error) {
30
+ await this.mcp?.close();
31
+ throw error;
32
+ }
33
+ }
34
+ async load() {
35
+ const events = createEventBus();
36
+ const bridge = await explicitExtensionLoader();
37
+ const shared = createExtensionRuntime();
38
+ const paths = [...this.definition.resources.extensions];
39
+ this.mcp = await prepareMcp(this.root, this.workspace, this.env, this.expectedMcp);
40
+ if (this.mcp) {
41
+ for (const name of ["builtin:codemode", "builtin:tool_search"])
42
+ if (!paths.includes(name) && !this.definition.settings.extensions?.includes(`-${name}`))
43
+ paths.push(name);
44
+ }
45
+ const alias = {};
46
+ alias["pi.lock"] = fileURLToPath(new URL("./index.js", import.meta.url));
47
+ for (const name of ["@earendil-works/pi-coding-agent", "@earendil-works/pi-agent-core", "@earendil-works/pi-tui", "typebox", "typebox/compile", "typebox/value"])
48
+ alias[name] = fileURLToPath(import.meta.resolve(name));
49
+ for (const sub of ["", "/compat", "/oauth", "/providers/all"])
50
+ alias[`@earendil-works/pi-ai${sub}`] = fileURLToPath(import.meta.resolve(`@earendil-works/pi-ai${sub || "/compat"}`));
51
+ for (const [key, value] of Object.entries({ ...alias }))
52
+ if (key.startsWith("@earendil-works/"))
53
+ alias[key.replace("@earendil-works/", "@mariozechner/")] = value;
54
+ alias["@sinclair/typebox"] = alias.typebox;
55
+ alias["@sinclair/typebox/compile"] = alias["typebox/compile"];
56
+ alias["@sinclair/typebox/value"] = alias["typebox/value"];
57
+ const jiti = createJiti(import.meta.url, { alias, moduleCache: false, fsCache: false, tsconfigPaths: false, tryNative: false, interopDefault: true, transformModules: [], nativeModules: ["@earendil-works/pi-coding-agent", "@earendil-works/pi-ai", "@earendil-works/pi-agent-core", "@earendil-works/pi-tui", "typebox"] });
58
+ const result = { extensions: [], errors: [], runtime: shared };
59
+ try {
60
+ for (const path of paths.filter(p => !p.startsWith("builtin:"))) {
61
+ const full = resolve(this.root, path);
62
+ const factory = await jiti.import(full, { default: true });
63
+ if (typeof factory !== "function")
64
+ fail("INVALID_EXTENSION", `${path} must export a default Pi extension factory.`);
65
+ result.extensions.push(await bridge.loadExtensionFromFactory(factory, this.workspace, events, shared, full));
66
+ }
67
+ }
68
+ catch (error) {
69
+ await this.mcp?.close();
70
+ throw error;
71
+ }
72
+ // Reorder factories to exactly the locked declaration order, including built-ins.
73
+ const ordered = [];
74
+ for (const path of paths) {
75
+ if (path.startsWith("builtin:")) {
76
+ const factory = path === "builtin:codemode" ? createCodemodeExtension() : createToolSearchExtension();
77
+ ordered.push(await bridge.loadExtensionFromFactory(factory, this.workspace, events, shared, path));
78
+ }
79
+ else {
80
+ const extension = result.extensions.find(e => e.resolvedPath === resolve(this.root, path) || e.path === resolve(this.root, path));
81
+ if (extension)
82
+ ordered.push(extension);
83
+ }
84
+ }
85
+ if (this.mcp)
86
+ ordered.push(await bridge.loadExtensionFromFactory(this.mcp.factory, this.workspace, events, shared, "builtin:mcp"));
87
+ if (result.errors.length)
88
+ fail("EXTENSION_LOAD_FAILED", result.errors.map(e => `${e.path}: ${e.error}`).join("\n"));
89
+ const names = new Set();
90
+ for (const extension of ordered)
91
+ for (const name of extension.tools.keys()) {
92
+ if (names.has(name))
93
+ fail("RESOURCE_COLLISION", `Duplicate tool name ${name}.`);
94
+ names.add(name);
95
+ }
96
+ this.extensions = { ...result, extensions: ordered };
97
+ const themeModule = this.definition.resources.themes.length ? await internalModule("./modes/interactive/theme/theme.js") : undefined;
98
+ this.themes = this.definition.resources.themes.map(path => themeModule.loadThemeFromPath(resolve(this.root, path)));
99
+ this.getSkills();
100
+ this.getPrompts(); // Validate metadata and duplicate names before running.
101
+ }
102
+ getExtensions() { return this.extensions; }
103
+ getSkills() {
104
+ const names = new Set();
105
+ const skills = this.definition.resources.skills.map(path => {
106
+ const filePath = resolve(this.root, path);
107
+ const { frontmatter } = parseFrontmatter(readFileSync(filePath, "utf8"));
108
+ const name = String(frontmatter.name ?? (basename(path) === "SKILL.md" ? basename(dirname(path)) : basename(path, ".md")));
109
+ if (!frontmatter.description || typeof frontmatter.description !== "string")
110
+ fail("INVALID_SKILL", `${path} needs a description in its frontmatter.`);
111
+ if (names.has(name))
112
+ fail("RESOURCE_COLLISION", `Duplicate skill name ${name}.`);
113
+ names.add(name);
114
+ return { name, description: frontmatter.description, filePath, baseDir: dirname(filePath), sourceInfo: createSyntheticSourceInfo(filePath, { source: "pi.lock", scope: "project" }), disableModelInvocation: frontmatter["disable-model-invocation"] === true };
115
+ });
116
+ return { skills, diagnostics: [] };
117
+ }
118
+ getPrompts() {
119
+ const names = new Set();
120
+ const prompts = this.definition.resources.prompts.map(path => {
121
+ const { frontmatter, body } = parseFrontmatter(readFileSync(resolve(this.root, path), "utf8"));
122
+ const name = basename(path, ".md");
123
+ if (names.has(name))
124
+ fail("RESOURCE_COLLISION", `Duplicate prompt name ${name}.`);
125
+ names.add(name);
126
+ return { name, description: String(frontmatter.description ?? body.split("\n").find(s => s.trim()) ?? name), content: body, sourceInfo: createSyntheticSourceInfo(resolve(this.root, path), { source: "pi.lock", scope: "project" }), filePath: resolve(this.root, path) };
127
+ });
128
+ return { prompts, diagnostics: [] };
129
+ }
130
+ getThemes() { return { themes: this.themes, diagnostics: [] }; }
131
+ getAgentsFiles() { return { agentsFiles: this.definition.resources.context.map(path => ({ path: resolve(this.root, path), content: readFileSync(resolve(this.root, path), "utf8") })) }; }
132
+ getSystemPrompt() { const p = this.definition.resources.system; return p ? readFileSync(resolve(this.root, p), "utf8") : undefined; }
133
+ getSystemPromptSource() { const p = this.definition.resources.system; return p ? { path: resolve(this.root, p) } : undefined; }
134
+ getAppendSystemPrompt() { const p = this.definition.resources.append; return p ? [readFileSync(resolve(this.root, p), "utf8")] : []; }
135
+ getAppendSystemPromptSources() { const p = this.definition.resources.append; return p ? [{ path: resolve(this.root, p) }] : []; }
136
+ extendResources(paths) {
137
+ if ([paths.skillPaths, paths.promptPaths, paths.themePaths].some(p => p?.length))
138
+ fail("UNLOCKED_RESOURCE", "An extension attempted to discover additional resources. Declare them in .pi/settings.json and re-lock.");
139
+ }
140
+ }
141
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
package/dist/lock.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { runtimeIdentity, type Definition } from "./definition.js";
2
+ export interface AgentLock {
3
+ lockfileVersion: 1;
4
+ runtime: ReturnType<typeof runtimeIdentity>;
5
+ definition: Definition;
6
+ model: unknown;
7
+ effective?: unknown;
8
+ agentDigest: string;
9
+ }
10
+ export declare function lockDigest(lock: Omit<AgentLock, "agentDigest"> | AgentLock): string;
11
+ export declare function draftLock(root: string, allowUnselectedModel?: boolean): Promise<AgentLock>;
12
+ export declare function readLock(root: string): AgentLock;
13
+ export declare function verifyDefinition(root: string, lock: AgentLock): void;
14
+ export declare function verifySnapshot(root: string, lock: AgentLock): void;
15
+ export declare function verifySourcesBeforeInstall(root: string, lock: AgentLock): void;
16
+ export declare function materialize(root: string, lock: AgentLock): string;
17
+ export declare function saveLock(root: string, lock: AgentLock): void;
package/dist/lock.js ADDED
@@ -0,0 +1,93 @@
1
+ import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
2
+ import { dirname, resolve } from "node:path";
3
+ import { atomicJson, digest, fail, FORMAT, hash, inside, json, PI_VERSION } from "./common.js";
4
+ import { readDefinition, runtimeIdentity } from "./definition.js";
5
+ import { modelIdentity, modelRuntime, selectedModel } from "./model.js";
6
+ export function lockDigest(lock) {
7
+ const { agentDigest: _, ...content } = lock;
8
+ return digest(content);
9
+ }
10
+ export async function draftLock(root, allowUnselectedModel = false) {
11
+ const definition = readDefinition(root, allowUnselectedModel);
12
+ const runtime = await modelRuntime(definition, { env: {} });
13
+ const selected = selectedModel(runtime, definition, allowUnselectedModel);
14
+ const model = selected ? modelIdentity(selected) : null;
15
+ const content = { lockfileVersion: FORMAT, runtime: runtimeIdentity(), definition, model };
16
+ return { ...content, agentDigest: lockDigest(content) };
17
+ }
18
+ export function readLock(root) {
19
+ const path = resolve(root, "pi.lock");
20
+ if (!existsSync(path))
21
+ fail("LOCK_MISSING", "No pi.lock found. Run pi-lock lock once before frozen execution, or use --dev while editing.");
22
+ const lock = json(path);
23
+ if (lock.lockfileVersion !== FORMAT || !Array.isArray(lock.definition?.files) || !lock.runtime)
24
+ fail("LOCK_FORMAT", "Unsupported or malformed pi.lock.");
25
+ if (lockDigest(lock) !== lock.agentDigest)
26
+ fail("LOCK_CORRUPT", "pi.lock content does not match its digest.");
27
+ if (lock.runtime.pi !== PI_VERSION || digest(lock.runtime) !== digest(runtimeIdentity()))
28
+ fail("ENGINE_MISMATCH", "Installed Pi/pi-lock runtime differs from pi.lock. Restore the matching npm dependencies and pi-lock release.");
29
+ return lock;
30
+ }
31
+ export function verifyDefinition(root, lock) {
32
+ const definition = readDefinition(root);
33
+ if (digest(definition) !== digest(lock.definition)) {
34
+ const changed = definition.files.filter(f => lock.definition.files.find(p => p.path === f.path)?.sha256 !== f.sha256).map(f => f.path);
35
+ const removed = lock.definition.files.filter(f => !definition.files.some(p => p.path === f.path)).map(f => f.path);
36
+ fail("LOCK_DRIFT", `Agent files/configuration differ from pi.lock: ${[...changed, ...removed].slice(0, 8).join(", ") || "resolved resources"}. Review your changes, then run pi-lock lock.`);
37
+ }
38
+ }
39
+ export function verifySnapshot(root, lock) {
40
+ for (const file of lock.definition.files) {
41
+ const path = inside(root, file.path);
42
+ if (!existsSync(path) || hash(readFileSync(path)) !== file.sha256 || Boolean(statSync(path).mode & 0o111) !== file.executable)
43
+ fail("SNAPSHOT_CORRUPT", `Release resource changed: ${file.path}`);
44
+ }
45
+ }
46
+ export function verifySourcesBeforeInstall(root, lock) {
47
+ for (const file of lock.definition.files.filter(f => !f.path.startsWith("node_modules/") && !f.path.includes("/node_modules/"))) {
48
+ const path = inside(root, file.path);
49
+ if (!existsSync(path) || hash(readFileSync(path)) !== file.sha256)
50
+ fail("LOCK_DRIFT", `Source changed before restoring dependencies: ${file.path}`);
51
+ }
52
+ }
53
+ export function materialize(root, lock) {
54
+ const release = resolve(root, ".pi-lock/releases", lock.agentDigest);
55
+ if (existsSync(resolve(release, ".complete"))) {
56
+ verifySnapshot(release, lock);
57
+ return release;
58
+ }
59
+ mkdirSync(dirname(release), { recursive: true });
60
+ const staging = `${release}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
61
+ mkdirSync(staging);
62
+ try {
63
+ for (const file of lock.definition.files) {
64
+ const source = inside(root, file.path);
65
+ const target = inside(staging, file.path);
66
+ const data = readFileSync(source);
67
+ if (hash(data) !== file.sha256)
68
+ fail("LOCK_DRIFT", `Source changed while creating release: ${file.path}`);
69
+ mkdirSync(dirname(target), { recursive: true });
70
+ writeFileSync(target, data, { mode: file.executable ? 0o755 : 0o644 });
71
+ }
72
+ verifySnapshot(staging, lock);
73
+ writeFileSync(resolve(staging, ".complete"), lock.agentDigest);
74
+ try {
75
+ renameSync(staging, release);
76
+ }
77
+ catch (e) {
78
+ if (!existsSync(resolve(release, ".complete")))
79
+ throw e;
80
+ rmSync(staging, { recursive: true, force: true });
81
+ }
82
+ }
83
+ catch (e) {
84
+ rmSync(staging, { recursive: true, force: true });
85
+ throw e;
86
+ }
87
+ return release;
88
+ }
89
+ export function saveLock(root, lock) {
90
+ lock.agentDigest = lockDigest(lock);
91
+ atomicJson(resolve(root, "pi.lock"), lock);
92
+ }
93
+ //# sourceMappingURL=lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.js","sourceRoot":"","sources":["../src/lock.ts"],"names":[],"mappings":"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"}
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { ExtensionFactory } from "@earendil-works/pi-coding-agent";
2
+ export interface LockedMcp {
3
+ factory: ExtensionFactory;
4
+ catalog: Record<string, unknown>;
5
+ check(): Promise<void>;
6
+ close(): Promise<void>;
7
+ }
8
+ export declare function prepareMcp(root: string, workspace: string, env: Record<string, string | undefined>, expected?: Record<string, unknown>): Promise<LockedMcp | undefined>;
package/dist/mcp.js ADDED
@@ -0,0 +1,113 @@
1
+ import { existsSync } from "node:fs";
2
+ import { dirname, resolve } from "node:path";
3
+ import { pathToFileURL } from "node:url";
4
+ import { McpClient, StdioTransport, StreamableHttpTransport } from "@earendil-works/pi-mcp";
5
+ import { Type } from "typebox";
6
+ import { digest, fail, inside, json } from "./common.js";
7
+ import { internalModule } from "./bridge.js";
8
+ function interpolate(value, env) {
9
+ return value.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/g, (_, name) => env[name] ?? fail("MISSING_CREDENTIAL", `MCP needs environment binding ${name}.`));
10
+ }
11
+ export async function prepareMcp(root, workspace, env, expected) {
12
+ const path = resolve(root, ".pi/mcp.json");
13
+ if (!existsSync(path))
14
+ return undefined;
15
+ const cfg = json(path);
16
+ const catalog = {};
17
+ const clients = new Map();
18
+ const toolModule = await internalModule("./extensions/mcp/tools.js");
19
+ const close = async () => { await Promise.allSettled([...clients.values()].map(c => c.close())); };
20
+ function metadata(client, tools) {
21
+ return { server: client.serverInfo, capabilities: client.serverCapabilities, instructions: client.instructions, tools };
22
+ }
23
+ try {
24
+ for (const [name, server] of Object.entries(cfg.mcpServers ?? {})) {
25
+ if (server.enabled === false || server.exposure === "hidden")
26
+ continue;
27
+ if (server.oauth || server.auth)
28
+ fail("UNSUPPORTED_MCP_AUTH", `${name}: supply an explicit HTTP Authorization environment binding; global Pi OAuth is never loaded.`);
29
+ const client = new McpClient({ name: "pi-lock", version: "0.1.1", requestTimeoutMs: server.timeout ?? 10000,
30
+ roots: [{ uri: pathToFileURL(workspace).href, name: "workspace" }] });
31
+ clients.set(name, client);
32
+ if (server.command) {
33
+ const command = server.command === "node" ? process.execPath : server.command.startsWith(".") ? inside(root, server.command) : fail("UNLOCKED_MCP_COMMAND", `${name}: use node or a checked-in project-relative executable; install runner dependencies locally instead of using npx/global commands.`);
34
+ const args = (server.args ?? []).map((arg) => interpolate(arg.replaceAll("${WORKSPACE}", workspace).replaceAll("${AGENT_ROOT}", root), env));
35
+ const variables = Object.fromEntries(Object.entries(server.env ?? {}).map(([key, value]) => [key, interpolate(value, env)]));
36
+ await client.connect(new StdioTransport({ command, args, cwd: root, inheritEnv: false, env: { PATH: dirname(process.execPath), ...variables }, stderr: "pipe" }));
37
+ }
38
+ else if (server.url) {
39
+ for (const [key, value] of Object.entries(server.headers ?? {}))
40
+ if (/authorization|token|api[-_]?key/i.test(key) && !/\$\{[A-Z_][A-Z0-9_]*\}/.test(value))
41
+ fail("SECRET_IN_DEFINITION", `${name}: ${key} must use an environment binding, not a literal secret.`);
42
+ const headers = Object.fromEntries(Object.entries(server.headers ?? {}).map(([key, value]) => [key, interpolate(value, env)]));
43
+ await client.connect(new StreamableHttpTransport({ url: server.url, headers, openGetStream: true }));
44
+ }
45
+ else
46
+ fail("INVALID_MCP", `${name}: expected command or url.`);
47
+ const tools = client.serverCapabilities?.tools ? await client.listTools() : [];
48
+ catalog[name] = metadata(client, tools);
49
+ }
50
+ if (expected && digest(catalog) !== digest(expected))
51
+ fail("MCP_SCHEMA_DRIFT", "MCP server instructions, capabilities or tool schemas differ from pi.lock. Review and re-lock.");
52
+ }
53
+ catch (e) {
54
+ await close();
55
+ throw e;
56
+ }
57
+ const check = async () => {
58
+ for (const [name, client] of clients) {
59
+ const current = metadata(client, client.serverCapabilities?.tools ? await client.listTools() : []);
60
+ if (digest(current) !== digest(catalog[name]))
61
+ fail("MCP_SCHEMA_DRIFT", `MCP ${name} changed its catalogue during this session.`);
62
+ }
63
+ };
64
+ const factory = pi => {
65
+ const used = new Set();
66
+ for (const [name, client] of clients) {
67
+ const entry = cfg.mcpServers[name];
68
+ const data = catalog[name];
69
+ const namespace = { name: `mcp__${name}`, aliases: [name], description: name, instructions: data.instructions };
70
+ for (const tool of data.tools) {
71
+ const fullName = toolModule.createMcpToolName(name, tool.name, (candidate) => used.has(candidate));
72
+ used.add(fullName);
73
+ pi.registerTool(toolModule.createMcpToolDefinition({ server: name, tool, name: fullName,
74
+ exposure: entry.toolExposure?.[tool.name] ?? entry.exposure ?? "codemode", namespace,
75
+ timeoutMs: entry.timeout ?? 10000,
76
+ getClient: async () => { await check(); return client; },
77
+ readableResources: () => Boolean(client.serverCapabilities?.resources),
78
+ }));
79
+ }
80
+ }
81
+ const servers = () => [...clients].map(([name]) => name);
82
+ if ([...clients.values()].some(c => c.serverCapabilities?.resources)) {
83
+ pi.registerTool({ name: "list_mcp_resources", label: "MCP resources", description: "List resources from the locked MCP servers.", parameters: Type.Object({ server: Type.Optional(Type.String()) }),
84
+ execute: async (_id, args) => ({ content: [{ type: "text", text: JSON.stringify(await Promise.all(servers().filter(n => !args.server || n === args.server).map(async (server) => ({ server, resources: await clients.get(server).listResources() })))) }], details: {} }) });
85
+ pi.registerTool({ name: "list_mcp_resource_templates", label: "MCP templates", description: "List resource templates from the locked MCP servers.", parameters: Type.Object({ server: Type.Optional(Type.String()) }),
86
+ execute: async (_id, args) => ({ content: [{ type: "text", text: JSON.stringify(await Promise.all(servers().filter(n => !args.server || n === args.server).map(async (server) => ({ server, templates: await clients.get(server).listResourceTemplates() })))) }], details: {} }) });
87
+ pi.registerTool({ name: "read_mcp_resource", label: "Read MCP resource", description: "Read a resource from a locked MCP server.", parameters: Type.Object({ server: Type.String(), uri: Type.String() }),
88
+ execute: async (_id, args, signal) => {
89
+ const client = clients.get(args.server) ?? fail("UNKNOWN_MCP", `Unknown server ${args.server}`);
90
+ const result = await client.readResource(args.uri, { signal });
91
+ return { content: [{ type: "text", text: JSON.stringify(result) }], details: {} };
92
+ } });
93
+ }
94
+ pi.on("session_start", () => {
95
+ const active = new Set(pi.getActiveTools());
96
+ for (const [name] of clients) {
97
+ const exposure = cfg.mcpServers[name].exposure ?? "codemode";
98
+ if (exposure === "codemode" && cfg.autoEnableCodemode !== false)
99
+ active.add("codemode");
100
+ if (exposure === "deferred")
101
+ active.add("tool_search");
102
+ }
103
+ pi.setActiveTools([...active]);
104
+ });
105
+ pi.on("before_agent_start", event => {
106
+ const instructions = [...clients].map(([name, client]) => `${name}: ${client.instructions ?? ""}`).join("\n");
107
+ event.systemPromptOptions.sections.mcp_servers = instructions;
108
+ });
109
+ pi.on("session_shutdown", close);
110
+ };
111
+ return { factory, catalog, check, close };
112
+ }
113
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { ModelRuntime } from "@earendil-works/pi-coding-agent";
2
+ import { type CredentialStore } from "@earendil-works/pi-ai";
3
+ import type { Definition } from "./definition.js";
4
+ export interface CredentialsOptions {
5
+ apiKey?: string;
6
+ credentials?: CredentialStore;
7
+ /** Only named credential bindings are read. Never pass process.env into provider options. */
8
+ env?: Record<string, string | undefined>;
9
+ }
10
+ export declare function keyBinding(def: Definition): string;
11
+ export declare function modelRuntime(def: Definition, options?: CredentialsOptions, development?: boolean): Promise<ModelRuntime>;
12
+ export declare function selectedModel(runtime: ModelRuntime, def: Definition, allowUnselected?: boolean): import("@earendil-works/pi-ai").Model<import("@earendil-works/pi-ai").Api> | undefined;
13
+ export declare function modelIdentity(model: unknown): unknown;
14
+ export declare function assertModel(actual: unknown, expected: unknown): void;
package/dist/model.js ADDED
@@ -0,0 +1,78 @@
1
+ import { ModelRuntime } from "@earendil-works/pi-coding-agent";
2
+ import { InMemoryCredentialStore, InMemoryModelsStore } from "@earendil-works/pi-ai";
3
+ import { digest, fail } from "./common.js";
4
+ export function keyBinding(def) {
5
+ const provider = def.settings.defaultProvider;
6
+ const nativeNames = {
7
+ google: "GEMINI_API_KEY", "google-vertex": "GOOGLE_CLOUD_API_KEY", azure: "AZURE_OPENAI_API_KEY",
8
+ "vercel-ai-gateway": "AI_GATEWAY_API_KEY", huggingface: "HF_TOKEN", "github-copilot": "COPILOT_GITHUB_TOKEN",
9
+ moonshotai: "MOONSHOT_API_KEY", "moonshotai-cn": "MOONSHOT_API_KEY", "kimi-coding": "KIMI_API_KEY",
10
+ "opencode-go": "OPENCODE_API_KEY", "cloudflare-workers-ai": "CLOUDFLARE_API_KEY", "cloudflare-ai-gateway": "CLOUDFLARE_API_KEY",
11
+ "qwen-token-plan-individual": "QWEN_TOKEN_PLAN_API_KEY",
12
+ };
13
+ return def.modelConfig.providers?.[provider]?.apiKey ?? nativeNames[provider] ?? `${provider.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_API_KEY`;
14
+ }
15
+ export async function modelRuntime(def, options = {}, development = false) {
16
+ const provider = def.settings.defaultProvider;
17
+ const credentials = options.credentials ?? new InMemoryCredentialStore();
18
+ if (options.apiKey && !provider)
19
+ fail("MODEL_PROVIDER_REQUIRED", "Set a provider before injecting a single apiKey, or use named provider credentials in dev mode.");
20
+ const key = provider ? options.apiKey ?? (options.env ?? process.env)[keyBinding(def)] : undefined;
21
+ if (key && provider)
22
+ await credentials.modify(provider, async () => ({ type: "api_key", key }));
23
+ const runtime = await ModelRuntime.create({ credentials, modelsPath: null, modelsStore: new InMemoryModelsStore(), refreshOnCreate: false, allowModelNetwork: false });
24
+ for (const [id, config] of Object.entries(def.modelConfig.providers ?? {})) {
25
+ runtime.registerProvider(id, { ...config, apiKey: undefined });
26
+ }
27
+ const keys = new Map();
28
+ if (key && provider)
29
+ keys.set(provider, key);
30
+ if (development)
31
+ for (const entry of runtime.getProviders()) {
32
+ if (entry.id === provider)
33
+ continue;
34
+ const binding = keyBinding({ ...def, settings: { ...def.settings, defaultProvider: entry.id } });
35
+ const value = (options.env ?? process.env)[binding];
36
+ if (value) {
37
+ keys.set(entry.id, value);
38
+ await credentials.modify(entry.id, async () => ({ type: "api_key", key: value }));
39
+ }
40
+ }
41
+ const configured = async (id) => Boolean((development || id === provider) && (await credentials.read(id) || keys.has(id) || runtime.getRegisteredProviderConfig(id)?.apiKey));
42
+ const auth = runtime.getAuth.bind(runtime);
43
+ runtime.getAuth = (async (selected, overrides = {}) => {
44
+ const id = typeof selected === "string" ? selected : selected.provider;
45
+ if (!development && id !== provider)
46
+ fail("FROZEN_MODEL", `Agent is locked to provider ${provider}.`);
47
+ if (!await configured(id))
48
+ fail("MISSING_CREDENTIAL", `Supply apiKey/credentials through the SDK or set ${keyBinding({ ...def, settings: { ...def.settings, defaultProvider: id } })}. Global Pi authentication is not read.`);
49
+ return auth(selected, { ...overrides, apiKey: keys.get(id) ?? overrides.apiKey, env: {} });
50
+ });
51
+ const checkAuth = runtime.checkAuth.bind(runtime);
52
+ runtime.checkAuth = async (id, opts) => await configured(id) ? checkAuth(id, opts) : undefined;
53
+ // There is no need to discover another provider or refresh a remote catalog in a locked agent.
54
+ const refresh = runtime.refresh.bind(runtime);
55
+ runtime.refresh = async (opts = {}) => {
56
+ const selected = development ? opts.providers ?? runtime.getProviders().map(p => p.id) : [provider];
57
+ const safe = [];
58
+ for (const id of selected)
59
+ if (await configured(id))
60
+ safe.push(id);
61
+ return safe.length ? refresh({ ...opts, providers: safe, allowNetwork: false }) : { aborted: false, errors: new Map() };
62
+ };
63
+ return runtime;
64
+ }
65
+ export function selectedModel(runtime, def, allowUnselected = false) {
66
+ if (allowUnselected && (!def.settings.defaultProvider || !def.settings.defaultModel))
67
+ return undefined;
68
+ const model = runtime.getModel(def.settings.defaultProvider, def.settings.defaultModel);
69
+ if (!model)
70
+ fail("MODEL_NOT_FOUND", `Model ${def.settings.defaultProvider}/${def.settings.defaultModel} is not in Pi 1.3.0 or local .pi/models.json. No fallback model will be selected.`);
71
+ return model;
72
+ }
73
+ export function modelIdentity(model) { return model == null ? model : JSON.parse(JSON.stringify(model)); }
74
+ export function assertModel(actual, expected) {
75
+ if (digest(modelIdentity(actual)) !== digest(expected))
76
+ fail("MODEL_DRIFT", "The loaded model definition differs from pi.lock. Re-lock intentionally after reviewing the change.");
77
+ }
78
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { SessionManager, type AgentSession, type AgentSessionRuntime, type ExtensionUIContext } from "@earendil-works/pi-coding-agent";
2
+ import { type AgentLock } from "./lock.js";
3
+ import { type CredentialsOptions } from "./model.js";
4
+ export interface LockedSessionOptions extends CredentialsOptions {
5
+ /** Agent definition root. Defaults to the nearest pi.lock/.pi/settings.json above cwd. */
6
+ projectRoot?: string;
7
+ /** Task workspace; never used for resource discovery when projectRoot is supplied. */
8
+ cwd?: string;
9
+ sessionManager?: SessionManager;
10
+ sessionDir?: string;
11
+ /** Like pi --session; existing sessions must contain the same agentDigest. */
12
+ sessionFile?: string;
13
+ /** Explicit Pi UI callbacks; missing interaction handlers report INTERACTION_REQUIRED. */
14
+ uiContext?: Partial<ExtensionUIContext>;
15
+ dev?: boolean;
16
+ }
17
+ export interface LockedRuntime {
18
+ runtime: AgentSessionRuntime;
19
+ lock: AgentLock;
20
+ projectRoot: string;
21
+ releaseRoot: string;
22
+ inspect(): unknown;
23
+ bind(mode?: "tui" | "rpc" | "json" | "print", ui?: Partial<ExtensionUIContext>): Promise<void>;
24
+ dispose(): Promise<void>;
25
+ }
26
+ export declare function headlessUI(overrides?: Partial<ExtensionUIContext>): ExtensionUIContext;
27
+ export declare function effectiveConfiguration(session: AgentSession, releaseRoot: string, cwd: string, lock: AgentLock): unknown;
28
+ export declare function createLockedRuntime(options?: LockedSessionOptions, prepared?: AgentLock): Promise<LockedRuntime>;
29
+ /** Drop-in-shaped SDK entry: same Pi session, with project-only loading and frozen checks. */
30
+ export declare function createAgentSession(options?: LockedSessionOptions): Promise<{
31
+ readonly session: AgentSession;
32
+ runtime: AgentSessionRuntime;
33
+ inspect: () => unknown;
34
+ readonly agentDigest: string;
35
+ dispose: () => Promise<void>;
36
+ }>;
37
+ export declare function lockProject(projectRoot: string): Promise<AgentLock>;