libretto 0.4.2 → 0.5.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/dist/cli/cli.js +20 -19
- package/dist/cli/commands/ai.js +1 -1
- package/dist/cli/commands/browser.js +3 -3
- package/dist/cli/commands/execution.js +3 -3
- package/dist/cli/commands/init.js +30 -21
- package/dist/cli/commands/logs.js +1 -1
- package/dist/cli/commands/snapshot.js +6 -1
- package/dist/cli/core/ai-config.js +62 -12
- package/dist/cli/core/browser.js +11 -6
- package/dist/cli/core/context.js +4 -18
- package/dist/cli/core/session.js +2 -2
- package/dist/cli/core/snapshot-analyzer.js +2 -2
- package/dist/cli/core/snapshot-api-config.js +46 -5
- package/dist/cli/router.js +1 -1
- package/dist/cli/workers/run-integration-runtime.js +2 -4
- package/dist/shared/debug/index.d.ts +1 -1
- package/dist/shared/debug/index.js +2 -3
- package/dist/shared/debug/pause.d.ts +2 -6
- package/dist/shared/debug/pause.js +27 -20
- package/dist/shared/llm/client.js +5 -5
- package/dist/shared/paths/paths.js +2 -1
- package/dist/shared/paths/repo-root.d.ts +3 -0
- package/dist/shared/paths/repo-root.js +24 -0
- package/package.json +8 -8
- package/scripts/postinstall.mjs +50 -0
- package/skills/libretto/SKILL.md +93 -404
- package/skills/libretto/references/auth-profiles.md +30 -0
- package/skills/libretto/references/pages-and-page-targeting.md +29 -0
- package/skills/libretto/references/reverse-engineering-network-requests.md +39 -0
- package/skills/libretto/references/user-action-log.md +31 -0
- package/src/cli/cli.ts +173 -0
- package/src/cli/commands/ai.ts +35 -0
- package/src/cli/commands/browser.ts +165 -0
- package/src/cli/commands/execution.ts +691 -0
- package/src/cli/commands/init.ts +327 -0
- package/src/cli/commands/logs.ts +128 -0
- package/src/cli/commands/shared.ts +70 -0
- package/src/cli/commands/snapshot.ts +327 -0
- package/src/cli/core/ai-config.ts +255 -0
- package/src/cli/core/api-snapshot-analyzer.ts +97 -0
- package/src/cli/core/browser.ts +839 -0
- package/src/cli/core/context.ts +122 -0
- package/src/cli/core/pause-signals.ts +35 -0
- package/src/cli/core/session-telemetry.ts +553 -0
- package/src/cli/core/session.ts +209 -0
- package/src/cli/core/snapshot-analyzer.ts +875 -0
- package/src/cli/core/snapshot-api-config.ts +236 -0
- package/src/cli/core/telemetry.ts +446 -0
- package/src/cli/framework/simple-cli.ts +1273 -0
- package/src/cli/index.ts +13 -0
- package/src/cli/router.ts +28 -0
- package/src/cli/workers/run-integration-runtime.ts +311 -0
- package/src/cli/workers/run-integration-worker-protocol.ts +14 -0
- package/src/cli/workers/run-integration-worker.ts +75 -0
- package/src/index.ts +120 -0
- package/src/runtime/download/download.ts +100 -0
- package/src/runtime/download/index.ts +7 -0
- package/src/runtime/extract/extract.ts +92 -0
- package/src/runtime/extract/index.ts +1 -0
- package/src/runtime/network/index.ts +5 -0
- package/src/runtime/network/network.ts +113 -0
- package/src/runtime/recovery/agent.ts +256 -0
- package/src/runtime/recovery/errors.ts +152 -0
- package/src/runtime/recovery/index.ts +7 -0
- package/src/runtime/recovery/recovery.ts +50 -0
- package/{dist/shared/condense-dom/condense-dom.cjs → src/shared/condense-dom/condense-dom.ts} +243 -115
- package/src/shared/config/config.ts +22 -0
- package/src/shared/config/index.ts +5 -0
- package/src/shared/debug/index.ts +1 -0
- package/src/shared/debug/pause.ts +85 -0
- package/src/shared/instrumentation/errors.ts +82 -0
- package/src/shared/instrumentation/index.ts +9 -0
- package/src/shared/instrumentation/instrument.ts +276 -0
- package/src/shared/llm/ai-sdk-adapter.ts +78 -0
- package/src/shared/llm/client.ts +217 -0
- package/src/shared/llm/index.ts +3 -0
- package/src/shared/llm/types.ts +63 -0
- package/src/shared/logger/index.ts +6 -0
- package/src/shared/logger/logger.ts +352 -0
- package/src/shared/logger/sinks.ts +144 -0
- package/src/shared/paths/paths.ts +109 -0
- package/src/shared/paths/repo-root.ts +27 -0
- package/src/shared/run/api.ts +2 -0
- package/src/shared/run/browser.ts +98 -0
- package/src/shared/state/index.ts +11 -0
- package/src/shared/state/session-state.ts +74 -0
- package/src/shared/visualization/ghost-cursor.ts +200 -0
- package/src/shared/visualization/highlight.ts +146 -0
- package/src/shared/visualization/index.ts +18 -0
- package/src/shared/workflow/workflow.ts +42 -0
- package/dist/index.cjs +0 -144
- package/dist/index.d.cts +0 -21
- package/dist/runtime/download/download.cjs +0 -70
- package/dist/runtime/download/download.d.cts +0 -35
- package/dist/runtime/download/index.cjs +0 -30
- package/dist/runtime/download/index.d.cts +0 -3
- package/dist/runtime/extract/extract.cjs +0 -88
- package/dist/runtime/extract/extract.d.cts +0 -23
- package/dist/runtime/extract/index.cjs +0 -28
- package/dist/runtime/extract/index.d.cts +0 -5
- package/dist/runtime/network/index.cjs +0 -28
- package/dist/runtime/network/index.d.cts +0 -4
- package/dist/runtime/network/network.cjs +0 -91
- package/dist/runtime/network/network.d.cts +0 -28
- package/dist/runtime/recovery/agent.cjs +0 -223
- package/dist/runtime/recovery/agent.d.cts +0 -13
- package/dist/runtime/recovery/errors.cjs +0 -124
- package/dist/runtime/recovery/errors.d.cts +0 -31
- package/dist/runtime/recovery/index.cjs +0 -34
- package/dist/runtime/recovery/index.d.cts +0 -7
- package/dist/runtime/recovery/recovery.cjs +0 -55
- package/dist/runtime/recovery/recovery.d.cts +0 -12
- package/dist/shared/condense-dom/condense-dom.d.cts +0 -34
- package/dist/shared/config/config.cjs +0 -44
- package/dist/shared/config/config.d.cts +0 -10
- package/dist/shared/config/index.cjs +0 -32
- package/dist/shared/config/index.d.cts +0 -1
- package/dist/shared/debug/index.cjs +0 -30
- package/dist/shared/debug/index.d.cts +0 -1
- package/dist/shared/debug/pause.cjs +0 -90
- package/dist/shared/debug/pause.d.cts +0 -16
- package/dist/shared/instrumentation/errors.cjs +0 -81
- package/dist/shared/instrumentation/errors.d.cts +0 -12
- package/dist/shared/instrumentation/index.cjs +0 -35
- package/dist/shared/instrumentation/index.d.cts +0 -6
- package/dist/shared/instrumentation/instrument.cjs +0 -206
- package/dist/shared/instrumentation/instrument.d.cts +0 -32
- package/dist/shared/llm/ai-sdk-adapter.cjs +0 -71
- package/dist/shared/llm/ai-sdk-adapter.d.cts +0 -22
- package/dist/shared/llm/client.cjs +0 -218
- package/dist/shared/llm/client.d.cts +0 -13
- package/dist/shared/llm/index.cjs +0 -31
- package/dist/shared/llm/index.d.cts +0 -5
- package/dist/shared/llm/types.cjs +0 -16
- package/dist/shared/llm/types.d.cts +0 -67
- package/dist/shared/logger/index.cjs +0 -37
- package/dist/shared/logger/index.d.cts +0 -2
- package/dist/shared/logger/logger.cjs +0 -232
- package/dist/shared/logger/logger.d.cts +0 -86
- package/dist/shared/logger/sinks.cjs +0 -160
- package/dist/shared/logger/sinks.d.cts +0 -9
- package/dist/shared/paths/paths.cjs +0 -104
- package/dist/shared/paths/paths.d.cts +0 -10
- package/dist/shared/run/api.cjs +0 -28
- package/dist/shared/run/api.d.cts +0 -2
- package/dist/shared/run/browser.cjs +0 -98
- package/dist/shared/run/browser.d.cts +0 -22
- package/dist/shared/state/index.cjs +0 -38
- package/dist/shared/state/index.d.cts +0 -2
- package/dist/shared/state/session-state.cjs +0 -92
- package/dist/shared/state/session-state.d.cts +0 -40
- package/dist/shared/visualization/ghost-cursor.cjs +0 -174
- package/dist/shared/visualization/ghost-cursor.d.cts +0 -37
- package/dist/shared/visualization/highlight.cjs +0 -134
- package/dist/shared/visualization/highlight.d.cts +0 -22
- package/dist/shared/visualization/index.cjs +0 -45
- package/dist/shared/visualization/index.d.cts +0 -3
- package/dist/shared/workflow/workflow.cjs +0 -47
- package/dist/shared/workflow/workflow.d.cts +0 -21
- package/skills/libretto/code-generation-rules.md +0 -223
- package/skills/libretto/integration-approach-selection.md +0 -174
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Called by the CLI runtime to make the session name available to `pause()`.
|
|
3
|
-
*/
|
|
4
|
-
declare function setSessionForPause(session: string): void;
|
|
5
1
|
/**
|
|
6
2
|
* Standalone pause function.
|
|
7
3
|
*
|
|
@@ -11,6 +7,6 @@ declare function setSessionForPause(session: string): void;
|
|
|
11
7
|
*
|
|
12
8
|
* Import directly: `import { pause } from "libretto";`
|
|
13
9
|
*/
|
|
14
|
-
declare function pause(): Promise<void>;
|
|
10
|
+
declare function pause(session: string): Promise<void>;
|
|
15
11
|
|
|
16
|
-
export { pause
|
|
12
|
+
export { pause };
|
|
@@ -1,32 +1,40 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
function getSessionFromProcessArgs() {
|
|
8
|
-
const rawPayload = process.argv[2];
|
|
9
|
-
if (!rawPayload) return void 0;
|
|
3
|
+
import { getSessionDir } from "../../cli/core/context.js";
|
|
4
|
+
import { getPauseSignalPaths, removeSignalIfExists } from "../../cli/core/pause-signals.js";
|
|
5
|
+
import { listSessionsWithStateFile, readSessionState } from "../../cli/core/session.js";
|
|
6
|
+
function isPidRunning(pid) {
|
|
10
7
|
try {
|
|
11
|
-
|
|
12
|
-
return
|
|
8
|
+
process.kill(pid, 0);
|
|
9
|
+
return true;
|
|
13
10
|
} catch {
|
|
14
|
-
return
|
|
11
|
+
return false;
|
|
15
12
|
}
|
|
16
13
|
}
|
|
17
|
-
function
|
|
18
|
-
return
|
|
14
|
+
function getRunningSessions() {
|
|
15
|
+
return listSessionsWithStateFile().filter((candidate) => {
|
|
16
|
+
const state = readSessionState(candidate);
|
|
17
|
+
return state !== null && isPidRunning(state.pid);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function throwMissingSessionError() {
|
|
21
|
+
const runningSessions = getRunningSessions();
|
|
22
|
+
const lines = ["pause(session) requires a non-empty session ID."];
|
|
23
|
+
if (runningSessions.length > 0) {
|
|
24
|
+
lines.push("", "Running sessions:");
|
|
25
|
+
for (const runningSession of runningSessions) {
|
|
26
|
+
lines.push(` ${runningSession}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
throw new Error(lines.join("\n"));
|
|
19
30
|
}
|
|
20
|
-
async function pause() {
|
|
31
|
+
async function pause(session) {
|
|
21
32
|
if (process.env.NODE_ENV === "production") {
|
|
22
33
|
return;
|
|
23
34
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return;
|
|
35
|
+
if (typeof session !== "string" || session.trim().length === 0) {
|
|
36
|
+
throwMissingSessionError();
|
|
27
37
|
}
|
|
28
|
-
const { getPauseSignalPaths, removeSignalIfExists } = await import("../../cli/core/pause-signals.js");
|
|
29
|
-
const { getSessionDir } = await import("../../cli/core/context.js");
|
|
30
38
|
const signalPaths = getPauseSignalPaths(session);
|
|
31
39
|
const { pausedSignalPath, resumeSignalPath } = signalPaths;
|
|
32
40
|
await mkdir(getSessionDir(session), { recursive: true });
|
|
@@ -50,6 +58,5 @@ async function pause() {
|
|
|
50
58
|
console.log("[pause] Resume signal received. Continuing workflow...");
|
|
51
59
|
}
|
|
52
60
|
export {
|
|
53
|
-
pause
|
|
54
|
-
setSessionForPause
|
|
61
|
+
pause
|
|
55
62
|
};
|
|
@@ -26,7 +26,7 @@ function parseModel(model) {
|
|
|
26
26
|
const slashIndex = model.indexOf("/");
|
|
27
27
|
if (slashIndex === -1) {
|
|
28
28
|
throw new Error(
|
|
29
|
-
`Invalid model string "${model}". Expected format: "provider/model-id" (for example "openai/gpt-5.4", "anthropic/claude-sonnet-4-6", "google/gemini-
|
|
29
|
+
`Invalid model string "${model}". Expected format: "provider/model-id" (for example "openai/gpt-5.4", "anthropic/claude-sonnet-4-6", "google/gemini-3-flash-preview", or "vertex/gemini-2.5-pro").`
|
|
30
30
|
);
|
|
31
31
|
}
|
|
32
32
|
const providerInput = model.slice(0, slashIndex).toLowerCase();
|
|
@@ -54,14 +54,14 @@ function hasProviderCredentials(provider, env = process.env) {
|
|
|
54
54
|
function missingProviderCredentialsMessage(provider) {
|
|
55
55
|
switch (provider) {
|
|
56
56
|
case "google":
|
|
57
|
-
return "
|
|
57
|
+
return "Gemini API key is missing. Set GEMINI_API_KEY or GOOGLE_GENERATIVE_AI_API_KEY.";
|
|
58
58
|
case "vertex":
|
|
59
|
-
return "
|
|
59
|
+
return "Vertex AI project is missing. Set GOOGLE_CLOUD_PROJECT (or GCLOUD_PROJECT) and ensure application default credentials are configured.";
|
|
60
60
|
case "anthropic": {
|
|
61
|
-
return "
|
|
61
|
+
return "Anthropic API key is missing. Set ANTHROPIC_API_KEY.";
|
|
62
62
|
}
|
|
63
63
|
case "openai": {
|
|
64
|
-
return "
|
|
64
|
+
return "OpenAI API key is missing. Set OPENAI_API_KEY.";
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mkdirSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
|
+
import { resolveLibrettoRepoRoot } from "./repo-root.js";
|
|
3
4
|
const LIBRETTO_DIRNAME = ".libretto";
|
|
4
5
|
const LIBRETTO_SESSIONS_DIRNAME = "sessions";
|
|
5
6
|
const SESSION_STATE_FILENAME = "state.json";
|
|
@@ -8,7 +9,7 @@ const RUNNER_LOG_FILENAME = "logs.jsonl";
|
|
|
8
9
|
const PAUSED_SIGNAL_SUFFIX = "paused";
|
|
9
10
|
const RESUME_SIGNAL_SUFFIX = "resume";
|
|
10
11
|
function getLibrettoRoot(cwd = process.cwd()) {
|
|
11
|
-
return join(cwd, LIBRETTO_DIRNAME);
|
|
12
|
+
return join(resolveLibrettoRepoRoot(cwd), LIBRETTO_DIRNAME);
|
|
12
13
|
}
|
|
13
14
|
function getLibrettoSessionsDir(cwd = process.cwd()) {
|
|
14
15
|
return join(getLibrettoRoot(cwd), LIBRETTO_SESSIONS_DIRNAME);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
const repoRootCache = /* @__PURE__ */ new Map();
|
|
4
|
+
function resolveLibrettoRepoRoot(cwd = process.cwd()) {
|
|
5
|
+
const override = process.env.LIBRETTO_REPO_ROOT?.trim();
|
|
6
|
+
if (override) {
|
|
7
|
+
return resolve(override);
|
|
8
|
+
}
|
|
9
|
+
const normalizedCwd = resolve(cwd);
|
|
10
|
+
const cached = repoRootCache.get(normalizedCwd);
|
|
11
|
+
if (cached) {
|
|
12
|
+
return cached;
|
|
13
|
+
}
|
|
14
|
+
const result = spawnSync("git", ["rev-parse", "--show-toplevel"], {
|
|
15
|
+
cwd: normalizedCwd,
|
|
16
|
+
encoding: "utf-8"
|
|
17
|
+
});
|
|
18
|
+
const repoRoot = result.status === 0 && result.stdout ? result.stdout.trim() : normalizedCwd;
|
|
19
|
+
repoRootCache.set(normalizedCwd, repoRoot);
|
|
20
|
+
return repoRoot;
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
resolveLibrettoRepoRoot
|
|
24
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libretto",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "AI-powered browser automation library and CLI built on Playwright",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -14,24 +14,24 @@
|
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
|
+
"src",
|
|
18
|
+
"scripts",
|
|
17
19
|
"skills/libretto"
|
|
18
20
|
],
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
19
22
|
"bin": {
|
|
20
|
-
"libretto": "./dist/cli/index.js"
|
|
21
|
-
"libretto-cli": "./dist/cli/index.js"
|
|
23
|
+
"libretto": "./dist/cli/index.js"
|
|
22
24
|
},
|
|
23
25
|
"exports": {
|
|
24
26
|
".": {
|
|
25
27
|
"types": "./dist/index.d.ts",
|
|
26
28
|
"import": "./dist/index.js",
|
|
27
|
-
"
|
|
29
|
+
"default": "./dist/index.js"
|
|
28
30
|
}
|
|
29
31
|
},
|
|
30
32
|
"scripts": {
|
|
31
|
-
"postinstall": "
|
|
32
|
-
"build": "
|
|
33
|
-
"build:runtime": "tsup --config tsup.config.ts",
|
|
34
|
-
"build:cli": "tsup --config tsup.cli.config.ts",
|
|
33
|
+
"postinstall": "node scripts/postinstall.mjs",
|
|
34
|
+
"build": "tsup --config tsup.config.ts",
|
|
35
35
|
"type-check": "tsc --noEmit",
|
|
36
36
|
"test": "pnpm run build && vitest run",
|
|
37
37
|
"eval": "pnpm run build && vitest run --config vitest.evals.config.ts",
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { cpSync, existsSync, mkdirSync, readdirSync, rmSync } from "node:fs";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { spawnSync } from "node:child_process";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const packageRoot = join(__dirname, "..");
|
|
10
|
+
|
|
11
|
+
// Install Playwright Chromium
|
|
12
|
+
spawnSync("npx", ["playwright", "install", "chromium"], {
|
|
13
|
+
stdio: "inherit",
|
|
14
|
+
shell: true,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const installCwd = process.env.INIT_CWD?.trim() || null;
|
|
18
|
+
if (!installCwd) {
|
|
19
|
+
console.warn(
|
|
20
|
+
"libretto: automatic skill install failed because INIT_CWD is not set. Run `npx skills add saffron-health/libretto` to add the skills manually.",
|
|
21
|
+
);
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Resolve the consuming project's repo root from the original install cwd,
|
|
26
|
+
// not pnpm's content-addressable store path.
|
|
27
|
+
const gitResult = spawnSync("git", ["rev-parse", "--show-toplevel"], {
|
|
28
|
+
cwd: installCwd,
|
|
29
|
+
encoding: "utf-8",
|
|
30
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
31
|
+
});
|
|
32
|
+
const repoRoot = gitResult.status === 0 && gitResult.stdout
|
|
33
|
+
? gitResult.stdout.trim()
|
|
34
|
+
: installCwd;
|
|
35
|
+
|
|
36
|
+
// Sync skills to any agent dirs at repo root
|
|
37
|
+
const sourceDir = join(packageRoot, "skills", "libretto");
|
|
38
|
+
if (!existsSync(sourceDir)) process.exit(0);
|
|
39
|
+
|
|
40
|
+
const agentDirNames = [".agents", ".claude"];
|
|
41
|
+
for (const name of agentDirNames) {
|
|
42
|
+
const agentDir = join(repoRoot, name);
|
|
43
|
+
if (!existsSync(agentDir)) continue;
|
|
44
|
+
const dest = join(agentDir, "skills", "libretto");
|
|
45
|
+
if (existsSync(dest)) rmSync(dest, { recursive: true });
|
|
46
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
47
|
+
cpSync(sourceDir, dest, { recursive: true });
|
|
48
|
+
const count = readdirSync(dest).length;
|
|
49
|
+
console.log(`libretto: synced ${count} skill files to ${dest}`);
|
|
50
|
+
}
|