sv 1.2.0 → 1.4.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.
Files changed (30) hide show
  1. package/dist/{shared.json → addons/ai-tools.json} +18 -199
  2. package/dist/{addons-Ih-Pmrow.mjs → addons-B9USH0bk.mjs} +101 -26
  3. package/dist/bin.mjs +46 -29
  4. package/dist/{engine-0i6PA_0L.mjs → engine-B1nZjPzd.mjs} +7 -61
  5. package/dist/playground/PlaygroundLayout.svelte +218 -0
  6. package/dist/src/index.d.mts +5 -4
  7. package/dist/src/index.mjs +2 -2
  8. package/dist/src/testing.mjs +1 -1
  9. package/dist/templates/addon/assets/CONTRIBUTING.md +48 -0
  10. package/dist/templates/addon/assets/README.md +29 -0
  11. package/dist/templates/addon/files.types=checkjs.json +10 -1
  12. package/dist/templates/addon/files.types=none.json +10 -1
  13. package/dist/templates/addon/files.types=typescript.json +10 -1
  14. package/dist/templates/addon/package.json +22 -16
  15. package/dist/templates/demo/assets/README.md +49 -0
  16. package/dist/templates/demo/files.types=checkjs.json +12 -0
  17. package/dist/templates/demo/files.types=none.json +12 -0
  18. package/dist/templates/demo/files.types=typescript.json +12 -0
  19. package/dist/templates/demo/package.json +10 -6
  20. package/dist/templates/library/assets/README.md +72 -0
  21. package/dist/templates/library/files.types=checkjs.json +12 -0
  22. package/dist/templates/library/files.types=none.json +12 -0
  23. package/dist/templates/library/files.types=typescript.json +12 -0
  24. package/dist/templates/library/package.json +28 -17
  25. package/dist/templates/minimal/assets/README.md +49 -0
  26. package/dist/templates/minimal/files.types=checkjs.json +12 -0
  27. package/dist/templates/minimal/files.types=none.json +12 -0
  28. package/dist/templates/minimal/files.types=typescript.json +12 -0
  29. package/dist/templates/minimal/package.json +10 -6
  30. package/package.json +2 -4
@@ -1,7 +1,7 @@
1
- import { E as getSharedFiles, _ as defineAddon, mt as R, v as defineAddonOptions } from "./engine-0i6PA_0L.mjs";
1
+ import { T as dist_dir, _ as defineAddon, pt as R, v as defineAddonOptions } from "./engine-B1nZjPzd.mjs";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
- import { KIT3_TSCONFIG, Walker, coerceVersion, color, createPrinter, dedent, defineDemoPage, defineEnv, fileExists, isKit3, loadPackageJson, pnpm, resolveCommandArray, resolveLibPrefix, sanitizeName, svelteConfig, transforms } from "@sveltejs/sv-utils";
4
+ import { KIT3_TSCONFIG, Walker, coerceVersion, color, createPrinter, dedent, defineDemoPage, defineEnv, fileExists, isKit3, loadPackageJson, pnpm, resolveCommandArray, resolveHooksTypesFrom, resolveLibPrefix, sanitizeName, svelteConfig, transforms } from "@sveltejs/sv-utils";
5
5
  import V from "node:process";
6
6
  import crypto from "node:crypto";
7
7
  //#region src/addons/ids.ts
@@ -56,6 +56,11 @@ const CLIENTS = {
56
56
  agentPath: "AGENTS.md",
57
57
  configPath: ".cursor/mcp.json",
58
58
  skillsPath: ".cursor/skills",
59
+ alsoReadsSkillsFrom: [
60
+ ".agents/skills",
61
+ ".claude/skills",
62
+ ".codex/skills"
63
+ ],
59
64
  agentsPath: ".cursor/agents",
60
65
  mcpOptions: {}
61
66
  },
