create-avocado-site 0.11.6 → 0.11.8
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/index.js +82 -11
- package/dist/prompts.d.ts +39 -1
- package/dist/prompts.js +107 -2
- package/dist/templates/demo-app.js +31 -2
- package/dist/types.d.ts +14 -0
- package/dist/versions.d.ts +1 -1
- package/dist/versions.js +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -4,19 +4,39 @@ import { spawn } from "node:child_process";
|
|
|
4
4
|
import { mkdir, readdir } from "node:fs/promises";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { resolve } from "node:path";
|
|
7
|
-
import { runPrompts, demoConfig } from "./prompts.js";
|
|
7
|
+
import { runPrompts, demoConfig, promptForApiKey, AVOCADO_INTRO } from "./prompts.js";
|
|
8
8
|
import { collectFiles, collectDemoFiles, generateFiles } from "./generator.js";
|
|
9
9
|
import { printInstructions } from "./instructions.js";
|
|
10
10
|
async function main() {
|
|
11
11
|
const cwd = process.cwd();
|
|
12
12
|
/*
|
|
13
13
|
* `npm create avocado-site my-demo` — a directory argument means the demo,
|
|
14
|
-
* with no questions. Somebody who has typed a name has
|
|
15
|
-
* only one that mattered, and the fastest path to
|
|
16
|
-
* not be gated behind three selects.
|
|
14
|
+
* with no *configuration* questions. Somebody who has typed a name has
|
|
15
|
+
* already answered the only one that mattered, and the fastest path to
|
|
16
|
+
* seeing the product should not be gated behind three selects.
|
|
17
|
+
*
|
|
18
|
+
* One question survives that rule, and it earns its place: the API key.
|
|
19
|
+
*
|
|
20
|
+
* Not to gate anything — everything except chat works without one, and that
|
|
21
|
+
* is deliberate and worth protecting, so Enter skips it. It is here because
|
|
22
|
+
* **keys are read at startup**. A key given now is live the first time the
|
|
23
|
+
* dev server runs; a key added afterwards needs a file edit *and* a restart,
|
|
24
|
+
* and nothing in the product confirms either happened. "I added the key and
|
|
25
|
+
* nothing changed" has no error message anywhere in the system, and this
|
|
26
|
+
* prompt is the cheapest way to stop most people arriving there.
|
|
17
27
|
*/
|
|
18
28
|
const target = process.argv.slice(2).find((arg) => !arg.startsWith("-"));
|
|
19
|
-
|
|
29
|
+
let config;
|
|
30
|
+
if (target) {
|
|
31
|
+
// `runPrompts` opens with this; the fast path had no intro at all, so a
|
|
32
|
+
// stranger's first interaction with the product was an unexplained request
|
|
33
|
+
// for a credential on an otherwise blank terminal.
|
|
34
|
+
p.intro(AVOCADO_INTRO);
|
|
35
|
+
config = await demoConfig(target, await promptForApiKey());
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
config = await runPrompts(cwd);
|
|
39
|
+
}
|
|
20
40
|
if (!config)
|
|
21
41
|
return;
|
|
22
42
|
if (config.mode === "demo") {
|
|
@@ -78,10 +98,9 @@ async function bootstrapDemo(cwd, dirName, config) {
|
|
|
78
98
|
p.log.warn(`Run \`npm install\` in ${dirName} yourself — everything else is in place.`);
|
|
79
99
|
}
|
|
80
100
|
p.log.message([
|
|
81
|
-
` cd ${dirName}`,
|
|
82
|
-
` npm run dev`,
|
|
101
|
+
` cd ${dirName} && npm run dev`,
|
|
83
102
|
``,
|
|
84
|
-
`
|
|
103
|
+
` opens the editor at`,
|
|
85
104
|
``,
|
|
86
105
|
` http://localhost:${config.editorPort}/?siteId=${config.siteId}&session=dev`,
|
|
87
106
|
``,
|
|
@@ -90,10 +109,62 @@ async function bootstrapDemo(cwd, dirName, config) {
|
|
|
90
109
|
` default site when the URL does not name one. \`npm run dev\` opens this`,
|
|
91
110
|
` URL for you.`,
|
|
92
111
|
``,
|
|
93
|
-
|
|
94
|
-
|
|
112
|
+
/*
|
|
113
|
+
* Two whole sentences, not one with a dangling clause.
|
|
114
|
+
*
|
|
115
|
+
* This was a single line ending "…add ANTHROPIC_API_KEY to .env.local"
|
|
116
|
+
* followed by a hard-coded "when you want to edit by chat." — fine as one
|
|
117
|
+
* sentence, nonsense as soon as the first half could say something else.
|
|
118
|
+
* The keyed variant read "Chat is enabled — OPENAI_API_KEY is in
|
|
119
|
+
* .env.local when you want to edit by chat."
|
|
120
|
+
*/
|
|
121
|
+
...(config.apiKey
|
|
122
|
+
? [` Chat is enabled \u2014 ${config.apiKey.variable} is in .env.local.`]
|
|
123
|
+
: [
|
|
124
|
+
` No API key needed to look around. Add ANTHROPIC_API_KEY,`,
|
|
125
|
+
` OPENAI_API_KEY or GOOGLE_GENAI_API_KEY to .env.local and restart`,
|
|
126
|
+
` when you want to edit by chat.`,
|
|
127
|
+
]),
|
|
95
128
|
].join("\n"));
|
|
96
|
-
|
|
129
|
+
/*
|
|
130
|
+
* Offer to run it, rather than ending on homework.
|
|
131
|
+
*
|
|
132
|
+
* The scaffold installed 29 files and every dependency, chose two free ports,
|
|
133
|
+
* generated three secrets and wrote a key — and then handed back two commands
|
|
134
|
+
* to type. Everything it needed to know it already knew; the remaining steps
|
|
135
|
+
* were manual only because nobody had automated them.
|
|
136
|
+
*
|
|
137
|
+
* Asked, not assumed. Starting two long-running servers is not something to
|
|
138
|
+
* do to somebody's terminal without permission, and anyone scaffolding into a
|
|
139
|
+
* script or a container wants the files and nothing else. The default is yes
|
|
140
|
+
* because the overwhelmingly common case is a person who wants to see it.
|
|
141
|
+
*/
|
|
142
|
+
const start = await p.confirm({
|
|
143
|
+
message: `Start it now? (runs \`npm run dev\` in ${dirName})`,
|
|
144
|
+
initialValue: true,
|
|
145
|
+
});
|
|
146
|
+
if (p.isCancel(start) || !start) {
|
|
147
|
+
p.outro(`Done. Run \`cd ${dirName} && npm run dev\` when you are ready.`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
p.outro("Starting \u2014 press Ctrl+C to stop.");
|
|
151
|
+
/*
|
|
152
|
+
* `stdio: "inherit"` and no `await` on a resolved promise: this is the user's
|
|
153
|
+
* session now. The dev script prints its own banner, opens the editor, and
|
|
154
|
+
* owns Ctrl+C from here.
|
|
155
|
+
*/
|
|
156
|
+
const dev = spawn("npm", ["run", "dev"], {
|
|
157
|
+
cwd: dir,
|
|
158
|
+
stdio: "inherit",
|
|
159
|
+
shell: process.platform === "win32",
|
|
160
|
+
});
|
|
161
|
+
await new Promise((resolve) => {
|
|
162
|
+
dev.on("exit", () => resolve());
|
|
163
|
+
dev.on("error", () => {
|
|
164
|
+
p.log.warn(`Could not start it. Run \`cd ${dirName} && npm run dev\` yourself.`);
|
|
165
|
+
resolve();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
97
168
|
}
|
|
98
169
|
/** Resolves false rather than throwing — the caller decides what a failure means. */
|
|
99
170
|
function run(command, args, cwd) {
|
package/dist/prompts.d.ts
CHANGED
|
@@ -1,8 +1,46 @@
|
|
|
1
1
|
import type { ScaffoldConfig } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The product, named, with its own mark.
|
|
4
|
+
*
|
|
5
|
+
* Shared so both entry paths use it. The directory-argument path had no intro
|
|
6
|
+
* at all — it went straight from an `npx` line to a demand for a secret.
|
|
7
|
+
*/
|
|
8
|
+
export declare const AVOCADO_INTRO = "\uD83E\uDD51 Avocado Studio";
|
|
2
9
|
/** A directory name turned into something the orchestrator will accept as a site id. */
|
|
3
10
|
export declare function toSiteId(name: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Which provider a pasted key belongs to, by prefix.
|
|
13
|
+
*
|
|
14
|
+
* Exported so `api-key-prompt.test.ts` can check the classification without a
|
|
15
|
+
* terminal. Unknown shapes are not rejected — a key format can change, and
|
|
16
|
+
* refusing a real key because this list is out of date is worse than writing it
|
|
17
|
+
* under the most likely variable and letting the server report the truth.
|
|
18
|
+
*/
|
|
19
|
+
export declare function variableForKey(raw: string): string | null;
|
|
20
|
+
/**
|
|
21
|
+
* Offer to take an API key now. One keypress to skip.
|
|
22
|
+
*
|
|
23
|
+
* The product deliberately works without one — the preview, click-to-select,
|
|
24
|
+
* the property panel, publishing and every metadata guarantee need no model,
|
|
25
|
+
* and "no API key needed to look around" is a real differentiator worth
|
|
26
|
+
* protecting. So this must never become a gate: Enter continues, and the copy
|
|
27
|
+
* says so before it says anything else.
|
|
28
|
+
*
|
|
29
|
+
* What it buys is the restart. Keys are read at startup, so a key set *here* is
|
|
30
|
+
* live the first time the dev server runs, while a key added afterwards needs
|
|
31
|
+
* a file edit and a restart — and nothing in the product confirms either
|
|
32
|
+
* happened. "I added the key and nothing changed" has no error message
|
|
33
|
+
* anywhere, and this is the cheapest way to stop most people reaching it.
|
|
34
|
+
*/
|
|
35
|
+
export declare function promptForApiKey(): Promise<{
|
|
36
|
+
variable: string;
|
|
37
|
+
value: string;
|
|
38
|
+
} | undefined>;
|
|
4
39
|
/** Everything a demo scaffold needs, with no questions asked. */
|
|
5
|
-
export declare function demoConfig(dirName: string
|
|
40
|
+
export declare function demoConfig(dirName: string, apiKey?: {
|
|
41
|
+
variable: string;
|
|
42
|
+
value: string;
|
|
43
|
+
}): Promise<ScaffoldConfig>;
|
|
6
44
|
/**
|
|
7
45
|
* The mode question, asked first.
|
|
8
46
|
*
|
package/dist/prompts.js
CHANGED
|
@@ -3,13 +3,115 @@ import { randomBytes } from "node:crypto";
|
|
|
3
3
|
import { basename } from "node:path";
|
|
4
4
|
import { detectNextMajor } from "./next-version.js";
|
|
5
5
|
import { findFreePort } from "./ports.js";
|
|
6
|
+
/**
|
|
7
|
+
* The product, named, with its own mark.
|
|
8
|
+
*
|
|
9
|
+
* Shared so both entry paths use it. The directory-argument path had no intro
|
|
10
|
+
* at all — it went straight from an `npx` line to a demand for a secret.
|
|
11
|
+
*/
|
|
12
|
+
export const AVOCADO_INTRO = "\u{1F951} Avocado Studio";
|
|
6
13
|
/** A directory name turned into something the orchestrator will accept as a site id. */
|
|
7
14
|
export function toSiteId(name) {
|
|
8
15
|
const cleaned = name.replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
9
16
|
return cleaned.length > 0 ? cleaned : "avocado-demo";
|
|
10
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Which provider a pasted key belongs to, by prefix.
|
|
20
|
+
*
|
|
21
|
+
* Exported so `api-key-prompt.test.ts` can check the classification without a
|
|
22
|
+
* terminal. Unknown shapes are not rejected — a key format can change, and
|
|
23
|
+
* refusing a real key because this list is out of date is worse than writing it
|
|
24
|
+
* under the most likely variable and letting the server report the truth.
|
|
25
|
+
*/
|
|
26
|
+
export function variableForKey(raw) {
|
|
27
|
+
const key = raw.trim();
|
|
28
|
+
if (!key)
|
|
29
|
+
return null;
|
|
30
|
+
if (key.startsWith("sk-ant-"))
|
|
31
|
+
return "ANTHROPIC_API_KEY";
|
|
32
|
+
if (key.startsWith("sk-"))
|
|
33
|
+
return "OPENAI_API_KEY";
|
|
34
|
+
if (key.startsWith("AIza"))
|
|
35
|
+
return "GOOGLE_GENAI_API_KEY";
|
|
36
|
+
return "ANTHROPIC_API_KEY";
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Offer to take an API key now. One keypress to skip.
|
|
40
|
+
*
|
|
41
|
+
* The product deliberately works without one — the preview, click-to-select,
|
|
42
|
+
* the property panel, publishing and every metadata guarantee need no model,
|
|
43
|
+
* and "no API key needed to look around" is a real differentiator worth
|
|
44
|
+
* protecting. So this must never become a gate: Enter continues, and the copy
|
|
45
|
+
* says so before it says anything else.
|
|
46
|
+
*
|
|
47
|
+
* What it buys is the restart. Keys are read at startup, so a key set *here* is
|
|
48
|
+
* live the first time the dev server runs, while a key added afterwards needs
|
|
49
|
+
* a file edit and a restart — and nothing in the product confirms either
|
|
50
|
+
* happened. "I added the key and nothing changed" has no error message
|
|
51
|
+
* anywhere, and this is the cheapest way to stop most people reaching it.
|
|
52
|
+
*/
|
|
53
|
+
export async function promptForApiKey() {
|
|
54
|
+
/*
|
|
55
|
+
* Say what this is before asking for a secret.
|
|
56
|
+
*
|
|
57
|
+
* On the `npm create avocado-site my-site` path this was the **first thing a
|
|
58
|
+
* stranger ever saw** — no product name, no explanation, just "Paste an API
|
|
59
|
+
* key" on an otherwise empty terminal. Asking for a credential is the one
|
|
60
|
+
* moment where an unexplained prompt is not merely unfriendly; it is the
|
|
61
|
+
* shape of something a careful person refuses.
|
|
62
|
+
*
|
|
63
|
+
* It also never said *which* key. Three providers are accepted and the
|
|
64
|
+
* variable is chosen from the prefix, so a reader had no way to know whether
|
|
65
|
+
* their key was one of the right ones.
|
|
66
|
+
*/
|
|
67
|
+
p.note("Chat needs a model. Everything else works without one \u2014 the preview,\n" +
|
|
68
|
+
"click-to-select, the property panel and publishing.\n\n" +
|
|
69
|
+
"Accepted: ANTHROPIC_API_KEY \u00b7 OPENAI_API_KEY \u00b7 GOOGLE_GENAI_API_KEY\n" +
|
|
70
|
+
"The right variable is picked from the key itself.", "Optional \u2014 enable chat now");
|
|
71
|
+
const key = await p.password({
|
|
72
|
+
message: "Paste a key, or press Enter to skip",
|
|
73
|
+
mask: "\u2022",
|
|
74
|
+
validate: () => undefined,
|
|
75
|
+
});
|
|
76
|
+
if (p.isCancel(key))
|
|
77
|
+
return undefined;
|
|
78
|
+
const value = typeof key === "string" ? key.trim() : "";
|
|
79
|
+
if (!value) {
|
|
80
|
+
p.note("Chat will use the built-in demo planner, which handles simple, literal edits.\n" +
|
|
81
|
+
"Everything else works: the preview, click-to-select, the property panel and publishing.\n" +
|
|
82
|
+
"You can add a key to .env.local later and restart the dev server.", "No key \u2014 that is fine");
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
const variable = variableForKey(value);
|
|
86
|
+
if (!variable)
|
|
87
|
+
return undefined;
|
|
88
|
+
/*
|
|
89
|
+
* Say *why* this variable, and how to change it.
|
|
90
|
+
*
|
|
91
|
+
* The confirmation used to state a conclusion and nothing else. A tester who
|
|
92
|
+
* meant to paste an Anthropic key and grabbed an OpenAI one from the line
|
|
93
|
+
* above it in the same file read "Writing OPENAI_API_KEY" and had no idea
|
|
94
|
+
* whether the product had misread the key or they had copied the wrong line —
|
|
95
|
+
* and no route back either way. Naming the evidence (the prefix) settles
|
|
96
|
+
* which of the two happened in one glance.
|
|
97
|
+
*/
|
|
98
|
+
const hint = value.startsWith("sk-ant-")
|
|
99
|
+
? "sk-ant-"
|
|
100
|
+
: value.startsWith("sk-")
|
|
101
|
+
? "sk-"
|
|
102
|
+
: value.startsWith("AIza")
|
|
103
|
+
? "AIza"
|
|
104
|
+
: null;
|
|
105
|
+
p.note(`${variable} \u2192 .env.local\n` +
|
|
106
|
+
(hint
|
|
107
|
+
? `Chosen because the key starts with "${hint}".\n`
|
|
108
|
+
: "The key matched no known prefix, so this is a best guess.\n") +
|
|
109
|
+
"Wrong one? Edit .env.local and restart \u2014 nothing else needs to change.\n\n" +
|
|
110
|
+
"Live on first start. No restart needed now.", "Key saved");
|
|
111
|
+
return { variable, value };
|
|
112
|
+
}
|
|
11
113
|
/** Everything a demo scaffold needs, with no questions asked. */
|
|
12
|
-
export async function demoConfig(dirName) {
|
|
114
|
+
export async function demoConfig(dirName, apiKey) {
|
|
13
115
|
const sitePort = await findFreePort(3000);
|
|
14
116
|
const editorPort = await findFreePort(4100);
|
|
15
117
|
return {
|
|
@@ -21,6 +123,7 @@ export async function demoConfig(dirName) {
|
|
|
21
123
|
editorPort,
|
|
22
124
|
draftSecret: randomBytes(24).toString("hex"),
|
|
23
125
|
publishToken: randomBytes(24).toString("hex"),
|
|
126
|
+
apiKey,
|
|
24
127
|
};
|
|
25
128
|
}
|
|
26
129
|
/**
|
|
@@ -31,7 +134,7 @@ export async function demoConfig(dirName) {
|
|
|
31
134
|
* seen what the product does.
|
|
32
135
|
*/
|
|
33
136
|
export async function runPrompts(cwd) {
|
|
34
|
-
p.intro(
|
|
137
|
+
p.intro(AVOCADO_INTRO);
|
|
35
138
|
const mode = await p.select({
|
|
36
139
|
message: "What would you like to do?",
|
|
37
140
|
options: [
|
|
@@ -101,6 +204,7 @@ async function integratePrompts(cwd) {
|
|
|
101
204
|
p.cancel("Cancelled.");
|
|
102
205
|
return null;
|
|
103
206
|
}
|
|
207
|
+
const apiKey = await promptForApiKey();
|
|
104
208
|
return {
|
|
105
209
|
mode: "integrate",
|
|
106
210
|
cms: cms,
|
|
@@ -117,5 +221,6 @@ async function integratePrompts(cwd) {
|
|
|
117
221
|
// that already looks filled in is a step nobody performs.
|
|
118
222
|
draftSecret: randomBytes(24).toString("hex"),
|
|
119
223
|
publishToken: randomBytes(24).toString("hex"),
|
|
224
|
+
apiKey,
|
|
120
225
|
};
|
|
121
226
|
}
|
|
@@ -155,7 +155,9 @@ function envLocal(config) {
|
|
|
155
155
|
# installs it for you and a Gemini plan fails on the
|
|
156
156
|
# first call without it.
|
|
157
157
|
#
|
|
158
|
-
|
|
158
|
+
${config.apiKey
|
|
159
|
+
? `${config.apiKey.variable}=${config.apiKey.value}`
|
|
160
|
+
: "# ANTHROPIC_API_KEY="}
|
|
159
161
|
|
|
160
162
|
# The orchestrator runs inside this app, at /api/avocado. There is no third
|
|
161
163
|
# service to start and nothing to deploy separately.
|
|
@@ -270,6 +272,7 @@ function devScript(config) {
|
|
|
270
272
|
* at /api/avocado. Two processes, one terminal, no third service.
|
|
271
273
|
*/
|
|
272
274
|
import { spawn } from "node:child_process"
|
|
275
|
+
import { readFileSync } from "node:fs"
|
|
273
276
|
import { createConnection } from "node:net"
|
|
274
277
|
|
|
275
278
|
const SITE_PORT = process.env.PORT ?? "${config.sitePort}"
|
|
@@ -295,8 +298,34 @@ const OPEN_URL = \`\${EDITOR_URL}/?siteId=\${SITE_ID}&session=dev\`
|
|
|
295
298
|
|
|
296
299
|
const children = []
|
|
297
300
|
|
|
301
|
+
/*
|
|
302
|
+
* Read DRAFT_MODE_SECRET out of .env.local and hand it to the children.
|
|
303
|
+
*
|
|
304
|
+
* Next loads .env.local by itself; an npm script does not, so the editor CLI
|
|
305
|
+
* would otherwise never see it. Without it the editor cannot select or edit
|
|
306
|
+
* anything once the site is built for production — the SDK requires \`secret=\`
|
|
307
|
+
* on the preview URL there, and with none it renders an ordinary public page
|
|
308
|
+
* with no block markers at all.
|
|
309
|
+
*/
|
|
310
|
+
function envFromLocalFile() {
|
|
311
|
+
try {
|
|
312
|
+
const text = readFileSync(new URL("../.env.local", import.meta.url), "utf8")
|
|
313
|
+
const match = text.match(/^\\s*DRAFT_MODE_SECRET\\s*=\\s*(.+)\\s*$/m)
|
|
314
|
+
const value = match?.[1]?.trim().replace(/^["']|["']$/g, "")
|
|
315
|
+
return value ? { DRAFT_MODE_SECRET: value } : {}
|
|
316
|
+
} catch {
|
|
317
|
+
return {}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const EXTRA_ENV = envFromLocalFile()
|
|
322
|
+
|
|
298
323
|
function run(command, args) {
|
|
299
|
-
const child = spawn(command, args, {
|
|
324
|
+
const child = spawn(command, args, {
|
|
325
|
+
stdio: "inherit",
|
|
326
|
+
shell: process.platform === "win32",
|
|
327
|
+
env: { ...process.env, ...EXTRA_ENV }
|
|
328
|
+
})
|
|
300
329
|
children.push(child)
|
|
301
330
|
child.on("exit", (code) => {
|
|
302
331
|
// If either half dies the other is useless, so take both down rather than
|
package/dist/types.d.ts
CHANGED
|
@@ -40,6 +40,20 @@ export type ScaffoldConfig = {
|
|
|
40
40
|
* `POST /api/editor/publish` took content from anyone who asked.
|
|
41
41
|
*/
|
|
42
42
|
publishToken: string;
|
|
43
|
+
/**
|
|
44
|
+
* An API key pasted during setup, written straight into `.env.local`.
|
|
45
|
+
*
|
|
46
|
+
* Offered once, skippable in one keypress. The point is not to gate the
|
|
47
|
+
* product — everything except chat works without a key, and that is a real
|
|
48
|
+
* feature — it is that **a key set before the dev server first starts needs
|
|
49
|
+
* no restart**. Keys are read at startup, so one added afterwards requires
|
|
50
|
+
* editing a file *and* restarting, and "I added the key and nothing changed"
|
|
51
|
+
* is a failure mode with no error message anywhere.
|
|
52
|
+
*/
|
|
53
|
+
apiKey?: {
|
|
54
|
+
variable: string;
|
|
55
|
+
value: string;
|
|
56
|
+
};
|
|
43
57
|
};
|
|
44
58
|
export type GeneratedFile = {
|
|
45
59
|
path: string;
|
package/dist/versions.d.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* `@avocadostudio-ai/orchestrator-core`, already pinned there; naming it again
|
|
18
18
|
* here is how a project ends up with two.
|
|
19
19
|
*/
|
|
20
|
-
export declare const AVOCADO = "0.11.
|
|
20
|
+
export declare const AVOCADO = "0.11.8";
|
|
21
21
|
/**
|
|
22
22
|
* Next 15.5.15 rather than 16, because that is the version every example app
|
|
23
23
|
* and the demo site in this repository build and test against. The SDK
|
package/dist/versions.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* `@avocadostudio-ai/orchestrator-core`, already pinned there; naming it again
|
|
18
18
|
* here is how a project ends up with two.
|
|
19
19
|
*/
|
|
20
|
-
export const AVOCADO = "0.11.
|
|
20
|
+
export const AVOCADO = "0.11.8";
|
|
21
21
|
/**
|
|
22
22
|
* Next 15.5.15 rather than 16, because that is the version every example app
|
|
23
23
|
* and the demo site in this repository build and test against. The SDK
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-avocado-site",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.8",
|
|
4
4
|
"description": "Bootstrap a runnable Avocado Studio demo site, or wire Avocado into an existing Next.js project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"@types/node": "^22.13.10",
|
|
35
35
|
"tsx": "^4.19.0",
|
|
36
36
|
"typescript": "^5.7.3",
|
|
37
|
-
"@avocadostudio-ai/site-sdk": "0.11.
|
|
38
|
-
"@avocadostudio-ai/shared": "0.11.
|
|
37
|
+
"@avocadostudio-ai/site-sdk": "0.11.8",
|
|
38
|
+
"@avocadostudio-ai/shared": "0.11.8"
|
|
39
39
|
},
|
|
40
40
|
"license": "Apache-2.0",
|
|
41
41
|
"homepage": "https://docs.avocadostudio.dev",
|