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.
- package/README.md +91 -2
- package/dist/bridge.d.ts +7 -0
- package/dist/bridge.js +18 -0
- package/dist/bridge.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +82 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.d.ts +1 -0
- package/dist/commands.js +114 -0
- package/dist/commands.js.map +1 -0
- package/dist/common.d.ts +17 -0
- package/dist/common.js +87 -0
- package/dist/common.js.map +1 -0
- package/dist/definition.d.ts +32 -0
- package/dist/definition.js +384 -0
- package/dist/definition.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +6 -0
- package/dist/init.js +39 -0
- package/dist/init.js.map +1 -0
- package/dist/loader.d.ts +48 -0
- package/dist/loader.js +141 -0
- package/dist/loader.js.map +1 -0
- package/dist/lock.d.ts +17 -0
- package/dist/lock.js +93 -0
- package/dist/lock.js.map +1 -0
- package/dist/mcp.d.ts +8 -0
- package/dist/mcp.js +113 -0
- package/dist/mcp.js.map +1 -0
- package/dist/model.d.ts +14 -0
- package/dist/model.js +78 -0
- package/dist/model.js.map +1 -0
- package/dist/runtime.d.ts +37 -0
- package/dist/runtime.js +266 -0
- package/dist/runtime.js.map +1 -0
- package/docs/acceptance.md +54 -0
- package/docs/acceptance.tap +178 -0
- package/docs/architecture.md +47 -0
- package/examples/demo/.pi/SYSTEM.md +1 -0
- package/examples/demo/.pi/extensions/demo.ts +13 -0
- package/examples/demo/.pi/models.json +26 -0
- package/examples/demo/.pi/prompts/hello.md +4 -0
- package/examples/demo/.pi/settings.json +15 -0
- package/examples/demo/.pi/skills/explain/SKILL.md +5 -0
- package/examples/demo/pi.lock +473 -0
- package/npm-shrinkwrap.json +1880 -0
- package/package.json +46 -4
package/README.md
CHANGED
|
@@ -1,3 +1,92 @@
|
|
|
1
|
-
#
|
|
1
|
+
# pi.lock
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use one Pi agent from the terminal, RPC, or the SDK with the same project configuration and resources. Commit `pi.lock` with your code to deploy or roll back the agent through Git.
|
|
4
|
+
|
|
5
|
+
Requires Node.js **22.19+** and supports Pi **1.3.0**.
|
|
6
|
+
|
|
7
|
+
## Install and configure
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install pi.lock
|
|
11
|
+
npx pi-lock init --provider deepseek --model deepseek-chat
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Set your provider API key, for example `DEEPSEEK_API_KEY`. If you already have `.pi/settings.json`, keep it and skip `init`.
|
|
15
|
+
|
|
16
|
+
Tune the agent in development mode. Edit its instructions, skills, or extensions under `.pi/` as needed:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npx pi-lock --dev
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
If no default model is configured, start anyway. Sign in with `/login` if needed, then choose a model with Pi's `/model` selector. The first selection is saved to this project's `.pi/settings.json`.
|
|
23
|
+
|
|
24
|
+
When it is ready, record its configuration and resources in `pi.lock`:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
npx pi-lock lock
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Run the agent
|
|
31
|
+
|
|
32
|
+
The default command opens Pi's native TUI. You can also send a one-shot prompt or use Pi's RPC protocol:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
npx pi-lock
|
|
36
|
+
npx pi-lock -p "Summarize these files"
|
|
37
|
+
npx pi-lock --mode rpc
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Normal mode is frozen: if locked files, dependencies, model settings, or tool schemas change, pi.lock reports an error. Make changes with `--dev`, then run `lock` again.
|
|
41
|
+
|
|
42
|
+
## Use it from the SDK
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { createAgentSession } from "pi.lock";
|
|
46
|
+
|
|
47
|
+
const agent = await createAgentSession({
|
|
48
|
+
projectRoot: "/app/my-agent", // Directory containing .pi/ and pi.lock
|
|
49
|
+
cwd: "/data/current-task", // Working directory for this task
|
|
50
|
+
apiKey: process.env.DEEPSEEK_API_KEY,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
await agent.session.prompt("Summarize these files");
|
|
55
|
+
console.log(agent.session.getLastAssistantText());
|
|
56
|
+
} finally {
|
|
57
|
+
await agent.dispose();
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`projectRoot` selects the agent definition; `cwd` selects the task's working directory. Both can be omitted when running from the agent project directory. The returned session is Pi's native `AgentSession`.
|
|
62
|
+
|
|
63
|
+
## Keep the agent with your project
|
|
64
|
+
|
|
65
|
+
Commit the agent definition, `pi.lock`, and npm lockfiles to Git:
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
my-agent/
|
|
69
|
+
├── .pi/
|
|
70
|
+
│ ├── settings.json
|
|
71
|
+
│ ├── SYSTEM.md
|
|
72
|
+
│ ├── extensions/
|
|
73
|
+
│ ├── skills/
|
|
74
|
+
│ └── prompts/
|
|
75
|
+
├── pi.lock
|
|
76
|
+
├── package.json
|
|
77
|
+
└── package-lock.json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The project root's `AGENTS.md` and project-local `.agents/skills/` are included. pi.lock does not load `~/.pi`, `~/.agents`, or resources from parent directories. Local sessions, credentials, and runtime snapshots go in `.pi-lock/` and should not be committed.
|
|
81
|
+
|
|
82
|
+
For deployment, install the versions recorded by your package lockfile and verify the agent before starting it:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
npm ci
|
|
86
|
+
npx --no-install pi-lock sync --frozen
|
|
87
|
+
npx --no-install pi-lock verify
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
To roll back, check out the earlier Git commit and install that commit's dependency versions. Each running session remains bound to its agent version.
|
|
91
|
+
|
|
92
|
+
For extension, MCP, and compatibility details, see the [architecture notes](docs/architecture.md). Test coverage and environment limits are in the [acceptance report](docs/acceptance.md).
|
package/dist/bridge.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ExtensionFactory, LoadExtensionsResult, ExtensionRuntime, EventBus } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
export declare function assertEngine(): void;
|
|
3
|
+
export declare function explicitExtensionLoader(): Promise<{
|
|
4
|
+
loadExtensions: (paths: string[], cwd: string, events?: EventBus, runtime?: ExtensionRuntime) => Promise<LoadExtensionsResult>;
|
|
5
|
+
loadExtensionFromFactory: (factory: ExtensionFactory, cwd: string, events: EventBus, runtime: ExtensionRuntime, name?: string) => Promise<LoadExtensionsResult["extensions"][number]>;
|
|
6
|
+
}>;
|
|
7
|
+
export declare function internalModule(path: string): Promise<any>;
|
package/dist/bridge.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Pi 1.3.0 exposes ResourceLoader publicly but not its explicit-only extension loader.
|
|
2
|
+
// Keep these version-specific imports in one audited bridge; never call discovery.
|
|
3
|
+
import { VERSION } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
import { PI_VERSION, fail } from "./common.js";
|
|
5
|
+
const entry = import.meta.resolve("@earendil-works/pi-coding-agent");
|
|
6
|
+
export function assertEngine() {
|
|
7
|
+
if (VERSION !== PI_VERSION)
|
|
8
|
+
fail("ENGINE_MISMATCH", `pi-lock supports Pi ${PI_VERSION}; installed Pi is ${VERSION}. Run npm ci.`);
|
|
9
|
+
}
|
|
10
|
+
export async function explicitExtensionLoader() {
|
|
11
|
+
assertEngine();
|
|
12
|
+
return import(new URL("./core/extensions/loader.js", entry).href);
|
|
13
|
+
}
|
|
14
|
+
export async function internalModule(path) {
|
|
15
|
+
assertEngine();
|
|
16
|
+
return import(new URL(path, entry).href);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,mFAAmF;AACnF,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;AACrE,MAAM,UAAU,YAAY;IAC1B,IAAI,OAAO,KAAK,UAAU;QAAE,IAAI,CAAC,iBAAiB,EAAE,uBAAuB,UAAU,qBAAqB,OAAO,eAAe,CAAC,CAAC;AACpI,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAI3C,YAAY,EAAE,CAAC;IACf,OAAO,MAAM,CAAC,IAAI,GAAG,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;AACpE,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,YAAY,EAAE,CAAC;IACf,OAAO,MAAM,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;AAC3C,CAAC"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// This entry intentionally imports no Pi code until its per-process paths are bound locally.
|
|
3
|
+
import { mkdirSync } from "node:fs";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { fail, findProject, LockError, PI_VERSION } from "./common.js";
|
|
6
|
+
const help = `pi-lock — Pi ${PI_VERSION}, project-local and reproducible
|
|
7
|
+
|
|
8
|
+
pi-lock init [--demo] Create ordinary .pi settings and resources
|
|
9
|
+
pi-lock lock Generate/update pi.lock after editing
|
|
10
|
+
pi-lock Open Pi's native TUI (frozen by default)
|
|
11
|
+
pi-lock -p "prompt" Print a response and exit
|
|
12
|
+
pi-lock --mode rpc Use Pi's JSONL RPC protocol
|
|
13
|
+
pi-lock --mode json "prompt" Stream Pi JSON events
|
|
14
|
+
pi-lock inspect Show the locked resources and fingerprint
|
|
15
|
+
pi-lock verify Verify source/dependencies against pi.lock
|
|
16
|
+
pi-lock sync --frozen npm ci, then verify; never rewrite pi.lock
|
|
17
|
+
|
|
18
|
+
--project <dir> Agent definition root (auto-detected)
|
|
19
|
+
--cwd <dir> Task workspace (does not change the agent)
|
|
20
|
+
--dev Edit/tune before locking; /reload reads local edits
|
|
21
|
+
--provider <id> --model <id> init/--dev only; saves local Pi settings
|
|
22
|
+
--thinking <level> --tools <list> --dev only; saves local Pi settings
|
|
23
|
+
--session <file> Resume a matching locked session
|
|
24
|
+
--session-dir <dir> Explicit application-owned session directory
|
|
25
|
+
--no-session Use an in-memory session
|
|
26
|
+
-c, --continue Continue latest session of this Agent version
|
|
27
|
+
`;
|
|
28
|
+
async function main() {
|
|
29
|
+
const args = process.argv.slice(2);
|
|
30
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
31
|
+
console.log(help);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (args.includes("--version") || args.includes("-v")) {
|
|
35
|
+
console.log(`pi-lock 0.1.1 (Pi ${PI_VERSION})`);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const commands = new Set(["init", "lock", "inspect", "verify", "sync"]);
|
|
39
|
+
let command = commands.has(args[0]) ? args.shift() : "run";
|
|
40
|
+
const flags = {};
|
|
41
|
+
const messages = [];
|
|
42
|
+
const booleanFlags = new Set(["--demo", "--dev", "--no-session", "--frozen", "--continue", "-c", "-p", "--print"]);
|
|
43
|
+
const valueFlags = new Set(["--project", "--cwd", "--mode", "--provider", "--model", "--thinking", "--tools", "--session", "--session-dir"]);
|
|
44
|
+
while (args.length) {
|
|
45
|
+
const arg = args.shift();
|
|
46
|
+
if (arg === "--") {
|
|
47
|
+
messages.push(...args);
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
if (booleanFlags.has(arg))
|
|
51
|
+
flags[arg] = true;
|
|
52
|
+
else if (valueFlags.has(arg)) {
|
|
53
|
+
const value = args.shift();
|
|
54
|
+
if (!value || value.startsWith("--"))
|
|
55
|
+
fail("ARGUMENT", `${arg} needs a value.`);
|
|
56
|
+
flags[arg] = value;
|
|
57
|
+
}
|
|
58
|
+
else if (arg.startsWith("-"))
|
|
59
|
+
fail("ARGUMENT", `Unknown option ${arg}. Run pi-lock --help.`);
|
|
60
|
+
else if (command === "run" && !messages.length && !flags["-p"] && !flags["--print"] && !flags["--mode"] && commands.has(arg))
|
|
61
|
+
command = arg;
|
|
62
|
+
else
|
|
63
|
+
messages.push(arg);
|
|
64
|
+
}
|
|
65
|
+
const cwd = resolve(String(flags["--cwd"] ?? process.cwd()));
|
|
66
|
+
const root = command === "init" ? resolve(String(flags["--project"] ?? cwd)) : findProject(cwd, flags["--project"]);
|
|
67
|
+
// Pi TUI helpers still use getAgentDir(); set it before importing Pi, inside this CLI process only.
|
|
68
|
+
const uiRoot = resolve(root, ".pi-lock/state/ui");
|
|
69
|
+
mkdirSync(uiRoot, { recursive: true });
|
|
70
|
+
process.env.PI_CODING_AGENT_DIR = uiRoot;
|
|
71
|
+
process.env.PI_CODING_AGENT_SESSION_DIR = resolve(root, ".pi-lock/state/sessions");
|
|
72
|
+
process.env.PI_OFFLINE = "1";
|
|
73
|
+
process.env.PI_SKIP_VERSION_CHECK = "1";
|
|
74
|
+
process.env.PI_TELEMETRY = "0";
|
|
75
|
+
const { execute } = await import("./commands.js");
|
|
76
|
+
await execute(command, root, cwd, flags, messages);
|
|
77
|
+
}
|
|
78
|
+
main().catch(error => {
|
|
79
|
+
console.error(`${error instanceof LockError ? error.code : "PI_LOCK_ERROR"}: ${error.message}`);
|
|
80
|
+
process.exitCode = 1;
|
|
81
|
+
});
|
|
82
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function execute(command: string, root: string, cwd: string, flags: Record<string, string | boolean>, messages: string[]): Promise<void>;
|
package/dist/commands.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, rmSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import { InteractiveMode, initTheme, runPrintMode, runRpcMode, SessionManager } from "@earendil-works/pi-coding-agent";
|
|
5
|
+
import { atomicJson, digest, fail, json } from "./common.js";
|
|
6
|
+
import { internalModule } from "./bridge.js";
|
|
7
|
+
import { initialize } from "./init.js";
|
|
8
|
+
import { createLockedRuntime, lockProject } from "./runtime.js";
|
|
9
|
+
import { materialize, readLock, verifyDefinition, verifySourcesBeforeInstall } from "./lock.js";
|
|
10
|
+
async function npmCi(cwd) {
|
|
11
|
+
await new Promise((done, reject) => {
|
|
12
|
+
const child = spawn("npm", ["ci", "--no-audit", "--no-fund"], { cwd, stdio: "inherit", shell: false });
|
|
13
|
+
child.on("error", reject);
|
|
14
|
+
child.on("close", code => code === 0 ? done() : reject(new Error(`npm ci failed (${code}) in ${cwd}`)));
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export async function execute(command, root, cwd, flags, messages) {
|
|
18
|
+
if (command === "init") {
|
|
19
|
+
initialize(root, { demo: Boolean(flags["--demo"]), provider: flags["--provider"], model: flags["--model"] });
|
|
20
|
+
console.log(`Created .pi/settings.json${flags["--demo"] ? " and offline demo" : ""}. Run pi-lock --dev to tune, then pi-lock lock.`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (command === "lock") {
|
|
24
|
+
const lock = await lockProject(root);
|
|
25
|
+
console.log(`Locked Pi ${lock.runtime.pi}: ${lock.agentDigest}\nCommit .pi/ and pi.lock to Git.`);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (command === "sync") {
|
|
29
|
+
if (!flags["--frozen"])
|
|
30
|
+
fail("ARGUMENT", "Use pi-lock sync --frozen to restore dependencies without changing pi.lock.");
|
|
31
|
+
const lock = readLock(root);
|
|
32
|
+
verifySourcesBeforeInstall(root, lock);
|
|
33
|
+
for (const path of [root, resolve(root, ".pi/npm")])
|
|
34
|
+
if (existsSync(resolve(path, "package-lock.json")))
|
|
35
|
+
await npmCi(path);
|
|
36
|
+
}
|
|
37
|
+
if (["verify", "inspect", "sync"].includes(command)) {
|
|
38
|
+
const lock = readLock(root);
|
|
39
|
+
verifyDefinition(root, lock);
|
|
40
|
+
materialize(root, lock);
|
|
41
|
+
if (command === "inspect")
|
|
42
|
+
console.log(JSON.stringify({ agentDigest: lock.agentDigest, pi: lock.runtime.pi, configuration: lock.effective, resources: lock.definition.resources, dependencies: lock.definition.dependencies }, null, 2));
|
|
43
|
+
else
|
|
44
|
+
console.log(`Verified ${lock.agentDigest}`);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const edits = { "--model": "defaultModel", "--provider": "defaultProvider", "--thinking": "defaultThinkingLevel", "--tools": "defaultTools" };
|
|
48
|
+
for (const [flag, field] of Object.entries(edits))
|
|
49
|
+
if (flags[flag] !== undefined) {
|
|
50
|
+
if (!flags["--dev"])
|
|
51
|
+
fail("FROZEN_SETTING", `${flag} changes locked behavior. Start --dev to tune, then pi-lock lock.`);
|
|
52
|
+
const path = resolve(root, ".pi/settings.json");
|
|
53
|
+
const config = json(path);
|
|
54
|
+
config[field] = flag === "--tools" ? String(flags[flag]).split(",") : flags[flag];
|
|
55
|
+
atomicJson(path, config);
|
|
56
|
+
}
|
|
57
|
+
const mode = flags["--mode"] ?? ((flags["-p"] || flags["--print"]) ? "print" : "tui");
|
|
58
|
+
if (!["tui", "rpc", "json", "print", "text"].includes(String(mode)))
|
|
59
|
+
fail("ARGUMENT", `Unknown mode ${mode}.`);
|
|
60
|
+
const state = resolve(root, ".pi-lock/state");
|
|
61
|
+
mkdirSync(state, { recursive: true });
|
|
62
|
+
const { AuthStorage } = await internalModule("./core/auth-storage.js");
|
|
63
|
+
const credentials = AuthStorage.create(resolve(state, "auth.json"));
|
|
64
|
+
const opts = { projectRoot: root, cwd, credentials, dev: Boolean(flags["--dev"]), sessionFile: flags["--session"], sessionDir: flags["--session-dir"] };
|
|
65
|
+
if (flags["--no-session"])
|
|
66
|
+
opts.sessionManager = SessionManager.inMemory(cwd);
|
|
67
|
+
if (flags["--continue"] || flags["-c"]) {
|
|
68
|
+
if (opts.dev)
|
|
69
|
+
fail("ARGUMENT", "Continue a frozen version, or use --session explicitly while developing.");
|
|
70
|
+
const lock = readLock(root);
|
|
71
|
+
const dir = resolve(String(flags["--session-dir"] ?? resolve(state, "sessions", lock.agentDigest, digest(cwd).slice(0, 12))));
|
|
72
|
+
opts.sessionManager = SessionManager.continueRecent(cwd, dir);
|
|
73
|
+
}
|
|
74
|
+
if (mode !== "tui")
|
|
75
|
+
(await internalModule("./core/output-guard.js")).takeOverStdout();
|
|
76
|
+
const locked = await createLockedRuntime(opts);
|
|
77
|
+
const themeModule = await internalModule("./modes/interactive/theme/theme.js");
|
|
78
|
+
themeModule.setRegisteredThemes(locked.runtime.services.resourceLoader.getThemes().themes);
|
|
79
|
+
initTheme(locked.runtime.services.settingsManager.getTheme(), false);
|
|
80
|
+
const keys = resolve(locked.releaseRoot, ".pi/keybindings.json");
|
|
81
|
+
if (existsSync(keys))
|
|
82
|
+
copyFileSync(keys, resolve(state, "ui/keybindings.json"));
|
|
83
|
+
else
|
|
84
|
+
rmSync(resolve(state, "ui/keybindings.json"), { force: true });
|
|
85
|
+
try {
|
|
86
|
+
if (mode === "rpc") {
|
|
87
|
+
await runRpcMode(locked.runtime);
|
|
88
|
+
}
|
|
89
|
+
else if (mode === "tui") {
|
|
90
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY)
|
|
91
|
+
fail("TTY_REQUIRED", "TUI requires a terminal. Use -p or --mode rpc for non-interactive execution.");
|
|
92
|
+
const tui = new InteractiveMode(locked.runtime, { initialMessage: messages.join(" ") || undefined, initialImages: [], initialMessages: [], migratedProviders: [], verbose: false });
|
|
93
|
+
await tui.run();
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
let prompt = messages.join(" ");
|
|
97
|
+
if (!process.stdin.isTTY) {
|
|
98
|
+
const chunks = [];
|
|
99
|
+
for await (const chunk of process.stdin)
|
|
100
|
+
chunks.push(Buffer.from(chunk));
|
|
101
|
+
const input = Buffer.concat(chunks).toString("utf8").trim();
|
|
102
|
+
if (input)
|
|
103
|
+
prompt = [input, prompt].filter(Boolean).join("\n\n");
|
|
104
|
+
}
|
|
105
|
+
if (!prompt)
|
|
106
|
+
fail("PROMPT_REQUIRED", "Pass a prompt or pipe input into pi-lock -p.");
|
|
107
|
+
process.exitCode = await runPrintMode(locked.runtime, { mode: mode === "json" ? "json" : "text", initialMessage: prompt, initialImages: [], messages: [] });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
await locked.dispose();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
|
package/dist/common.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const PI_VERSION = "1.3.0";
|
|
2
|
+
export declare const FORMAT = 1;
|
|
3
|
+
export declare class LockError extends Error {
|
|
4
|
+
code: string;
|
|
5
|
+
constructor(code: string, message: string);
|
|
6
|
+
}
|
|
7
|
+
export declare function fail(code: string, message: string): never;
|
|
8
|
+
export declare function canonical(value: unknown): string;
|
|
9
|
+
export declare function hash(value: string | Buffer): string;
|
|
10
|
+
export declare function digest(value: unknown): string;
|
|
11
|
+
export declare function json<T = any>(path: string): T;
|
|
12
|
+
export declare function atomicJson(path: string, value: unknown): void;
|
|
13
|
+
export declare function inside(root: string, path: string): string;
|
|
14
|
+
export declare function portablePath(root: string, full: string): string;
|
|
15
|
+
export declare function walk(root: string, path: string, skip?: Set<string>): string[];
|
|
16
|
+
export declare function findProject(start: string, explicit?: string): string;
|
|
17
|
+
export declare function replaceRoots(value: unknown, roots: Array<[string, string]>): unknown;
|
package/dist/common.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync, lstatSync, readFileSync, realpathSync, readdirSync, statSync, mkdirSync, renameSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
4
|
+
export const PI_VERSION = "1.3.0";
|
|
5
|
+
export const FORMAT = 1;
|
|
6
|
+
export class LockError extends Error {
|
|
7
|
+
code;
|
|
8
|
+
constructor(code, message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.name = "LockError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function fail(code, message) { throw new LockError(code, message); }
|
|
15
|
+
export function canonical(value) {
|
|
16
|
+
if (Array.isArray(value))
|
|
17
|
+
return `[${value.map(canonical).join(",")}]`;
|
|
18
|
+
if (value && typeof value === "object") {
|
|
19
|
+
return `{${Object.keys(value).filter(k => value[k] !== undefined).sort().map(k => `${JSON.stringify(k)}:${canonical(value[k])}`).join(",")}}`;
|
|
20
|
+
}
|
|
21
|
+
return JSON.stringify(value);
|
|
22
|
+
}
|
|
23
|
+
export function hash(value) { return createHash("sha256").update(value).digest("hex"); }
|
|
24
|
+
export function digest(value) { return hash(canonical(value)); }
|
|
25
|
+
export function json(path) {
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
return fail("INVALID_JSON", `${path}: ${e.message}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function atomicJson(path, value) {
|
|
34
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
35
|
+
const temp = `${path}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
36
|
+
writeFileSync(temp, JSON.stringify(value, null, 2) + "\n", { mode: 0o600 });
|
|
37
|
+
renameSync(temp, path);
|
|
38
|
+
}
|
|
39
|
+
export function inside(root, path) {
|
|
40
|
+
const full = resolve(root, path);
|
|
41
|
+
const rel = relative(root, full);
|
|
42
|
+
if (isAbsolute(rel) || rel === ".." || rel.startsWith(`..${sep}`))
|
|
43
|
+
fail("OUTSIDE_PROJECT", `Resource must be inside the agent project: ${path}`);
|
|
44
|
+
if (existsSync(full)) {
|
|
45
|
+
const actual = relative(realpathSync(root), realpathSync(full));
|
|
46
|
+
if (isAbsolute(actual) || actual === ".." || actual.startsWith(`..${sep}`))
|
|
47
|
+
fail("OUTSIDE_PROJECT", `Symlink leaves agent project: ${path}`);
|
|
48
|
+
}
|
|
49
|
+
return full;
|
|
50
|
+
}
|
|
51
|
+
export function portablePath(root, full) { return relative(root, full).split(sep).join("/"); }
|
|
52
|
+
export function walk(root, path, skip = new Set()) {
|
|
53
|
+
if (!existsSync(path))
|
|
54
|
+
return [];
|
|
55
|
+
inside(root, path);
|
|
56
|
+
if (lstatSync(path).isSymbolicLink())
|
|
57
|
+
fail("SYMLINK_RESOURCE", `Use ordinary project files instead of symlinks: ${path}`);
|
|
58
|
+
if (!statSync(path).isDirectory())
|
|
59
|
+
return [path];
|
|
60
|
+
return readdirSync(path).sort().filter(name => !skip.has(name)).flatMap(name => walk(root, resolve(path, name), skip));
|
|
61
|
+
}
|
|
62
|
+
export function findProject(start, explicit) {
|
|
63
|
+
if (explicit)
|
|
64
|
+
return realpathSync(resolve(explicit));
|
|
65
|
+
let path = realpathSync(resolve(start));
|
|
66
|
+
while (true) {
|
|
67
|
+
if (existsSync(resolve(path, "pi.lock")) || existsSync(resolve(path, ".pi/settings.json")))
|
|
68
|
+
return path;
|
|
69
|
+
const parent = dirname(path);
|
|
70
|
+
if (parent === path)
|
|
71
|
+
fail("NO_PROJECT", "No pi.lock or .pi/settings.json found. Run pi-lock init in the agent project.");
|
|
72
|
+
path = parent;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export function replaceRoots(value, roots) {
|
|
76
|
+
if (typeof value === "string") {
|
|
77
|
+
for (const [root, label] of [...roots].sort((a, b) => b[0].length - a[0].length))
|
|
78
|
+
value = value.split(root).join(label);
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
if (Array.isArray(value))
|
|
82
|
+
return value.map(v => replaceRoots(v, roots));
|
|
83
|
+
if (value && typeof value === "object")
|
|
84
|
+
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, replaceRoots(v, roots)]));
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACzI,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAExE,MAAM,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC;AAClC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC;AACxB,MAAM,OAAO,SAAU,SAAQ,KAAK;IACf,IAAI;IAAvB,YAAmB,IAAY,EAAE,OAAe;QAAI,KAAK,CAAC,OAAO,CAAC,CAAC;oBAAhD,IAAI;QAA6C,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAAC,CAAC;CAC/F;AACD,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,OAAe,IAAW,MAAM,IAAI,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AAClG,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IACvE,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAE,KAAa,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,CAAE,KAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAClK,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AACD,MAAM,UAAU,IAAI,CAAC,KAAsB,IAAY,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACjH,MAAM,UAAU,MAAM,CAAC,KAAc,IAAY,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACjF,MAAM,UAAU,IAAI,CAAU,IAAY;IACxC,IAAI,CAAC;QAAC,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAAC,CAAC;IACtD,OAAO,CAAC,EAAE,CAAC;QAAC,OAAO,IAAI,CAAC,cAAc,EAAE,GAAG,IAAI,KAAM,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAAC,CAAC;AAChF,CAAC;AACD,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,KAAc;IACrD,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IACjF,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5E,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACzB,CAAC;AACD,MAAM,UAAU,MAAM,CAAC,IAAY,EAAE,IAAY;IAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC;QAAE,IAAI,CAAC,iBAAiB,EAAE,8CAA8C,IAAI,EAAE,CAAC,CAAC;IACjJ,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAChE,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC;YAAE,IAAI,CAAC,iBAAiB,EAAE,iCAAiC,IAAI,EAAE,CAAC,CAAC;IAC/I,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AACD,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,IAAY,IAAY,OAAO,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACtH,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,IAAY,EAAE,IAAI,GAAG,IAAI,GAAG,EAAU;IACvE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACnB,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE;QAAE,IAAI,CAAC,kBAAkB,EAAE,mDAAmD,IAAI,EAAE,CAAC,CAAC;IAC1H,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AACzH,CAAC;AACD,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,QAAiB;IAC1D,IAAI,QAAQ;QAAE,OAAO,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACrD,IAAI,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACxC,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACxG,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,KAAK,IAAI;YAAE,IAAI,CAAC,YAAY,EAAE,+EAA+E,CAAC,CAAC;QACzH,IAAI,GAAG,MAAM,CAAC;IAChB,CAAC;AACH,CAAC;AACD,MAAM,UAAU,YAAY,CAAC,KAAc,EAAE,KAA8B;IACzE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,KAAK,GAAI,KAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpI,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IACxE,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACtI,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface FileRecord {
|
|
2
|
+
path: string;
|
|
3
|
+
sha256: string;
|
|
4
|
+
executable: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface Resources {
|
|
7
|
+
extensions: string[];
|
|
8
|
+
skills: string[];
|
|
9
|
+
prompts: string[];
|
|
10
|
+
themes: string[];
|
|
11
|
+
context: string[];
|
|
12
|
+
system?: string;
|
|
13
|
+
append?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface Definition {
|
|
16
|
+
settings: Record<string, any>;
|
|
17
|
+
files: FileRecord[];
|
|
18
|
+
resources: Resources;
|
|
19
|
+
dependencies: Array<{
|
|
20
|
+
path: string;
|
|
21
|
+
name: string;
|
|
22
|
+
version: string;
|
|
23
|
+
integrity?: string;
|
|
24
|
+
}>;
|
|
25
|
+
modelConfig: Record<string, any>;
|
|
26
|
+
}
|
|
27
|
+
export declare function readDefinition(root: string, allowUnselectedModel?: boolean): Definition;
|
|
28
|
+
export declare function runtimeIdentity(): {
|
|
29
|
+
pi: string;
|
|
30
|
+
adapter: string;
|
|
31
|
+
sha256: string;
|
|
32
|
+
};
|