@@ -64,6 +69,7 @@ const CLIENTS = {
64
69
  agentPath: "GEMINI.md",
65
70
  configPath: ".gemini/settings.json",
66
71
  skillsPath: ".gemini/skills",
72
+ alsoReadsSkillsFrom: [".agents/skills"],
67
73
  agentsPath: ".gemini/agents",
68
74
  schema: "https://raw.githubusercontent.com/google-gemini/gemini-cli/main/schemas/settings.schema.json",
69
75
  mcpOptions: {}
@@ -71,8 +77,9 @@ const CLIENTS = {
71
77
  opencode: {
72
78
  label: "OpenCode",
73
79
  pluginOnly: true,
74
- agentPath: "AGENTS.md",
75
80
  configPath: ".opencode/opencode.json",
81
+ skillsPath: ".opencode/skills",
82
+ alsoReadsSkillsFrom: [".agents/skills"],
76
83
  schema: "https://opencode.ai/config.json",
77
84
  customData: { plugin: ["@sveltejs/opencode"] },
78
85
  extraFiles: [{
@@ -80,11 +87,25 @@ const CLIENTS = {
80
87
  data: { $schema: "https://svelte.dev/opencode/schema.json" }
81
88
  }]
82
89
  },
90
+ pi: {
91
+ label: "Pi",
92
+ pluginOnly: true,
93
+ configPath: ".pi/settings.json",
94
+ skillsPath: ".pi/skills",
95
+ alsoReadsSkillsFrom: [".agents/skills"],
96
+ schema: "https://pi.dev/schemas/settings.schema.json",
97
+ customData: { packages: ["npm:@sveltejs/pi"] },
98
+ extraFiles: [{
99
+ path: ".pi/svelte.json",
100
+ data: { $schema: "https://svelte.dev/pi/schema.json" }
101
+ }]
102
+ },
83
103
  vscode: {
84
104
  label: "VS Code",
85
105
  agentPath: "AGENTS.md",
86
106
  configPath: ".vscode/mcp.json",
87
107
  skillsPath: ".github/skills",
108
+ alsoReadsSkillsFrom: [".claude/skills", ".agents/skills"],
88
109
  agentsPath: ".github/agents",
89
110
  agentExtension: ".agent.md",
90
111
  mcpOptions: { serversKey: "servers" }
@@ -97,6 +118,7 @@ const CLIENTS = {
97
118
  const acceptsTools = (client) => Boolean(client && !client.pluginOnly && (client.skillsPath || client.agentsPath || client.configPath));
98
119
  const wantsLooseTools = (client, delivery) => acceptsTools(client) && (!client.pluginSettings || delivery !== "plugin");
99
120
  const wantsMcpConfig = (client, delivery) => Boolean(client?.mcpOptions) && wantsLooseTools(client, delivery);
121
+ const writesAgentFile = (client, delivery) => Boolean(client?.agentPath) && !(client.pluginSettings && delivery === "plugin");
100
122
  const TOOLS = {
101
123
  mcp: {
102
124
  label: "MCP server",
@@ -118,6 +140,29 @@ const TOOLS = {
118
140
  hint: "sub-agent"
119
141
  }
120
142
  };
143
+ const OPT_IN_SKILLS = { "svelte-mcp-feedback": {
144
+ label: "svelte-mcp-feedback",
145
+ hint: "reports Svelte mistakes you correct to sveltejs/ai-tools"
146
+ } };
147
+ const skillDirsOf = (client) => client.skillsPath ? [client.skillsPath, ...client.alsoReadsSkillsFrom ?? []] : [];
148
+ const hasSkillIn = (cwd, dir, skill) => fs.existsSync(path.resolve(cwd, dir, skill, "SKILL.md"));
149
+ const isSkillInstalled = (cwd, client, skill) => skillDirsOf(client).some((dir) => hasSkillIn(cwd, dir, skill));
150
+ const readersOf = (dir) => Object.values(CLIENTS).filter((client) => skillDirsOf(client).includes(dir)).length;
151
+ const optInSkillsQuestion = (isInstalled = () => false) => {
152
+ const missingFor = (ides) => Object.keys(OPT_IN_SKILLS).filter((skill) => ides.some((i) => CLIENTS[i]?.skillsPath && !isInstalled(CLIENTS[i], skill)));
153
+ return {
154
+ question: "Would you like to add any opt-in skills?",
155
+ type: "multiselect",
156
+ default: [],
157
+ options: missingFor(Object.keys(CLIENTS)).map((value) => ({
158
+ value,
159
+ label: OPT_IN_SKILLS[value].label,
160
+ hint: OPT_IN_SKILLS[value].hint
161
+ })),
162
+ required: false,
163
+ condition: ({ ide }) => missingFor(ide).length > 0
164
+ };
165
+ };
121
166
  const options$8 = defineAddonOptions().add("ide", {
122
167
  question: "Which client would you like to use?",
123
168
  type: "multiselect",
@@ -166,18 +211,28 @@ const options$8 = defineAddonOptions().add("ide", {
166
211
  hint: "will use a remote endpoint"
167
212
  }],
168
213
  condition: ({ ide, delivery, tools }) => (tools === void 0 || tools.includes("mcp")) && ide.some((i) => wantsMcpConfig(CLIENTS[i], delivery))
169
- }).build();
214
+ }).add("agentsMd", {
215
+ question: "Would you like to add an AGENTS.md (or similar) with instructions for agents?",
216
+ type: "boolean",
217
+ default: true,
218
+ condition: ({ ide, delivery }) => ide.some((i) => writesAgentFile(CLIENTS[i], delivery))
219
+ }).add("optInSkills", optInSkillsQuestion()).build();
170
220
  const addon$8 = defineAddon({
171
221
  id: ADDON_IDS.aiTools,
172
222
  shortDescription: "Svelte AI tools",
173
223
  homepage: "https://svelte.dev/docs/ai",
174
224
  options: options$8,
175
- run: ({ sv, options }) => {
225
+ setup: ({ cwd, addOption }) => {
226
+ addOption("optInSkills", optInSkillsQuestion((client, skill) => isSkillInstalled(cwd, client, skill)));
227
+ },
228
+ run: ({ sv, options, cwd }) => {
176
229
  const usePlugin = options.delivery === "plugin";
177
230
  const selected = options.tools ?? Object.keys(TOOLS);
178
231
  const selectedSkills = selected.filter((t) => TOOLS[t]?.kind === "skill");
179
232
  const selectedAgents = selected.filter((t) => TOOLS[t]?.kind === "agent");
180
233
  const wantsMcp = selected.includes("mcp");
234
+ const selectedOptInSkills = (options.optInSkills ?? []).filter((s) => s in OPT_IN_SKILLS);
235
+ const wantsAgentFile = options.agentsMd !== false;
181
236
  const getLocalConfig = (o) => {
182
237
  return {
183
238
  ...o?.typeLocal ? { type: o.typeLocal } : {},
@@ -194,10 +249,14 @@ const addon$8 = defineAddon({
194
249
  };
195
250
  const filesAdded = [];
196
251
  const filesExistingAlready = [];
197
- const sharedFiles = getSharedFiles();
198
- const mcpFiles = sharedFiles.filter((file) => file.include.includes("mcp"));
199
- const skillFiles = sharedFiles.filter((file) => file.include.includes("skills"));
200
- const agentFiles = sharedFiles.filter((file) => file.include.includes("agents"));
252
+ const { files } = JSON.parse(fs.readFileSync(path.join(dist_dir, "addons", "ai-tools.json"), "utf-8"));
253
+ const at = (kind) => files.filter((file) => file.name.startsWith(`${kind}/`)).map((file) => ({
254
+ ...file,
255
+ name: file.name.slice(kind.length + 1)
256
+ }));
257
+ const mcpFiles = at("mcp");
258
+ const skillFiles = at("skills");
259
+ const agentFiles = at("agents");
201
260
  const agentFile = mcpFiles.find((file) => file.name === "AGENTS.md");
202
261
  const addFile = (path, contents) => {
203
262
  sv.file(path, (content) => {
@@ -209,6 +268,16 @@ const addon$8 = defineAddon({
209
268
  return contents;
210
269
  });
211
270
  };
271
+ const optInClients = options.ide.map((ide) => CLIENTS[ide]).filter((client) => Boolean(client?.skillsPath)).sort((a, b) => readersOf(b.skillsPath) - readersOf(a.skillsPath));
272
+ for (const skill of selectedOptInSkills) {
273
+ const files = skillFiles.filter((file) => file.name.split("/")[0] === skill);
274
+ const writtenDirs = /* @__PURE__ */ new Set();
275
+ for (const client of optInClients) {
276
+ if (skillDirsOf(client).some((dir) => writtenDirs.has(dir) || hasSkillIn(cwd, dir, skill))) continue;
277
+ for (const file of files) addFile(`${client.skillsPath}/${file.name}`, file.contents);
278
+ writtenDirs.add(client.skillsPath);
279
+ }
280
+ }
212
281
  for (const ide of options.ide) {
213
282
  const client = CLIENTS[ide];
214
283
  if (!client) continue;
@@ -225,17 +294,18 @@ const addon$8 = defineAddon({
225
294
  }));
226
295
  continue;
227
296
  }
228
- if (!client.agentPath) continue;
229
297
  const { mcpOptions, agentPath, agentLink, configPath, skillsPath, agentsPath, agentExtension, schema, customData, extraFiles } = client;
230
- if (!filesAdded.includes(agentPath)) sv.file(agentPath, (content) => {
231
- if (content) {
232
- if (!filesExistingAlready.includes(agentPath)) filesExistingAlready.push(agentPath);
233
- return false;
234
- }
235
- filesAdded.push(agentPath);
236
- return agentFile?.contents ?? "";
237
- });
238
- if (agentLink) addFile(agentLink.path, agentLink.contents);
298
+ if (agentPath && wantsAgentFile) {
299
+ if (!filesAdded.includes(agentPath)) sv.file(agentPath, (content) => {
300
+ if (content) {
301
+ if (!filesExistingAlready.includes(agentPath)) filesExistingAlready.push(agentPath);
302
+ return false;
303
+ }
304
+ filesAdded.push(agentPath);
305
+ return agentFile?.contents ?? "";
306
+ });
307
+ if (agentLink) addFile(agentLink.path, agentLink.contents);
308
+ }
239
309
  const writeMcp = Boolean(mcpOptions) && wantsMcp;
240
310
  if (configPath && (writeMcp || customData)) sv.file(configPath, transforms.json(({ data }) => {
241
311
  if (schema) data["$schema"] = schema;
@@ -249,11 +319,12 @@ const addon$8 = defineAddon({
249
319
  if (extraFiles) for (const extra of extraFiles) sv.file(extra.path, transforms.json(({ data }) => {
250
320
  for (const [key, value] of Object.entries(extra.data)) data[key] = value;
251
321
  }));
252
- if (skillsPath) for (const file of skillFiles) {
322
+ const looseTools = wantsLooseTools(client, options.delivery);
323
+ if (skillsPath && looseTools) for (const file of skillFiles) {
253
324
  if (!selectedSkills.includes(file.name.split("/")[0])) continue;
254
325
  addFile(`${skillsPath}/${file.name}`, file.contents);
255
326
  }
256
- if (agentsPath) for (const file of agentFiles) {
327
+ if (agentsPath && looseTools) for (const file of agentFiles) {
257
328
  if (!selectedAgents.includes(file.name.replace(REGEX_MD, ""))) continue;
258
329
  const ext = agentExtension ?? ".md";
259
330
  addFile(`${agentsPath}/${file.name.replace(REGEX_MD, ext)}`, file.contents);
@@ -318,7 +389,8 @@ const addon$7 = defineAddon({
318
389
  runsAfter(ADDON_IDS.experimental);
319
390
  },
320
391
  run: ({ sv, cwd, language, options, directory, dependencyVersion, file }) => {
321
- const lib = resolveLibPrefix(dependencyVersion("@sveltejs/kit"));
392
+ const kitRange = dependencyVersion("@sveltejs/kit");
393
+ const lib = resolveLibPrefix(kitRange);
322
394
  const svelteVersion = dependencyVersion("svelte");
323
395
  const svelte5 = !!svelteVersion && coerceVersion(svelteVersion).major === 5;
324
396
  const [ts, s5] = createPrinter(language === "ts", svelte5);
@@ -512,7 +584,8 @@ const addon$7 = defineAddon({
512
584
  language,
513
585
  newHandleName: "handleBetterAuth",
514
586
  handleContent,
515
- comments
587
+ comments,
588
+ kitVersion: kitRange
516
589
  });
517
590
  }));
518
591
  if (hasDemo) {
@@ -1705,6 +1778,7 @@ const addon$4 = defineAddon({
1705
1778
  const kitRange = dependencyVersion("@sveltejs/kit");
1706
1779
  const lib = resolveLibPrefix(kitRange);
1707
1780
  const pathType = isKit3(kitRange) ? "Path" : "Pathname";
1781
+ const hooksTypesFrom = resolveHooksTypesFrom(kitRange);
1708
1782
  const paraglideOutDir = `${directory.lib}/paraglide`;
1709
1783
  sv.devDependency("@inlang/paraglide-js", "^2.18.2");
1710
1784
  sv.file(file.viteConfig, transforms.script(({ ast, js }) => {
@@ -1736,11 +1810,11 @@ const addon$4 = defineAddon({
1736
1810
  });
1737
1811
  if (existingExport.declaration !== rerouteIdentifier) R.warn("Adding the reroute hook automatically failed. Add it manually");
1738
1812
  if (language === "ts") js.imports.addNamed(ast, {
1739
- from: "@sveltejs/kit/hooks",
1813
+ from: hooksTypesFrom,
1740
1814
  imports: ["Reroute"],
1741
1815
  isType: true
1742
1816
  });
1743
- else js.common.addJsDocTypeComment(existingExport, comments, { type: "import('@sveltejs/kit/hooks').Reroute" });
1817
+ else js.common.addJsDocTypeComment(existingExport, comments, { type: `import('${hooksTypesFrom}').Reroute` });
1744
1818
  }));
1745
1819
  sv.file(`src/hooks.server.${language}`, transforms.script(({ ast, comments, js }) => {
1746
1820
  js.imports.addNamed(ast, {
@@ -1759,7 +1833,8 @@ const addon$4 = defineAddon({
1759
1833
  transformPageChunk: ({ html }) => html.replace('%paraglide.lang%', locale).replace('%paraglide.dir%', getTextDirection(locale))
1760
1834
  });
1761
1835
  });`,
1762
- comments
1836
+ comments,
1837
+ kitVersion: kitRange
1763
1838
  });
1764
1839
  }));
1765
1840
  sv.file("src/app.html", transforms.html(({ ast, html }) => {
package/dist/bin.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { $ as optional, A as buildAndLogArgs, B as parseAddonOptions, C as create$1, D as up$2, E as getSharedFiles, F as getHelpSections, G as updateReadme, H as runCommand, I as getPadding, J as version, K as UnsupportedError, L as helpConfig, M as errorAndExit, N as filePaths, O as from, P as forwardExitCode, Q as nonEmpty, R as isNodeError, S as execSync, T as dist_dir, U as updateAgent, V as runAndValidateVerifications, W as updateLibraryBuild, X as boolean, Y as array, Z as literal, _t as le, a as setupAddons, at as strictObject, b as NonZeroExitError, bt as we, c as AGENT_NAMES, ct as union, d as detectPackageManager, dt as Option, et as parse$1, f as installDependencies, ft as Ce, g as createLoadedAddon, gt as ge, h as up$1, ht as Re, i as prepareSvApi, it as safeParse, j as cliOptions, k as PackageJSONSchema, l as addAllowBuildsIfPnpm, lt as program, m as packageManagerPrompt, mt as R, n as applyAddons, nt as pipe, o as createWorkspace, ot as string, p as installOption, pt as Ee, q as name, r as orderAddons, rt as record, s as findWorkspaceRoot, st as transform, tt as picklist, u as addEngineStrict, ut as Command, vt as pe, w as templates, x as exec, xt as R$1, y as getErrorHint, yt as vt, z as normalizePosix } from "./engine-0i6PA_0L.mjs";
3
- import { n as officialAddons$1, t as getAddonDetails } from "./addons-Ih-Pmrow.mjs";
2
+ import { $ as parse$1, A as cliOptions, B as runAndValidateVerifications, C as create$1, D as from, E as up$2, F as getPadding, G as UnsupportedError, H as updateAgent, I as helpConfig, J as array, K as name, L as isNodeError, M as filePaths, N as forwardExitCode, O as PackageJSONSchema, P as getHelpSections, Q as optional, R as normalizePosix, S as execSync, T as dist_dir, U as updateLibraryBuild, V as runCommand, W as updateReadme, X as literal, Y as boolean, Z as nonEmpty, _t as pe, a as setupAddons, at as string, b as NonZeroExitError, bt as R$1, c as AGENT_NAMES, ct as program, d as detectPackageManager, dt as Ce, et as picklist, f as installDependencies, ft as Ee, g as createLoadedAddon, gt as le, h as up$1, ht as ge, i as prepareSvApi, it as strictObject, j as errorAndExit, k as buildAndLogArgs, l as addAllowBuildsIfPnpm, lt as Command, m as packageManagerPrompt, mt as Re, n as applyAddons, nt as record, o as createWorkspace, ot as transform, p as installOption, pt as R, q as version, r as orderAddons, rt as safeParse, s as findWorkspaceRoot, st as union, tt as pipe, u as addEngineStrict, ut as Option, vt, w as templates, x as exec, y as getErrorHint, yt as we, z as parseAddonOptions } from "./engine-B1nZjPzd.mjs";
3
+ import { n as officialAddons$1, t as getAddonDetails } from "./addons-B9USH0bk.mjs";
4
4
  import * as fs$1 from "node:fs";
5
5
  import fs from "node:fs";
6
6
  import * as path$1 from "node:path";
@@ -1936,8 +1936,12 @@ const check = new Command("check").description("a CLI for checking your Svelte c
1936
1936
  });
1937
1937
  async function runCheck(cwd, args) {
1938
1938
  const pm = await detectPackageManager(cwd);
1939
- if (!from(cwd, "svelte-check", true)) {
1940
- console.error(`'svelte-check' is not installed locally. Install it with: ${color.command(resolveCommandArray(pm, "add", ["-D", "svelte-check"]))}`);
1939
+ const resolvedCwd = path.resolve(cwd);
1940
+ if (!up$1(path.join("node_modules", ".bin", "svelte-check"), {
1941
+ cwd: resolvedCwd,
1942
+ last: findWorkspaceRoot(resolvedCwd)
1943
+ })) {
1944
+ console.error(`'svelte-check' is not installed in your project. Install it with: ${color.command(resolveCommandArray(pm, "add", ["-D", "svelte-check"]))}`);
1941
1945
  V.exit(1);
1942
1946
  }
1943
1947
  if (args.includes("--help")) {
@@ -2063,25 +2067,19 @@ function setupPlaygroundProject(url, playground, cwd, installDependencies) {
2063
2067
  fs.writeFileSync(filePath, file.content, "utf8");
2064
2068
  }
2065
2069
  {
2066
- const playgroundFiles = getSharedFiles().filter((file) => file.include.includes("playground"));
2067
- for (const file of playgroundFiles) {
2068
- let contentToWrite = file.contents;
2069
- if (file.name === "src/lib/PlaygroundLayout.svelte") {
2070
- const { ast, generateCode } = parse.svelte(file.contents);
2071
- svelte.ensureScript(ast);
2072
- Walker.walk(ast.instance.content, null, { Literal(node) {
2073
- if (node.value === "$sv-title-$sv") {
2074
- node.value = playground.name;
2075
- node.raw = void 0;
2076
- } else if (node.value === "$sv-url-$sv") {
2077
- node.value = url;
2078
- node.raw = void 0;
2079
- }
2080
- } });
2081
- contentToWrite = generateCode();
2070
+ const layout = fs.readFileSync(path.join(dist_dir, "playground", "PlaygroundLayout.svelte"), "utf-8");
2071
+ const { ast, generateCode } = parse.svelte(layout);
2072
+ svelte.ensureScript(ast);
2073
+ Walker.walk(ast.instance.content, null, { Literal(node) {
2074
+ if (node.value === "$sv-title-$sv") {
2075
+ node.value = playground.name;
2076
+ node.raw = void 0;
2077
+ } else if (node.value === "$sv-url-$sv") {
2078
+ node.value = url;
2079
+ node.raw = void 0;
2082
2080
  }
2083
- fs.writeFileSync(path.join(cwd, file.name), contentToWrite, "utf-8");
2084
- }
2081
+ } });
2082
+ fs.writeFileSync(path.join(cwd, "src/lib/PlaygroundLayout.svelte"), generateCode(), "utf-8");
2085
2083
  }
2086
2084
  const filePath = path.join(cwd, "src/routes/+page.svelte");
2087
2085
  const content = fs.readFileSync(filePath, "utf-8");
@@ -2232,10 +2230,11 @@ async function createProject(cwd, options) {
2232
2230
  },
2233
2231
  force: async ({ results: { directory } }) => {
2234
2232
  if (!options.dirCheck) return;
2233
+ if (!directory) return;
2235
2234
  if (!fs.existsSync(directory)) return;
2236
- if (!fs.readdirSync(directory).some((file) => !file.startsWith(".git"))) return;
2235
+ if (fs.readdirSync(directory).every((entry) => entry === ".git")) return;
2237
2236
  const force = await le({
2238
- message: "Directory not empty. Continue?",
2237
+ message: `Directory not empty:\n${color.path(path.resolve(directory))}\n\nContinue?`,
2239
2238
  initialValue: false
2240
2239
  });
2241
2240
  if (R$1(force) || !force) {
@@ -2801,6 +2800,16 @@ const migrationTasks = [
2801
2800
  instructions: "Import `version` from `$app/env`, application asset metadata from `$app/manifest`, and path helpers from `$app/paths`. Account for the new manifest value shapes rather than blindly renaming `build` or `files` imports.",
2802
2801
  links: guideLink("$service-worker-(removed)")
2803
2802
  },
2803
+ {
2804
+ title: "Remove `rewriteRelativeImportExtensions` from tsconfig.json",
2805
+ checks: [{
2806
+ include: "**/tsconfig.json",
2807
+ patterns: [/["']rewriteRelativeImportExtensions["']/]
2808
+ }],
2809
+ summary: "`rewriteRelativeImportExtensions` will flag subpath imports with `.ts` as type errors.",
2810
+ instructions: "Remove `rewriteRelativeImportExtensions` from tsconfig.json.",
2811
+ links: [...guideLink("$lib-is-now-lib"), ...guideLink("$app-tsconfig")]
2812
+ },
2804
2813
  {
2805
2814
  title: "Create a TypeScript project for the service worker",
2806
2815
  checks: [{
@@ -3852,7 +3861,8 @@ function libSubpathImports(libDir) {
3852
3861
  var lib_alias_default = defineMigrationTask({
3853
3862
  id: "lib-alias",
3854
3863
  description: "Replace the $lib alias with #lib subpath imports",
3855
- run: ({ sv, cwd, directory }) => {
3864
+ run: ({ sv, cwd, file, directory, dependencyVersion }) => {
3865
+ const isLibrary = Boolean(dependencyVersion("@sveltejs/package"));
3856
3866
  sv.file("package.json", transforms.json(({ data }) => {
3857
3867
  data.imports = {
3858
3868
  ...libSubpathImports(directory.lib),
@@ -3869,16 +3879,23 @@ var lib_alias_default = defineMigrationTask({
3869
3879
  match = match.replace("$lib", "#lib");
3870
3880
  if (import_path && !import_path.endsWith(".js") && !import_path.endsWith(".ts")) {
3871
3881
  for (const ending of [
3872
- ".js",
3873
3882
  ".ts",
3874
- "/index.js",
3875
- "/index.ts"
3876
- ]) if (fs.existsSync(path.join(cwd, directory.lib, import_path + ending))) return match.slice(0, -1) + ending.replace(".ts", ".js") + match.slice(-1);
3883
+ ".js",
3884
+ "/index.ts",
3885
+ "/index.js"
3886
+ ]) if (fs.existsSync(path.join(cwd, directory.lib, import_path + ending))) {
3887
+ const specifier = isLibrary ? ending.replace(".ts", ".js") : ending;
3888
+ return match.slice(0, -1) + specifier + match.slice(-1);
3889
+ }
3877
3890
  }
3878
3891
  return match;
3879
3892
  });
3880
3893
  return rewritten === content ? false : rewritten;
3881
3894
  });
3895
+ if (file.typeConfig) sv.file(path.relative(cwd, file.typeConfig), (content) => {
3896
+ if (!content.includes("rewriteRelativeImportExtensions") || content.includes("@migration-task")) return false;
3897
+ return createMigrationTaskComment("remove `rewriteRelativeImportExtensions` - the `#lib/*.ts` subpath imports are not relative paths, but the flag errors with TS2877") + "\n" + content;
3898
+ });
3882
3899
  }
3883
3900
  });
3884
3901
  //#endregion
@@ -5020,7 +5020,7 @@ function safeParse(schema, input, config$1) {
5020
5020
  //#endregion
5021
5021
  //#region package.json
5022
5022
  var name = "sv";
5023
- var version = "1.2.0";
5023
+ var version = "1.4.0";
5024
5024
  //#endregion
5025
5025
  //#region src/core/errors.ts
5026
5026
  var UnsupportedError = class extends Error {
@@ -5046,7 +5046,8 @@ const PackageJSONSchema = /* @__PURE__ */ looseObject({
5046
5046
  /* @__PURE__ */ string(),
5047
5047
  /* @__PURE__ */ array(/* @__PURE__ */ string()),
5048
5048
  /* @__PURE__ */ record(/* @__PURE__ */ string(), /* @__PURE__ */ any$1())
5049
- ]))
5049
+ ])),
5050
+ scripts: /* @__PURE__ */ optional(StringRecordSchema)
5050
5051
  });
5051
5052
  const cliOptions = {
5052
5053
  noDownloadCheck: new Option("--no-download-check", "do not warn about downloads from community add-ons"),
@@ -5337,7 +5338,7 @@ function up$1(base, options) {
5337
5338
  //#region src/create/utils.ts
5338
5339
  /**
5339
5340
  * @returns an absolute path to the `dist` directory
5340
- * containing templates, add-ons and shared files
5341
+ * containing templates and add-on content
5341
5342
  *
5342
5343
  * this function can be called during runtime or devtime
5343
5344
  */
@@ -5385,11 +5386,6 @@ function copy(from, to, rename = identity, kv = {}) {
5385
5386
  else fs.copyFileSync(from, to);
5386
5387
  }
5387
5388
  }
5388
- function getSharedFiles() {
5389
- const shared = path.join(dist_dir, "shared.json");
5390
- const { files } = JSON.parse(fs.readFileSync(shared, "utf-8"));
5391
- return files;
5392
- }
5393
5389
  //#endregion
5394
5390
  //#region src/create/index.ts
5395
5391
  const publicTemplateTypes = [
@@ -5398,22 +5394,10 @@ const publicTemplateTypes = [
5398
5394
  "library",
5399
5395
  "addon"
5400
5396
  ];
5401
- const templateTypes = [
5402
- "minimal",
5403
- "demo",
5404
- "library",
5405
- "addon",
5406
- "svelte"
5407
- ];
5408
- const languageTypes = [
5409
- "typescript",
5410
- "checkjs",
5411
- "none"
5412
- ];
5413
5397
  function create({ cwd, ...options }) {
5414
5398
  mkdirp(cwd);
5415
5399
  write_template_files(options.template, options.types, options.name, cwd);
5416
- if (options.template !== "svelte") write_common_files(cwd, options, options.name);
5400
+ if (options.template !== "svelte") finalize_package_json(cwd, options.name);
5417
5401
  if (options.template === "addon") for (const name of [
5418
5402
  "svelte.config.js",
5419
5403
  "svelte.config.ts",
@@ -5441,41 +5425,14 @@ function write_template_files(template, types, name, cwd) {
5441
5425
  fs.writeFileSync(dest, replace(file.contents, kv(name)));
5442
5426
  });
5443
5427
  }
5444
- function write_common_files(cwd, options, name) {
5445
- const files = getSharedFiles();
5428
+ function finalize_package_json(cwd, name) {
5446
5429
  const pkg_file = path.join(cwd, filePaths.packageJson);
5447
5430
  const pkg = JSON.parse(fs.readFileSync(pkg_file, "utf-8"));
5448
- sort_files(files).forEach((file) => {
5449
- const include = file.include.every((condition) => matches_condition(condition, options));
5450
- if (file.exclude.some((condition) => matches_condition(condition, options)) || !include) return;
5451
- if (file.name === filePaths.packageJson) {
5452
- const new_pkg = JSON.parse(file.contents);
5453
- merge(pkg, new_pkg);
5454
- } else {
5455
- const dest = path.join(cwd, file.name);
5456
- mkdirp(path.dirname(dest));
5457
- fs.writeFileSync(dest, replace(file.contents, kv(name)));
5458
- }
5459
- });
5460
5431
  pkg.dependencies = sort_keys(pkg.dependencies);
5461
5432
  pkg.devDependencies = sort_keys(pkg.devDependencies);
5462
5433
  pkg.name = sanitizeName(name, "package");
5463
5434
  fs.writeFileSync(pkg_file, JSON.stringify(pkg, null, " ") + "\n");
5464
5435
  }
5465
- function matches_condition(condition, options) {
5466
- if (templateTypes.includes(condition)) return options.template === condition;
5467
- if (languageTypes.includes(condition)) return options.types === condition;
5468
- return Boolean(options[condition]);
5469
- }
5470
- function merge(target, source) {
5471
- for (const key in source) if (key in target) {
5472
- const target_value = target[key];
5473
- const source_value = source[key];
5474
- if (typeof source_value !== typeof target_value || Array.isArray(source_value) !== Array.isArray(target_value)) throw new Error("Mismatched values");
5475
- if (typeof source_value === "object") merge(target_value, source_value);
5476
- else target[key] = source_value;
5477
- } else target[key] = source[key];
5478
- }
5479
5436
  function sort_keys(obj) {
5480
5437
  if (!obj) return;
5481
5438
  return Object.keys(obj).sort().reduce((sorted, key) => {
@@ -5483,17 +5440,6 @@ function sort_keys(obj) {
5483
5440
  return sorted;
5484
5441
  }, {});
5485
5442
  }
5486
- /**
5487
- * Sort files so that those which apply more generically come first so they
5488
- * can be overwritten by files for more precise cases later.
5489
- */
5490
- function sort_files(files) {
5491
- return files.sort((f1, f2) => {
5492
- const f1_more_generic = f1.include.every((include) => f2.include.includes(include)) && f1.exclude.every((exclude) => f2.exclude.includes(exclude));
5493
- const f2_more_generic = f2.include.every((include) => f1.include.includes(include)) && f2.exclude.every((exclude) => f1.exclude.includes(exclude));
5494
- return f1_more_generic && f2_more_generic || !f1_more_generic && !f2_more_generic ? 0 : f1_more_generic ? -1 : 1;
5495
- });
5496
- }
5497
5443
  //#endregion
5498
5444
  //#region ../../node_modules/.pnpm/tinyexec@1.3.1/node_modules/tinyexec/dist/main.mjs
5499
5445
  const isPathLikePattern = /^path$/i;
@@ -6489,4 +6435,4 @@ function orderAddons(addons, setupResults) {
6489
6435
  return ordered;
6490
6436
  }
6491
6437
  //#endregion
6492
- export { optional as $, buildAndLogArgs as A, parseAddonOptions as B, create as C, __require as Ct, up$1 as D, getSharedFiles as E, getHelpSections as F, updateReadme as G, runCommand as H, getPadding as I, version as J, UnsupportedError as K, helpConfig as L, errorAndExit as M, filePaths as N, from as O, forwardExitCode as P, nonEmpty as Q, isNodeError as R, execSync as S, __commonJSMin as St, dist_dir as T, updateAgent as U, runAndValidateVerifications as V, updateLibraryBuild as W, boolean as X, array as Y, literal as Z, defineAddon as _, le as _t, setupAddons as a, strictObject as at, NonZeroExitError as b, we as bt, AGENT_NAMES as c, union as ct, detectPackageManager as d, Option as dt, parse$1 as et, installDependencies as f, Ce as ft, createLoadedAddon as g, ge as gt, up as h, Re as ht, prepareSvApi as i, safeParse as it, cliOptions as j, PackageJSONSchema as k, addAllowBuildsIfPnpm as l, program as lt, packageManagerPrompt as m, R as mt, applyAddons as n, pipe as nt, createWorkspace as o, string as ot, installOption as p, Ee as pt, name as q, orderAddons as r, record as rt, findWorkspaceRoot as s, transform as st, add as t, picklist as tt, addEngineStrict as u, Command as ut, defineAddonOptions as v, pe as vt, templates as w, __toESM as wt, exec as x, R$1 as xt, getErrorHint as y, vt as yt, normalizePosix as z };
6438
+ export { parse$1 as $, cliOptions as A, runAndValidateVerifications as B, create as C, __toESM as Ct, from as D, up$1 as E, getPadding as F, UnsupportedError as G, updateAgent as H, helpConfig as I, array as J, name as K, isNodeError as L, filePaths as M, forwardExitCode as N, PackageJSONSchema as O, getHelpSections as P, optional as Q, normalizePosix as R, execSync as S, __require as St, dist_dir as T, updateLibraryBuild as U, runCommand as V, updateReadme as W, literal as X, boolean as Y, nonEmpty as Z, defineAddon as _, pe as _t, setupAddons as a, string as at, NonZeroExitError as b, R$1 as bt, AGENT_NAMES as c, program as ct, detectPackageManager as d, Ce as dt, picklist as et, installDependencies as f, Ee as ft, createLoadedAddon as g, le as gt, up as h, ge as ht, prepareSvApi as i, strictObject as it, errorAndExit as j, buildAndLogArgs as k, addAllowBuildsIfPnpm as l, Command as lt, packageManagerPrompt as m, Re as mt, applyAddons as n, record as nt, createWorkspace as o, transform as ot, installOption as p, R as pt, version as q, orderAddons as r, safeParse as rt, findWorkspaceRoot as s, union as st, add as t, pipe as tt, addEngineStrict as u, Option as ut, defineAddonOptions as v, vt, templates as w, exec as x, __commonJSMin as xt, getErrorHint as y, we as yt, parseAddonOptions as z };