create-libretto 0.6.2 → 0.6.3

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/index.mjs CHANGED
@@ -29,6 +29,59 @@ const RED = "\x1b[31m";
29
29
  const GREEN = "\x1b[32m";
30
30
  const CYAN = "\x1b[36m";
31
31
 
32
+ // ---------------------------------------------------------------------------
33
+ // Provider → AI SDK package mapping
34
+ // ---------------------------------------------------------------------------
35
+
36
+ const PROVIDER_SDK_PACKAGES = {
37
+ openai: "@ai-sdk/openai",
38
+ anthropic: "@ai-sdk/anthropic",
39
+ google: "@ai-sdk/google",
40
+ vertex: "@ai-sdk/google-vertex",
41
+ };
42
+
43
+ /**
44
+ * Read `.libretto/config.json` and extract the provider prefix from `ai.model`.
45
+ * Returns null if config is missing or model is not recognized.
46
+ */
47
+ function detectProviderFromConfig(targetDir) {
48
+ const configPath = join(targetDir, ".libretto", "config.json");
49
+ if (!existsSync(configPath)) return null;
50
+
51
+ try {
52
+ const config = JSON.parse(readFileSync(configPath, "utf-8"));
53
+ const model = config?.ai?.model;
54
+ if (typeof model !== "string") return null;
55
+
56
+ const provider = model.split("/")[0];
57
+ if (provider in PROVIDER_SDK_PACKAGES) return provider;
58
+ return null;
59
+ } catch {
60
+ return null;
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Read the peer-dependency version range for the SDK package from the
66
+ * installed libretto package.json. Falls back to "latest" if not found.
67
+ */
68
+ function resolveSdkVersionSpec(targetDir, sdkPackage) {
69
+ try {
70
+ const librettoPkgPath = join(
71
+ targetDir,
72
+ "node_modules",
73
+ "libretto",
74
+ "package.json",
75
+ );
76
+ const librettoPkg = JSON.parse(readFileSync(librettoPkgPath, "utf-8"));
77
+ const range = librettoPkg.peerDependencies?.[sdkPackage];
78
+ if (range) return `${sdkPackage}@${range}`;
79
+ } catch {
80
+ // fall through
81
+ }
82
+ return sdkPackage;
83
+ }
84
+
32
85
  // ---------------------------------------------------------------------------
33
86
  // Package manager detection
34
87
  // ---------------------------------------------------------------------------
@@ -71,6 +124,20 @@ function installCommand(pkgManager) {
71
124
  }
72
125
  }
73
126
 
127
+ /** Return the command for adding a specific package (e.g. `npm install <pkg>`). */
128
+ function addCommand(pkgManager) {
129
+ switch (pkgManager) {
130
+ case "yarn":
131
+ return "yarn add";
132
+ case "bun":
133
+ return "bun add";
134
+ case "pnpm":
135
+ return "pnpm add";
136
+ default:
137
+ return "npm install";
138
+ }
139
+ }
140
+
74
141
  /** Return the run command for scripts (used in next-steps messaging). */
75
142
  function runCommand(pkgManager) {
76
143
  switch (pkgManager) {
@@ -320,6 +387,29 @@ export async function scaffoldProject(
320
387
  console.error(`\nFailed to run libretto setup.`);
321
388
  process.exit(1);
322
389
  }
390
+
391
+ // 6. Install the AI SDK package for the selected provider
392
+ const provider = detectProviderFromConfig(targetDir);
393
+ if (provider) {
394
+ const sdkPackage = PROVIDER_SDK_PACKAGES[provider];
395
+ const spec = resolveSdkVersionSpec(targetDir, sdkPackage);
396
+ const add = addCommand(pkgManager);
397
+ console.log(`\nInstalling ${spec}...`);
398
+ const sdkSpinner = createSpinner(`Installing ${sdkPackage}...`);
399
+ const sdkResult = await runInstallAsync(
400
+ `${add} ${spec}`,
401
+ targetDir,
402
+ );
403
+ sdkSpinner.stop();
404
+
405
+ if (sdkResult.status !== 0) {
406
+ console.error(
407
+ `\nFailed to install ${sdkPackage}. Install it manually: ${add} ${spec}`,
408
+ );
409
+ } else {
410
+ console.log(`${GREEN}✓${RESET} Installed ${sdkPackage}`);
411
+ }
412
+ }
323
413
  }
324
414
  }
325
415
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-libretto",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "Create and set up a Libretto project",
5
5
  "license": "MIT",
6
6
  "repository": {
File without changes
@@ -2,9 +2,9 @@
2
2
 
3
3
  Browser automations built with [Libretto](https://libretto.sh).
4
4
 
5
- ## Development
5
+ ## Quick Start
6
6
 
7
- Start exploring a page interactively:
7
+ Open a page interactively to inspect and prototype:
8
8
 
9
9
  ```bash
10
10
  {{runCommand}} libretto open https://example.com --headed
@@ -16,8 +16,14 @@ Run a workflow:
16
16
  {{runCommand}} libretto run src/workflows/star-repo.ts
17
17
  ```
18
18
 
19
- ## Learn more
19
+ ## Agent Skills
20
20
 
21
- - [Libretto docs](https://libretto.sh)
22
- - [CLI reference](https://libretto.sh/cli-reference/open-and-connect)
23
- - [Workflow API](https://libretto.sh/library-api/workflow)
21
+ Libretto ships with agent skills that let AI coding assistants (Claude Code, Codex, etc.) build and maintain workflows for you. After running `libretto setup`, the skill files are installed at the root of your project in `.agents/skills/` and `.claude/skills/`. These root-level skill directories are what your AI assistant reads to understand how to use Libretto.
22
+
23
+ ## Links
24
+
25
+ - [Website](https://libretto.sh)
26
+ - [Documentation](https://libretto.sh/get-started/introduction)
27
+ - [CLI Reference](https://libretto.sh/cli-reference/open-and-connect)
28
+ - [Library API Reference](https://libretto.sh/library-api/workflow)
29
+ - [GitHub](https://github.com/saffron-health/libretto)
@@ -1 +1 @@
1
- export { starRepo } from "./workflows/star-repo.js";
1
+ export { default as starRepo } from "./workflows/star-repo.js";
@@ -1,3 +1,6 @@
1
+ // This is example utility code generated by create-libretto.
2
+ // Feel free to modify or delete it entirely.
3
+
1
4
  export function log(message: string): void {
2
5
  console.log(`[libretto] ${message}`);
3
6
  }
@@ -1,9 +1,20 @@
1
+ // This is an example workflow generated by create-libretto.
2
+ // Feel free to modify or delete it entirely and create your own workflows.
3
+
1
4
  import { workflow } from "libretto";
2
5
  import { log } from "../shared/utils.js";
3
6
 
4
- export const starRepo = workflow("star-repo", async ({ page }) => {
7
+ export default workflow("star-repo", async ({ page }) => {
5
8
  log("Navigating to Libretto repo...");
6
9
  await page.goto("https://github.com/saffron-health/libretto");
7
- await page.locator('button:has-text("Star")').click();
8
- log("Starred the repo!");
10
+
11
+ const description = await page
12
+ .locator('meta[name="description"]')
13
+ .getAttribute("content");
14
+ log(`Repo description: ${description}`);
15
+
16
+ const stars = await page.locator("#repo-stars-counter-star").textContent();
17
+ log(`Stars: ${stars?.trim()}`);
18
+
19
+ log("Done! Edit this workflow or create your own in src/workflows/.");
9
20
  });