libretto 0.6.12 → 0.6.14
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 +3 -8
- package/README.template.md +3 -8
- package/dist/cli/cli.js +0 -23
- package/dist/cli/commands/auth.js +24 -33
- package/dist/cli/commands/billing.js +3 -5
- package/dist/cli/commands/browser.js +4 -13
- package/dist/cli/commands/deploy.js +54 -45
- package/dist/cli/commands/execution.js +6 -3
- package/dist/cli/commands/experiments.js +1 -1
- package/dist/cli/commands/setup.js +2 -295
- package/dist/cli/commands/shared.js +1 -1
- package/dist/cli/commands/snapshot.js +10 -100
- package/dist/cli/commands/status.js +2 -42
- package/dist/cli/core/auth-fetch.js +11 -6
- package/dist/cli/core/browser.js +13 -8
- package/dist/cli/core/config.js +3 -6
- package/dist/cli/core/daemon/daemon.js +88 -74
- package/dist/cli/core/daemon/exec-repl.js +133 -0
- package/dist/cli/core/daemon/exec.js +6 -21
- package/dist/cli/core/daemon/ipc.js +47 -4
- package/dist/cli/core/daemon/ipc.spec.js +21 -0
- package/dist/cli/core/daemon/snapshot.js +2 -29
- package/dist/cli/core/exec-compiler.js +8 -3
- package/dist/cli/core/experiments.js +1 -28
- package/dist/cli/core/providers/index.js +13 -4
- package/dist/cli/core/providers/libretto-cloud.js +178 -26
- package/dist/cli/index.js +0 -2
- package/dist/cli/router.js +9 -6
- package/dist/shared/instrumentation/instrument.js +4 -4
- package/dist/shared/ipc/socket-transport.d.ts +2 -1
- package/dist/shared/ipc/socket-transport.js +16 -5
- package/dist/shared/ipc/socket-transport.spec.js +5 -0
- package/docs/releasing.md +8 -6
- package/package.json +3 -2
- package/skills/libretto/SKILL.md +49 -47
- package/skills/libretto/references/code-generation-rules.md +6 -0
- package/skills/libretto/references/configuration-file-reference.md +14 -12
- package/skills/libretto/references/pages-and-page-targeting.md +1 -1
- package/skills/libretto/references/site-security-review.md +6 -6
- package/skills/libretto-readonly/SKILL.md +2 -9
- package/src/cli/cli.ts +0 -24
- package/src/cli/commands/auth.ts +24 -33
- package/src/cli/commands/billing.ts +3 -5
- package/src/cli/commands/browser.ts +6 -16
- package/src/cli/commands/deploy.ts +55 -49
- package/src/cli/commands/execution.ts +6 -3
- package/src/cli/commands/experiments.ts +1 -1
- package/src/cli/commands/setup.ts +2 -381
- package/src/cli/commands/shared.ts +1 -1
- package/src/cli/commands/snapshot.ts +9 -137
- package/src/cli/commands/status.ts +2 -50
- package/src/cli/core/auth-fetch.ts +9 -4
- package/src/cli/core/browser.ts +15 -8
- package/src/cli/core/config.ts +3 -6
- package/src/cli/core/daemon/daemon.ts +106 -76
- package/src/cli/core/daemon/exec-repl.ts +189 -0
- package/src/cli/core/daemon/exec.ts +8 -43
- package/src/cli/core/daemon/ipc.spec.ts +27 -0
- package/src/cli/core/daemon/ipc.ts +81 -23
- package/src/cli/core/daemon/snapshot.ts +1 -43
- package/src/cli/core/exec-compiler.ts +8 -3
- package/src/cli/core/experiments.ts +9 -38
- package/src/cli/core/providers/index.ts +17 -4
- package/src/cli/core/providers/libretto-cloud.ts +224 -36
- package/src/cli/core/resolve-model.ts +5 -0
- package/src/cli/core/workflow-runtime.ts +1 -0
- package/src/cli/index.ts +0 -1
- package/src/cli/router.ts +9 -6
- package/src/shared/instrumentation/instrument.ts +4 -4
- package/src/shared/ipc/socket-transport.spec.ts +6 -0
- package/src/shared/ipc/socket-transport.ts +20 -5
- package/dist/cli/commands/ai.js +0 -110
- package/dist/cli/core/ai-model.js +0 -195
- package/dist/cli/core/api-snapshot-analyzer.js +0 -86
- package/dist/cli/core/snapshot-analyzer.js +0 -667
- package/dist/cli/framework/simple-cli.js +0 -880
- package/scripts/summarize-evals.mjs +0 -135
- package/src/cli/commands/ai.ts +0 -144
- package/src/cli/core/ai-model.ts +0 -301
- package/src/cli/core/api-snapshot-analyzer.ts +0 -110
- package/src/cli/core/snapshot-analyzer.ts +0 -856
- package/src/cli/framework/simple-cli.ts +0 -1459
|
@@ -1,22 +1,12 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
import type { LoggerApi } from "../../shared/logger/index.js";
|
|
4
|
-
import { condenseDom } from "../../shared/condense-dom/condense-dom.js";
|
|
5
3
|
import { readSessionState } from "../core/session.js";
|
|
6
|
-
import {
|
|
7
|
-
type InterpretArgs,
|
|
8
|
-
type ScreenshotPair,
|
|
9
|
-
} from "../core/snapshot-analyzer.js";
|
|
10
|
-
import { SimpleCLI } from "../framework/simple-cli.js";
|
|
4
|
+
import { SimpleCLI } from "affordance";
|
|
11
5
|
import {
|
|
12
6
|
pageOption,
|
|
13
7
|
sessionOption,
|
|
14
|
-
withExperiments,
|
|
15
8
|
withRequiredSession,
|
|
16
9
|
} from "./shared.js";
|
|
17
|
-
import { runApiInterpret } from "../core/api-snapshot-analyzer.js";
|
|
18
|
-
import { readSnapshotModel } from "../core/config.js";
|
|
19
|
-
import { resolveSnapshotApiModelOrThrow } from "../core/ai-model.js";
|
|
20
10
|
import { DaemonClient } from "../core/daemon/ipc.js";
|
|
21
11
|
import { librettoCommand } from "../../shared/package-manager.js";
|
|
22
12
|
import { renderSnapshot } from "../../shared/snapshot/render-snapshot.js";
|
|
@@ -116,101 +106,6 @@ export async function forceSnapshotViewport(
|
|
|
116
106
|
});
|
|
117
107
|
}
|
|
118
108
|
|
|
119
|
-
async function captureSnapshot(
|
|
120
|
-
session: string,
|
|
121
|
-
logger: LoggerApi,
|
|
122
|
-
daemonSocketPath: string,
|
|
123
|
-
pageId?: string,
|
|
124
|
-
): Promise<ScreenshotPair> {
|
|
125
|
-
logger.info("snapshot-via-daemon", { session, pageId });
|
|
126
|
-
const client = await DaemonClient.connect(daemonSocketPath);
|
|
127
|
-
let snapshotResult: Awaited<ReturnType<DaemonClient["snapshot"]>>;
|
|
128
|
-
try {
|
|
129
|
-
snapshotResult = await client.snapshot({ pageId });
|
|
130
|
-
} finally {
|
|
131
|
-
client.destroy();
|
|
132
|
-
}
|
|
133
|
-
if (!("htmlPath" in snapshotResult)) {
|
|
134
|
-
throw new Error("Daemon returned a compact snapshot for a legacy request.");
|
|
135
|
-
}
|
|
136
|
-
const { pngPath, htmlPath, snapshotRunId, pageUrl, title } = snapshotResult;
|
|
137
|
-
|
|
138
|
-
// condenseDom runs in the CLI process, not the daemon.
|
|
139
|
-
const htmlContent = readFileSync(htmlPath, "utf8");
|
|
140
|
-
const condenseResult = condenseDom(htmlContent);
|
|
141
|
-
const condensedHtmlPath = htmlPath.replace(/\.html$/, ".condensed.html");
|
|
142
|
-
writeFileSync(condensedHtmlPath, condenseResult.html);
|
|
143
|
-
|
|
144
|
-
logger.info("snapshot-daemon-success", {
|
|
145
|
-
session,
|
|
146
|
-
pageUrl,
|
|
147
|
-
title,
|
|
148
|
-
pngPath,
|
|
149
|
-
htmlPath,
|
|
150
|
-
condensedHtmlPath,
|
|
151
|
-
snapshotRunId,
|
|
152
|
-
domCondenseStats: {
|
|
153
|
-
originalLength: condenseResult.originalLength,
|
|
154
|
-
condensedLength: condenseResult.condensedLength,
|
|
155
|
-
reductions: condenseResult.reductions,
|
|
156
|
-
},
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
return { pngPath, htmlPath, condensedHtmlPath, baseName: snapshotRunId };
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
async function runSnapshot(
|
|
163
|
-
session: string,
|
|
164
|
-
logger: LoggerApi,
|
|
165
|
-
pageId: string | undefined,
|
|
166
|
-
objective: string | undefined,
|
|
167
|
-
context: string | undefined,
|
|
168
|
-
): Promise<void> {
|
|
169
|
-
if (objective === undefined) {
|
|
170
|
-
throw new Error("Missing required option --objective.");
|
|
171
|
-
}
|
|
172
|
-
if (context === undefined) {
|
|
173
|
-
throw new Error("Missing required option --context.");
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const normalizedObjective = objective.trim();
|
|
177
|
-
const normalizedContext = context.trim();
|
|
178
|
-
|
|
179
|
-
const snapshotModel = readSnapshotModel();
|
|
180
|
-
resolveSnapshotApiModelOrThrow(snapshotModel);
|
|
181
|
-
|
|
182
|
-
const state = readSessionState(session, logger);
|
|
183
|
-
if (!state?.daemonSocketPath) {
|
|
184
|
-
throw new Error(
|
|
185
|
-
`Session "${session}" has no daemon socket. The browser daemon may have crashed. ` +
|
|
186
|
-
`Close and reopen the session: ${librettoCommand(`close --session ${session}`)}`,
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const { pngPath, htmlPath, condensedHtmlPath } =
|
|
191
|
-
await captureSnapshot(session, logger, state.daemonSocketPath, pageId);
|
|
192
|
-
|
|
193
|
-
console.log("Screenshot saved:");
|
|
194
|
-
console.log(` PNG: ${pngPath}`);
|
|
195
|
-
console.log(` HTML: ${htmlPath}`);
|
|
196
|
-
console.log(` Condensed HTML: ${condensedHtmlPath}`);
|
|
197
|
-
|
|
198
|
-
const interpretArgs: InterpretArgs = {
|
|
199
|
-
objective: normalizedObjective,
|
|
200
|
-
session,
|
|
201
|
-
context: normalizedContext,
|
|
202
|
-
pngPath,
|
|
203
|
-
htmlPath,
|
|
204
|
-
condensedHtmlPath,
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
// Analysis uses direct API calls via the Vercel AI SDK (see api-snapshot-analyzer.ts).
|
|
208
|
-
// The legacy CLI-agent path (spawning codex/claude/gemini as a subprocess) is preserved
|
|
209
|
-
// in snapshot-analyzer.ts — to switch back, replace this call with:
|
|
210
|
-
// await runInterpret(interpretArgs, logger);
|
|
211
|
-
await runApiInterpret(interpretArgs, logger, snapshotModel);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
109
|
async function runCompactSnapshot(
|
|
215
110
|
args: {
|
|
216
111
|
session: string;
|
|
@@ -237,17 +132,12 @@ async function runCompactSnapshot(
|
|
|
237
132
|
let result: Awaited<ReturnType<DaemonClient["snapshot"]>>;
|
|
238
133
|
try {
|
|
239
134
|
result = await client.snapshot({
|
|
240
|
-
mode: "compact",
|
|
241
135
|
pageId: args.pageId,
|
|
242
136
|
useCachedSnapshot: args.ref !== undefined,
|
|
243
137
|
});
|
|
244
138
|
} finally {
|
|
245
139
|
client.destroy();
|
|
246
140
|
}
|
|
247
|
-
if (!("mode" in result) || result.mode !== "compact") {
|
|
248
|
-
throw new Error("Daemon returned a legacy snapshot for a compact request.");
|
|
249
|
-
}
|
|
250
|
-
|
|
251
141
|
console.log(`Screenshot at ${result.pngPath}`);
|
|
252
142
|
console.log(renderSnapshot(result.snapshot, args.ref));
|
|
253
143
|
console.log(
|
|
@@ -270,34 +160,16 @@ export const snapshotInput = SimpleCLI.input({
|
|
|
270
160
|
});
|
|
271
161
|
|
|
272
162
|
export const snapshotCommand = SimpleCLI.command({
|
|
273
|
-
description: "Capture
|
|
163
|
+
description: "Capture a screenshot and compact accessibility snapshot",
|
|
274
164
|
})
|
|
275
165
|
.input(snapshotInput)
|
|
276
166
|
.use(withRequiredSession())
|
|
277
|
-
.use(withExperiments())
|
|
278
167
|
.handle(async ({ input, ctx }) => {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
});
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
if (input.ref) {
|
|
291
|
-
throw new Error(
|
|
292
|
-
`Snapshot refs require the compact-snapshot-format experiment. Enable it with ${librettoCommand("experiments enable compact-snapshot-format")}.`,
|
|
293
|
-
);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
await runSnapshot(
|
|
297
|
-
ctx.session,
|
|
298
|
-
ctx.logger,
|
|
299
|
-
input.page,
|
|
300
|
-
input.objective,
|
|
301
|
-
input.context,
|
|
302
|
-
);
|
|
168
|
+
await runCompactSnapshot({
|
|
169
|
+
session: ctx.session,
|
|
170
|
+
daemonSocketPath: ctx.sessionState.daemonSocketPath,
|
|
171
|
+
logger: ctx.logger,
|
|
172
|
+
pageId: input.page,
|
|
173
|
+
ref: input.ref,
|
|
174
|
+
});
|
|
303
175
|
});
|
|
@@ -1,50 +1,5 @@
|
|
|
1
|
-
import { LIBRETTO_CONFIG_PATH } from "../core/context.js";
|
|
2
|
-
import { type AiSetupStatus, resolveAiSetupStatus } from "../core/ai-model.js";
|
|
3
|
-
import { librettoCommand } from "../../shared/package-manager.js";
|
|
4
1
|
import { listRunningSessions, type SessionState } from "../core/session.js";
|
|
5
|
-
import { SimpleCLI } from "
|
|
6
|
-
|
|
7
|
-
// ── AI status printing ──────────────────────────────────────────────────────
|
|
8
|
-
|
|
9
|
-
function printAiStatus(status: AiSetupStatus): void {
|
|
10
|
-
console.log("AI configuration:");
|
|
11
|
-
|
|
12
|
-
switch (status.kind) {
|
|
13
|
-
case "ready":
|
|
14
|
-
console.log(` ✓ Snapshot model: ${status.model}`);
|
|
15
|
-
if (status.source === "config") {
|
|
16
|
-
console.log(` Config: ${LIBRETTO_CONFIG_PATH}`);
|
|
17
|
-
} else {
|
|
18
|
-
console.log(` Source: ${status.source}`);
|
|
19
|
-
}
|
|
20
|
-
console.log(
|
|
21
|
-
` To change: ${librettoCommand("ai configure openai | anthropic | gemini | vertex | openrouter")}`,
|
|
22
|
-
);
|
|
23
|
-
break;
|
|
24
|
-
|
|
25
|
-
case "configured-missing-credentials":
|
|
26
|
-
console.log(
|
|
27
|
-
` ✗ ${status.provider} is configured (model: ${status.model}), but credentials are missing.`,
|
|
28
|
-
);
|
|
29
|
-
console.log(` Run \`${librettoCommand("setup")}\` to repair.`);
|
|
30
|
-
break;
|
|
31
|
-
|
|
32
|
-
case "invalid-config":
|
|
33
|
-
console.log(" ✗ Config is invalid:");
|
|
34
|
-
for (const line of status.message.split("\n")) {
|
|
35
|
-
console.log(` ${line}`);
|
|
36
|
-
}
|
|
37
|
-
console.log(` Run \`${librettoCommand("setup")}\` to reconfigure.`);
|
|
38
|
-
break;
|
|
39
|
-
|
|
40
|
-
case "unconfigured":
|
|
41
|
-
console.log(" ✗ No AI model configured.");
|
|
42
|
-
console.log(
|
|
43
|
-
` Run \`${librettoCommand("setup")}\` or \`${librettoCommand("ai configure")}\` to set up.`,
|
|
44
|
-
);
|
|
45
|
-
break;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
2
|
+
import { SimpleCLI } from "affordance";
|
|
48
3
|
|
|
49
4
|
// ── Session status printing ─────────────────────────────────────────────────
|
|
50
5
|
|
|
@@ -68,13 +23,10 @@ function printOpenSessions(sessions: SessionState[]): void {
|
|
|
68
23
|
// ── Command ─────────────────────────────────────────────────────────────────
|
|
69
24
|
|
|
70
25
|
export const statusCommand = SimpleCLI.command({
|
|
71
|
-
description: "Show workspace status
|
|
26
|
+
description: "Show workspace status and open sessions",
|
|
72
27
|
})
|
|
73
28
|
.input(SimpleCLI.input({ positionals: [], named: {} }))
|
|
74
29
|
.handle(async () => {
|
|
75
|
-
const aiStatus = resolveAiSetupStatus();
|
|
76
|
-
printAiStatus(aiStatus);
|
|
77
|
-
|
|
78
30
|
const sessions = listRunningSessions();
|
|
79
31
|
printOpenSessions(sessions);
|
|
80
32
|
});
|
|
@@ -11,7 +11,11 @@
|
|
|
11
11
|
|
|
12
12
|
import { readAuthState, writeAuthState, type AuthState } from "./auth-storage.js";
|
|
13
13
|
|
|
14
|
-
export const
|
|
14
|
+
export const DEFAULT_HOSTED_API_URL = "https://api.libretto.sh";
|
|
15
|
+
|
|
16
|
+
export function resolveHostedApiUrl(): string {
|
|
17
|
+
return process.env.LIBRETTO_API_URL?.trim() || DEFAULT_HOSTED_API_URL;
|
|
18
|
+
}
|
|
15
19
|
|
|
16
20
|
/**
|
|
17
21
|
* Shared "you have no usable credential" message. Pointed at the two
|
|
@@ -19,8 +23,9 @@ export const HOSTED_API_URL = "https://api.libretto.sh";
|
|
|
19
23
|
*/
|
|
20
24
|
export const NOT_AUTHENTICATED_MESSAGE = [
|
|
21
25
|
"Not authenticated.",
|
|
22
|
-
" •
|
|
23
|
-
" •
|
|
26
|
+
" • New account: run `libretto cloud auth signup`.",
|
|
27
|
+
" • Existing account: run `libretto cloud auth login`.",
|
|
28
|
+
" • Automation: set LIBRETTO_API_KEY in your env (issue one with `libretto cloud auth api-key issue --label <label>` after signing in).",
|
|
24
29
|
].join("\n");
|
|
25
30
|
|
|
26
31
|
export type CredentialSource = "env-api-key" | "cookie" | "none";
|
|
@@ -41,7 +46,7 @@ export function pickCredential(state: AuthState | null): CredentialChoice {
|
|
|
41
46
|
}
|
|
42
47
|
|
|
43
48
|
export function resolveApiUrl(_state: AuthState | null): string {
|
|
44
|
-
return
|
|
49
|
+
return resolveHostedApiUrl();
|
|
45
50
|
}
|
|
46
51
|
|
|
47
52
|
type FetchOptions = {
|
package/src/cli/core/browser.ts
CHANGED
|
@@ -6,15 +6,20 @@ import {
|
|
|
6
6
|
type Page,
|
|
7
7
|
} from "playwright";
|
|
8
8
|
import { existsSync, readFileSync, writeFileSync, unlinkSync } from "node:fs";
|
|
9
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
9
10
|
import { dirname, join } from "node:path";
|
|
10
11
|
import { createServer } from "node:net";
|
|
12
|
+
import { isWindowsNamedPipePath } from "../../shared/ipc/socket-transport.js";
|
|
11
13
|
import type { LoggerApi } from "../../shared/logger/index.js";
|
|
12
14
|
import type { SessionAccessMode } from "../../shared/state/index.js";
|
|
13
15
|
import type { Experiments } from "./experiments.js";
|
|
14
16
|
import { getSessionProviderClosePath, PROFILES_DIR } from "./context.js";
|
|
15
17
|
import { readLibrettoConfig } from "./config.js";
|
|
16
18
|
import { librettoCommand } from "../../shared/package-manager.js";
|
|
17
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
getCloudProviderApi,
|
|
21
|
+
getProviderStartupTimeoutMs,
|
|
22
|
+
} from "./providers/index.js";
|
|
18
23
|
import {
|
|
19
24
|
assertSessionAvailableForStart,
|
|
20
25
|
clearSessionState,
|
|
@@ -88,7 +93,8 @@ export function normalizeUrl(url: string): URL {
|
|
|
88
93
|
if (
|
|
89
94
|
parsedUrl.protocol === "http:" ||
|
|
90
95
|
parsedUrl.protocol === "https:" ||
|
|
91
|
-
parsedUrl.protocol === "file:"
|
|
96
|
+
parsedUrl.protocol === "file:" ||
|
|
97
|
+
parsedUrl.href === "about:blank"
|
|
92
98
|
) {
|
|
93
99
|
return parsedUrl;
|
|
94
100
|
}
|
|
@@ -98,7 +104,7 @@ export function normalizeUrl(url: string): URL {
|
|
|
98
104
|
}
|
|
99
105
|
|
|
100
106
|
throw new Error(
|
|
101
|
-
`Unsupported URL protocol: ${parsedUrl.protocol}. Use http://, https://, or
|
|
107
|
+
`Unsupported URL protocol: ${parsedUrl.protocol}. Use http://, https://, file://, or about:blank.`,
|
|
102
108
|
);
|
|
103
109
|
}
|
|
104
110
|
|
|
@@ -547,8 +553,8 @@ export async function runOpenWithProvider(
|
|
|
547
553
|
},
|
|
548
554
|
logger,
|
|
549
555
|
logPath: runLogPath,
|
|
550
|
-
// Remote
|
|
551
|
-
startupTimeoutMs:
|
|
556
|
+
// Remote provider creation can wait for cloud capacity before CDP exists.
|
|
557
|
+
startupTimeoutMs: getProviderStartupTimeoutMs(providerName),
|
|
552
558
|
});
|
|
553
559
|
client.destroy();
|
|
554
560
|
|
|
@@ -657,9 +663,8 @@ export async function runSave(
|
|
|
657
663
|
}
|
|
658
664
|
|
|
659
665
|
const state = { cookies, origins };
|
|
660
|
-
|
|
661
|
-
await
|
|
662
|
-
await fs.writeFile(profilePath, JSON.stringify(state, null, 2));
|
|
666
|
+
await mkdir(dirname(profilePath), { recursive: true });
|
|
667
|
+
await writeFile(profilePath, JSON.stringify(state, null, 2));
|
|
663
668
|
|
|
664
669
|
logger.info("save-success", {
|
|
665
670
|
domain,
|
|
@@ -974,6 +979,8 @@ function unlinkDaemonSocket(
|
|
|
974
979
|
session: string,
|
|
975
980
|
): void {
|
|
976
981
|
if (!socketPath) return;
|
|
982
|
+
if (isWindowsNamedPipePath(socketPath)) return;
|
|
983
|
+
|
|
977
984
|
try {
|
|
978
985
|
unlinkSync(socketPath);
|
|
979
986
|
} catch (err) {
|
package/src/cli/core/config.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { dirname } from "node:path";
|
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { SessionAccessModeSchema } from "../../shared/state/index.js";
|
|
5
5
|
import { LIBRETTO_CONFIG_PATH } from "./context.js";
|
|
6
|
-
import { librettoCommand } from "../../shared/package-manager.js";
|
|
7
6
|
|
|
8
7
|
export const CURRENT_CONFIG_VERSION = 1;
|
|
9
8
|
|
|
@@ -42,7 +41,6 @@ function formatExpectedConfigExample(): string {
|
|
|
42
41
|
return JSON.stringify(
|
|
43
42
|
{
|
|
44
43
|
version: CURRENT_CONFIG_VERSION,
|
|
45
|
-
snapshotModel: "openai/gpt-5.4",
|
|
46
44
|
viewport: {
|
|
47
45
|
width: 1280,
|
|
48
46
|
height: 800,
|
|
@@ -66,10 +64,9 @@ function invalidConfigError(configPath: string, detail?: string): Error {
|
|
|
66
64
|
"Expected config example:",
|
|
67
65
|
formatExpectedConfigExample(),
|
|
68
66
|
"Notes:",
|
|
69
|
-
' - "
|
|
70
|
-
' - "snapshotModel"
|
|
71
|
-
"Fix the file to match this shape, or delete it and rerun
|
|
72
|
-
` ${librettoCommand("ai configure openai | anthropic | gemini | vertex | openrouter")}`,
|
|
67
|
+
' - "viewport", "windowPosition", and "sessionMode" are optional.',
|
|
68
|
+
' - "snapshotModel" is deprecated and ignored by snapshot.',
|
|
69
|
+
"Fix the file to match this shape, or delete it and rerun setup.",
|
|
73
70
|
]
|
|
74
71
|
.filter(Boolean)
|
|
75
72
|
.join("\n"),
|