acrylblends 1.0.2 → 1.0.4

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 (49) hide show
  1. package/dist/index.js +7 -5
  2. package/dist/index.js.map +1 -1
  3. package/docs/framework/README.md +1 -0
  4. package/docs/framework/agents/index.md +1 -1
  5. package/docs/framework/guides/data.md +12 -0
  6. package/docs/framework/workshop/README.md +381 -0
  7. package/docs/framework/workshop/facilitator.md +108 -0
  8. package/lib/{audit-BXnYsLge.d.ts → audit-D5z9uwOP.d.ts} +14 -1
  9. package/lib/cordis/db-sqlite.js +10 -2
  10. package/lib/cordis/door.d.ts +8 -2
  11. package/lib/cordis/door.js +88 -12
  12. package/lib/cordis/inspect.js +1 -1
  13. package/lib/cordis/kv-json.js +10 -2
  14. package/lib/cordis/node-server.js +1 -1
  15. package/lib/cordis/router-http.d.ts +1 -1
  16. package/lib/cordis/router-http.js +1 -1
  17. package/lib/cordis/router.d.ts +1 -1
  18. package/lib/cordis/router.js +1 -1
  19. package/lib/cordis/state.js +1 -1
  20. package/lib/door/host.d.ts +2 -2
  21. package/lib/door/host.js +1 -1
  22. package/lib/door/page.d.ts +12 -1
  23. package/lib/door/page.js +21 -0
  24. package/lib/door/protocol.d.ts +2 -2
  25. package/lib/door/protocol.js +19 -3
  26. package/lib/{index-D4nVR3wu.d.ts → index-DMOtA-NJ.d.ts} +7 -1
  27. package/lib/node-server.js +1 -1
  28. package/lib/{protocol-BizVt4J6.d.ts → protocol-C37gPePD.d.ts} +9 -2
  29. package/lib/{snapshot-text-DmE0YfeZ.js → snapshot-text-BLz8nlSc.js} +49 -1
  30. package/lib/{src-2Z4mJg0x.js → src-dy3Fk9tA.js} +16 -0
  31. package/lib/{test-websocket-ZXHNHQSU.js → test-websocket-D8WWqE5G.js} +1 -2
  32. package/package.json +1 -1
  33. package/plugins/acryl-db-sqlite/plugin.json +1 -1
  34. package/plugins/acryl-db-sqlite/src/index.ts +8 -1
  35. package/plugins/acryl-door/src/cli/acryl.ts +5 -3
  36. package/plugins/acryl-door/src/host/channel.ts +36 -0
  37. package/plugins/acryl-door/src/host/door.ts +26 -4
  38. package/plugins/acryl-door/src/host/shim.ts +23 -0
  39. package/plugins/acryl-door/src/host/verbs.ts +4 -3
  40. package/plugins/acryl-door/src/index.ts +26 -3
  41. package/plugins/acryl-door/src/page/driver/driver.ts +22 -1
  42. package/plugins/acryl-door/src/page/protocol.ts +13 -2
  43. package/plugins/acryl-kv-json/plugin.json +1 -1
  44. package/plugins/acryl-kv-json/src/index.ts +8 -1
  45. package/plugins/acryl-node-server/src/adapter/request.ts +3 -2
  46. package/plugins/acryl-router/src/service.ts +19 -1
  47. package/plugins/agent-panel/client/main.ts +63 -34
  48. package/plugins/agent-panel/index.ts +115 -25
  49. package/shared/DEFAULTS.md +4 -0
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["parse","parse","parse","posix"],"sources":["../src/templates.ts","../src/version.ts","../src/lock.ts","../src/rewrite.ts","../src/library.ts","../src/project.ts","../src/init.ts","../src/mount.ts","../src/add.ts","../src/build-client.ts","../src/check-deps.ts","../src/spawn.ts","../src/io.ts","../src/kv-import.ts","../src/diff.ts","../src/upgrade.ts","../src/cli.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\n/** The templates, all Cordis apps: a web app with a page and a client component (nodejs), a notes app and a chat app on the db port (notes, chat), a blank app on the router, a todo list on the router and state, and the blank app with the offline agent. */\nexport const TEMPLATES = ['blank', 'nodejs', 'notes', 'chat', 'todo', 'agent'] as const\nexport type Template = (typeof TEMPLATES)[number]\n\n/** One line per template: the single list `acrylblends init` and `create-acrylblends` both show (`create-acrylblends` tests that its own copy equals this one). */\nexport const TEMPLATE_SUMMARY: Record<(typeof TEMPLATES)[number], string> = {\n blank: 'the router, a server and one route: the smallest app',\n nodejs: 'a web app with a page and a client component',\n notes: 'a multi-user notes app on the db port (sign-up, log-in, sessions)',\n chat: 'a chat app that streams an answer over server-sent events',\n todo: 'a to-do list on the router and state',\n agent: 'the blank app with an offline agent that builds plugins into the running app',\n}\n\n/** Names that were templates once and still work: `create-acrylblends --template acryl-app` made the agent app. */\nexport const TEMPLATE_ALIASES: Record<string, Template> = { 'acryl-app': 'agent' }\n\nexport function isTemplate(value: string): value is Template {\n return (TEMPLATES as readonly string[]).includes(value)\n}\n\n/** The template a name means: itself, or what an old name stands for; undefined for anything else. */\nexport function resolveTemplate(value: string): Template | undefined {\n return isTemplate(value) ? value : TEMPLATE_ALIASES[value]\n}\n\n/**\n * The `templates/` folder of this package. The module sits at different depths in source (`src/`) and in the build\n * (`dist/`), so walk up until a `templates` folder holds the `blank` template.\n */\nexport function templatesRoot(): string {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n const candidate = join(dir, 'templates')\n if (existsSync(join(candidate, 'blank'))) return candidate\n const parent = dirname(dir)\n if (parent === dir) throw new Error('acrylblends cannot find its templates folder')\n dir = parent\n }\n}\n\n/** Absolute path of a template folder. */\nexport function templateDir(template: Template): string {\n return join(templatesRoot(), template)\n}\n\n/** The text every generated app's `AGENTS.md` starts with (`shared/`, beside `templates/`). */\nexport function sharedDir(): string {\n return join(dirname(templatesRoot()), 'shared')\n}\n\n/**\n * The framework's docs, as ACRYL wrote them: `docs/framework` of the repository, or the copy `prepack` puts inside the package. The module sits at\n * different depths in source and in the build, so walk up until a `docs/framework` folder holds the README.\n */\nexport function frameworkDocsRoot(): string {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n const candidate = join(dir, 'docs', 'framework')\n if (existsSync(join(candidate, 'README.md'))) return candidate\n const parent = dirname(dir)\n if (parent === dir)\n throw new Error('acrylblends cannot find the framework docs (docs/framework)')\n dir = parent\n }\n}\n","import { createRequire } from 'node:module'\n\n/** The version of this package. */\nexport const VERSION: string = (\n createRequire(import.meta.url)('../package.json') as { version: string }\n).version\n","/**\n * What an app knows about the library plugins it carries: `plugins/library.lock.json` records, for every library plugin copied into the app, the version it came from and a hash of each file\n * as it was copied. `acrylblends upgrade` reads it to tell a file nobody touched (safe to replace) from one the app edited (never replaced without `--force`). An app made before the lock existed\n * has none; for it `upgrade` falls back to the hashes of the released versions (`shared/library-history.json`, made by `scripts/build-library-history.mjs`).\n */\nimport { createHash } from 'node:crypto'\nimport { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { sharedDir } from './templates'\nimport { VERSION } from './version'\n\nexport const LOCK_FILE = 'library.lock.json'\n\nexport interface Lock {\n version: number\n plugins: Record<string, { from: string; files: Record<string, string> }>\n}\n\n/** A file's identity: a hash of its text with line endings normalized (a checkout may have changed them), cut to 20 hex digits. */\nexport function digest(content: Buffer | string): string {\n const text = typeof content === 'string' ? content : content.toString('utf8')\n return createHash('sha256').update(text.replace(/\\r\\n/gu, '\\n')).digest('hex').slice(0, 20)\n}\n\n/** Every file below `dir`, as `relative/path` (forward slashes) to its {@link digest}. */\nexport function hashFolder(dir: string): Record<string, string> {\n const files: Record<string, string> = {}\n const walk = (folder: string, inside: string): void => {\n for (const entry of readdirSync(folder).sort()) {\n const path = join(folder, entry)\n const name = inside === '' ? entry : `${inside}/${entry}`\n if (statSync(path).isDirectory()) walk(path, name)\n else files[name] = digest(readFileSync(path))\n }\n }\n if (existsSync(dir)) walk(dir, '')\n return files\n}\n\nexport function readLock(pluginsDir: string): Lock {\n const file = join(pluginsDir, LOCK_FILE)\n if (!existsSync(file)) return { version: 1, plugins: {} }\n try {\n const lock = JSON.parse(readFileSync(file, 'utf8')) as Lock\n return { version: 1, plugins: lock.plugins ?? {} }\n } catch {\n return { version: 1, plugins: {} }\n }\n}\n\n/** Record that `name` was copied from this version of the library, with the hashes of the files as they now are. */\nexport function recordLock(pluginsDir: string, name: string, files: Record<string, string>): void {\n const lock = readLock(pluginsDir)\n lock.plugins[name] = { from: VERSION, files }\n const sorted = Object.fromEntries(\n Object.entries(lock.plugins).sort(([a], [b]) => a.localeCompare(b)),\n )\n writeFileSync(\n join(pluginsDir, LOCK_FILE),\n `${JSON.stringify({ version: 1, plugins: sorted }, null, 2)}\\n`,\n )\n}\n\n/** Plugin to file to the hashes that file has had in released versions. */\nexport type History = Record<string, Record<string, string[]>>\n\nexport function readHistory(): History {\n const file = join(sharedDir(), 'library-history.json')\n if (!existsSync(file)) return {}\n return JSON.parse(readFileSync(file, 'utf8')) as History\n}\n","import { dirname, posix } from 'node:path'\n\n/**\n * The framework plugins import each other by package name (`acryl-router`, `acryl-router/middleware`): inside this repository they are workspace packages. An app has\n * no such packages, only the copied source, so `acrylblends init` and `add` rewrite those specifiers to relative paths when they copy a plugin. The file each name stands\n * for is the `entries` table of the plugin's `plugin.json`.\n */\n\n/** `acryl-router/middleware` to `acryl-router/src/middleware/index.ts`: every importable name of every library plugin. */\nexport type EntryTable = ReadonlyMap<string, string>\n\nexport function entryTable(\n library: ReadonlyMap<string, { readonly entries?: Readonly<Record<string, string>> | undefined }>,\n): EntryTable {\n const table = new Map<string, string>()\n for (const [plugin, { entries }] of library)\n for (const [subpath, file] of Object.entries(entries ?? {}))\n table.set(`${plugin}${subpath}`, `${plugin}/${file}`)\n return table\n}\n\n/** For every character of a TypeScript source: 0 = code, 1 = inside a comment, 2 = inside a string or template literal. */\nfunction classify(source: string): Uint8Array {\n const kind = new Uint8Array(source.length)\n let i = 0\n while (i < source.length) {\n const c = source[i]\n const next = source[i + 1]\n if (c === '/' && next === '/') {\n const end = source.indexOf('\\n', i)\n const stop = end === -1 ? source.length : end\n kind.fill(1, i, stop)\n i = stop\n } else if (c === '/' && next === '*') {\n const end = source.indexOf('*/', i + 2)\n const stop = end === -1 ? source.length : end + 2\n kind.fill(1, i, stop)\n i = stop\n } else if (c === \"'\" || c === '\"' || c === '`') {\n let j = i + 1\n while (j < source.length && source[j] !== c) {\n if (source[j] === '\\\\') j += 1\n else if (c !== '`' && source[j] === '\\n') break\n j += 1\n }\n kind.fill(2, i, Math.min(j + 1, source.length))\n i = j + 1\n } else i += 1\n }\n return kind\n}\n\nconst SPECIFIER =\n /(\\bfrom\\s+|\\bimport\\s*\\(\\s*|\\bimport\\s+)(['\"])(acryl-[A-Za-z0-9-]+(?:\\/[A-Za-z0-9./-]+)?)\\2/gu\n\n/**\n * Rewrite the specifiers that name another library plugin to relative paths. `file` is the path of the file inside the plugins folder (for example\n * `acryl-state/src/service.ts`). Only real import and export statements are touched: a specifier named in a comment or in a string (a documentation example) is text,\n * not a dependency. Any other `acryl-*` specifier in code is an error: a library plugin may depend only on the others and on public packages.\n */\nexport function rewriteSpecifiers(source: string, file: string, entries: EntryTable): string {\n const kind = classify(source)\n return source.replace(\n SPECIFIER,\n (match, lead: string, quote: string, specifier: string, offset: number) => {\n if (kind[offset] !== 0) return match\n const target = entries.get(specifier)\n if (target === undefined)\n throw new Error(`${file}: imports \"${specifier}\", which is not a library plugin`)\n let path = posix.relative(dirname(file), target)\n if (!path.startsWith('.')) path = `./${path}`\n return `${lead}${quote}${path}${quote}`\n },\n )\n}\n","import { cpSync, existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'\nimport { dirname, join, sep } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { hashFolder, recordLock } from './lock'\nimport { type EntryTable, entryTable, rewriteSpecifiers } from './rewrite'\n\n/** One entry of the plugin library: `plugins/<name>/plugin.json` in this repository. */\nexport interface LibraryPlugin {\n readonly name: string\n readonly description: string\n /** Library plugins this one imports; they are copied with it. */\n readonly requires: readonly string[]\n /** npm packages an app needs at run time for this plugin. */\n readonly dependencies: Readonly<Record<string, string>>\n /** npm packages an app needs only to develop or run this plugin's tooling (for example `electron` for the desktop shell). */\n readonly devDependencies?: Readonly<Record<string, string>>\n /** `package.json` scripts the plugin adds; a script the app already has is kept. */\n readonly scripts?: Readonly<Record<string, string>>\n /** Lines the app's `.gitignore` needs for this plugin (added when missing, if the app has a `.gitignore`). */\n readonly gitignore?: readonly string[]\n /** The port's conformance suite, a path inside the plugin: shipped in the package, but copied into an app only by `acrylblends add <plugin> --suite` (it needs vitest). */\n readonly suite?: string\n /** What other library plugins may import from this one: the import name after the plugin's own (`''`, `/middleware`) and the file it stands for. Used to rewrite `acryl-*` imports when a plugin is copied. */\n readonly entries?: Readonly<Record<string, string>>\n /** `package.json` \"imports\" entries the app gets (`#acryl-kv`): a path below the plugins folder. A plugin of your own imports the port by that name, in tests and the type-check as well as when installed live. */\n readonly imports?: Readonly<Record<string, string>>\n /** How to mount it, shown after `acrylblends add`. */\n readonly mount?: string\n /**\n * Paths inside the plugin folder that are not copied into an app (for example a React hook an app without React cannot type-check, or colocated test\n * files). A pattern is an exact path or a glob: `*` matches within one folder name, `**` across folders, `?` one character; `**` followed by a slash also matches no folder.\n */\n readonly omit?: readonly string[]\n}\n\n/** A glob as a regular expression: `*` within a name, `**` across folders, `**` plus a slash may match no folder, `?` one character. */\nfunction globToRegExp(glob: string): RegExp {\n let source = ''\n for (let i = 0; i < glob.length; i += 1) {\n const c = glob[i] as string\n if (c === '*' && glob[i + 1] === '*') {\n if (glob[i + 2] === '/') {\n source += '(?:.*/)?'\n i += 2\n } else {\n source += '.*'\n i += 1\n }\n } else if (c === '*') source += '[^/]*'\n else if (c === '?') source += '[^/]'\n else source += c.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n }\n return new RegExp(`^${source}$`)\n}\n\n/** Whether a path inside a plugin folder (relative, any separator) is named by one of its `omit` patterns. */\nexport function isOmitted(inside: string, patterns: readonly string[] | undefined): boolean {\n if (!patterns || patterns.length === 0) return false\n const path = inside.split(sep).join('/')\n return patterns.some((pattern) =>\n /[*?]/.test(pattern) ? globToRegExp(pattern).test(path) : pattern === path,\n )\n}\n\n/** Files of a library plugin that stay in the repository: its manifest and its tests. */\nconst LIBRARY_ONLY = new Set(['plugin.json', 'test', 'tests'])\n\nexport class LibraryError extends Error {\n override name = 'LibraryError'\n}\n\n/** The library folder (`plugins/` at the repository root): walk up from this module, in source or in the build. */\nexport function libraryRoot(): string {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n const candidate = join(dir, 'plugins')\n if (existsSync(join(candidate, 'instance', 'plugin.json'))) return candidate\n const parent = dirname(dir)\n if (parent === dir)\n throw new LibraryError('acrylblends cannot find its plugin library (plugins/)')\n dir = parent\n }\n}\n\n/** Every plugin in the library, by name. */\nexport function readLibrary(root: string = libraryRoot()): Map<string, LibraryPlugin> {\n const plugins = new Map<string, LibraryPlugin>()\n for (const entry of readdirSync(root, { withFileTypes: true })) {\n const manifest = join(root, entry.name, 'plugin.json')\n if (!entry.isDirectory() || !existsSync(manifest)) continue\n const plugin = JSON.parse(readFileSync(manifest, 'utf8')) as LibraryPlugin\n if (plugin.name !== entry.name)\n throw new LibraryError(`plugins/${entry.name}/plugin.json names \"${plugin.name}\"`)\n plugins.set(plugin.name, {\n ...plugin,\n requires: plugin.requires ?? [],\n dependencies: plugin.dependencies ?? {},\n })\n }\n return plugins\n}\n\n/** The plugins to copy for `names`: each one after everything it requires, no duplicates. */\nexport function closure(\n names: readonly string[],\n library: Map<string, LibraryPlugin>,\n): LibraryPlugin[] {\n const ordered: LibraryPlugin[] = []\n const visiting = new Set<string>()\n const visit = (name: string, trail: string[]) => {\n if (ordered.some((plugin) => plugin.name === name)) return\n const plugin = library.get(name)\n if (!plugin)\n throw new LibraryError(\n `no plugin \"${name}\" in the library${trail.length ? ` (required by ${trail.at(-1)})` : ''}`,\n )\n if (visiting.has(name))\n throw new LibraryError(\n `plugins require each other in a cycle: ${[...trail, name].join(' -> ')}`,\n )\n visiting.add(name)\n for (const required of plugin.requires) visit(required, [...trail, name])\n visiting.delete(name)\n ordered.push(plugin)\n }\n for (const name of names) visit(name, [])\n return ordered\n}\n\n/** The one folder every plugin of an app lives in, library copies and the ones an agent writes. */\nexport const PLUGINS_DIR = 'plugins'\n/** Where apps made before 0.7.8 kept library copies; still understood for one release. */\nexport const LEGACY_PLUGINS_DIR = join('src', 'plugins')\n/** The list of library copies in the plugins folder; the extensions plugin installs every other folder there. */\nexport const LIBRARY_LIST = 'library.json'\n\n/** The plugins folder of an app: `plugins/`, or `src/plugins/` for an app that still has the old layout (and no `plugins/`). */\nexport function pluginsFolder(appDir: string): { dir: string; legacy: boolean } {\n const legacy =\n existsSync(join(appDir, LEGACY_PLUGINS_DIR)) && !existsSync(join(appDir, PLUGINS_DIR))\n return { dir: join(appDir, legacy ? LEGACY_PLUGINS_DIR : PLUGINS_DIR), legacy }\n}\n\n/** The warning for an app with the old layout. */\nexport const LEGACY_WARNING =\n 'warning: this app keeps its plugins in src/plugins/ (and extensions/); plugins now live in one folder, plugins/. Move them with \"git mv src/plugins plugins\", fix the paths in tsconfig.json, package.json and src/, and see docs/framework/agents/index.md. The old layout is read for this release only.'\n\n/** List `name` among the library copies of a plugins folder (`library.json`). */\nexport function recordLibraryCopy(folder: string, name: string): void {\n const file = join(folder, LIBRARY_LIST)\n const names: string[] = existsSync(file)\n ? (JSON.parse(readFileSync(file, 'utf8')) as { plugins: string[] }).plugins\n : []\n if (!names.includes(name)) names.push(name)\n writeFileSync(file, `${JSON.stringify({ plugins: names.sort() }, null, 2)}\\n`)\n}\n\n/** Copy one library plugin's source into `<app>/plugins/<name>/`. Throws when that folder already exists. */\nexport function copyPlugin(\n plugin: LibraryPlugin,\n appDir: string,\n root: string = libraryRoot(),\n): string {\n const folder = pluginsFolder(appDir)\n const target = join(folder.dir, plugin.name)\n if (existsSync(target))\n throw new LibraryError(\n `${relativeName(appDir, target)} already exists; remove it first to copy a fresh one`,\n )\n const source = join(root, plugin.name)\n // A framework package (it has a package.json in the repository) is copied as its source: `src/` and the licence; the package shipped by npm already holds only that. Its\n // `plugin.json` lists `entries`, and the imports of such a plugin are rewritten to relative paths, in the repository and in the installed package alike.\n const isPackage = existsSync(join(source, 'package.json'))\n const entries = plugin.entries === undefined ? undefined : entryTable(readLibrary(root))\n cpSync(source, target, {\n recursive: true,\n filter: (path) => {\n const inside = path\n .slice(source.length + 1)\n .split(sep)\n .join('/')\n if (\n isPackage &&\n inside !== '' &&\n inside !== 'LICENSE' &&\n inside !== 'src' &&\n !inside.startsWith('src/')\n )\n return false\n return (\n !(dirname(path) === source && LIBRARY_ONLY.has(inside)) &&\n !isOmitted(inside, plugin.omit) &&\n inside !== plugin.suite\n )\n },\n })\n if (entries) rewriteTree(join(target, 'src'), plugin.name, 'src', entries)\n if (!folder.legacy) {\n recordLibraryCopy(folder.dir, plugin.name)\n // The hashes of the files as copied: `acrylblends upgrade` tells an untouched file from an edited one by them.\n recordLock(folder.dir, plugin.name, hashFolder(target))\n }\n return target\n}\n\n/** Rewrite the `acryl-*` imports of every TypeScript file below `dir` (the plugin's `src/`) to relative paths. */\nfunction rewriteTree(dir: string, plugin: string, inside: string, entries: EntryTable): void {\n for (const entry of readdirSync(dir)) {\n const path = join(dir, entry)\n if (statSync(path).isDirectory()) rewriteTree(path, plugin, `${inside}/${entry}`, entries)\n else if (/\\.(?:ts|tsx|mts)$/u.test(entry))\n writeFileSync(\n path,\n rewriteSpecifiers(readFileSync(path, 'utf8'), `${plugin}/${inside}/${entry}`, entries),\n )\n }\n}\n\n/** Copy one file of a library plugin (a conformance suite) with its `acryl-*` imports rewritten, as `copyPlugin` does for the rest. */\nexport function copyRewritten(\n from: string,\n to: string,\n plugin: string,\n inside: string,\n root: string = libraryRoot(),\n): void {\n writeFileSync(\n to,\n rewriteSpecifiers(\n readFileSync(from, 'utf8'),\n `${plugin}/${inside}`,\n entryTable(readLibrary(root)),\n ),\n )\n}\n\nconst relativeName = (appDir: string, path: string) =>\n path\n .slice(appDir.length + 1)\n .split(sep)\n .join('/')\n","import {\n cpSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from 'node:fs'\nimport { join } from 'node:path'\nimport { VERSION } from './version'\n\n/** Thrown when the target directory exists and is not empty. Nothing has been written. */\nexport class TargetNotEmptyError extends Error {\n constructor(readonly target: string) {\n super(\n `refusing to write into \"${target}\": the directory is not empty. Choose an empty or new directory.`,\n )\n this.name = 'TargetNotEmptyError'\n }\n}\n\n/** A project name npm accepts: lower case letters, digits and dashes, starting with a letter. */\nexport function isValidName(name: string): boolean {\n return /^[a-z][a-z0-9-]*$/.test(name) && name.length <= 214\n}\n\n/** A valid default project name derived from a directory path. */\nexport function nameFrom(directory: string): string {\n const base = directory.split(/[\\\\/]/).filter(Boolean).pop() ?? ''\n const cleaned = base\n .toLowerCase()\n .replace(/[^a-z0-9-]+/g, '-')\n .replace(/^[^a-z]+/, '')\n .replace(/-+$/, '')\n return cleaned || 'my-app'\n}\n\n/** Refuse a target that exists and is not an empty directory. A missing target is fine: it is created. */\nexport function assertTargetFree(target: string): void {\n if (!existsSync(target)) return\n if (!statSync(target).isDirectory() || readdirSync(target).length > 0)\n throw new TargetNotEmptyError(target)\n}\n\n/**\n * Copy a template into `target`, replacing `__APP_NAME__` with `name` and `__ACRYLBLENDS_RANGE__` with the range of this release. Checks the target before writing anything.\n *\n * @returns the copied files, relative to `target`\n */\nexport function copyTemplate(source: string, target: string, name: string): string[] {\n assertTargetFree(target)\n mkdirSync(target, { recursive: true })\n const written: string[] = []\n const walk = (from: string, to: string, prefix: string) => {\n for (const entry of readdirSync(from, { withFileTypes: true })) {\n if (\n entry.name === 'node_modules' ||\n (prefix === '' &&\n (entry.name === TEMPLATE_MANIFEST ||\n entry.name === 'upstream.json' ||\n entry.name === 'AGENTS.md'))\n )\n continue\n const sourcePath = join(from, entry.name)\n // npm and git treat a file named .gitignore specially, so templates keep it as `gitignore` (and `dockerignore`).\n const targetName =\n prefix === '' && (entry.name === 'gitignore' || entry.name === 'dockerignore')\n ? `.${entry.name}`\n : entry.name\n const targetPath = join(to, targetName)\n if (entry.isDirectory()) {\n mkdirSync(targetPath, { recursive: true })\n walk(sourcePath, targetPath, `${prefix}${entry.name}/`)\n continue\n }\n const text = readFileSync(sourcePath, 'utf8')\n if (text.includes('__APP_NAME__') || text.includes('__ACRYLBLENDS_RANGE__'))\n writeFileSync(\n targetPath,\n text.replaceAll('__APP_NAME__', name).replaceAll('__ACRYLBLENDS_RANGE__', `^${VERSION}`),\n )\n else cpSync(sourcePath, targetPath)\n written.push(`${prefix}${targetName}`)\n }\n }\n walk(source, target, '')\n return written\n}\n\n/** A template's own manifest, `template.json`: the library plugins it is built from. Never copied (nor is `upstream.json`, the record of what was synced from ACRYL, nor the template's `AGENTS.md`, which `writeAgentFiles` joins to the shared core). */\nexport const TEMPLATE_MANIFEST = 'template.json'\n\n/** The address a template's desktop window opens on, when it is not the root (`template.json`: `desktopPath`). */\nexport function readTemplateDesktopPath(templateDir: string): string | undefined {\n const file = join(templateDir, TEMPLATE_MANIFEST)\n if (!existsSync(file)) return undefined\n return (JSON.parse(readFileSync(file, 'utf8')) as { desktopPath?: string }).desktopPath\n}\n\n/** Record where the desktop window opens in package.json (`acrylblends.desktopPath`), read by `plugins/desktop/main.ts`. */\nexport function writeDesktopPath(appDir: string, path: string): void {\n const file = join(appDir, 'package.json')\n const manifest = JSON.parse(readFileSync(file, 'utf8')) as {\n acrylblends?: Record<string, unknown>\n }\n manifest.acrylblends = { ...manifest.acrylblends, desktopPath: path }\n writeFileSync(file, `${JSON.stringify(manifest, null, 2)}\\n`)\n}\n\nexport function readTemplatePlugins(templateDir: string): string[] {\n const file = join(templateDir, TEMPLATE_MANIFEST)\n if (!existsSync(file)) return []\n const { plugins } = JSON.parse(readFileSync(file, 'utf8')) as { plugins?: string[] }\n return plugins ?? []\n}\n\n/** Add run-time dependencies to an app's package.json, keeping what is there and sorting the keys. Returns the names added. */\nexport function mergeDependencies(\n appDir: string,\n dependencies: Readonly<Record<string, string>>,\n): string[] {\n const file = join(appDir, 'package.json')\n const manifest = JSON.parse(readFileSync(file, 'utf8')) as {\n dependencies?: Record<string, string>\n }\n const current = manifest.dependencies ?? {}\n const added = Object.keys(dependencies).filter((name) => !(name in current))\n const merged = { ...dependencies, ...current }\n manifest.dependencies = Object.fromEntries(\n Object.entries(merged).sort(([a], [b]) => a.localeCompare(b)),\n )\n writeFileSync(file, `${JSON.stringify(manifest, null, 2)}\\n`)\n return added\n}\n\n/** Add `package.json` \"imports\" entries (`#acryl-kv`: `./plugins/acryl-kv/src/index.ts`); an entry the app already has is kept. Returns the names added. */\nexport function mergeImports(\n appDir: string,\n imports: Readonly<Record<string, string>>,\n pluginsDir: string,\n): string[] {\n const file = join(appDir, 'package.json')\n const manifest = JSON.parse(readFileSync(file, 'utf8')) as { imports?: Record<string, string> }\n const current = manifest.imports ?? {}\n const added = Object.keys(imports).filter((name) => !(name in current))\n manifest.imports = {\n ...Object.fromEntries(\n Object.entries(imports).map(([name, path]) => [name, `./${pluginsDir}/${path}`]),\n ),\n ...current,\n }\n writeFileSync(file, `${JSON.stringify(manifest, null, 2)}\\n`)\n return added\n}\n\n/** Declare a file as an opener in package.json (`\"acryl\": { \"opener\": [...] }`): the one place that may import a database provider. */\nexport function mergeOpener(appDir: string, opener: string): void {\n const file = join(appDir, 'package.json')\n const manifest = JSON.parse(readFileSync(file, 'utf8')) as {\n acryl?: { opener?: string | string[] }\n }\n const current = manifest.acryl?.opener\n const list = typeof current === 'string' ? [current] : (current ?? [])\n if (list.includes(opener)) return\n manifest.acryl = { ...manifest.acryl, opener: [...list, opener] }\n writeFileSync(file, `${JSON.stringify(manifest, null, 2)}\\n`)\n}\n\n/**\n * Add a plugin's development dependencies and scripts to an app's package.json: nothing the app already has is replaced. Returns the names of the development dependencies\n * and scripts added.\n */\nexport function mergeTooling(\n appDir: string,\n tooling: {\n devDependencies?: Readonly<Record<string, string>> | undefined\n scripts?: Readonly<Record<string, string>> | undefined\n },\n): { devDependencies: string[]; scripts: string[] } {\n const file = join(appDir, 'package.json')\n const manifest = JSON.parse(readFileSync(file, 'utf8')) as {\n devDependencies?: Record<string, string>\n scripts?: Record<string, string>\n }\n const dev = manifest.devDependencies ?? {}\n const scripts = manifest.scripts ?? {}\n const addedDev = Object.keys(tooling.devDependencies ?? {}).filter((name) => !(name in dev))\n const addedScripts = Object.keys(tooling.scripts ?? {}).filter((name) => !(name in scripts))\n manifest.devDependencies = Object.fromEntries(\n Object.entries({ ...tooling.devDependencies, ...dev }).sort(([a], [b]) => a.localeCompare(b)),\n )\n manifest.scripts = { ...tooling.scripts, ...scripts }\n writeFileSync(file, `${JSON.stringify(manifest, null, 2)}\\n`)\n return { devDependencies: addedDev, scripts: addedScripts }\n}\n\n/** What an app runs before `dev`, `start`, `test` and `check`: refuses a Node too old to run it, in plain words, before anything that would fail confusingly (a plain CommonJS file, so any Node can read it). */\nconst CHECK_NODE = `// Refuses a Node that is too old to run this app, before the command that would fail on it. Plain CommonJS so that any Node can read it.\nconst [major, minor] = process.versions.node.split('.').map(Number)\nif (major < 22 || (major === 22 && minor < 19)) {\n console.error(\n \\`Node 22.19+ needed, you have \\${process.versions.node}: install it from https://nodejs.org or with nvm (nvm install 22), then run this again.\\`,\n )\n process.exit(1)\n}\n`\n\n/** Write \\`scripts/check-node.cjs\\` and run it before the app's \\`dev\\`, \\`start\\`, \\`test\\` and \\`check\\` scripts (npm and pnpm run \\`pre<script>\\` first). Existing \\`pre*\\` scripts are kept. */\nexport function addNodePreflight(appDir: string): void {\n mkdirSync(join(appDir, 'scripts'), { recursive: true })\n writeFileSync(join(appDir, 'scripts', 'check-node.cjs'), CHECK_NODE)\n const file = join(appDir, 'package.json')\n const manifest = JSON.parse(readFileSync(file, 'utf8')) as { scripts?: Record<string, string> }\n const scripts = manifest.scripts ?? {}\n for (const name of ['dev', 'start', 'test', 'check'])\n if (name in scripts && !(`pre${name}` in scripts))\n scripts[`pre${name}`] = 'node scripts/check-node.cjs'\n manifest.scripts = scripts\n writeFileSync(file, `${JSON.stringify(manifest, null, 2)}\\n`)\n}\n\n/** Add the lines a plugin needs to the app's \\`.gitignore\\` when it has one and they are missing. Returns the lines added. */\nexport function appendGitignore(appDir: string, lines: readonly string[] | undefined): string[] {\n const file = join(appDir, '.gitignore')\n if (!lines || lines.length === 0 || !existsSync(file)) return []\n const current = readFileSync(file, 'utf8')\n const present = new Set(current.split('\\n').map((line) => line.trim()))\n const missing = lines.filter((line) => !present.has(line))\n if (missing.length > 0)\n writeFileSync(\n file,\n `${current}${current.endsWith('\\n') || current === '' ? '' : '\\n'}${missing.join('\\n')}\\n`,\n )\n return missing\n}\n\n/** The generated app's guide for a coding agent: the shared core, then the template's own part. `CLAUDE.md` is only an import of it. */\nexport function writeAgentFiles(\n sharedDir: string,\n templateDir: string,\n target: string,\n name: string,\n): string[] {\n const core = readFileSync(join(sharedDir, 'AGENTS.core.md'), 'utf8')\n const own = existsSync(join(templateDir, 'AGENTS.md'))\n ? readFileSync(join(templateDir, 'AGENTS.md'), 'utf8')\n : ''\n const defaults = readFileSync(join(sharedDir, 'DEFAULTS.md'), 'utf8')\n const text = `${core}${defaults}${own}`.replaceAll('__APP_NAME__', name)\n // AGENTS.md and CLAUDE.md are the same text; the one skill is written where each kind of agent looks for skills.\n writeFileSync(join(target, 'AGENTS.md'), text)\n writeFileSync(join(target, 'CLAUDE.md'), text)\n const skill = readFileSync(join(sharedDir, 'SKILL.md'), 'utf8').replaceAll('__APP_NAME__', name)\n const written = ['AGENTS.md', 'CLAUDE.md']\n for (const folder of ['.claude/skills/app-guide', '.agents/skills/app-guide']) {\n mkdirSync(join(target, folder), { recursive: true })\n writeFileSync(join(target, folder, 'SKILL.md'), skill)\n written.push(`${folder}/SKILL.md`)\n }\n return written\n}\n\n/**\n * Copy the framework's docs (a generated copy of ACRYL's `docs/framework`, already checked against its digest) into `<app>/docs/framework/`,\n * so a coding agent working in the app reads the API from the folder it is in. The generated-copy notes and the digest record stay behind.\n *\n * @returns the copied files, relative to `target`\n */\nexport function copyFrameworkDocs(source: string, target: string): string[] {\n const written: string[] = []\n const walk = (from: string, to: string, prefix: string) => {\n for (const entry of readdirSync(from, { withFileTypes: true })) {\n if (entry.name === 'upstream.json' || entry.name === 'UPSTREAM.md') continue\n const sourcePath = join(from, entry.name)\n const targetPath = join(to, entry.name)\n if (entry.isDirectory()) {\n mkdirSync(targetPath, { recursive: true })\n walk(sourcePath, targetPath, `${prefix}${entry.name}/`)\n continue\n }\n cpSync(sourcePath, targetPath)\n written.push(`docs/framework/${prefix}${entry.name}`)\n }\n }\n mkdirSync(join(target, 'docs', 'framework'), { recursive: true })\n walk(source, join(target, 'docs', 'framework'), '')\n return written\n}\n","import { resolve } from 'node:path'\nimport { parseArgs } from 'node:util'\nimport type { Io } from './io'\nimport { closure, copyPlugin, readLibrary } from './library'\nimport {\n addNodePreflight,\n copyFrameworkDocs,\n copyTemplate,\n isValidName,\n mergeDependencies,\n mergeImports,\n mergeTooling,\n nameFrom,\n readTemplateDesktopPath,\n readTemplatePlugins,\n TargetNotEmptyError,\n writeAgentFiles,\n writeDesktopPath,\n} from './project'\nimport {\n frameworkDocsRoot,\n resolveTemplate,\n sharedDir,\n TEMPLATE_SUMMARY,\n TEMPLATES,\n type Template,\n templateDir,\n} from './templates'\n\n/** A command line mistake. The CLI prints it with the help text and exits 2. */\nexport class UsageError extends Error {\n override name = 'UsageError'\n}\n\n/** What `init` was asked for. Anything left undefined is asked for on a terminal, or defaulted. */\nexport interface InitOptions {\n directory: string | undefined\n name: string | undefined\n template: Template | undefined\n install: boolean | undefined\n /** Also add the desktop shell (`add desktop`): an Electron window on the app's own server. */\n desktop: boolean\n /** Print no \"Next:\" block: `create-acrylblends` runs `init` and prints its own, for the package manager it knows. */\n quietNext: boolean\n yes: boolean\n}\n\n/** Parse `init [dir] [--template t] [--agent|--no-agent] [--name n] [--install] [-y]`. `--agent` means `--template agent`, `--no-agent` means `--template blank`. */\nexport function parseInitOptions(argv: readonly string[]): InitOptions {\n let parsed: ReturnType<typeof parse>\n try {\n parsed = parse(argv)\n } catch (error) {\n throw new UsageError((error as Error).message)\n }\n const { values, positionals } = parsed\n if (positionals.length > 1) throw new UsageError('init takes at most one directory')\n if (values.agent && values['no-agent'])\n throw new UsageError('use --agent or --no-agent, not both')\n const named = values.template === undefined ? undefined : resolveTemplate(values.template)\n if (values.template !== undefined && named === undefined)\n throw new UsageError(`unknown template \"${values.template}\" (${TEMPLATES.join(', ')})`)\n const alias: Template | undefined = values.agent\n ? 'agent'\n : values['no-agent']\n ? 'blank'\n : undefined\n if (named !== undefined && alias !== undefined && named !== alias)\n throw new UsageError(\n `--template ${values.template} contradicts --${alias === 'agent' ? 'agent' : 'no-agent'}`,\n )\n return {\n directory: positionals[0],\n name: values.name,\n template: named ?? alias,\n install: values.install,\n desktop: values.desktop === true,\n quietNext: values['no-next'] === true,\n yes: values.yes === true,\n }\n}\n\nconst parse = (argv: readonly string[]) =>\n parseArgs({\n args: [...argv],\n allowPositionals: true,\n strict: true,\n options: {\n name: { type: 'string' },\n template: { type: 'string' },\n agent: { type: 'boolean' },\n 'no-agent': { type: 'boolean' },\n install: { type: 'boolean' },\n desktop: { type: 'boolean' },\n 'no-next': { type: 'boolean' },\n yes: { type: 'boolean', short: 'y' },\n },\n })\n\nconst yes = (answer: string) => ['y', 'yes'].includes(answer.trim().toLowerCase())\n\nasync function askTemplate(ask: (question: string) => Promise<string>): Promise<Template> {\n const answer = (\n await ask(\n `Templates:\\n${TEMPLATES.map((name) => ` ${name.padEnd(7)} ${TEMPLATE_SUMMARY[name]}`).join('\\n')}\\nTemplate [blank]: `,\n )\n )\n .trim()\n .toLowerCase()\n if (answer === '') return 'blank'\n const chosen = resolveTemplate(answer)\n if (chosen !== undefined) return chosen\n throw new UsageError(`unknown template \"${answer}\" (${TEMPLATES.join(', ')})`)\n}\n\n/** Scaffold a Cordis app. Returns the exit code: 0 done, 1 refused or failed. Never overwrites anything. */\nexport async function init(options: InitOptions, io: Io): Promise<number> {\n const relative = options.directory ?? '.'\n const directory = resolve(io.cwd, relative)\n const ask = options.yes ? undefined : io.ask\n\n let name = options.name ?? nameFrom(directory)\n if (options.name === undefined && ask)\n name = (await ask(`Project name (${name}): `)).trim() || name\n if (!isValidName(name)) {\n throw new UsageError(\n `\"${name}\" is not a valid project name (lower case letters, digits and dashes, starting with a letter)`,\n )\n }\n const template = options.template ?? (ask ? await askTemplate(ask) : 'blank')\n const install =\n options.install ?? (ask ? yes(await ask('Install dependencies with npm now? (y/N): ')) : false)\n\n let files: string[]\n try {\n files = copyTemplate(templateDir(template), directory, name)\n files.push(...writeAgentFiles(sharedDir(), templateDir(template), directory, name))\n files.push(...copyFrameworkDocs(frameworkDocsRoot(), directory))\n } catch (error) {\n if (!(error instanceof TargetNotEmptyError)) throw error\n io.stderr.write(`error: ${error.message}\\n`)\n return 1\n }\n const own = closure(readTemplatePlugins(templateDir(template)), readLibrary())\n const plugins = options.desktop\n ? closure([...own.map((plugin) => plugin.name), 'desktop'], readLibrary())\n : own\n // What only the desktop shell brought (and needs), named apart so the list does not read as if the web app had asked for it.\n const forDesktop = plugins.filter((plugin) => !own.some((owned) => owned.name === plugin.name))\n for (const plugin of plugins) {\n copyPlugin(plugin, directory)\n if (plugin.imports) mergeImports(directory, plugin.imports, 'plugins')\n mergeDependencies(directory, plugin.dependencies)\n mergeTooling(directory, plugin)\n }\n addNodePreflight(directory)\n const desktopPath = options.desktop ? readTemplateDesktopPath(templateDir(template)) : undefined\n if (desktopPath !== undefined) writeDesktopPath(directory, desktopPath)\n io.stdout.write(\n `created ${name} (${template}) in ${directory}: ${files.length} files, plugins ${own.map((plugin) => plugin.name).join(', ')}${forDesktop.length > 0 ? `; the desktop shell adds ${forDesktop.map((plugin) => plugin.name).join(', ')}, which it needs` : ''}\\n`,\n )\n\n if (install && (await io.install(directory)) !== 0) {\n io.stderr.write('error: npm install failed; run it yourself in the new directory\\n')\n return 1\n }\n const steps = [\n relative === '.' ? '' : ` cd ${relative}\\n`,\n install ? '' : ' npm install\\n',\n ' npm run dev\\n npm test\\n',\n ]\n if (!options.quietNext) io.stdout.write(`\\nNext:\\n${steps.join('')}`)\n return 0\n}\n","import { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\n\n/**\n * Plugins that `acrylblends add` mounts itself: a row in `blend.yaml` (after the row it needs, before the `routes` row) and an entry in the `registry` of `src/app.ts`.\n * `needs` are the rows the plugin cannot run without; an app that lacks them is refused before anything is copied.\n */\nexport interface Mounted {\n readonly name: string\n /** The identifier of the registry import, and the plugin names (the `name:` of a row) it needs. */\n readonly local: string\n readonly needs: readonly string[]\n /** The row this one goes after (it goes before `routes` otherwise). */\n readonly after?: string\n}\n\nexport const MOUNTED: readonly Mounted[] = [\n { name: 'agent-panel', local: 'panel', needs: ['agent', 'extensions'] },\n { name: 'driver-pty', local: 'driverPty', needs: ['agent-panel'], after: 'agent-panel' },\n { name: 'driver-acp', local: 'driverAcp', needs: ['agent-panel'], after: 'agent-panel' },\n]\n\nconst ROW = /^( *)- id: ?(\\S+)\\n\\1 {2}name: ?(\\S+)\\n/gmu\n\n/** The `name:` of every row of the app's `blend.yaml`, or `undefined` when it has none. */\nexport function rowNames(appDir: string): string[] | undefined {\n const file = join(appDir, 'blend.yaml')\n if (!existsSync(file)) return undefined\n return [...readFileSync(file, 'utf8').matchAll(ROW)].map((match) => match[3] as string)\n}\n\n/** What a plugin to be mounted is missing: the rows it needs that neither the app nor this same command brings. */\nexport function missingRows(\n appDir: string,\n plugin: Mounted,\n alsoAdded: readonly string[],\n): string[] {\n const have = rowNames(appDir) ?? []\n return plugin.needs.filter((need) => !have.includes(need) && !alsoAdded.includes(need))\n}\n\nexport interface MountResult {\n readonly done: boolean\n /** What was edited, or why it was not (the person finishes by hand). */\n readonly note: string\n}\n\n/** Add the row to `blend.yaml` and the entry to `src/app.ts`; each only when it is not there yet and its place is where the template puts it. */\nexport function mount(appDir: string, plugin: Mounted): MountResult {\n const done: string[] = []\n const failed: string[] = []\n const manifestFile = join(appDir, 'blend.yaml')\n if (existsSync(manifestFile)) {\n let text = readFileSync(manifestFile, 'utf8')\n if ([...text.matchAll(ROW)].some((match) => match[3] === plugin.name))\n done.push('blend.yaml (already has the row)')\n else {\n const anchor = plugin.after\n ? new RegExp(\n `^( *)- id: ?\\\\S+\\\\n\\\\1 {2}name: ?${plugin.after}\\\\n(?:\\\\1 {2}config:\\\\n(?:\\\\1 {4}.*\\\\n|\\\\1 {2}\\\\s*\\\\n)*)?`,\n 'mu',\n )\n : /^( *)- id: ?routes\\n/mu\n const found = anchor.exec(text)\n if (found) {\n const indent = found[1] as string\n const row = `${indent}- id: ${plugin.name}\\n${indent} name: ${plugin.name}\\n`\n const at = plugin.after ? found.index + found[0].length : found.index\n text = text.slice(0, at) + row + text.slice(at)\n writeFileSync(manifestFile, text)\n done.push(`blend.yaml (row ${plugin.name})`)\n } else\n failed.push(\n `blend.yaml: add a row \\`- id: ${plugin.name}\\` / \\`name: ${plugin.name}\\` ${plugin.after ? `after the ${plugin.after} row` : 'before the `routes` row'}`,\n )\n }\n }\n const appFile = join(appDir, 'src', 'app.ts')\n if (existsSync(appFile)) {\n let text = readFileSync(appFile, 'utf8')\n const entry = `'${plugin.name}': ${plugin.local}`\n if (text.includes(entry)) done.push('src/app.ts (already registered)')\n else {\n const imports = [...text.matchAll(/^import .* from '\\.\\.\\/plugins\\/[^']+'\\n/gmu)]\n const last = imports.at(-1)\n const table = /^export const registry = \\{\\n/mu.exec(text)\n if (last && table) {\n const line = `import * as ${plugin.local} from '../plugins/${plugin.name}/index.ts'\\n`\n text =\n text.slice(0, table.index + table[0].length) +\n ` ${entry},\\n` +\n text.slice(table.index + table[0].length)\n const lastEnd = last.index + last[0].length\n text = text.slice(0, lastEnd) + line + text.slice(lastEnd)\n writeFileSync(appFile, text)\n done.push(`src/app.ts (registered as ${plugin.local})`)\n } else\n failed.push(\n `src/app.ts: import it as \\`${plugin.local}\\` from '../plugins/${plugin.name}/index.ts' and add \\`${entry}\\` to the registry`,\n )\n }\n } else failed.push(`src/app.ts: not found; register ${entry(plugin)} in the app's registry`)\n return {\n done: failed.length === 0,\n note: [\n done.length > 0 ? `mounted in ${done.join(' and ')}` : '',\n ...failed.map((line) => `could not edit ${line}`),\n ]\n .filter(Boolean)\n .join('\\n'),\n }\n}\n\nconst entry = (plugin: Mounted) => `'${plugin.name}': ${plugin.local}`\n","import { cpSync, existsSync, mkdirSync, readFileSync, statSync } from 'node:fs'\nimport { basename, dirname, join, relative, resolve, sep } from 'node:path'\nimport { parseArgs } from 'node:util'\nimport { UsageError } from './init'\nimport type { Io } from './io'\nimport {\n closure,\n copyPlugin,\n copyRewritten,\n LEGACY_WARNING,\n type LibraryPlugin,\n libraryRoot,\n PLUGINS_DIR,\n pluginsFolder,\n readLibrary,\n} from './library'\nimport { MOUNTED, type Mounted, missingRows, mount, rowNames } from './mount'\nimport {\n appendGitignore,\n mergeDependencies,\n mergeImports,\n mergeOpener,\n mergeTooling,\n} from './project'\n\nexport interface AddOptions {\n readonly names: readonly string[]\n readonly directory: string | undefined\n /** Also copy the port's conformance suite (`src/conformance.ts`) and the `vitest` it runs on: what a provider of your own must pass. */\n readonly suite: boolean\n}\n\n/** Parse `add <plugin...> [--dir <app>] [--suite]`. */\nexport function parseAddOptions(argv: readonly string[]): AddOptions {\n let parsed: ReturnType<typeof parse>\n try {\n parsed = parse(argv)\n } catch (error) {\n throw new UsageError((error as Error).message)\n }\n if (parsed.positionals.length === 0)\n throw new UsageError('add needs at least one plugin name (see \"acrylblends plugins\")')\n return {\n names: parsed.positionals,\n directory: parsed.values.dir,\n suite: parsed.values.suite === true,\n }\n}\n\nconst parse = (argv: readonly string[]) =>\n parseArgs({\n args: [...argv],\n allowPositionals: true,\n strict: true,\n options: { dir: { type: 'string' }, suite: { type: 'boolean' } },\n })\n\nconst present = (appDir: string, name: string) => existsSync(join(pluginsFolder(appDir).dir, name))\n\n/**\n * Copy library plugins into an existing app, with the plugins they require, and add their npm packages to its package.json.\n * Refuses a plugin the app already has. Returns the exit code.\n */\nexport async function add(options: AddOptions, io: Io): Promise<number> {\n const appDir = resolve(io.cwd, options.directory ?? '.')\n if (!existsSync(join(appDir, 'package.json')) || !existsSync(join(appDir, 'src'))) {\n io.stderr.write(\n `error: ${appDir} is not an app (no package.json and src/); run \"acrylblends init\" first\\n`,\n )\n return 1\n }\n if (pluginsFolder(appDir).legacy) io.stderr.write(`${LEGACY_WARNING}\\n`)\n // A path is an external plugin folder; anything else is a library plugin name.\n const external = options.names.filter((name) => /[\\\\/]/.test(name) || name.startsWith('.'))\n for (const folder of external) {\n const code = addExternal(resolve(io.cwd, folder), appDir, io)\n if (code !== 0) return code\n }\n // The desktop shell has two forms: the Blend app (it needs the `instance` plugin) and a plain Acryl app (`export default app`); `desktop` means the one that fits.\n const plain = !existsSync(join(pluginsFolder(appDir).dir, 'instance'))\n if (plain && options.names.includes('db')) {\n io.stderr.write(\n 'error: \"db\" is the Cordis plugin for a Blend app. A plain Acryl app opens its database with openDb from \"acrylblends/db/sqlite\" (see docs/framework/guides/data.md)\\n',\n )\n return 1\n }\n if (plain && options.names.includes('kv')) {\n io.stderr.write(\n 'error: \"kv\" is the Cordis plugin for a Blend app. A plain Acryl app opens its store with openKv from \"acrylblends/kv/json\" (see docs/framework/guides/data.md#a-tiny-app-kv)\\n',\n )\n return 1\n }\n const names = options.names\n .filter((name) => !external.includes(name))\n // `db` is the SQLite provider of the db port (it brings the port); a plain app opens its database with `acrylblends/db/sqlite` instead.\n .map((name) => (name === 'db' ? 'acryl-db-sqlite' : name))\n // `kv` is the JSON-file provider of the kv port (it brings the port); `acryl-kv-db` is the one over db.\n .map((name) => (name === 'kv' ? 'acryl-kv-json' : name))\n .map((name) => (name === 'desktop' && plain ? 'desktop-web' : name))\n if (names.length === 0) return 0\n const already = options.suite ? [] : names.filter((name) => present(appDir, name))\n if (already.length > 0) {\n io.stderr.write(\n `error: the app already has ${already\n .map(\n (name) =>\n `${relative(appDir, join(pluginsFolder(appDir).dir, name))\n .split(sep)\n .join('/')}`,\n )\n .join(', ')}\\n`,\n )\n return 1\n }\n // The agent panel and the PTY driver cannot run without the rows of the agent template: refuse before anything is copied, and say exactly what is missing.\n const mounting = MOUNTED.filter((plugin) => names.includes(plugin.name))\n for (const plugin of mounting) {\n const missing = missingRows(appDir, plugin, names)\n if (missing.length > 0) {\n io.stderr.write(\n `error: ${plugin.name} needs the ${missing.map((row) => `\\`${row}\\``).join(' and ')} ${missing.length === 1 ? 'row' : 'rows'} in blend.yaml, and this app has ${describeRows(appDir)}. ` +\n `${plugin.name === 'driver-pty' ? 'Add agent-panel first (acrylblends add agent-panel driver-pty), which needs the agent template. ' : ''}` +\n `The rows come with the agent template: start from it (npm create acrylblends@latest my-app agent) and add ${plugin.name} there. Nothing was changed.\\n`,\n )\n return 1\n }\n }\n const toCopy: LibraryPlugin[] = closure(names, readLibrary()).filter(\n (plugin) => !present(appDir, plugin.name),\n )\n const addedDependencies: string[] = []\n for (const plugin of toCopy) {\n copyPlugin(plugin, appDir)\n if (plugin.imports)\n mergeImports(\n appDir,\n plugin.imports,\n relative(appDir, pluginsFolder(appDir).dir).split(sep).join('/'),\n )\n addedDependencies.push(...mergeDependencies(appDir, plugin.dependencies))\n const tooling = mergeTooling(appDir, plugin)\n appendGitignore(appDir, plugin.gitignore)\n // The provider is mounted from src/app.ts, which is therefore the one file that may import it (`acrylblends check-deps`).\n if (plugin.name === 'acryl-db-sqlite') mergeOpener(appDir, 'src/app.ts')\n addedDependencies.push(...tooling.devDependencies)\n if (tooling.scripts.length > 0)\n io.stdout.write(\n `new scripts: ${tooling.scripts.map((name) => `npm run ${name}`).join(', ')}\\n`,\n )\n }\n if (options.suite) {\n const refused = copySuites(names, appDir, addedDependencies, io)\n if (refused !== 0) return refused\n }\n io.stdout.write(`added ${toCopy.map((plugin) => plugin.name).join(', ')} to ${appDir}\\n`)\n if (addedDependencies.length > 0)\n io.stdout.write(`new dependencies: ${addedDependencies.join(', ')} (run npm install)\\n`)\n for (const plugin of toCopy.filter((plugin) => names.includes(plugin.name))) {\n const mounted = MOUNTED.find((candidate) => candidate.name === plugin.name)\n const result = mounted ? mount(appDir, mounted) : undefined\n io.stdout.write(\n `\\n${plugin.name}: ${result?.done ? `${result.note}${extraNote(mounted)}` : `${result ? `${result.note}\\n` : ''}${plugin.mount ?? `import it from '../plugins/${plugin.name}/index.ts' and mount it in src/app.ts`}`}\\n`,\n )\n }\n return 0\n}\n\n/** What an app has to say about its rows, for an error: the `name:` of each, or that it has no blend.yaml. */\nfunction describeRows(appDir: string): string {\n const rows = rowNames(appDir)\n return rows === undefined ? 'no blend.yaml' : `the rows ${rows.join(', ') || '(none)'}`\n}\n\n/** What to do after `npm install` for a plugin that needs more than the install: node-pty compiles a native module in an install script, which npm 11 and pnpm skip until approved. */\nfunction extraNote(plugin: Mounted | undefined): string {\n return plugin?.name === 'driver-pty'\n ? \"\\nnpm 11 and pnpm warn that node-pty's install script was not run, because they ask you to approve dependency install scripts. node-pty ships prebuilt binaries for macOS, Windows and Linux (x64, arm64), so you can usually ignore the warning. If the panel lists no `pty:` terminal (the app prints why at start), approve it and rebuild: `npm approve-scripts node-pty`, then `npm rebuild node-pty` (pnpm: `pnpm approve-builds`).\"\n : ''\n}\n\n/**\n * The vitest the suites run on. 3.2.x, not the newest: npm 10 (the npm of Node 22) crashes on the dependency tree of vitest 4 and 5 (\"Cannot read properties of null (reading\n * 'edgesOut')\"), and the suites use only `describe`, `it` and `expect`, which are the same in all of them. An app on a newer npm may raise it.\n */\nconst SUITE_RUNNER = { vitest: '3.2.4' }\n\n/**\n * Copy the conformance suite of each named port next to its source (`plugins/<name>/src/conformance.ts`), and add `vitest` to the app's development\n * dependencies. The suite is left out of a normal copy because an app that only uses a port has no use for it. Returns the exit code: 1 when a plugin has none.\n */\nfunction copySuites(names: readonly string[], appDir: string, added: string[], io: Io): number {\n const copies: Array<{ from: string; to: string }> = []\n // The suite belongs to the port: `add kv --suite` (acryl-kv-json, or acryl-kv-db) brings the suite of acryl-kv.\n const ports = [\n ...new Set(names.map((name) => name.replace(/^(acryl-(?:kv|db))(?:-.*)?$/u, '$1'))),\n ]\n const library = readLibrary()\n for (const name of ports) {\n const suite = library.get(name)?.suite\n const from = suite === undefined ? '' : join(libraryRoot(), name, suite)\n if (suite === undefined || !existsSync(from)) {\n io.stderr.write(`error: ${name} has no conformance suite (the ports db and kv do)\\n`)\n return 1\n }\n copies.push({ from, to: join(pluginsFolder(appDir).dir, name, suite) })\n }\n for (const { from, to } of copies) {\n mkdirSync(dirname(to), { recursive: true })\n copyRewritten(from, to, pluginOf(to), suiteOf(to))\n io.stdout.write(`added the conformance suite ${relative(appDir, to).split(sep).join('/')}\\n`)\n }\n added.push(...mergeTooling(appDir, { devDependencies: SUITE_RUNNER }).devDependencies)\n return 0\n}\n\n/** The plugin folder name and the file inside it, from a path below the plugins folder (`.../plugins/acryl-kv/src/conformance.ts`). */\nconst pluginOf = (path: string): string => path.split(sep).slice(-3, -2)[0] ?? ''\nconst suiteOf = (path: string): string => path.split(sep).slice(-2).join('/')\n\nconst PLUGIN_NAME = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/\n\n/**\n * Bring an external plugin folder (a package made with the builder's package_plugin, or any folder with an index.ts that exports a\n * Cordis plugin) into the app's `plugins/`, where the extensions plugin installs it like any other: checked, staged, started,\n * verified. Its runtime dependencies are not installed here; they are reported so the user adds them deliberately.\n */\nfunction addExternal(folder: string, appDir: string, io: Io): number {\n if (!existsSync(folder) || !statSync(folder).isDirectory()) {\n io.stderr.write(`error: ${folder} is not a folder\\n`)\n return 1\n }\n if (!['index.ts', 'index.js', 'index.mjs'].some((entry) => existsSync(join(folder, entry)))) {\n io.stderr.write(`error: ${folder} has no index.ts that exports a Cordis plugin\\n`)\n return 1\n }\n const manifestFile = join(folder, 'package.json')\n const manifest = existsSync(manifestFile)\n ? (JSON.parse(readFileSync(manifestFile, 'utf8')) as {\n name?: string\n dependencies?: Record<string, string>\n })\n : {}\n const name = (manifest.name ?? basename(folder)).replace(/^@[^/]+\\//, '')\n if (!PLUGIN_NAME.test(name)) {\n io.stderr.write(\n `error: \"${name}\" is not a plugin name (lowercase letters, digits and dashes)\\n`,\n )\n return 1\n }\n const target = join(\n pluginsFolder(appDir).legacy ? join(appDir, 'extensions') : join(appDir, PLUGINS_DIR),\n name,\n )\n if (existsSync(target)) {\n io.stderr.write(`error: the app already has ${relative(appDir, target).split(sep).join('/')}\\n`)\n return 1\n }\n cpSync(folder, target, {\n recursive: true,\n filter: (path) => !/[\\\\/](node_modules|\\.git)([\\\\/]|$)/.test(path.slice(folder.length)),\n })\n io.stdout.write(\n `added external plugin ${name} to ${dirname(target)}; it installs at the next start\\n`,\n )\n const dependencies = Object.keys(manifest.dependencies ?? {})\n if (dependencies.length > 0)\n io.stdout.write(\n `it uses ${dependencies.join(', ')}: add them to the app with npm install first\\n`,\n )\n return 0\n}\n\n/** `acrylblends plugins`: the library, one line per plugin. */\nexport function listPlugins(io: Io): number {\n for (const plugin of readLibrary().values()) {\n const requires = plugin.requires.length > 0 ? ` (requires ${plugin.requires.join(', ')})` : ''\n io.stdout.write(`${plugin.name.padEnd(12)} ${plugin.description}${requires}\\n`)\n }\n return 0\n}\n","import { existsSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { relative, resolve } from 'node:path'\nimport { UsageError } from './init'\nimport type { Io } from './io'\n\n/** Parse `build-client [root] [outDir]`. */\nexport function parseBuildClientOptions(argv: readonly string[]): { root: string; outDir: string } {\n const args = argv.filter((a) => !a.startsWith('-'))\n if (args.length !== argv.length)\n throw new UsageError('build-client takes [root] [outDir] and no options')\n if (args.length > 2)\n throw new UsageError('build-client takes at most two arguments: [root] [outDir]')\n return { root: args[0] ?? 'src/client', outDir: args[1] ?? 'dist/client' }\n}\n\n/**\n * Compile the app's client modules once (`buildClientModules` of the framework), for a production install that has no compiler at run time.\n * The framework is the one installed in the app (so the compiled files match the server that serves them), else this package's own.\n */\nexport async function buildClient(\n options: { root: string; outDir: string },\n io: Io,\n): Promise<number> {\n const root = resolve(io.cwd, options.root)\n if (!existsSync(root)) {\n io.stderr.write(\n `error: ${root} does not exist; the client modules live in src/client by default\\n`,\n )\n return 1\n }\n const outDir = resolve(io.cwd, options.outDir)\n const here = createRequire(resolve(io.cwd, 'package.json'))\n let specifier = 'acrylblends/node-server'\n try {\n here.resolve(specifier)\n } catch {\n specifier = new URL('../lib/node-server.js', import.meta.url).href\n }\n const mod = (await import(\n specifier.startsWith('file:') ? specifier : here.resolve(specifier)\n )) as typeof import('../lib/node-server')\n const written = mod.buildClientModules({ root, outDir })\n for (const file of written) io.stdout.write(`${relative(io.cwd, resolve(outDir, file))}\\n`)\n io.stdout.write(`built ${written.length} files in ${relative(io.cwd, outDir) || '.'}\\n`)\n return 0\n}\n","import { existsSync, readdirSync, readFileSync } from 'node:fs'\nimport { join, relative, resolve, sep } from 'node:path'\nimport type { Io } from './io'\n\n/**\n * The dependency rule (spec 049): app code imports a port, never a provider. A port is `acrylblends/db` (the `Db` type); a provider is a\n * driver or the one function that opens a database. Only the opener, a file the app names once in package.json, may import a provider.\n */\n\n/** A package that is a database driver. An import of it, or of anything below it, is a provider import. */\nconst DRIVERS = [\n 'node:sqlite',\n 'sqlite',\n 'sqlite3',\n 'better-sqlite3',\n '@libsql/client',\n 'libsql',\n 'pg',\n 'pg-pool',\n 'pg-native',\n 'postgres',\n '@electric-sql/pglite',\n '@neondatabase/serverless',\n '@vercel/postgres',\n 'mysql',\n 'mysql2',\n]\n/** The openers a provider ships: importing one of them is opening a database. */\nconst OPENERS = ['acrylblends/db/sqlite', 'acryl-db-sqlite']\n/** The desktop shell is where Electron lives (`acrylblends add desktop` copies it). */\nconst ELECTRON = 'electron'\nconst ELECTRON_HOMES = [\n 'plugins/desktop/',\n 'plugins/desktop-web/',\n 'src/plugins/desktop/',\n 'src/plugins/desktop-web/',\n]\n/** The provider plugins themselves may import what they wrap. */\nconst PROVIDER_HOMES = ['plugins/acryl-db-sqlite/', 'src/plugins/acryl-db-sqlite/']\n\nconst SOURCE = /\\.(?:[cm]?[jt]s|[jt]sx)$/u\nconst SKIP_DIRS = new Set(['node_modules', 'dist', 'lib', 'build', 'coverage'])\nconst ROOTS = ['src', 'test', 'tests', 'plugins', 'extensions']\n\nexport interface Violation {\n readonly file: string\n readonly line: number\n readonly specifier: string\n readonly kind: 'driver' | 'opener' | 'electron'\n}\n\nconst matches = (specifier: string, name: string): boolean =>\n specifier === name || specifier.startsWith(`${name}/`)\n\n/** What a specifier is to the rule, or undefined when it is not a provider. */\nexport function classifySpecifier(specifier: string): Violation['kind'] | undefined {\n if (DRIVERS.some((name) => matches(specifier, name))) return 'driver'\n if (OPENERS.some((name) => matches(specifier, name))) return 'opener'\n if (matches(specifier, ELECTRON)) return 'electron'\n return undefined\n}\n\n/** The source with every comment replaced by spaces (newlines kept), so a line number still means what it did and a commented import is not an import. */\nexport function blankComments(source: string): string {\n let out = ''\n let i = 0\n while (i < source.length) {\n const c = source[i] as string\n const next = source[i + 1]\n if (c === '/' && next === '/') {\n const end = source.indexOf('\\n', i)\n const stop = end === -1 ? source.length : end\n out += ' '.repeat(stop - i)\n i = stop\n } else if (c === '/' && next === '*') {\n const end = source.indexOf('*/', i + 2)\n const stop = end === -1 ? source.length : end + 2\n out += source.slice(i, stop).replace(/[^\\n]/gu, ' ')\n i = stop\n } else if (c === \"'\" || c === '\"' || c === '`') {\n let j = i + 1\n while (j < source.length && source[j] !== c) {\n if (source[j] === '\\\\') j += 1\n else if (c !== '`' && source[j] === '\\n') break\n j += 1\n }\n out += source.slice(i, Math.min(j + 1, source.length))\n i = j + 1\n } else {\n out += c\n i += 1\n }\n }\n return out\n}\n\n/** `import x from 'a'`, `export * from 'a'`, `import 'a'`, `import('a')` and `require('a')`, with the line of each. */\nconst IMPORT =\n /(?:^|[\\s;{}()])(?:import\\s*(?:type\\s+)?(?:[\\w*${},\\s]*?\\s*from\\s*)?|export\\s*(?:type\\s+)?[\\w*${},\\s]*?\\s*from\\s*|import\\s*\\(\\s*|require\\s*\\(\\s*)(['\"])([^'\"\\n]+)\\1/gu\n\nexport function importsOf(source: string): { specifier: string; line: number }[] {\n const code = blankComments(source)\n const found: { specifier: string; line: number }[] = []\n for (const match of code.matchAll(IMPORT)) {\n const specifier = match[2] as string\n const at = (match.index ?? 0) + match[0].length - specifier.length - 2\n found.push({ specifier, line: code.slice(0, at).split('\\n').length })\n }\n return found\n}\n\nfunction listSources(dir: string, out: string[] = []): string[] {\n if (!existsSync(dir)) return out\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.name.startsWith('.') || SKIP_DIRS.has(entry.name)) continue\n const path = join(dir, entry.name)\n if (entry.isDirectory()) listSources(path, out)\n else if (SOURCE.test(entry.name) && !entry.name.endsWith('.d.ts')) out.push(path)\n }\n return out\n}\n\n/** The opener files the app declares: `\"acryl\": { \"opener\": \"src/db.ts\" }` (or a list) in package.json. */\nexport function openersOf(appDir: string): string[] {\n const file = join(appDir, 'package.json')\n if (!existsSync(file)) return []\n const declared = (JSON.parse(readFileSync(file, 'utf8')) as { acryl?: { opener?: unknown } })\n .acryl?.opener\n const list = typeof declared === 'string' ? [declared] : Array.isArray(declared) ? declared : []\n return list.filter((entry): entry is string => typeof entry === 'string')\n}\n\n/** Every provider import outside the declared opener (and the homes that may hold one), in file and line order. */\nexport function findViolations(appDir: string): Violation[] {\n const openers = new Set(openersOf(appDir).map((entry) => entry.split(sep).join('/')))\n const violations: Violation[] = []\n for (const root of ROOTS) {\n for (const path of listSources(join(appDir, root)).sort()) {\n const file = relative(appDir, path).split(sep).join('/')\n if (openers.has(file)) continue\n for (const { specifier, line } of importsOf(readFileSync(path, 'utf8'))) {\n const kind = classifySpecifier(specifier)\n if (kind === undefined) continue\n if (kind === 'electron' && ELECTRON_HOMES.some((home) => file.startsWith(home))) continue\n if (kind !== 'electron' && PROVIDER_HOMES.some((home) => file.startsWith(home))) continue\n violations.push({ file, line, specifier, kind })\n }\n }\n }\n return violations\n}\n\nconst GUIDE = 'docs/framework/guides/data.md#why-the-database-is-opened-in-one-place'\n\nfunction advice(violation: Violation, openers: readonly string[]): string {\n if (violation.kind === 'electron')\n return `\"${violation.specifier}\" is the desktop shell's: only plugins/desktop (added with \"acrylblends add desktop\") imports electron`\n const where =\n openers.length > 0\n ? openers.join(', ')\n : 'a file named in package.json \"acryl\": { \"opener\": \"...\" }'\n return violation.kind === 'driver'\n ? `\"${violation.specifier}\" is a database driver; take a Db (import type { Db } from \"acrylblends/db\") as an argument and let ${where} open the database`\n : `\"${violation.specifier}\" opens a database, and only ${where} may; take a Db (import type { Db } from \"acrylblends/db\") as an argument`\n}\n\n/** Parse `check-deps [dir]`. */\nexport function parseCheckDepsOptions(argv: readonly string[]): { directory: string | undefined } {\n const args = argv.filter((a) => !a.startsWith('-'))\n if (args.length !== argv.length || args.length > 1)\n throw new Error('check-deps takes at most one argument: the app folder')\n return { directory: args[0] }\n}\n\n/** Report each provider import outside the opener, as `file:line: why`. Returns the exit code: 1 when there is one. */\nexport function checkDeps(options: { directory: string | undefined }, io: Io): number {\n const appDir = resolve(io.cwd, options.directory ?? '.')\n const violations = findViolations(appDir)\n if (violations.length === 0) {\n io.stdout.write('check-deps: no app code imports a database provider outside the opener\\n')\n return 0\n }\n const openers = openersOf(appDir)\n for (const violation of violations)\n io.stderr.write(`${violation.file}:${violation.line}: ${advice(violation, openers)}\\n`)\n io.stderr.write(`See ${GUIDE}\\n`)\n return 1\n}\n","import { existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\n\nexport interface Invocation {\n file: string\n args: string[]\n}\n\n/**\n * How to start a package manager without the shell option (Node warns about passing args to a shell, DEP0190, and a `.cmd` shim cannot be spawned directly).\n * Off Windows the command runs as it is. On Windows npm runs as `node npm-cli.js` (the one npm is running from, else the one beside `node`); any other\n * manager goes through `cmd.exe /d /s /c <name>.cmd`, whose arguments stay an array.\n */\nexport function packageManagerInvocation(\n command: string,\n args: readonly string[],\n platform: NodeJS.Platform = process.platform,\n env: NodeJS.ProcessEnv = process.env,\n exists: (path: string) => boolean = existsSync,\n execPath: string = process.execPath,\n): Invocation {\n if (platform !== 'win32') return { file: command, args: [...args] }\n if (command === 'npm') {\n const running = env.npm_execpath\n const cli =\n running !== undefined && /npm-cli\\.c?js$/.test(running)\n ? running\n : join(dirname(execPath), 'node_modules', 'npm', 'bin', 'npm-cli.js')\n if (exists(cli)) return { file: execPath, args: [cli, ...args] }\n }\n return { file: env.ComSpec ?? 'cmd.exe', args: ['/d', '/s', '/c', `${command}.cmd`, ...args] }\n}\n","import { spawn } from 'node:child_process'\nimport { createInterface } from 'node:readline/promises'\nimport { packageManagerInvocation } from './spawn'\n\n/** Everything the CLI touches outside the filesystem. Tests pass their own. */\nexport interface Io {\n stdout: { write(text: string): unknown }\n stderr: { write(text: string): unknown }\n cwd: string\n /** Ask one question; `undefined` when there is no terminal to ask on. */\n ask: ((question: string) => Promise<string>) | undefined\n /** Install dependencies in a directory; resolves to the exit code. */\n install(directory: string): Promise<number>\n}\n\n/** The real terminal and `npm install`. */\nexport function processIo(): Io {\n const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY)\n return {\n stdout: process.stdout,\n stderr: process.stderr,\n cwd: process.cwd(),\n ask: interactive\n ? async (question) => {\n const rl = createInterface({ input: process.stdin, output: process.stdout })\n try {\n return await rl.question(question)\n } finally {\n rl.close()\n }\n }\n : undefined,\n install: (directory) =>\n new Promise((done) => {\n const { file, args } = packageManagerInvocation('npm', ['install'])\n const child = spawn(file, args, { cwd: directory, stdio: 'inherit' })\n child.on('error', () => done(1))\n child.on('exit', (code) => done(code ?? 1))\n }),\n }\n}\n","import { existsSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { resolve } from 'node:path'\nimport { parseArgs } from 'node:util'\nimport { UsageError } from './init'\nimport type { Io } from './io'\n\nexport interface KvImportOptions {\n readonly from: string\n readonly to: string\n readonly overwrite: boolean\n readonly table: string | undefined\n readonly migrations: string | undefined\n}\n\n/** Parse `kv import <kv.json> <database.sqlite> [--overwrite] [--table name] [--migrations dir]`. */\nexport function parseKvOptions(argv: readonly string[]): KvImportOptions {\n let parsed: ReturnType<typeof parse>\n try {\n parsed = parse(argv)\n } catch (error) {\n throw new UsageError((error as Error).message)\n }\n const [action, from, to, ...rest] = parsed.positionals\n if (action !== 'import')\n throw new UsageError('kv takes one subcommand: kv import <kv.json> <database.sqlite>')\n if (from === undefined || to === undefined || rest.length > 0)\n throw new UsageError('kv import takes two arguments: the JSON file and the SQLite file')\n return {\n from,\n to,\n overwrite: parsed.values.overwrite ?? false,\n table: parsed.values.table,\n migrations: parsed.values.migrations,\n }\n}\n\nconst parse = (argv: readonly string[]) =>\n parseArgs({\n args: [...argv],\n allowPositionals: true,\n strict: true,\n options: {\n overwrite: { type: 'boolean' },\n table: { type: 'string' },\n migrations: { type: 'string' },\n },\n })\n\n/** The framework as the app has it installed (so the code that reads the file is the code the app runs), else this package's own. */\nasync function framework<T>(io: Io, subpath: string, own: string): Promise<T> {\n const here = createRequire(resolve(io.cwd, 'package.json'))\n try {\n return (await import(here.resolve(`acrylblends/${subpath}`))) as T\n } catch {\n return (await import(new URL(`../lib/${own}`, import.meta.url).href)) as T\n }\n}\n\n/**\n * Import a JSON-file kv store into the `kv` table of an app's SQLite database: the move from `acryl-kv-json` to SQL. The file is not changed.\n * The database is opened with the app's `migrations/` folder when it has one (a database whose schema is newer than the files given is refused),\n * and the table is created when missing. Refuses to overwrite a key the table already has unless `--overwrite`.\n */\nexport async function kvImport(options: KvImportOptions, io: Io): Promise<number> {\n const from = resolve(io.cwd, options.from)\n const to = resolve(io.cwd, options.to)\n if (!existsSync(from)) {\n io.stderr.write(`error: ${from} does not exist\\n`)\n return 1\n }\n const kvCore = await framework<typeof import('../lib/kv')>(io, 'kv', 'kv.js')\n const json = await framework<typeof import('../lib/kv/json')>(io, 'kv/json', 'kv/json.js')\n const onDb = await framework<typeof import('../lib/kv/db')>(io, 'kv/db', 'kv/db.js')\n const sqlite = await framework<typeof import('../lib/db/sqlite')>(io, 'db/sqlite', 'db/sqlite.js')\n const migrations =\n options.migrations !== undefined\n ? resolve(io.cwd, options.migrations)\n : existsSync(resolve(io.cwd, 'migrations'))\n ? resolve(io.cwd, 'migrations')\n : undefined\n const source = await json.openKv({ path: from })\n try {\n const database = await sqlite.openDb({\n path: to,\n ...(migrations === undefined ? {} : { migrations }),\n })\n try {\n const target = onDb.kvOnDb(\n database.db,\n options.table === undefined ? {} : { table: options.table },\n )\n const result = await kvCore.copyKv(source.kv, target, { overwrite: options.overwrite })\n io.stdout.write(\n `imported ${result.copied} ${result.copied === 1 ? 'key' : 'keys'} from ${options.from} into ${options.to}` +\n `${options.table === undefined ? '' : ` (table ${options.table})`}` +\n `${result.overwritten > 0 ? `, ${result.overwritten} overwritten` : ''}\\n`,\n )\n return 0\n } finally {\n await database.close()\n }\n } finally {\n await source.close()\n }\n}\n","/** A unified diff of two texts (3 lines of context), for showing what an upgrade changes. Very large pairs are summarized instead. */\n\nexport interface DiffStat {\n readonly added: number\n readonly removed: number\n}\n\ntype Op = { kind: ' ' | '+' | '-'; line: string }\n\nfunction ops(a: string[], b: string[]): Op[] | undefined {\n if (a.length * b.length > 6_000_000) return undefined\n // Longest common subsequence by dynamic programming over the suffixes.\n const width = b.length + 1\n const table = new Uint32Array((a.length + 1) * width)\n for (let i = a.length - 1; i >= 0; i -= 1)\n for (let j = b.length - 1; j >= 0; j -= 1)\n table[i * width + j] =\n a[i] === b[j]\n ? (table[(i + 1) * width + j + 1] as number) + 1\n : Math.max(table[(i + 1) * width + j] as number, table[i * width + j + 1] as number)\n const out: Op[] = []\n let i = 0\n let j = 0\n while (i < a.length && j < b.length) {\n if (a[i] === b[j]) {\n out.push({ kind: ' ', line: a[i] as string })\n i += 1\n j += 1\n } else if ((table[(i + 1) * width + j] as number) >= (table[i * width + j + 1] as number)) {\n out.push({ kind: '-', line: a[i] as string })\n i += 1\n } else {\n out.push({ kind: '+', line: b[j] as string })\n j += 1\n }\n }\n for (; i < a.length; i += 1) out.push({ kind: '-', line: a[i] as string })\n for (; j < b.length; j += 1) out.push({ kind: '+', line: b[j] as string })\n return out\n}\n\nconst lines = (text: string): string[] =>\n text === '' ? [] : text.replace(/\\r\\n/gu, '\\n').replace(/\\n$/u, '').split('\\n')\n\n/** How many lines a change adds and removes; undefined counts when the pair is too large to compare. */\nexport function diffStat(from: string, to: string): DiffStat {\n const all = ops(lines(from), lines(to))\n if (all === undefined) return { added: lines(to).length, removed: lines(from).length }\n return {\n added: all.filter((op) => op.kind === '+').length,\n removed: all.filter((op) => op.kind === '-').length,\n }\n}\n\n/** `--- a/<name>`, `+++ b/<name>` and the hunks; empty when the texts are equal. */\nexport function unifiedDiff(name: string, from: string, to: string, context = 3): string {\n const a = lines(from)\n const b = lines(to)\n const all = ops(a, b)\n if (all === undefined)\n return `--- a/${name}\\n+++ b/${name}\\n(too large to compare line by line: ${a.length} lines became ${b.length})\\n`\n if (!all.some((op) => op.kind !== ' ')) return ''\n const out = [`--- a/${name}`, `+++ b/${name}`]\n let at = 0\n let aLine = 1\n let bLine = 1\n const positions = all.map((op) => {\n const here = { a: aLine, b: bLine }\n if (op.kind !== '+') aLine += 1\n if (op.kind !== '-') bLine += 1\n return here\n })\n while (at < all.length) {\n while (at < all.length && all[at]?.kind === ' ') at += 1\n if (at >= all.length) break\n const start = Math.max(0, at - context)\n let end = at\n for (let k = at; k < all.length; k += 1) {\n if (all[k]?.kind !== ' ') end = k\n else if (k - end > context * 2) break\n }\n const stop = Math.min(all.length, end + context + 1)\n const slice = all.slice(start, stop)\n const first = positions[start] as { a: number; b: number }\n out.push(\n `@@ -${first.a},${slice.filter((op) => op.kind !== '+').length} +${first.b},${slice.filter((op) => op.kind !== '-').length} @@`,\n )\n for (const op of slice) out.push(`${op.kind}${op.line}`)\n at = stop\n }\n return `${out.join('\\n')}\\n`\n}\n","import {\n cpSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n rmSync,\n statSync,\n writeFileSync,\n} from 'node:fs'\nimport { dirname, join, relative, resolve, sep } from 'node:path'\nimport { parseArgs } from 'node:util'\nimport { diffStat, unifiedDiff } from './diff'\nimport { UsageError } from './init'\nimport type { Io } from './io'\nimport {\n closure,\n copyPlugin,\n LEGACY_WARNING,\n LIBRARY_LIST,\n type LibraryPlugin,\n pluginsFolder,\n readLibrary,\n recordLibraryCopy,\n} from './library'\nimport { hashFolder, readHistory, readLock, recordLock } from './lock'\nimport { appendGitignore, mergeDependencies, mergeImports, mergeTooling } from './project'\nimport { VERSION } from './version'\n\nexport interface UpgradeOptions {\n /** Library plugins to upgrade; none means every library plugin the app carries. */\n readonly names: readonly string[]\n readonly directory: string | undefined\n /** Show what would change and stop. */\n readonly dryRun: boolean\n /** Replace a file the app edited too (the edited version is saved first). */\n readonly force: boolean\n /** Print the diff of every changed file, not only of the edited ones. */\n readonly diff: boolean\n}\n\n/** Parse `upgrade [plugin...] [--dir <app>] [--dry-run] [--force] [--diff]`. */\nexport function parseUpgradeOptions(argv: readonly string[]): UpgradeOptions {\n let parsed: ReturnType<typeof parse>\n try {\n parsed = parse(argv)\n } catch (error) {\n throw new UsageError((error as Error).message)\n }\n return {\n names: parsed.positionals,\n directory: parsed.values.dir,\n dryRun: parsed.values['dry-run'] === true,\n force: parsed.values.force === true,\n diff: parsed.values.diff === true,\n }\n}\n\nconst parse = (argv: readonly string[]) =>\n parseArgs({\n args: [...argv],\n allowPositionals: true,\n strict: true,\n options: {\n dir: { type: 'string' },\n 'dry-run': { type: 'boolean' },\n force: { type: 'boolean' },\n diff: { type: 'boolean' },\n },\n })\n\ntype FileState = 'same' | 'add' | 'update' | 'conflict' | 'remove' | 'extra'\n\ninterface PluginPlan {\n readonly plugin: LibraryPlugin\n /** The app does not have this plugin at all (a new requirement of one that it has). */\n readonly isNew: boolean\n /** Path inside the plugin folder to what happens to it. */\n readonly files: Map<string, FileState>\n /** The hashes of the files the current library would copy. */\n readonly fresh: Record<string, string>\n}\n\nconst posix = (path: string): string => path.split(sep).join('/')\n\nfunction readText(path: string): string {\n return readFileSync(path, 'utf8')\n}\n\n/** The library copies an app carries: the plugins listed in `plugins/library.json`, or when there is none the folders of `plugins/` that the library knows. */\nfunction carriedCopies(dir: string): string[] {\n const listFile = join(dir, LIBRARY_LIST)\n const listed = existsSync(listFile)\n ? ((JSON.parse(readFileSync(listFile, 'utf8')) as { plugins?: string[] }).plugins ?? [])\n : readdirSync(dir).filter((name) => statSync(join(dir, name)).isDirectory())\n return listed.filter((name) => existsSync(join(dir, name)))\n}\n\n/**\n * `acrylblends upgrade`: bring the library plugins an app carries (the router, the server, the door, `extensions`, ...) up to the version of this package. Each file is compared with what\n * the app was given: an untouched file is replaced, a file the app edited stops the upgrade (it is shown as a diff and nothing changes) unless `--force`, which saves the edited version\n * under `.acrylblends/upgrade-backup/` first. Returns the exit code: 0 done or nothing to do, 1 refused or failed.\n */\nexport async function upgrade(options: UpgradeOptions, io: Io): Promise<number> {\n const appDir = resolve(io.cwd, options.directory ?? '.')\n if (!existsSync(join(appDir, 'package.json')) || !existsSync(join(appDir, 'src'))) {\n io.stderr.write(\n `error: ${appDir} is not an app (no package.json and src/); run \"acrylblends init\" first\\n`,\n )\n return 1\n }\n const folder = pluginsFolder(appDir)\n if (folder.legacy) {\n io.stderr.write(\n `${LEGACY_WARNING}\\nerror: upgrade needs the one-folder layout (plugins/); move the plugins first\\n`,\n )\n return 1\n }\n const library = readLibrary()\n const carried = carriedCopies(folder.dir)\n const unknown = carried.filter((name) => !library.has(name))\n for (const name of options.names)\n if (!carried.includes(name)) {\n io.stderr.write(\n `error: the app carries no library plugin \"${name}\" (it carries: ${carried.filter((n) => library.has(n)).join(', ') || 'none'})\\n`,\n )\n return 1\n }\n const selected = (options.names.length > 0 ? [...options.names] : carried).filter((name) =>\n library.has(name),\n )\n if (selected.length === 0) {\n io.stdout.write('nothing to upgrade: the app carries no library plugins\\n')\n return 0\n }\n\n // What the current library would copy, into a scratch folder inside the app (`.acrylblends/` is ignored by git).\n const scratch = join(appDir, '.acrylblends', `upgrade-${process.pid}-${Date.now()}`)\n const lock = readLock(folder.dir)\n const history = readHistory()\n const plans: PluginPlan[] = []\n try {\n mkdirSync(join(scratch, 'plugins'), { recursive: true })\n const wanted = closure(selected, library)\n for (const plugin of wanted) copyPlugin(plugin, scratch)\n for (const plugin of wanted) {\n const here = join(folder.dir, plugin.name)\n const fresh = hashFolder(join(scratch, 'plugins', plugin.name))\n const files = new Map<string, FileState>()\n const isNew = !existsSync(here)\n const mine = isNew ? {} : hashFolder(here)\n const recorded = lock.plugins[plugin.name]?.files ?? {}\n const pristine = (file: string, hash: string): boolean =>\n recorded[file] === hash || (history[plugin.name]?.[file]?.includes(hash) ?? false)\n for (const [file, hash] of Object.entries(fresh)) {\n const have = mine[file]\n files.set(\n file,\n have === undefined\n ? 'add'\n : have === hash\n ? 'same'\n : pristine(file, have)\n ? 'update'\n : 'conflict',\n )\n }\n for (const [file, hash] of Object.entries(mine))\n if (!(file in fresh)) files.set(file, pristine(file, hash) ? 'remove' : 'extra')\n plans.push({ plugin, isNew, files, fresh })\n }\n\n // The report.\n const count = (plan: PluginPlan, state: FileState): string[] =>\n [...plan.files].filter(([, s]) => s === state).map(([file]) => file)\n io.stdout.write(`upgrade: the library plugins of ${appDir} to acrylblends ${VERSION}\\n`)\n let conflicts = 0\n let changes = 0\n for (const plan of plans) {\n const [updated, added, removed, edited, extra] = (\n ['update', 'add', 'remove', 'conflict', 'extra'] as const\n ).map((state) => count(plan, state))\n const label = plan.plugin.name.padEnd(22)\n conflicts += (edited as string[]).length\n if (plan.isNew) {\n changes += 1\n io.stdout.write(` ${label} new (required by a plugin of the app)\\n`)\n continue\n }\n if (\n (updated as string[]).length +\n (added as string[]).length +\n (removed as string[]).length +\n (edited as string[]).length ===\n 0\n ) {\n io.stdout.write(\n ` ${label} up to date${(extra as string[]).length > 0 ? ` (keeps ${(extra as string[]).length} file(s) of its own)` : ''}\\n`,\n )\n continue\n }\n changes += 1\n let plus = 0\n let minus = 0\n for (const file of [...(updated as string[]), ...(edited as string[])]) {\n const stat = diffStat(\n readText(join(folder.dir, plan.plugin.name, file)),\n readText(join(scratch, 'plugins', plan.plugin.name, file)),\n )\n plus += stat.added\n minus += stat.removed\n }\n const parts = [\n (updated as string[]).length > 0\n ? `${(updated as string[]).length} updated (+${plus} -${minus})`\n : '',\n (added as string[]).length > 0 ? `${(added as string[]).length} added` : '',\n (removed as string[]).length > 0 ? `${(removed as string[]).length} removed` : '',\n (edited as string[]).length > 0 ? `${(edited as string[]).length} EDITED HERE` : '',\n (extra as string[]).length > 0 ? `${(extra as string[]).length} of its own kept` : '',\n ].filter(Boolean)\n io.stdout.write(` ${label} ${parts.join(', ')}\\n`)\n }\n for (const name of unknown)\n io.stdout.write(` ${name.padEnd(22)} not in this library: left alone\\n`)\n\n // Diffs: always of the edited files (what would be lost), of every changed file with --diff.\n for (const plan of plans) {\n for (const [file, state] of plan.files) {\n if (\n !(\n state === 'conflict' ||\n (options.diff && (state === 'update' || state === 'add' || state === 'remove'))\n )\n )\n continue\n const name = `plugins/${plan.plugin.name}/${file}`\n const before = state === 'add' ? '' : readText(join(folder.dir, plan.plugin.name, file))\n const after =\n state === 'remove' ? '' : readText(join(scratch, 'plugins', plan.plugin.name, file))\n io.stdout.write(\n `\\n${state === 'conflict' ? 'EDITED HERE, the upgrade would replace it:\\n' : ''}${unifiedDiff(name, before, after)}`,\n )\n }\n }\n if (conflicts > 0 && !options.force) {\n io.stderr.write(\n `\\nerror: ${conflicts} file(s) were edited in this app and the upgrade would replace them; nothing was changed. Review the diffs above, move your changes out of the plugin (a plugin of your own in plugins/<name>/), or run again with --force (the edited versions are saved under .acrylblends/upgrade-backup/)\\n`,\n )\n return 1\n }\n if (options.dryRun) {\n io.stdout.write(\n `\\n${changes === 0 ? 'everything is up to date' : 'dry run: nothing was changed'}\\n`,\n )\n return 0\n }\n if (changes === 0) {\n io.stdout.write('\\neverything is up to date\\n')\n return 0\n }\n\n // Apply.\n const backup = join(\n appDir,\n '.acrylblends',\n 'upgrade-backup',\n new Date().toISOString().replace(/[:.]/gu, '-'),\n )\n const addedDependencies: string[] = []\n for (const plan of plans) {\n const here = join(folder.dir, plan.plugin.name)\n if (plan.isNew) {\n // Copied the way `add` copies it: the plugin, and what it needs in package.json.\n mkdirSync(here, { recursive: true })\n cpSync(join(scratch, 'plugins', plan.plugin.name), here, { recursive: true })\n recordLibraryCopy(folder.dir, plan.plugin.name)\n } else {\n for (const [file, state] of plan.files) {\n const target = join(here, file)\n if (state === 'conflict') {\n mkdirSync(dirname(join(backup, plan.plugin.name, file)), { recursive: true })\n cpSync(target, join(backup, plan.plugin.name, file))\n }\n if (state === 'add' || state === 'update' || state === 'conflict') {\n mkdirSync(dirname(target), { recursive: true })\n cpSync(join(scratch, 'plugins', plan.plugin.name, file), target)\n } else if (state === 'remove') rmSync(target, { force: true })\n }\n recordLibraryCopy(folder.dir, plan.plugin.name)\n }\n recordLock(folder.dir, plan.plugin.name, plan.fresh)\n const plugin = plan.plugin\n if (plugin.imports) mergeImports(appDir, plugin.imports, posix(relative(appDir, folder.dir)))\n addedDependencies.push(...mergeDependencies(appDir, plugin.dependencies))\n addedDependencies.push(...mergeTooling(appDir, plugin).devDependencies)\n appendGitignore(appDir, plugin.gitignore)\n }\n // The package the app depends on moves with its plugins.\n const manifestFile = join(appDir, 'package.json')\n const manifest = JSON.parse(readFileSync(manifestFile, 'utf8')) as {\n dependencies?: Record<string, string>\n }\n if (\n manifest.dependencies?.acrylblends !== undefined &&\n manifest.dependencies.acrylblends !== `^${VERSION}`\n ) {\n manifest.dependencies.acrylblends = `^${VERSION}`\n writeFileSync(manifestFile, `${JSON.stringify(manifest, null, 2)}\\n`)\n }\n io.stdout.write(\n `\\nupgraded ${plans\n .filter((p) => [...p.files.values()].some((s) => s !== 'same' && s !== 'extra') || p.isNew)\n .map((p) => p.plugin.name)\n .join(', ')}\\n`,\n )\n if (conflicts > 0)\n io.stdout.write(\n `the ${conflicts} edited file(s) replaced by --force are saved in ${posix(relative(appDir, backup))}/\\n`,\n )\n io.stdout.write(\n `acrylblends is now ^${VERSION} in package.json${addedDependencies.length > 0 ? `; new dependencies: ${[...new Set(addedDependencies)].join(', ')}` : ''}: run npm install, then npm run check and npm test\\n`,\n )\n return 0\n } finally {\n rmSync(scratch, { recursive: true, force: true })\n }\n}\n","import { add, listPlugins, parseAddOptions } from './add'\nimport { buildClient, parseBuildClientOptions } from './build-client'\nimport { checkDeps, parseCheckDepsOptions } from './check-deps'\nimport { init, parseInitOptions, UsageError } from './init'\nimport { type Io, processIo } from './io'\nimport { kvImport, parseKvOptions } from './kv-import'\nimport { TEMPLATE_SUMMARY, TEMPLATES } from './templates'\nimport { parseUpgradeOptions, upgrade } from './upgrade'\nimport { VERSION } from './version'\n\nexport { VERSION }\n\nexport const HELP = `acrylblends ${VERSION} - scaffold Cordis apps\n\nUsage:\n acrylblends init [dir] [options] Create a Cordis app in an empty or new directory\n acrylblends add <plugin...> [--dir d] [--suite] Copy library plugins (and what they require) into an app;\n a folder path brings an external plugin into its plugins/;\n --suite also copies the port's conformance suite and vitest (add kv --suite)\n acrylblends upgrade [plugin...] [--dir d] [--dry-run] [--force] [--diff]\n Bring the library plugins an app carries (the router, the server, the door, ...) up to this\n version: untouched files are replaced, an edited file stops it (diff shown) unless --force\n acrylblends plugins List the plugin library\n acrylblends build-client [root] [out] Compile the client modules once for production (src/client to dist/client)\n acrylblends kv import <kv.json> <db> Move a JSON-file kv store into the kv table of a SQLite database [--overwrite] [--table t] [--migrations dir]\n acrylblends check-deps [dir] Fail when app code imports a database driver or opener outside the file named in\n package.json \"acryl\": { \"opener\": \"src/db.ts\" } (a port is imported, a provider is not)\n\nOptions for init:\n --template <name> one of the templates below (asked when not given); --agent means --template agent,\n --no-agent means --template blank\n --name <name> the project name (default: the directory name)\n --desktop also add the desktop shell: npm run desktop opens a window on the app\n --install run npm install after copying\n -y, --yes ask nothing; use defaults (the blank template, no install)\n\n -h, --help show this help\n -v, --version show the version\n\nTemplates (the same list as npm create acrylblends):\n${TEMPLATES.map((name) => ` ${name.padEnd(7)} ${TEMPLATE_SUMMARY[name]}`).join('\\n')}\n`\n\n/**\n * Run the CLI and return the exit code: 0 done, 1 failed or refused, 2 a usage error. Never calls `process.exit`.\n */\nexport async function runCli(argv: readonly string[], io: Io = processIo()): Promise<number> {\n const [command, ...args] = argv\n try {\n if (command === undefined || command === 'help' || command === '-h' || command === '--help') {\n io.stdout.write(HELP)\n return command === undefined ? 2 : 0\n }\n if (command === 'version' || command === '-v' || command === '--version') {\n io.stdout.write(`${VERSION}\\n`)\n return 0\n }\n if (command === 'init') return await init(parseInitOptions(args), io)\n if (command === 'add') return await add(parseAddOptions(args), io)\n if (command === 'upgrade') return await upgrade(parseUpgradeOptions(args), io)\n if (command === 'build-client') return await buildClient(parseBuildClientOptions(args), io)\n if (command === 'kv') return await kvImport(parseKv(args), io)\n if (command === 'check-deps') return checkDeps(parseCheckDeps(args), io)\n if (command === 'plugins') return listPlugins(io)\n throw new UsageError(`unknown command \"${command}\"`)\n } catch (error) {\n if (error instanceof UsageError) {\n io.stderr.write(`error: ${error.message}\\n\\n${HELP}`)\n return 2\n }\n io.stderr.write(`error: ${error instanceof Error ? error.message : String(error)}\\n`)\n return 1\n }\n}\n\nfunction parseCheckDeps(args: readonly string[]) {\n try {\n return parseCheckDepsOptions(args)\n } catch (error) {\n throw new UsageError((error as Error).message)\n }\n}\n\nfunction parseKv(args: readonly string[]) {\n return parseKvOptions(args)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["parse","parse","parse","posix"],"sources":["../src/templates.ts","../src/version.ts","../src/lock.ts","../src/rewrite.ts","../src/library.ts","../src/project.ts","../src/init.ts","../src/mount.ts","../src/add.ts","../src/build-client.ts","../src/check-deps.ts","../src/spawn.ts","../src/io.ts","../src/kv-import.ts","../src/diff.ts","../src/upgrade.ts","../src/cli.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\n/** The templates, all Cordis apps: a web app with a page and a client component (nodejs), a notes app and a chat app on the db port (notes, chat), a blank app on the router, a todo list on the router and state, and the blank app with the offline agent. */\nexport const TEMPLATES = ['blank', 'nodejs', 'notes', 'chat', 'todo', 'agent'] as const\nexport type Template = (typeof TEMPLATES)[number]\n\n/** One line per template: the single list `acrylblends init` and `create-acrylblends` both show (`create-acrylblends` tests that its own copy equals this one). */\nexport const TEMPLATE_SUMMARY: Record<(typeof TEMPLATES)[number], string> = {\n blank: 'the router, a server and one route: the smallest app',\n nodejs: 'a web app with a page and a client component',\n notes: 'a multi-user notes app on the db port (sign-up, log-in, sessions)',\n chat: 'a chat app that streams an answer over server-sent events',\n todo: 'a to-do list on the router and state',\n agent: 'the blank app with an offline agent that builds plugins into the running app',\n}\n\n/** Names that were templates once and still work: `create-acrylblends --template acryl-app` made the agent app. */\nexport const TEMPLATE_ALIASES: Record<string, Template> = { 'acryl-app': 'agent' }\n\nexport function isTemplate(value: string): value is Template {\n return (TEMPLATES as readonly string[]).includes(value)\n}\n\n/** The template a name means: itself, or what an old name stands for; undefined for anything else. */\nexport function resolveTemplate(value: string): Template | undefined {\n return isTemplate(value) ? value : TEMPLATE_ALIASES[value]\n}\n\n/**\n * The `templates/` folder of this package. The module sits at different depths in source (`src/`) and in the build\n * (`dist/`), so walk up until a `templates` folder holds the `blank` template.\n */\nexport function templatesRoot(): string {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n const candidate = join(dir, 'templates')\n if (existsSync(join(candidate, 'blank'))) return candidate\n const parent = dirname(dir)\n if (parent === dir) throw new Error('acrylblends cannot find its templates folder')\n dir = parent\n }\n}\n\n/** Absolute path of a template folder. */\nexport function templateDir(template: Template): string {\n return join(templatesRoot(), template)\n}\n\n/** The text every generated app's `AGENTS.md` starts with (`shared/`, beside `templates/`). */\nexport function sharedDir(): string {\n return join(dirname(templatesRoot()), 'shared')\n}\n\n/**\n * The framework's docs, as ACRYL wrote them: `docs/framework` of the repository, or the copy `prepack` puts inside the package. The module sits at\n * different depths in source and in the build, so walk up until a `docs/framework` folder holds the README.\n */\nexport function frameworkDocsRoot(): string {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n const candidate = join(dir, 'docs', 'framework')\n if (existsSync(join(candidate, 'README.md'))) return candidate\n const parent = dirname(dir)\n if (parent === dir)\n throw new Error('acrylblends cannot find the framework docs (docs/framework)')\n dir = parent\n }\n}\n","import { createRequire } from 'node:module'\n\n/** The version of this package. */\nexport const VERSION: string = (\n createRequire(import.meta.url)('../package.json') as { version: string }\n).version\n","/**\n * What an app knows about the library plugins it carries: `plugins/library.lock.json` records, for every library plugin copied into the app, the version it came from and a hash of each file\n * as it was copied. `acrylblends upgrade` reads it to tell a file nobody touched (safe to replace) from one the app edited (never replaced without `--force`). An app made before the lock existed\n * has none; for it `upgrade` falls back to the hashes of the released versions (`shared/library-history.json`, made by `scripts/build-library-history.mjs`).\n */\nimport { createHash } from 'node:crypto'\nimport { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { sharedDir } from './templates'\nimport { VERSION } from './version'\n\nexport const LOCK_FILE = 'library.lock.json'\n\nexport interface Lock {\n version: number\n plugins: Record<string, { from: string; files: Record<string, string> }>\n}\n\n/** A file's identity: a hash of its text with line endings normalized (a checkout may have changed them), cut to 20 hex digits. */\nexport function digest(content: Buffer | string): string {\n const text = typeof content === 'string' ? content : content.toString('utf8')\n return createHash('sha256').update(text.replace(/\\r\\n/gu, '\\n')).digest('hex').slice(0, 20)\n}\n\n/** Every file below `dir`, as `relative/path` (forward slashes) to its {@link digest}. */\nexport function hashFolder(dir: string): Record<string, string> {\n const files: Record<string, string> = {}\n const walk = (folder: string, inside: string): void => {\n for (const entry of readdirSync(folder).sort()) {\n const path = join(folder, entry)\n const name = inside === '' ? entry : `${inside}/${entry}`\n if (statSync(path).isDirectory()) walk(path, name)\n else files[name] = digest(readFileSync(path))\n }\n }\n if (existsSync(dir)) walk(dir, '')\n return files\n}\n\nexport function readLock(pluginsDir: string): Lock {\n const file = join(pluginsDir, LOCK_FILE)\n if (!existsSync(file)) return { version: 1, plugins: {} }\n try {\n const lock = JSON.parse(readFileSync(file, 'utf8')) as Lock\n return { version: 1, plugins: lock.plugins ?? {} }\n } catch {\n return { version: 1, plugins: {} }\n }\n}\n\n/** Record that `name` was copied from this version of the library, with the hashes of the files as they now are. */\nexport function recordLock(pluginsDir: string, name: string, files: Record<string, string>): void {\n const lock = readLock(pluginsDir)\n lock.plugins[name] = { from: VERSION, files }\n const sorted = Object.fromEntries(\n Object.entries(lock.plugins).sort(([a], [b]) => a.localeCompare(b)),\n )\n writeFileSync(\n join(pluginsDir, LOCK_FILE),\n `${JSON.stringify({ version: 1, plugins: sorted }, null, 2)}\\n`,\n )\n}\n\n/** Plugin to file to the hashes that file has had in released versions. */\nexport type History = Record<string, Record<string, string[]>>\n\nexport function readHistory(): History {\n const file = join(sharedDir(), 'library-history.json')\n if (!existsSync(file)) return {}\n return JSON.parse(readFileSync(file, 'utf8')) as History\n}\n","import { dirname, posix } from 'node:path'\n\n/**\n * The framework plugins import each other by package name (`acryl-router`, `acryl-router/middleware`): inside this repository they are workspace packages. An app has\n * no such packages, only the copied source, so `acrylblends init` and `add` rewrite those specifiers to relative paths when they copy a plugin. The file each name stands\n * for is the `entries` table of the plugin's `plugin.json`.\n */\n\n/** `acryl-router/middleware` to `acryl-router/src/middleware/index.ts`: every importable name of every library plugin. */\nexport type EntryTable = ReadonlyMap<string, string>\n\nexport function entryTable(\n library: ReadonlyMap<string, { readonly entries?: Readonly<Record<string, string>> | undefined }>,\n): EntryTable {\n const table = new Map<string, string>()\n for (const [plugin, { entries }] of library)\n for (const [subpath, file] of Object.entries(entries ?? {}))\n table.set(`${plugin}${subpath}`, `${plugin}/${file}`)\n return table\n}\n\n/** For every character of a TypeScript source: 0 = code, 1 = inside a comment, 2 = inside a string or template literal. */\nfunction classify(source: string): Uint8Array {\n const kind = new Uint8Array(source.length)\n let i = 0\n while (i < source.length) {\n const c = source[i]\n const next = source[i + 1]\n if (c === '/' && next === '/') {\n const end = source.indexOf('\\n', i)\n const stop = end === -1 ? source.length : end\n kind.fill(1, i, stop)\n i = stop\n } else if (c === '/' && next === '*') {\n const end = source.indexOf('*/', i + 2)\n const stop = end === -1 ? source.length : end + 2\n kind.fill(1, i, stop)\n i = stop\n } else if (c === \"'\" || c === '\"' || c === '`') {\n let j = i + 1\n while (j < source.length && source[j] !== c) {\n if (source[j] === '\\\\') j += 1\n else if (c !== '`' && source[j] === '\\n') break\n j += 1\n }\n kind.fill(2, i, Math.min(j + 1, source.length))\n i = j + 1\n } else i += 1\n }\n return kind\n}\n\nconst SPECIFIER =\n /(\\bfrom\\s+|\\bimport\\s*\\(\\s*|\\bimport\\s+)(['\"])(acryl-[A-Za-z0-9-]+(?:\\/[A-Za-z0-9./-]+)?)\\2/gu\n\n/**\n * Rewrite the specifiers that name another library plugin to relative paths. `file` is the path of the file inside the plugins folder (for example\n * `acryl-state/src/service.ts`). Only real import and export statements are touched: a specifier named in a comment or in a string (a documentation example) is text,\n * not a dependency. Any other `acryl-*` specifier in code is an error: a library plugin may depend only on the others and on public packages.\n */\nexport function rewriteSpecifiers(source: string, file: string, entries: EntryTable): string {\n const kind = classify(source)\n return source.replace(\n SPECIFIER,\n (match, lead: string, quote: string, specifier: string, offset: number) => {\n if (kind[offset] !== 0) return match\n const target = entries.get(specifier)\n if (target === undefined)\n throw new Error(`${file}: imports \"${specifier}\", which is not a library plugin`)\n let path = posix.relative(dirname(file), target)\n if (!path.startsWith('.')) path = `./${path}`\n return `${lead}${quote}${path}${quote}`\n },\n )\n}\n","import { cpSync, existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'\nimport { dirname, join, sep } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { hashFolder, recordLock } from './lock'\nimport { type EntryTable, entryTable, rewriteSpecifiers } from './rewrite'\n\n/** One entry of the plugin library: `plugins/<name>/plugin.json` in this repository. */\nexport interface LibraryPlugin {\n readonly name: string\n readonly description: string\n /** Library plugins this one imports; they are copied with it. */\n readonly requires: readonly string[]\n /** npm packages an app needs at run time for this plugin. */\n readonly dependencies: Readonly<Record<string, string>>\n /** npm packages an app needs only to develop or run this plugin's tooling (for example `electron` for the desktop shell). */\n readonly devDependencies?: Readonly<Record<string, string>>\n /** `package.json` scripts the plugin adds; a script the app already has is kept. */\n readonly scripts?: Readonly<Record<string, string>>\n /** Lines the app's `.gitignore` needs for this plugin (added when missing, if the app has a `.gitignore`). */\n readonly gitignore?: readonly string[]\n /** The port's conformance suite, a path inside the plugin: shipped in the package, but copied into an app only by `acrylblends add <plugin> --suite` (it needs vitest). */\n readonly suite?: string\n /** What other library plugins may import from this one: the import name after the plugin's own (`''`, `/middleware`) and the file it stands for. Used to rewrite `acryl-*` imports when a plugin is copied. */\n readonly entries?: Readonly<Record<string, string>>\n /** `package.json` \"imports\" entries the app gets (`#acryl-kv`): a path below the plugins folder. A plugin of your own imports the port by that name, in tests and the type-check as well as when installed live. */\n readonly imports?: Readonly<Record<string, string>>\n /** How to mount it, shown after `acrylblends add`. */\n readonly mount?: string\n /**\n * Paths inside the plugin folder that are not copied into an app (for example a React hook an app without React cannot type-check, or colocated test\n * files). A pattern is an exact path or a glob: `*` matches within one folder name, `**` across folders, `?` one character; `**` followed by a slash also matches no folder.\n */\n readonly omit?: readonly string[]\n}\n\n/** A glob as a regular expression: `*` within a name, `**` across folders, `**` plus a slash may match no folder, `?` one character. */\nfunction globToRegExp(glob: string): RegExp {\n let source = ''\n for (let i = 0; i < glob.length; i += 1) {\n const c = glob[i] as string\n if (c === '*' && glob[i + 1] === '*') {\n if (glob[i + 2] === '/') {\n source += '(?:.*/)?'\n i += 2\n } else {\n source += '.*'\n i += 1\n }\n } else if (c === '*') source += '[^/]*'\n else if (c === '?') source += '[^/]'\n else source += c.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n }\n return new RegExp(`^${source}$`)\n}\n\n/** Whether a path inside a plugin folder (relative, any separator) is named by one of its `omit` patterns. */\nexport function isOmitted(inside: string, patterns: readonly string[] | undefined): boolean {\n if (!patterns || patterns.length === 0) return false\n const path = inside.split(sep).join('/')\n return patterns.some((pattern) =>\n /[*?]/.test(pattern) ? globToRegExp(pattern).test(path) : pattern === path,\n )\n}\n\n/** Files of a library plugin that stay in the repository: its manifest and its tests. */\nconst LIBRARY_ONLY = new Set(['plugin.json', 'test', 'tests'])\n\nexport class LibraryError extends Error {\n override name = 'LibraryError'\n}\n\n/** The library folder (`plugins/` at the repository root): walk up from this module, in source or in the build. */\nexport function libraryRoot(): string {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n const candidate = join(dir, 'plugins')\n if (existsSync(join(candidate, 'instance', 'plugin.json'))) return candidate\n const parent = dirname(dir)\n if (parent === dir)\n throw new LibraryError('acrylblends cannot find its plugin library (plugins/)')\n dir = parent\n }\n}\n\n/** Every plugin in the library, by name. */\nexport function readLibrary(root: string = libraryRoot()): Map<string, LibraryPlugin> {\n const plugins = new Map<string, LibraryPlugin>()\n for (const entry of readdirSync(root, { withFileTypes: true })) {\n const manifest = join(root, entry.name, 'plugin.json')\n if (!entry.isDirectory() || !existsSync(manifest)) continue\n const plugin = JSON.parse(readFileSync(manifest, 'utf8')) as LibraryPlugin\n if (plugin.name !== entry.name)\n throw new LibraryError(`plugins/${entry.name}/plugin.json names \"${plugin.name}\"`)\n plugins.set(plugin.name, {\n ...plugin,\n requires: plugin.requires ?? [],\n dependencies: plugin.dependencies ?? {},\n })\n }\n return plugins\n}\n\n/** The plugins to copy for `names`: each one after everything it requires, no duplicates. */\nexport function closure(\n names: readonly string[],\n library: Map<string, LibraryPlugin>,\n): LibraryPlugin[] {\n const ordered: LibraryPlugin[] = []\n const visiting = new Set<string>()\n const visit = (name: string, trail: string[]) => {\n if (ordered.some((plugin) => plugin.name === name)) return\n const plugin = library.get(name)\n if (!plugin)\n throw new LibraryError(\n `no plugin \"${name}\" in the library${trail.length ? ` (required by ${trail.at(-1)})` : ''}`,\n )\n if (visiting.has(name))\n throw new LibraryError(\n `plugins require each other in a cycle: ${[...trail, name].join(' -> ')}`,\n )\n visiting.add(name)\n for (const required of plugin.requires) visit(required, [...trail, name])\n visiting.delete(name)\n ordered.push(plugin)\n }\n for (const name of names) visit(name, [])\n return ordered\n}\n\n/** The one folder every plugin of an app lives in, library copies and the ones an agent writes. */\nexport const PLUGINS_DIR = 'plugins'\n/** Where apps made before 0.7.8 kept library copies; still understood for one release. */\nexport const LEGACY_PLUGINS_DIR = join('src', 'plugins')\n/** The list of library copies in the plugins folder; the extensions plugin installs every other folder there. */\nexport const LIBRARY_LIST = 'library.json'\n\n/** The plugins folder of an app: `plugins/`, or `src/plugins/` for an app that still has the old layout (and no `plugins/`). */\nexport function pluginsFolder(appDir: string): { dir: string; legacy: boolean } {\n const legacy =\n existsSync(join(appDir, LEGACY_PLUGINS_DIR)) && !existsSync(join(appDir, PLUGINS_DIR))\n return { dir: join(appDir, legacy ? LEGACY_PLUGINS_DIR : PLUGINS_DIR), legacy }\n}\n\n/** The warning for an app with the old layout. */\nexport const LEGACY_WARNING =\n 'warning: this app keeps its plugins in src/plugins/ (and extensions/); plugins now live in one folder, plugins/. Move them with \"git mv src/plugins plugins\", fix the paths in tsconfig.json, package.json and src/, and see docs/framework/agents/index.md. The old layout is read for this release only.'\n\n/** List `name` among the library copies of a plugins folder (`library.json`). */\nexport function recordLibraryCopy(folder: string, name: string): void {\n const file = join(folder, LIBRARY_LIST)\n const names: string[] = existsSync(file)\n ? (JSON.parse(readFileSync(file, 'utf8')) as { plugins: string[] }).plugins\n : []\n if (!names.includes(name)) names.push(name)\n writeFileSync(file, `${JSON.stringify({ plugins: names.sort() }, null, 2)}\\n`)\n}\n\n/** Copy one library plugin's source into `<app>/plugins/<name>/`. Throws when that folder already exists. */\nexport function copyPlugin(\n plugin: LibraryPlugin,\n appDir: string,\n root: string = libraryRoot(),\n): string {\n const folder = pluginsFolder(appDir)\n const target = join(folder.dir, plugin.name)\n if (existsSync(target))\n throw new LibraryError(\n `${relativeName(appDir, target)} already exists; remove it first to copy a fresh one`,\n )\n const source = join(root, plugin.name)\n // A framework package (it has a package.json in the repository) is copied as its source: `src/` and the licence; the package shipped by npm already holds only that. Its\n // `plugin.json` lists `entries`, and the imports of such a plugin are rewritten to relative paths, in the repository and in the installed package alike.\n const isPackage = existsSync(join(source, 'package.json'))\n const entries = plugin.entries === undefined ? undefined : entryTable(readLibrary(root))\n cpSync(source, target, {\n recursive: true,\n filter: (path) => {\n const inside = path\n .slice(source.length + 1)\n .split(sep)\n .join('/')\n if (\n isPackage &&\n inside !== '' &&\n inside !== 'LICENSE' &&\n inside !== 'src' &&\n !inside.startsWith('src/')\n )\n return false\n return (\n !(dirname(path) === source && LIBRARY_ONLY.has(inside)) &&\n !isOmitted(inside, plugin.omit) &&\n inside !== plugin.suite\n )\n },\n })\n if (entries) rewriteTree(join(target, 'src'), plugin.name, 'src', entries)\n if (!folder.legacy) {\n recordLibraryCopy(folder.dir, plugin.name)\n // The hashes of the files as copied: `acrylblends upgrade` tells an untouched file from an edited one by them.\n recordLock(folder.dir, plugin.name, hashFolder(target))\n }\n return target\n}\n\n/** Rewrite the `acryl-*` imports of every TypeScript file below `dir` (the plugin's `src/`) to relative paths. */\nfunction rewriteTree(dir: string, plugin: string, inside: string, entries: EntryTable): void {\n for (const entry of readdirSync(dir)) {\n const path = join(dir, entry)\n if (statSync(path).isDirectory()) rewriteTree(path, plugin, `${inside}/${entry}`, entries)\n else if (/\\.(?:ts|tsx|mts)$/u.test(entry))\n writeFileSync(\n path,\n rewriteSpecifiers(readFileSync(path, 'utf8'), `${plugin}/${inside}/${entry}`, entries),\n )\n }\n}\n\n/** Copy one file of a library plugin (a conformance suite) with its `acryl-*` imports rewritten, as `copyPlugin` does for the rest. */\nexport function copyRewritten(\n from: string,\n to: string,\n plugin: string,\n inside: string,\n root: string = libraryRoot(),\n): void {\n writeFileSync(\n to,\n rewriteSpecifiers(\n readFileSync(from, 'utf8'),\n `${plugin}/${inside}`,\n entryTable(readLibrary(root)),\n ),\n )\n}\n\nconst relativeName = (appDir: string, path: string) =>\n path\n .slice(appDir.length + 1)\n .split(sep)\n .join('/')\n","import {\n cpSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from 'node:fs'\nimport { join } from 'node:path'\nimport { VERSION } from './version'\n\n/** Thrown when the target directory exists and is not empty. Nothing has been written. */\nexport class TargetNotEmptyError extends Error {\n constructor(readonly target: string) {\n super(\n `refusing to write into \"${target}\": the directory is not empty. Choose an empty or new directory.`,\n )\n this.name = 'TargetNotEmptyError'\n }\n}\n\n/** A project name npm accepts: lower case letters, digits and dashes, starting with a letter. */\nexport function isValidName(name: string): boolean {\n return /^[a-z][a-z0-9-]*$/.test(name) && name.length <= 214\n}\n\n/** A valid default project name derived from a directory path. */\nexport function nameFrom(directory: string): string {\n const base = directory.split(/[\\\\/]/).filter(Boolean).pop() ?? ''\n const cleaned = base\n .toLowerCase()\n .replace(/[^a-z0-9-]+/g, '-')\n .replace(/^[^a-z]+/, '')\n .replace(/-+$/, '')\n return cleaned || 'my-app'\n}\n\n/** Refuse a target that exists and is not an empty directory. A missing target is fine: it is created. */\nexport function assertTargetFree(target: string): void {\n if (!existsSync(target)) return\n if (!statSync(target).isDirectory() || readdirSync(target).length > 0)\n throw new TargetNotEmptyError(target)\n}\n\n/**\n * Copy a template into `target`, replacing `__APP_NAME__` with `name` and `__ACRYLBLENDS_RANGE__` with the range of this release. Checks the target before writing anything.\n *\n * @returns the copied files, relative to `target`\n */\nexport function copyTemplate(source: string, target: string, name: string): string[] {\n assertTargetFree(target)\n mkdirSync(target, { recursive: true })\n const written: string[] = []\n const walk = (from: string, to: string, prefix: string) => {\n for (const entry of readdirSync(from, { withFileTypes: true })) {\n if (\n entry.name === 'node_modules' ||\n (prefix === '' &&\n (entry.name === TEMPLATE_MANIFEST ||\n entry.name === 'upstream.json' ||\n entry.name === 'AGENTS.md'))\n )\n continue\n const sourcePath = join(from, entry.name)\n // npm and git treat a file named .gitignore specially, so templates keep it as `gitignore` (and `dockerignore`).\n const targetName =\n prefix === '' && (entry.name === 'gitignore' || entry.name === 'dockerignore')\n ? `.${entry.name}`\n : entry.name\n const targetPath = join(to, targetName)\n if (entry.isDirectory()) {\n mkdirSync(targetPath, { recursive: true })\n walk(sourcePath, targetPath, `${prefix}${entry.name}/`)\n continue\n }\n const text = readFileSync(sourcePath, 'utf8')\n if (text.includes('__APP_NAME__') || text.includes('__ACRYLBLENDS_RANGE__'))\n writeFileSync(\n targetPath,\n text.replaceAll('__APP_NAME__', name).replaceAll('__ACRYLBLENDS_RANGE__', `^${VERSION}`),\n )\n else cpSync(sourcePath, targetPath)\n written.push(`${prefix}${targetName}`)\n }\n }\n walk(source, target, '')\n return written\n}\n\n/** A template's own manifest, `template.json`: the library plugins it is built from. Never copied (nor is `upstream.json`, the record of what was synced from ACRYL, nor the template's `AGENTS.md`, which `writeAgentFiles` joins to the shared core). */\nexport const TEMPLATE_MANIFEST = 'template.json'\n\n/** The address a template's desktop window opens on, when it is not the root (`template.json`: `desktopPath`). */\nexport function readTemplateDesktopPath(templateDir: string): string | undefined {\n const file = join(templateDir, TEMPLATE_MANIFEST)\n if (!existsSync(file)) return undefined\n return (JSON.parse(readFileSync(file, 'utf8')) as { desktopPath?: string }).desktopPath\n}\n\n/** Record where the desktop window opens in package.json (`acrylblends.desktopPath`), read by `plugins/desktop/main.ts`. */\nexport function writeDesktopPath(appDir: string, path: string): void {\n const file = join(appDir, 'package.json')\n const manifest = JSON.parse(readFileSync(file, 'utf8')) as {\n acrylblends?: Record<string, unknown>\n }\n manifest.acrylblends = { ...manifest.acrylblends, desktopPath: path }\n writeFileSync(file, `${JSON.stringify(manifest, null, 2)}\\n`)\n}\n\nexport function readTemplatePlugins(templateDir: string): string[] {\n const file = join(templateDir, TEMPLATE_MANIFEST)\n if (!existsSync(file)) return []\n const { plugins } = JSON.parse(readFileSync(file, 'utf8')) as { plugins?: string[] }\n return plugins ?? []\n}\n\n/** Add run-time dependencies to an app's package.json, keeping what is there and sorting the keys. Returns the names added. */\nexport function mergeDependencies(\n appDir: string,\n dependencies: Readonly<Record<string, string>>,\n): string[] {\n const file = join(appDir, 'package.json')\n const manifest = JSON.parse(readFileSync(file, 'utf8')) as {\n dependencies?: Record<string, string>\n }\n const current = manifest.dependencies ?? {}\n const added = Object.keys(dependencies).filter((name) => !(name in current))\n const merged = { ...dependencies, ...current }\n manifest.dependencies = Object.fromEntries(\n Object.entries(merged).sort(([a], [b]) => a.localeCompare(b)),\n )\n writeFileSync(file, `${JSON.stringify(manifest, null, 2)}\\n`)\n return added\n}\n\n/** Add `package.json` \"imports\" entries (`#acryl-kv`: `./plugins/acryl-kv/src/index.ts`); an entry the app already has is kept. Returns the names added. */\nexport function mergeImports(\n appDir: string,\n imports: Readonly<Record<string, string>>,\n pluginsDir: string,\n): string[] {\n const file = join(appDir, 'package.json')\n const manifest = JSON.parse(readFileSync(file, 'utf8')) as { imports?: Record<string, string> }\n const current = manifest.imports ?? {}\n const added = Object.keys(imports).filter((name) => !(name in current))\n manifest.imports = {\n ...Object.fromEntries(\n Object.entries(imports).map(([name, path]) => [name, `./${pluginsDir}/${path}`]),\n ),\n ...current,\n }\n writeFileSync(file, `${JSON.stringify(manifest, null, 2)}\\n`)\n return added\n}\n\n/** Declare a file as an opener in package.json (`\"acryl\": { \"opener\": [...] }`): the one place that may import a database provider. */\nexport function mergeOpener(appDir: string, opener: string): void {\n const file = join(appDir, 'package.json')\n const manifest = JSON.parse(readFileSync(file, 'utf8')) as {\n acryl?: { opener?: string | string[] }\n }\n const current = manifest.acryl?.opener\n const list = typeof current === 'string' ? [current] : (current ?? [])\n if (list.includes(opener)) return\n manifest.acryl = { ...manifest.acryl, opener: [...list, opener] }\n writeFileSync(file, `${JSON.stringify(manifest, null, 2)}\\n`)\n}\n\n/**\n * Add a plugin's development dependencies and scripts to an app's package.json: nothing the app already has is replaced. Returns the names of the development dependencies\n * and scripts added.\n */\nexport function mergeTooling(\n appDir: string,\n tooling: {\n devDependencies?: Readonly<Record<string, string>> | undefined\n scripts?: Readonly<Record<string, string>> | undefined\n },\n): { devDependencies: string[]; scripts: string[] } {\n const file = join(appDir, 'package.json')\n const manifest = JSON.parse(readFileSync(file, 'utf8')) as {\n devDependencies?: Record<string, string>\n scripts?: Record<string, string>\n }\n const dev = manifest.devDependencies ?? {}\n const scripts = manifest.scripts ?? {}\n const addedDev = Object.keys(tooling.devDependencies ?? {}).filter((name) => !(name in dev))\n const addedScripts = Object.keys(tooling.scripts ?? {}).filter((name) => !(name in scripts))\n manifest.devDependencies = Object.fromEntries(\n Object.entries({ ...tooling.devDependencies, ...dev }).sort(([a], [b]) => a.localeCompare(b)),\n )\n manifest.scripts = { ...tooling.scripts, ...scripts }\n writeFileSync(file, `${JSON.stringify(manifest, null, 2)}\\n`)\n return { devDependencies: addedDev, scripts: addedScripts }\n}\n\n/** What an app runs before `dev`, `start`, `test` and `check`: refuses a Node too old to run it, in plain words, before anything that would fail confusingly (a plain CommonJS file, so any Node can read it). */\nconst CHECK_NODE = `// Refuses a Node that is too old to run this app, before the command that would fail on it. Plain CommonJS so that any Node can read it.\nconst [major, minor] = process.versions.node.split('.').map(Number)\nif (major < 22 || (major === 22 && minor < 19)) {\n console.error(\n \\`Node 22.19+ needed, you have \\${process.versions.node}: install it from https://nodejs.org or with nvm (nvm install 22), then run this again.\\`,\n )\n process.exit(1)\n}\n`\n\n/** Write \\`scripts/check-node.cjs\\` and run it before the app's \\`dev\\`, \\`start\\`, \\`test\\` and \\`check\\` scripts (npm and pnpm run \\`pre<script>\\` first). Existing \\`pre*\\` scripts are kept. */\nexport function addNodePreflight(appDir: string): void {\n mkdirSync(join(appDir, 'scripts'), { recursive: true })\n writeFileSync(join(appDir, 'scripts', 'check-node.cjs'), CHECK_NODE)\n const file = join(appDir, 'package.json')\n const manifest = JSON.parse(readFileSync(file, 'utf8')) as { scripts?: Record<string, string> }\n const scripts = manifest.scripts ?? {}\n for (const name of ['dev', 'start', 'test', 'check'])\n if (name in scripts && !(`pre${name}` in scripts))\n scripts[`pre${name}`] = 'node scripts/check-node.cjs'\n manifest.scripts = scripts\n writeFileSync(file, `${JSON.stringify(manifest, null, 2)}\\n`)\n}\n\n/** Add the lines a plugin needs to the app's \\`.gitignore\\` when it has one and they are missing. Returns the lines added. */\nexport function appendGitignore(appDir: string, lines: readonly string[] | undefined): string[] {\n const file = join(appDir, '.gitignore')\n if (!lines || lines.length === 0 || !existsSync(file)) return []\n const current = readFileSync(file, 'utf8')\n const present = new Set(current.split('\\n').map((line) => line.trim()))\n const missing = lines.filter((line) => !present.has(line))\n if (missing.length > 0)\n writeFileSync(\n file,\n `${current}${current.endsWith('\\n') || current === '' ? '' : '\\n'}${missing.join('\\n')}\\n`,\n )\n return missing\n}\n\n/** The generated app's guide for a coding agent: the shared core, then the template's own part. `CLAUDE.md` is only an import of it. */\nexport function writeAgentFiles(\n sharedDir: string,\n templateDir: string,\n target: string,\n name: string,\n): string[] {\n const core = readFileSync(join(sharedDir, 'AGENTS.core.md'), 'utf8')\n const own = existsSync(join(templateDir, 'AGENTS.md'))\n ? readFileSync(join(templateDir, 'AGENTS.md'), 'utf8')\n : ''\n const defaults = readFileSync(join(sharedDir, 'DEFAULTS.md'), 'utf8')\n const text = `${core}${defaults}${own}`.replaceAll('__APP_NAME__', name)\n // AGENTS.md and CLAUDE.md are the same text; the one skill is written where each kind of agent looks for skills.\n writeFileSync(join(target, 'AGENTS.md'), text)\n writeFileSync(join(target, 'CLAUDE.md'), text)\n const skill = readFileSync(join(sharedDir, 'SKILL.md'), 'utf8').replaceAll('__APP_NAME__', name)\n const written = ['AGENTS.md', 'CLAUDE.md']\n for (const folder of ['.claude/skills/app-guide', '.agents/skills/app-guide']) {\n mkdirSync(join(target, folder), { recursive: true })\n writeFileSync(join(target, folder, 'SKILL.md'), skill)\n written.push(`${folder}/SKILL.md`)\n }\n return written\n}\n\n/**\n * Copy the framework's docs (a generated copy of ACRYL's `docs/framework`, already checked against its digest) into `<app>/docs/framework/`,\n * so a coding agent working in the app reads the API from the folder it is in. The generated-copy notes and the digest record stay behind.\n *\n * @returns the copied files, relative to `target`\n */\nexport function copyFrameworkDocs(source: string, target: string): string[] {\n const written: string[] = []\n const walk = (from: string, to: string, prefix: string) => {\n for (const entry of readdirSync(from, { withFileTypes: true })) {\n if (entry.name === 'upstream.json' || entry.name === 'UPSTREAM.md') continue\n const sourcePath = join(from, entry.name)\n const targetPath = join(to, entry.name)\n if (entry.isDirectory()) {\n mkdirSync(targetPath, { recursive: true })\n walk(sourcePath, targetPath, `${prefix}${entry.name}/`)\n continue\n }\n cpSync(sourcePath, targetPath)\n written.push(`docs/framework/${prefix}${entry.name}`)\n }\n }\n mkdirSync(join(target, 'docs', 'framework'), { recursive: true })\n walk(source, join(target, 'docs', 'framework'), '')\n return written\n}\n","import { resolve } from 'node:path'\nimport { parseArgs } from 'node:util'\nimport type { Io } from './io'\nimport { closure, copyPlugin, readLibrary } from './library'\nimport {\n addNodePreflight,\n copyFrameworkDocs,\n copyTemplate,\n isValidName,\n mergeDependencies,\n mergeImports,\n mergeTooling,\n nameFrom,\n readTemplateDesktopPath,\n readTemplatePlugins,\n TargetNotEmptyError,\n writeAgentFiles,\n writeDesktopPath,\n} from './project'\nimport {\n frameworkDocsRoot,\n resolveTemplate,\n sharedDir,\n TEMPLATE_SUMMARY,\n TEMPLATES,\n type Template,\n templateDir,\n} from './templates'\n\n/** A command line mistake. The CLI prints it with the help text and exits 2. */\nexport class UsageError extends Error {\n override name = 'UsageError'\n}\n\n/** What `init` was asked for. Anything left undefined is asked for on a terminal, or defaulted. */\nexport interface InitOptions {\n directory: string | undefined\n name: string | undefined\n template: Template | undefined\n install: boolean | undefined\n /** Also add the desktop shell (`add desktop`): an Electron window on the app's own server. */\n desktop: boolean\n /** Print no \"Next:\" block: `create-acrylblends` runs `init` and prints its own, for the package manager it knows. */\n quietNext: boolean\n yes: boolean\n}\n\n/** Parse `init [dir] [--template t] [--agent|--no-agent] [--name n] [--install] [-y]`. `--agent` means `--template agent`, `--no-agent` means `--template blank`. */\nexport function parseInitOptions(argv: readonly string[]): InitOptions {\n let parsed: ReturnType<typeof parse>\n try {\n parsed = parse(argv)\n } catch (error) {\n throw new UsageError((error as Error).message)\n }\n const { values, positionals } = parsed\n if (positionals.length > 1) throw new UsageError('init takes at most one directory')\n if (values.agent && values['no-agent'])\n throw new UsageError('use --agent or --no-agent, not both')\n const named = values.template === undefined ? undefined : resolveTemplate(values.template)\n if (values.template !== undefined && named === undefined)\n throw new UsageError(`unknown template \"${values.template}\" (${TEMPLATES.join(', ')})`)\n const alias: Template | undefined = values.agent\n ? 'agent'\n : values['no-agent']\n ? 'blank'\n : undefined\n if (named !== undefined && alias !== undefined && named !== alias)\n throw new UsageError(\n `--template ${values.template} contradicts --${alias === 'agent' ? 'agent' : 'no-agent'}`,\n )\n return {\n directory: positionals[0],\n name: values.name,\n template: named ?? alias,\n install: values.install,\n desktop: values.desktop === true,\n quietNext: values['no-next'] === true,\n yes: values.yes === true,\n }\n}\n\nconst parse = (argv: readonly string[]) =>\n parseArgs({\n args: [...argv],\n allowPositionals: true,\n strict: true,\n options: {\n name: { type: 'string' },\n template: { type: 'string' },\n agent: { type: 'boolean' },\n 'no-agent': { type: 'boolean' },\n install: { type: 'boolean' },\n desktop: { type: 'boolean' },\n 'no-next': { type: 'boolean' },\n yes: { type: 'boolean', short: 'y' },\n },\n })\n\nconst yes = (answer: string) => ['y', 'yes'].includes(answer.trim().toLowerCase())\n\nasync function askTemplate(ask: (question: string) => Promise<string>): Promise<Template> {\n const answer = (\n await ask(\n `Templates:\\n${TEMPLATES.map((name) => ` ${name.padEnd(7)} ${TEMPLATE_SUMMARY[name]}`).join('\\n')}\\nTemplate [blank]: `,\n )\n )\n .trim()\n .toLowerCase()\n if (answer === '') return 'blank'\n const chosen = resolveTemplate(answer)\n if (chosen !== undefined) return chosen\n throw new UsageError(`unknown template \"${answer}\" (${TEMPLATES.join(', ')})`)\n}\n\n/** Scaffold a Cordis app. Returns the exit code: 0 done, 1 refused or failed. Never overwrites anything. */\nexport async function init(options: InitOptions, io: Io): Promise<number> {\n const relative = options.directory ?? '.'\n const directory = resolve(io.cwd, relative)\n const ask = options.yes ? undefined : io.ask\n\n let name = options.name ?? nameFrom(directory)\n if (options.name === undefined && ask)\n name = (await ask(`Project name (${name}): `)).trim() || name\n if (!isValidName(name)) {\n throw new UsageError(\n `\"${name}\" is not a valid project name (lower case letters, digits and dashes, starting with a letter)`,\n )\n }\n const template = options.template ?? (ask ? await askTemplate(ask) : 'blank')\n const install =\n options.install ?? (ask ? yes(await ask('Install dependencies with npm now? (y/N): ')) : false)\n\n let files: string[]\n try {\n files = copyTemplate(templateDir(template), directory, name)\n files.push(...writeAgentFiles(sharedDir(), templateDir(template), directory, name))\n files.push(...copyFrameworkDocs(frameworkDocsRoot(), directory))\n } catch (error) {\n if (!(error instanceof TargetNotEmptyError)) throw error\n io.stderr.write(`error: ${error.message}\\n`)\n return 1\n }\n const own = closure(readTemplatePlugins(templateDir(template)), readLibrary())\n const plugins = options.desktop\n ? closure([...own.map((plugin) => plugin.name), 'desktop'], readLibrary())\n : own\n // What only the desktop shell brought (and needs), named apart so the list does not read as if the web app had asked for it.\n const forDesktop = plugins.filter((plugin) => !own.some((owned) => owned.name === plugin.name))\n for (const plugin of plugins) {\n copyPlugin(plugin, directory)\n if (plugin.imports) mergeImports(directory, plugin.imports, 'plugins')\n mergeDependencies(directory, plugin.dependencies)\n mergeTooling(directory, plugin)\n }\n addNodePreflight(directory)\n const desktopPath = options.desktop ? readTemplateDesktopPath(templateDir(template)) : undefined\n if (desktopPath !== undefined) writeDesktopPath(directory, desktopPath)\n io.stdout.write(\n `created ${name} (${template}) in ${directory}: ${files.length} files, plugins ${own.map((plugin) => plugin.name).join(', ')}${forDesktop.length > 0 ? `; the desktop shell adds ${forDesktop.map((plugin) => plugin.name).join(', ')}, which it needs` : ''}\\n`,\n )\n\n if (install && (await io.install(directory)) !== 0) {\n io.stderr.write('error: npm install failed; run it yourself in the new directory\\n')\n return 1\n }\n const steps = [\n relative === '.' ? '' : ` cd ${relative}\\n`,\n install ? '' : ' npm install\\n',\n ' npm run dev\\n npm test\\n',\n ]\n if (!options.quietNext) io.stdout.write(`\\nNext:\\n${steps.join('')}`)\n return 0\n}\n","import { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\n\n/**\n * Plugins that `acrylblends add` mounts itself: a row in `blend.yaml` (after the row it needs, before the `routes` row) and an entry in the `registry` of `src/app.ts`.\n * `needs` are the rows the plugin cannot run without; an app that lacks them is refused before anything is copied.\n */\nexport interface Mounted {\n readonly name: string\n /** The identifier of the registry import, and the plugin names (the `name:` of a row) it needs. */\n readonly local: string\n readonly needs: readonly string[]\n /** The row this one goes after (it goes before `routes` otherwise). */\n readonly after?: string\n /** The `id:` of its row, when it is not the plugin's name (`db` for acryl-db-sqlite). */\n readonly row?: string\n /** Its entry file inside the plugin's folder (`index.ts`, or `src/index.ts` for the plugins that keep their source in `src/`). */\n readonly entry?: string\n}\n\nexport const MOUNTED: readonly Mounted[] = [\n { name: 'agent-panel', local: 'panel', needs: ['agent', 'extensions'] },\n { name: 'driver-pty', local: 'driverPty', needs: ['agent-panel'], after: 'agent-panel' },\n { name: 'driver-acp', local: 'driverAcp', needs: ['agent-panel'], after: 'agent-panel' },\n]\n\nconst ROW = /^( *)- id: ?(\\S+)\\n\\1 {2}name: ?(\\S+)\\n/gmu\n\n/** The `name:` of every row of the app's `blend.yaml`, or `undefined` when it has none. */\nexport function rowNames(appDir: string): string[] | undefined {\n const file = join(appDir, 'blend.yaml')\n if (!existsSync(file)) return undefined\n return [...readFileSync(file, 'utf8').matchAll(ROW)].map((match) => match[3] as string)\n}\n\n/** What a plugin to be mounted is missing: the rows it needs that neither the app nor this same command brings. */\nexport function missingRows(\n appDir: string,\n plugin: Mounted,\n alsoAdded: readonly string[],\n): string[] {\n const have = rowNames(appDir) ?? []\n return plugin.needs.filter((need) => !have.includes(need) && !alsoAdded.includes(need))\n}\n\nexport interface MountResult {\n readonly done: boolean\n /** What was edited, or why it was not (the person finishes by hand). */\n readonly note: string\n}\n\n/** Add the row to `blend.yaml` and the entry to `src/app.ts`; each only when it is not there yet and its place is where the template puts it. */\nexport function mount(appDir: string, plugin: Mounted): MountResult {\n const done: string[] = []\n const failed: string[] = []\n const manifestFile = join(appDir, 'blend.yaml')\n if (existsSync(manifestFile)) {\n let text = readFileSync(manifestFile, 'utf8')\n if ([...text.matchAll(ROW)].some((match) => match[3] === plugin.name))\n done.push('blend.yaml (already has the row)')\n else {\n const anchor = plugin.after\n ? new RegExp(\n `^( *)- id: ?\\\\S+\\\\n\\\\1 {2}name: ?${plugin.after}\\\\n(?:\\\\1 {2}config:\\\\n(?:\\\\1 {4}.*\\\\n|\\\\1 {2}\\\\s*\\\\n)*)?`,\n 'mu',\n )\n : /^( *)- id: ?routes\\n/mu\n const found = anchor.exec(text)\n if (found) {\n const indent = found[1] as string\n const row = `${indent}- id: ${plugin.row ?? plugin.name}\\n${indent} name: ${plugin.name}\\n`\n const at = plugin.after ? found.index + found[0].length : found.index\n text = text.slice(0, at) + row + text.slice(at)\n writeFileSync(manifestFile, text)\n done.push(`blend.yaml (row ${plugin.name})`)\n } else\n failed.push(\n `blend.yaml: add a row \\`- id: ${plugin.name}\\` / \\`name: ${plugin.name}\\` ${plugin.after ? `after the ${plugin.after} row` : 'before the `routes` row'}`,\n )\n }\n }\n const appFile = join(appDir, 'src', 'app.ts')\n if (existsSync(appFile)) {\n let text = readFileSync(appFile, 'utf8')\n const entry = `'${plugin.name}': ${plugin.local}`\n if (text.includes(entry)) done.push('src/app.ts (already registered)')\n else {\n const imports = [...text.matchAll(/^import .* from '\\.\\.\\/plugins\\/[^']+'\\n/gmu)]\n const last = imports.at(-1)\n // The registry as the templates write it: one entry per line, or all on one line (`{ 'acryl-router': router, routes }`).\n const table = /^export const registry = \\{(\\s)/mu.exec(text)\n if (last && table) {\n const file = plugin.entry ?? 'index.ts'\n const line = `import * as ${plugin.local} from '../plugins/${plugin.name}/${file}'\\n`\n const at = table.index + table[0].length\n text =\n text.slice(0, at) + (table[1] === '\\n' ? ` ${entry},\\n` : `${entry}, `) + text.slice(at)\n const lastEnd = last.index + last[0].length\n text = text.slice(0, lastEnd) + line + text.slice(lastEnd)\n writeFileSync(appFile, text)\n done.push(`src/app.ts (registered as ${plugin.local})`)\n } else\n failed.push(\n `src/app.ts: import it as \\`${plugin.local}\\` from '../plugins/${plugin.name}/${plugin.entry ?? 'index.ts'}' and add \\`${entry}\\` to the registry`,\n )\n }\n } else failed.push(`src/app.ts: not found; register ${entry(plugin)} in the app's registry`)\n return {\n done: failed.length === 0,\n note: [\n done.length > 0 ? `mounted in ${done.join(' and ')}` : '',\n ...failed.map((line) => `could not edit ${line}`),\n ]\n .filter(Boolean)\n .join('\\n'),\n }\n}\n\nconst entry = (plugin: Mounted) => `'${plugin.name}': ${plugin.local}`\n","import { cpSync, existsSync, mkdirSync, readFileSync, statSync } from 'node:fs'\nimport { basename, dirname, join, relative, resolve, sep } from 'node:path'\nimport { parseArgs } from 'node:util'\nimport { UsageError } from './init'\nimport type { Io } from './io'\nimport {\n closure,\n copyPlugin,\n copyRewritten,\n LEGACY_WARNING,\n type LibraryPlugin,\n libraryRoot,\n PLUGINS_DIR,\n pluginsFolder,\n readLibrary,\n} from './library'\nimport { MOUNTED, type Mounted, missingRows, mount, rowNames } from './mount'\nimport {\n appendGitignore,\n mergeDependencies,\n mergeImports,\n mergeOpener,\n mergeTooling,\n} from './project'\n\nexport interface AddOptions {\n readonly names: readonly string[]\n readonly directory: string | undefined\n /** Also copy the port's conformance suite (`src/conformance.ts`) and the `vitest` it runs on: what a provider of your own must pass. */\n readonly suite: boolean\n}\n\n/** Parse `add <plugin...> [--dir <app>] [--suite]`. */\nexport function parseAddOptions(argv: readonly string[]): AddOptions {\n let parsed: ReturnType<typeof parse>\n try {\n parsed = parse(argv)\n } catch (error) {\n throw new UsageError((error as Error).message)\n }\n if (parsed.positionals.length === 0)\n throw new UsageError('add needs at least one plugin name (see \"acrylblends plugins\")')\n return {\n names: parsed.positionals,\n directory: parsed.values.dir,\n suite: parsed.values.suite === true,\n }\n}\n\nconst parse = (argv: readonly string[]) =>\n parseArgs({\n args: [...argv],\n allowPositionals: true,\n strict: true,\n options: { dir: { type: 'string' }, suite: { type: 'boolean' } },\n })\n\nconst present = (appDir: string, name: string) => existsSync(join(pluginsFolder(appDir).dir, name))\n\n/**\n * Copy library plugins into an existing app, with the plugins they require, and add their npm packages to its package.json.\n * Refuses a plugin the app already has. Returns the exit code.\n */\nexport async function add(options: AddOptions, io: Io): Promise<number> {\n const appDir = resolve(io.cwd, options.directory ?? '.')\n if (!existsSync(join(appDir, 'package.json')) || !existsSync(join(appDir, 'src'))) {\n io.stderr.write(\n `error: ${appDir} is not an app (no package.json and src/); run \"acrylblends init\" first\\n`,\n )\n return 1\n }\n if (pluginsFolder(appDir).legacy) io.stderr.write(`${LEGACY_WARNING}\\n`)\n // A path is an external plugin folder; anything else is a library plugin name.\n const external = options.names.filter((name) => /[\\\\/]/.test(name) || name.startsWith('.'))\n for (const folder of external) {\n const code = addExternal(resolve(io.cwd, folder), appDir, io)\n if (code !== 0) return code\n }\n // The desktop shell has two forms: the Blend app (it needs the `instance` plugin) and a plain Acryl app (`export default app`); `desktop` means the one that fits.\n const plain = !existsSync(join(pluginsFolder(appDir).dir, 'instance'))\n if (plain && options.names.includes('db')) {\n io.stderr.write(\n 'error: \"db\" is the Cordis plugin for a Blend app. A plain Acryl app opens its database with openDb from \"acrylblends/db/sqlite\" (see docs/framework/guides/data.md)\\n',\n )\n return 1\n }\n if (plain && options.names.includes('kv')) {\n io.stderr.write(\n 'error: \"kv\" is the Cordis plugin for a Blend app. A plain Acryl app opens its store with openKv from \"acrylblends/kv/json\" (see docs/framework/guides/data.md#a-tiny-app-kv)\\n',\n )\n return 1\n }\n const names = options.names\n .filter((name) => !external.includes(name))\n // `db` is the SQLite provider of the db port (it brings the port); a plain app opens its database with `acrylblends/db/sqlite` instead.\n .map((name) => (name === 'db' ? 'acryl-db-sqlite' : name))\n // `kv` is the JSON-file provider of the kv port (it brings the port); `acryl-kv-db` is the one over db.\n .map((name) => (name === 'kv' ? 'acryl-kv-json' : name))\n .map((name) => (name === 'desktop' && plain ? 'desktop-web' : name))\n if (names.length === 0) return 0\n const already = options.suite ? [] : names.filter((name) => present(appDir, name))\n if (already.length > 0) {\n io.stderr.write(\n `error: the app already has ${already\n .map(\n (name) =>\n `${relative(appDir, join(pluginsFolder(appDir).dir, name))\n .split(sep)\n .join('/')}`,\n )\n .join(', ')}\\n`,\n )\n return 1\n }\n // The agent panel and the PTY driver cannot run without the rows of the agent template: refuse before anything is copied, and say exactly what is missing.\n const mounting = MOUNTED.filter((plugin) => names.includes(plugin.name))\n for (const plugin of mounting) {\n const missing = missingRows(appDir, plugin, names)\n if (missing.length > 0) {\n io.stderr.write(\n `error: ${plugin.name} needs the ${missing.map((row) => `\\`${row}\\``).join(' and ')} ${missing.length === 1 ? 'row' : 'rows'} in blend.yaml, and this app has ${describeRows(appDir)}. ` +\n `${plugin.name === 'driver-pty' ? 'Add agent-panel first (acrylblends add agent-panel driver-pty), which needs the agent template. ' : ''}` +\n `The rows come with the agent template: start from it (npm create acrylblends@latest my-app agent) and add ${plugin.name} there. Nothing was changed.\\n`,\n )\n return 1\n }\n }\n const toCopy: LibraryPlugin[] = closure(names, readLibrary()).filter(\n (plugin) => !present(appDir, plugin.name),\n )\n const addedDependencies: string[] = []\n for (const plugin of toCopy) {\n copyPlugin(plugin, appDir)\n if (plugin.imports)\n mergeImports(\n appDir,\n plugin.imports,\n relative(appDir, pluginsFolder(appDir).dir).split(sep).join('/'),\n )\n addedDependencies.push(...mergeDependencies(appDir, plugin.dependencies))\n const tooling = mergeTooling(appDir, plugin)\n appendGitignore(appDir, plugin.gitignore)\n // The provider is mounted from src/app.ts, which is therefore the one file that may import it (`acrylblends check-deps`).\n if (plugin.name === 'acryl-db-sqlite') mergeOpener(appDir, 'src/app.ts')\n addedDependencies.push(...tooling.devDependencies)\n if (tooling.scripts.length > 0)\n io.stdout.write(\n `new scripts: ${tooling.scripts.map((name) => `npm run ${name}`).join(', ')}\\n`,\n )\n }\n if (options.suite) {\n const refused = copySuites(names, appDir, addedDependencies, io)\n if (refused !== 0) return refused\n }\n io.stdout.write(`added ${toCopy.map((plugin) => plugin.name).join(', ')} to ${appDir}\\n`)\n if (addedDependencies.length > 0)\n io.stdout.write(`new dependencies: ${addedDependencies.join(', ')} (run npm install)\\n`)\n for (const plugin of toCopy.filter((plugin) => names.includes(plugin.name))) {\n const mounted = MOUNTED.find((candidate) => candidate.name === plugin.name)\n const result = mounted ? mount(appDir, mounted) : undefined\n io.stdout.write(\n `\\n${plugin.name}: ${result?.done ? `${result.note}${extraNote(mounted)}` : `${result ? `${result.note}\\n` : ''}${plugin.mount ?? `import it from '../plugins/${plugin.name}/index.ts' and mount it in src/app.ts`}`}\\n`,\n )\n }\n return 0\n}\n\n/** What an app has to say about its rows, for an error: the `name:` of each, or that it has no blend.yaml. */\nfunction describeRows(appDir: string): string {\n const rows = rowNames(appDir)\n return rows === undefined ? 'no blend.yaml' : `the rows ${rows.join(', ') || '(none)'}`\n}\n\n/** What to do after `npm install` for a plugin that needs more than the install: node-pty compiles a native module in an install script, which npm 11 and pnpm skip until approved. */\nfunction extraNote(plugin: Mounted | undefined): string {\n return plugin?.name === 'driver-pty'\n ? \"\\nnpm 11 and pnpm warn that node-pty's install script was not run, because they ask you to approve dependency install scripts. node-pty ships prebuilt binaries for macOS, Windows and Linux (x64, arm64), so you can usually ignore the warning. If the panel lists no `pty:` terminal (the app prints why at start), approve it and rebuild: `npm approve-scripts node-pty`, then `npm rebuild node-pty` (pnpm: `pnpm approve-builds`).\"\n : ''\n}\n\n/**\n * The vitest the suites run on. 3.2.x, not the newest: npm 10 (the npm of Node 22) crashes on the dependency tree of vitest 4 and 5 (\"Cannot read properties of null (reading\n * 'edgesOut')\"), and the suites use only `describe`, `it` and `expect`, which are the same in all of them. An app on a newer npm may raise it.\n */\nconst SUITE_RUNNER = { vitest: '3.2.4' }\n\n/**\n * Copy the conformance suite of each named port next to its source (`plugins/<name>/src/conformance.ts`), and add `vitest` to the app's development\n * dependencies. The suite is left out of a normal copy because an app that only uses a port has no use for it. Returns the exit code: 1 when a plugin has none.\n */\nfunction copySuites(names: readonly string[], appDir: string, added: string[], io: Io): number {\n const copies: Array<{ from: string; to: string }> = []\n // The suite belongs to the port: `add kv --suite` (acryl-kv-json, or acryl-kv-db) brings the suite of acryl-kv.\n const ports = [\n ...new Set(names.map((name) => name.replace(/^(acryl-(?:kv|db))(?:-.*)?$/u, '$1'))),\n ]\n const library = readLibrary()\n for (const name of ports) {\n const suite = library.get(name)?.suite\n const from = suite === undefined ? '' : join(libraryRoot(), name, suite)\n if (suite === undefined || !existsSync(from)) {\n io.stderr.write(`error: ${name} has no conformance suite (the ports db and kv do)\\n`)\n return 1\n }\n copies.push({ from, to: join(pluginsFolder(appDir).dir, name, suite) })\n }\n for (const { from, to } of copies) {\n mkdirSync(dirname(to), { recursive: true })\n copyRewritten(from, to, pluginOf(to), suiteOf(to))\n io.stdout.write(`added the conformance suite ${relative(appDir, to).split(sep).join('/')}\\n`)\n }\n added.push(...mergeTooling(appDir, { devDependencies: SUITE_RUNNER }).devDependencies)\n return 0\n}\n\n/** The plugin folder name and the file inside it, from a path below the plugins folder (`.../plugins/acryl-kv/src/conformance.ts`). */\nconst pluginOf = (path: string): string => path.split(sep).slice(-3, -2)[0] ?? ''\nconst suiteOf = (path: string): string => path.split(sep).slice(-2).join('/')\n\nconst PLUGIN_NAME = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/\n\n/**\n * Bring an external plugin folder (a package made with the builder's package_plugin, or any folder with an index.ts that exports a\n * Cordis plugin) into the app's `plugins/`, where the extensions plugin installs it like any other: checked, staged, started,\n * verified. Its runtime dependencies are not installed here; they are reported so the user adds them deliberately.\n */\nfunction addExternal(folder: string, appDir: string, io: Io): number {\n if (!existsSync(folder) || !statSync(folder).isDirectory()) {\n io.stderr.write(`error: ${folder} is not a folder\\n`)\n return 1\n }\n if (!['index.ts', 'index.js', 'index.mjs'].some((entry) => existsSync(join(folder, entry)))) {\n io.stderr.write(`error: ${folder} has no index.ts that exports a Cordis plugin\\n`)\n return 1\n }\n const manifestFile = join(folder, 'package.json')\n const manifest = existsSync(manifestFile)\n ? (JSON.parse(readFileSync(manifestFile, 'utf8')) as {\n name?: string\n dependencies?: Record<string, string>\n })\n : {}\n const name = (manifest.name ?? basename(folder)).replace(/^@[^/]+\\//, '')\n if (!PLUGIN_NAME.test(name)) {\n io.stderr.write(\n `error: \"${name}\" is not a plugin name (lowercase letters, digits and dashes)\\n`,\n )\n return 1\n }\n const target = join(\n pluginsFolder(appDir).legacy ? join(appDir, 'extensions') : join(appDir, PLUGINS_DIR),\n name,\n )\n if (existsSync(target)) {\n io.stderr.write(`error: the app already has ${relative(appDir, target).split(sep).join('/')}\\n`)\n return 1\n }\n cpSync(folder, target, {\n recursive: true,\n filter: (path) => !/[\\\\/](node_modules|\\.git)([\\\\/]|$)/.test(path.slice(folder.length)),\n })\n io.stdout.write(\n `added external plugin ${name} to ${dirname(target)}; it installs at the next start\\n`,\n )\n const dependencies = Object.keys(manifest.dependencies ?? {})\n if (dependencies.length > 0)\n io.stdout.write(\n `it uses ${dependencies.join(', ')}: add them to the app with npm install first\\n`,\n )\n return 0\n}\n\n/** `acrylblends plugins`: the library, one line per plugin. */\nexport function listPlugins(io: Io): number {\n for (const plugin of readLibrary().values()) {\n const requires = plugin.requires.length > 0 ? ` (requires ${plugin.requires.join(', ')})` : ''\n io.stdout.write(`${plugin.name.padEnd(12)} ${plugin.description}${requires}\\n`)\n }\n return 0\n}\n","import { existsSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { relative, resolve } from 'node:path'\nimport { UsageError } from './init'\nimport type { Io } from './io'\n\n/** Parse `build-client [root] [outDir]`. */\nexport function parseBuildClientOptions(argv: readonly string[]): { root: string; outDir: string } {\n const args = argv.filter((a) => !a.startsWith('-'))\n if (args.length !== argv.length)\n throw new UsageError('build-client takes [root] [outDir] and no options')\n if (args.length > 2)\n throw new UsageError('build-client takes at most two arguments: [root] [outDir]')\n return { root: args[0] ?? 'src/client', outDir: args[1] ?? 'dist/client' }\n}\n\n/**\n * Compile the app's client modules once (`buildClientModules` of the framework), for a production install that has no compiler at run time.\n * The framework is the one installed in the app (so the compiled files match the server that serves them), else this package's own.\n */\nexport async function buildClient(\n options: { root: string; outDir: string },\n io: Io,\n): Promise<number> {\n const root = resolve(io.cwd, options.root)\n if (!existsSync(root)) {\n io.stderr.write(\n `error: ${root} does not exist; the client modules live in src/client by default\\n`,\n )\n return 1\n }\n const outDir = resolve(io.cwd, options.outDir)\n const here = createRequire(resolve(io.cwd, 'package.json'))\n let specifier = 'acrylblends/node-server'\n try {\n here.resolve(specifier)\n } catch {\n specifier = new URL('../lib/node-server.js', import.meta.url).href\n }\n const mod = (await import(\n specifier.startsWith('file:') ? specifier : here.resolve(specifier)\n )) as typeof import('../lib/node-server')\n const written = mod.buildClientModules({ root, outDir })\n for (const file of written) io.stdout.write(`${relative(io.cwd, resolve(outDir, file))}\\n`)\n io.stdout.write(`built ${written.length} files in ${relative(io.cwd, outDir) || '.'}\\n`)\n return 0\n}\n","import { existsSync, readdirSync, readFileSync } from 'node:fs'\nimport { join, relative, resolve, sep } from 'node:path'\nimport type { Io } from './io'\n\n/**\n * The dependency rule (spec 049): app code imports a port, never a provider. A port is `acrylblends/db` (the `Db` type); a provider is a\n * driver or the one function that opens a database. Only the opener, a file the app names once in package.json, may import a provider.\n */\n\n/** A package that is a database driver. An import of it, or of anything below it, is a provider import. */\nconst DRIVERS = [\n 'node:sqlite',\n 'sqlite',\n 'sqlite3',\n 'better-sqlite3',\n '@libsql/client',\n 'libsql',\n 'pg',\n 'pg-pool',\n 'pg-native',\n 'postgres',\n '@electric-sql/pglite',\n '@neondatabase/serverless',\n '@vercel/postgres',\n 'mysql',\n 'mysql2',\n]\n/** The openers a provider ships: importing one of them is opening a database. */\nconst OPENERS = ['acrylblends/db/sqlite', 'acryl-db-sqlite']\n/** The desktop shell is where Electron lives (`acrylblends add desktop` copies it). */\nconst ELECTRON = 'electron'\nconst ELECTRON_HOMES = [\n 'plugins/desktop/',\n 'plugins/desktop-web/',\n 'src/plugins/desktop/',\n 'src/plugins/desktop-web/',\n]\n/** The provider plugins themselves may import what they wrap. */\nconst PROVIDER_HOMES = ['plugins/acryl-db-sqlite/', 'src/plugins/acryl-db-sqlite/']\n\nconst SOURCE = /\\.(?:[cm]?[jt]s|[jt]sx)$/u\nconst SKIP_DIRS = new Set(['node_modules', 'dist', 'lib', 'build', 'coverage'])\nconst ROOTS = ['src', 'test', 'tests', 'plugins', 'extensions']\n\nexport interface Violation {\n readonly file: string\n readonly line: number\n readonly specifier: string\n readonly kind: 'driver' | 'opener' | 'electron'\n}\n\nconst matches = (specifier: string, name: string): boolean =>\n specifier === name || specifier.startsWith(`${name}/`)\n\n/** What a specifier is to the rule, or undefined when it is not a provider. */\nexport function classifySpecifier(specifier: string): Violation['kind'] | undefined {\n if (DRIVERS.some((name) => matches(specifier, name))) return 'driver'\n if (OPENERS.some((name) => matches(specifier, name))) return 'opener'\n if (matches(specifier, ELECTRON)) return 'electron'\n return undefined\n}\n\n/** The source with every comment replaced by spaces (newlines kept), so a line number still means what it did and a commented import is not an import. */\nexport function blankComments(source: string): string {\n let out = ''\n let i = 0\n while (i < source.length) {\n const c = source[i] as string\n const next = source[i + 1]\n if (c === '/' && next === '/') {\n const end = source.indexOf('\\n', i)\n const stop = end === -1 ? source.length : end\n out += ' '.repeat(stop - i)\n i = stop\n } else if (c === '/' && next === '*') {\n const end = source.indexOf('*/', i + 2)\n const stop = end === -1 ? source.length : end + 2\n out += source.slice(i, stop).replace(/[^\\n]/gu, ' ')\n i = stop\n } else if (c === \"'\" || c === '\"' || c === '`') {\n let j = i + 1\n while (j < source.length && source[j] !== c) {\n if (source[j] === '\\\\') j += 1\n else if (c !== '`' && source[j] === '\\n') break\n j += 1\n }\n out += source.slice(i, Math.min(j + 1, source.length))\n i = j + 1\n } else {\n out += c\n i += 1\n }\n }\n return out\n}\n\n/** `import x from 'a'`, `export * from 'a'`, `import 'a'`, `import('a')` and `require('a')`, with the line of each. */\nconst IMPORT =\n /(?:^|[\\s;{}()])(?:import\\s*(?:type\\s+)?(?:[\\w*${},\\s]*?\\s*from\\s*)?|export\\s*(?:type\\s+)?[\\w*${},\\s]*?\\s*from\\s*|import\\s*\\(\\s*|require\\s*\\(\\s*)(['\"])([^'\"\\n]+)\\1/gu\n\nexport function importsOf(source: string): { specifier: string; line: number }[] {\n const code = blankComments(source)\n const found: { specifier: string; line: number }[] = []\n for (const match of code.matchAll(IMPORT)) {\n const specifier = match[2] as string\n const at = (match.index ?? 0) + match[0].length - specifier.length - 2\n found.push({ specifier, line: code.slice(0, at).split('\\n').length })\n }\n return found\n}\n\nfunction listSources(dir: string, out: string[] = []): string[] {\n if (!existsSync(dir)) return out\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.name.startsWith('.') || SKIP_DIRS.has(entry.name)) continue\n const path = join(dir, entry.name)\n if (entry.isDirectory()) listSources(path, out)\n else if (SOURCE.test(entry.name) && !entry.name.endsWith('.d.ts')) out.push(path)\n }\n return out\n}\n\n/** The opener files the app declares: `\"acryl\": { \"opener\": \"src/db.ts\" }` (or a list) in package.json. */\nexport function openersOf(appDir: string): string[] {\n const file = join(appDir, 'package.json')\n if (!existsSync(file)) return []\n const declared = (JSON.parse(readFileSync(file, 'utf8')) as { acryl?: { opener?: unknown } })\n .acryl?.opener\n const list = typeof declared === 'string' ? [declared] : Array.isArray(declared) ? declared : []\n return list.filter((entry): entry is string => typeof entry === 'string')\n}\n\n/** Every provider import outside the declared opener (and the homes that may hold one), in file and line order. */\nexport function findViolations(appDir: string): Violation[] {\n const openers = new Set(openersOf(appDir).map((entry) => entry.split(sep).join('/')))\n const violations: Violation[] = []\n for (const root of ROOTS) {\n for (const path of listSources(join(appDir, root)).sort()) {\n const file = relative(appDir, path).split(sep).join('/')\n if (openers.has(file)) continue\n for (const { specifier, line } of importsOf(readFileSync(path, 'utf8'))) {\n const kind = classifySpecifier(specifier)\n if (kind === undefined) continue\n if (kind === 'electron' && ELECTRON_HOMES.some((home) => file.startsWith(home))) continue\n if (kind !== 'electron' && PROVIDER_HOMES.some((home) => file.startsWith(home))) continue\n violations.push({ file, line, specifier, kind })\n }\n }\n }\n return violations\n}\n\nconst GUIDE = 'docs/framework/guides/data.md#why-the-database-is-opened-in-one-place'\n\nfunction advice(violation: Violation, openers: readonly string[]): string {\n if (violation.kind === 'electron')\n return `\"${violation.specifier}\" is the desktop shell's: only plugins/desktop (added with \"acrylblends add desktop\") imports electron`\n const where =\n openers.length > 0\n ? openers.join(', ')\n : 'a file named in package.json \"acryl\": { \"opener\": \"...\" }'\n return violation.kind === 'driver'\n ? `\"${violation.specifier}\" is a database driver; take a Db (import type { Db } from \"acrylblends/db\") as an argument and let ${where} open the database`\n : `\"${violation.specifier}\" opens a database, and only ${where} may; take a Db (import type { Db } from \"acrylblends/db\") as an argument`\n}\n\n/** Parse `check-deps [dir]`. */\nexport function parseCheckDepsOptions(argv: readonly string[]): { directory: string | undefined } {\n const args = argv.filter((a) => !a.startsWith('-'))\n if (args.length !== argv.length || args.length > 1)\n throw new Error('check-deps takes at most one argument: the app folder')\n return { directory: args[0] }\n}\n\n/** Report each provider import outside the opener, as `file:line: why`. Returns the exit code: 1 when there is one. */\nexport function checkDeps(options: { directory: string | undefined }, io: Io): number {\n const appDir = resolve(io.cwd, options.directory ?? '.')\n const violations = findViolations(appDir)\n if (violations.length === 0) {\n io.stdout.write('check-deps: no app code imports a database provider outside the opener\\n')\n return 0\n }\n const openers = openersOf(appDir)\n for (const violation of violations)\n io.stderr.write(`${violation.file}:${violation.line}: ${advice(violation, openers)}\\n`)\n io.stderr.write(`See ${GUIDE}\\n`)\n return 1\n}\n","import { existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\n\nexport interface Invocation {\n file: string\n args: string[]\n}\n\n/**\n * How to start a package manager without the shell option (Node warns about passing args to a shell, DEP0190, and a `.cmd` shim cannot be spawned directly).\n * Off Windows the command runs as it is. On Windows npm runs as `node npm-cli.js` (the one npm is running from, else the one beside `node`); any other\n * manager goes through `cmd.exe /d /s /c <name>.cmd`, whose arguments stay an array.\n */\nexport function packageManagerInvocation(\n command: string,\n args: readonly string[],\n platform: NodeJS.Platform = process.platform,\n env: NodeJS.ProcessEnv = process.env,\n exists: (path: string) => boolean = existsSync,\n execPath: string = process.execPath,\n): Invocation {\n if (platform !== 'win32') return { file: command, args: [...args] }\n if (command === 'npm') {\n const running = env.npm_execpath\n const cli =\n running !== undefined && /npm-cli\\.c?js$/.test(running)\n ? running\n : join(dirname(execPath), 'node_modules', 'npm', 'bin', 'npm-cli.js')\n if (exists(cli)) return { file: execPath, args: [cli, ...args] }\n }\n return { file: env.ComSpec ?? 'cmd.exe', args: ['/d', '/s', '/c', `${command}.cmd`, ...args] }\n}\n","import { spawn } from 'node:child_process'\nimport { createInterface } from 'node:readline/promises'\nimport { packageManagerInvocation } from './spawn'\n\n/** Everything the CLI touches outside the filesystem. Tests pass their own. */\nexport interface Io {\n stdout: { write(text: string): unknown }\n stderr: { write(text: string): unknown }\n cwd: string\n /** Ask one question; `undefined` when there is no terminal to ask on. */\n ask: ((question: string) => Promise<string>) | undefined\n /** Install dependencies in a directory; resolves to the exit code. */\n install(directory: string): Promise<number>\n}\n\n/** The real terminal and `npm install`. */\nexport function processIo(): Io {\n const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY)\n return {\n stdout: process.stdout,\n stderr: process.stderr,\n cwd: process.cwd(),\n ask: interactive\n ? async (question) => {\n const rl = createInterface({ input: process.stdin, output: process.stdout })\n try {\n return await rl.question(question)\n } finally {\n rl.close()\n }\n }\n : undefined,\n install: (directory) =>\n new Promise((done) => {\n const { file, args } = packageManagerInvocation('npm', ['install'])\n const child = spawn(file, args, { cwd: directory, stdio: 'inherit' })\n child.on('error', () => done(1))\n child.on('exit', (code) => done(code ?? 1))\n }),\n }\n}\n","import { existsSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { resolve } from 'node:path'\nimport { parseArgs } from 'node:util'\nimport { UsageError } from './init'\nimport type { Io } from './io'\n\nexport interface KvImportOptions {\n readonly from: string\n readonly to: string\n readonly overwrite: boolean\n readonly table: string | undefined\n readonly migrations: string | undefined\n}\n\n/** Parse `kv import <kv.json> <database.sqlite> [--overwrite] [--table name] [--migrations dir]`. */\nexport function parseKvOptions(argv: readonly string[]): KvImportOptions {\n let parsed: ReturnType<typeof parse>\n try {\n parsed = parse(argv)\n } catch (error) {\n throw new UsageError((error as Error).message)\n }\n const [action, from, to, ...rest] = parsed.positionals\n if (action !== 'import')\n throw new UsageError('kv takes one subcommand: kv import <kv.json> <database.sqlite>')\n if (from === undefined || to === undefined || rest.length > 0)\n throw new UsageError('kv import takes two arguments: the JSON file and the SQLite file')\n return {\n from,\n to,\n overwrite: parsed.values.overwrite ?? false,\n table: parsed.values.table,\n migrations: parsed.values.migrations,\n }\n}\n\nconst parse = (argv: readonly string[]) =>\n parseArgs({\n args: [...argv],\n allowPositionals: true,\n strict: true,\n options: {\n overwrite: { type: 'boolean' },\n table: { type: 'string' },\n migrations: { type: 'string' },\n },\n })\n\n/** The framework as the app has it installed (so the code that reads the file is the code the app runs), else this package's own. */\nasync function framework<T>(io: Io, subpath: string, own: string): Promise<T> {\n const here = createRequire(resolve(io.cwd, 'package.json'))\n try {\n return (await import(here.resolve(`acrylblends/${subpath}`))) as T\n } catch {\n return (await import(new URL(`../lib/${own}`, import.meta.url).href)) as T\n }\n}\n\n/**\n * Import a JSON-file kv store into the `kv` table of an app's SQLite database: the move from `acryl-kv-json` to SQL. The file is not changed.\n * The database is opened with the app's `migrations/` folder when it has one (a database whose schema is newer than the files given is refused),\n * and the table is created when missing. Refuses to overwrite a key the table already has unless `--overwrite`.\n */\nexport async function kvImport(options: KvImportOptions, io: Io): Promise<number> {\n const from = resolve(io.cwd, options.from)\n const to = resolve(io.cwd, options.to)\n if (!existsSync(from)) {\n io.stderr.write(`error: ${from} does not exist\\n`)\n return 1\n }\n const kvCore = await framework<typeof import('../lib/kv')>(io, 'kv', 'kv.js')\n const json = await framework<typeof import('../lib/kv/json')>(io, 'kv/json', 'kv/json.js')\n const onDb = await framework<typeof import('../lib/kv/db')>(io, 'kv/db', 'kv/db.js')\n const sqlite = await framework<typeof import('../lib/db/sqlite')>(io, 'db/sqlite', 'db/sqlite.js')\n const migrations =\n options.migrations !== undefined\n ? resolve(io.cwd, options.migrations)\n : existsSync(resolve(io.cwd, 'migrations'))\n ? resolve(io.cwd, 'migrations')\n : undefined\n const source = await json.openKv({ path: from })\n try {\n const database = await sqlite.openDb({\n path: to,\n ...(migrations === undefined ? {} : { migrations }),\n })\n try {\n const target = onDb.kvOnDb(\n database.db,\n options.table === undefined ? {} : { table: options.table },\n )\n const result = await kvCore.copyKv(source.kv, target, { overwrite: options.overwrite })\n io.stdout.write(\n `imported ${result.copied} ${result.copied === 1 ? 'key' : 'keys'} from ${options.from} into ${options.to}` +\n `${options.table === undefined ? '' : ` (table ${options.table})`}` +\n `${result.overwritten > 0 ? `, ${result.overwritten} overwritten` : ''}\\n`,\n )\n return 0\n } finally {\n await database.close()\n }\n } finally {\n await source.close()\n }\n}\n","/** A unified diff of two texts (3 lines of context), for showing what an upgrade changes. Very large pairs are summarized instead. */\n\nexport interface DiffStat {\n readonly added: number\n readonly removed: number\n}\n\ntype Op = { kind: ' ' | '+' | '-'; line: string }\n\nfunction ops(a: string[], b: string[]): Op[] | undefined {\n if (a.length * b.length > 6_000_000) return undefined\n // Longest common subsequence by dynamic programming over the suffixes.\n const width = b.length + 1\n const table = new Uint32Array((a.length + 1) * width)\n for (let i = a.length - 1; i >= 0; i -= 1)\n for (let j = b.length - 1; j >= 0; j -= 1)\n table[i * width + j] =\n a[i] === b[j]\n ? (table[(i + 1) * width + j + 1] as number) + 1\n : Math.max(table[(i + 1) * width + j] as number, table[i * width + j + 1] as number)\n const out: Op[] = []\n let i = 0\n let j = 0\n while (i < a.length && j < b.length) {\n if (a[i] === b[j]) {\n out.push({ kind: ' ', line: a[i] as string })\n i += 1\n j += 1\n } else if ((table[(i + 1) * width + j] as number) >= (table[i * width + j + 1] as number)) {\n out.push({ kind: '-', line: a[i] as string })\n i += 1\n } else {\n out.push({ kind: '+', line: b[j] as string })\n j += 1\n }\n }\n for (; i < a.length; i += 1) out.push({ kind: '-', line: a[i] as string })\n for (; j < b.length; j += 1) out.push({ kind: '+', line: b[j] as string })\n return out\n}\n\nconst lines = (text: string): string[] =>\n text === '' ? [] : text.replace(/\\r\\n/gu, '\\n').replace(/\\n$/u, '').split('\\n')\n\n/** How many lines a change adds and removes; undefined counts when the pair is too large to compare. */\nexport function diffStat(from: string, to: string): DiffStat {\n const all = ops(lines(from), lines(to))\n if (all === undefined) return { added: lines(to).length, removed: lines(from).length }\n return {\n added: all.filter((op) => op.kind === '+').length,\n removed: all.filter((op) => op.kind === '-').length,\n }\n}\n\n/** `--- a/<name>`, `+++ b/<name>` and the hunks; empty when the texts are equal. */\nexport function unifiedDiff(name: string, from: string, to: string, context = 3): string {\n const a = lines(from)\n const b = lines(to)\n const all = ops(a, b)\n if (all === undefined)\n return `--- a/${name}\\n+++ b/${name}\\n(too large to compare line by line: ${a.length} lines became ${b.length})\\n`\n if (!all.some((op) => op.kind !== ' ')) return ''\n const out = [`--- a/${name}`, `+++ b/${name}`]\n let at = 0\n let aLine = 1\n let bLine = 1\n const positions = all.map((op) => {\n const here = { a: aLine, b: bLine }\n if (op.kind !== '+') aLine += 1\n if (op.kind !== '-') bLine += 1\n return here\n })\n while (at < all.length) {\n while (at < all.length && all[at]?.kind === ' ') at += 1\n if (at >= all.length) break\n const start = Math.max(0, at - context)\n let end = at\n for (let k = at; k < all.length; k += 1) {\n if (all[k]?.kind !== ' ') end = k\n else if (k - end > context * 2) break\n }\n const stop = Math.min(all.length, end + context + 1)\n const slice = all.slice(start, stop)\n const first = positions[start] as { a: number; b: number }\n out.push(\n `@@ -${first.a},${slice.filter((op) => op.kind !== '+').length} +${first.b},${slice.filter((op) => op.kind !== '-').length} @@`,\n )\n for (const op of slice) out.push(`${op.kind}${op.line}`)\n at = stop\n }\n return `${out.join('\\n')}\\n`\n}\n","import {\n cpSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n rmSync,\n statSync,\n writeFileSync,\n} from 'node:fs'\nimport { dirname, join, relative, resolve, sep } from 'node:path'\nimport { parseArgs } from 'node:util'\nimport { diffStat, unifiedDiff } from './diff'\nimport { UsageError } from './init'\nimport type { Io } from './io'\nimport {\n closure,\n copyPlugin,\n LEGACY_WARNING,\n LIBRARY_LIST,\n type LibraryPlugin,\n pluginsFolder,\n readLibrary,\n recordLibraryCopy,\n} from './library'\nimport { hashFolder, readHistory, readLock, recordLock } from './lock'\nimport { appendGitignore, mergeDependencies, mergeImports, mergeTooling } from './project'\nimport { VERSION } from './version'\n\nexport interface UpgradeOptions {\n /** Library plugins to upgrade; none means every library plugin the app carries. */\n readonly names: readonly string[]\n readonly directory: string | undefined\n /** Show what would change and stop. */\n readonly dryRun: boolean\n /** Replace a file the app edited too (the edited version is saved first). */\n readonly force: boolean\n /** Print the diff of every changed file, not only of the edited ones. */\n readonly diff: boolean\n}\n\n/** Parse `upgrade [plugin...] [--dir <app>] [--dry-run] [--force] [--diff]`. */\nexport function parseUpgradeOptions(argv: readonly string[]): UpgradeOptions {\n let parsed: ReturnType<typeof parse>\n try {\n parsed = parse(argv)\n } catch (error) {\n throw new UsageError((error as Error).message)\n }\n return {\n names: parsed.positionals,\n directory: parsed.values.dir,\n dryRun: parsed.values['dry-run'] === true,\n force: parsed.values.force === true,\n diff: parsed.values.diff === true,\n }\n}\n\nconst parse = (argv: readonly string[]) =>\n parseArgs({\n args: [...argv],\n allowPositionals: true,\n strict: true,\n options: {\n dir: { type: 'string' },\n 'dry-run': { type: 'boolean' },\n force: { type: 'boolean' },\n diff: { type: 'boolean' },\n },\n })\n\ntype FileState = 'same' | 'add' | 'update' | 'conflict' | 'remove' | 'extra'\n\ninterface PluginPlan {\n readonly plugin: LibraryPlugin\n /** The app does not have this plugin at all (a new requirement of one that it has). */\n readonly isNew: boolean\n /** Path inside the plugin folder to what happens to it. */\n readonly files: Map<string, FileState>\n /** The hashes of the files the current library would copy. */\n readonly fresh: Record<string, string>\n}\n\nconst posix = (path: string): string => path.split(sep).join('/')\n\nfunction readText(path: string): string {\n return readFileSync(path, 'utf8')\n}\n\n/** The library copies an app carries: the plugins listed in `plugins/library.json`, or when there is none the folders of `plugins/` that the library knows. */\nfunction carriedCopies(dir: string): string[] {\n const listFile = join(dir, LIBRARY_LIST)\n const listed = existsSync(listFile)\n ? ((JSON.parse(readFileSync(listFile, 'utf8')) as { plugins?: string[] }).plugins ?? [])\n : readdirSync(dir).filter((name) => statSync(join(dir, name)).isDirectory())\n return listed.filter((name) => existsSync(join(dir, name)))\n}\n\n/**\n * `acrylblends upgrade`: bring the library plugins an app carries (the router, the server, the door, `extensions`, ...) up to the version of this package. Each file is compared with what\n * the app was given: an untouched file is replaced, a file the app edited stops the upgrade (it is shown as a diff and nothing changes) unless `--force`, which saves the edited version\n * under `.acrylblends/upgrade-backup/` first. Returns the exit code: 0 done or nothing to do, 1 refused or failed.\n */\nexport async function upgrade(options: UpgradeOptions, io: Io): Promise<number> {\n const appDir = resolve(io.cwd, options.directory ?? '.')\n if (!existsSync(join(appDir, 'package.json')) || !existsSync(join(appDir, 'src'))) {\n io.stderr.write(\n `error: ${appDir} is not an app (no package.json and src/); run \"acrylblends init\" first\\n`,\n )\n return 1\n }\n const folder = pluginsFolder(appDir)\n if (folder.legacy) {\n io.stderr.write(\n `${LEGACY_WARNING}\\nerror: upgrade needs the one-folder layout (plugins/); move the plugins first\\n`,\n )\n return 1\n }\n const library = readLibrary()\n const carried = carriedCopies(folder.dir)\n const unknown = carried.filter((name) => !library.has(name))\n for (const name of options.names)\n if (!carried.includes(name)) {\n io.stderr.write(\n `error: the app carries no library plugin \"${name}\" (it carries: ${carried.filter((n) => library.has(n)).join(', ') || 'none'})\\n`,\n )\n return 1\n }\n const selected = (options.names.length > 0 ? [...options.names] : carried).filter((name) =>\n library.has(name),\n )\n if (selected.length === 0) {\n io.stdout.write('nothing to upgrade: the app carries no library plugins\\n')\n return 0\n }\n\n // What the current library would copy, into a scratch folder inside the app (`.acrylblends/` is ignored by git).\n const scratch = join(appDir, '.acrylblends', `upgrade-${process.pid}-${Date.now()}`)\n const lock = readLock(folder.dir)\n const history = readHistory()\n const plans: PluginPlan[] = []\n try {\n mkdirSync(join(scratch, 'plugins'), { recursive: true })\n const wanted = closure(selected, library)\n for (const plugin of wanted) copyPlugin(plugin, scratch)\n for (const plugin of wanted) {\n const here = join(folder.dir, plugin.name)\n const fresh = hashFolder(join(scratch, 'plugins', plugin.name))\n const files = new Map<string, FileState>()\n const isNew = !existsSync(here)\n const mine = isNew ? {} : hashFolder(here)\n const recorded = lock.plugins[plugin.name]?.files ?? {}\n const pristine = (file: string, hash: string): boolean =>\n recorded[file] === hash || (history[plugin.name]?.[file]?.includes(hash) ?? false)\n for (const [file, hash] of Object.entries(fresh)) {\n const have = mine[file]\n files.set(\n file,\n have === undefined\n ? 'add'\n : have === hash\n ? 'same'\n : pristine(file, have)\n ? 'update'\n : 'conflict',\n )\n }\n for (const [file, hash] of Object.entries(mine))\n if (!(file in fresh)) files.set(file, pristine(file, hash) ? 'remove' : 'extra')\n plans.push({ plugin, isNew, files, fresh })\n }\n\n // The report.\n const count = (plan: PluginPlan, state: FileState): string[] =>\n [...plan.files].filter(([, s]) => s === state).map(([file]) => file)\n io.stdout.write(`upgrade: the library plugins of ${appDir} to acrylblends ${VERSION}\\n`)\n let conflicts = 0\n let changes = 0\n for (const plan of plans) {\n const [updated, added, removed, edited, extra] = (\n ['update', 'add', 'remove', 'conflict', 'extra'] as const\n ).map((state) => count(plan, state))\n const label = plan.plugin.name.padEnd(22)\n conflicts += (edited as string[]).length\n if (plan.isNew) {\n changes += 1\n io.stdout.write(` ${label} new (required by a plugin of the app)\\n`)\n continue\n }\n if (\n (updated as string[]).length +\n (added as string[]).length +\n (removed as string[]).length +\n (edited as string[]).length ===\n 0\n ) {\n io.stdout.write(\n ` ${label} up to date${(extra as string[]).length > 0 ? ` (keeps ${(extra as string[]).length} file(s) of its own)` : ''}\\n`,\n )\n continue\n }\n changes += 1\n let plus = 0\n let minus = 0\n for (const file of [...(updated as string[]), ...(edited as string[])]) {\n const stat = diffStat(\n readText(join(folder.dir, plan.plugin.name, file)),\n readText(join(scratch, 'plugins', plan.plugin.name, file)),\n )\n plus += stat.added\n minus += stat.removed\n }\n const parts = [\n (updated as string[]).length > 0\n ? `${(updated as string[]).length} updated (+${plus} -${minus})`\n : '',\n (added as string[]).length > 0 ? `${(added as string[]).length} added` : '',\n (removed as string[]).length > 0 ? `${(removed as string[]).length} removed` : '',\n (edited as string[]).length > 0 ? `${(edited as string[]).length} EDITED HERE` : '',\n (extra as string[]).length > 0 ? `${(extra as string[]).length} of its own kept` : '',\n ].filter(Boolean)\n io.stdout.write(` ${label} ${parts.join(', ')}\\n`)\n }\n for (const name of unknown)\n io.stdout.write(` ${name.padEnd(22)} not in this library: left alone\\n`)\n\n // Diffs: always of the edited files (what would be lost), of every changed file with --diff.\n for (const plan of plans) {\n for (const [file, state] of plan.files) {\n if (\n !(\n state === 'conflict' ||\n (options.diff && (state === 'update' || state === 'add' || state === 'remove'))\n )\n )\n continue\n const name = `plugins/${plan.plugin.name}/${file}`\n const before = state === 'add' ? '' : readText(join(folder.dir, plan.plugin.name, file))\n const after =\n state === 'remove' ? '' : readText(join(scratch, 'plugins', plan.plugin.name, file))\n io.stdout.write(\n `\\n${state === 'conflict' ? 'EDITED HERE, the upgrade would replace it:\\n' : ''}${unifiedDiff(name, before, after)}`,\n )\n }\n }\n if (conflicts > 0 && !options.force) {\n io.stderr.write(\n `\\nerror: ${conflicts} file(s) were edited in this app and the upgrade would replace them; nothing was changed. Review the diffs above, move your changes out of the plugin (a plugin of your own in plugins/<name>/), or run again with --force (the edited versions are saved under .acrylblends/upgrade-backup/)\\n`,\n )\n return 1\n }\n if (options.dryRun) {\n io.stdout.write(\n `\\n${changes === 0 ? 'everything is up to date' : 'dry run: nothing was changed'}\\n`,\n )\n return 0\n }\n if (changes === 0) {\n io.stdout.write('\\neverything is up to date\\n')\n return 0\n }\n\n // Apply.\n const backup = join(\n appDir,\n '.acrylblends',\n 'upgrade-backup',\n new Date().toISOString().replace(/[:.]/gu, '-'),\n )\n const addedDependencies: string[] = []\n for (const plan of plans) {\n const here = join(folder.dir, plan.plugin.name)\n if (plan.isNew) {\n // Copied the way `add` copies it: the plugin, and what it needs in package.json.\n mkdirSync(here, { recursive: true })\n cpSync(join(scratch, 'plugins', plan.plugin.name), here, { recursive: true })\n recordLibraryCopy(folder.dir, plan.plugin.name)\n } else {\n for (const [file, state] of plan.files) {\n const target = join(here, file)\n if (state === 'conflict') {\n mkdirSync(dirname(join(backup, plan.plugin.name, file)), { recursive: true })\n cpSync(target, join(backup, plan.plugin.name, file))\n }\n if (state === 'add' || state === 'update' || state === 'conflict') {\n mkdirSync(dirname(target), { recursive: true })\n cpSync(join(scratch, 'plugins', plan.plugin.name, file), target)\n } else if (state === 'remove') rmSync(target, { force: true })\n }\n recordLibraryCopy(folder.dir, plan.plugin.name)\n }\n recordLock(folder.dir, plan.plugin.name, plan.fresh)\n const plugin = plan.plugin\n if (plugin.imports) mergeImports(appDir, plugin.imports, posix(relative(appDir, folder.dir)))\n addedDependencies.push(...mergeDependencies(appDir, plugin.dependencies))\n addedDependencies.push(...mergeTooling(appDir, plugin).devDependencies)\n appendGitignore(appDir, plugin.gitignore)\n }\n // The package the app depends on moves with its plugins.\n const manifestFile = join(appDir, 'package.json')\n const manifest = JSON.parse(readFileSync(manifestFile, 'utf8')) as {\n dependencies?: Record<string, string>\n }\n if (\n manifest.dependencies?.acrylblends !== undefined &&\n manifest.dependencies.acrylblends !== `^${VERSION}`\n ) {\n manifest.dependencies.acrylblends = `^${VERSION}`\n writeFileSync(manifestFile, `${JSON.stringify(manifest, null, 2)}\\n`)\n }\n io.stdout.write(\n `\\nupgraded ${plans\n .filter((p) => [...p.files.values()].some((s) => s !== 'same' && s !== 'extra') || p.isNew)\n .map((p) => p.plugin.name)\n .join(', ')}\\n`,\n )\n if (conflicts > 0)\n io.stdout.write(\n `the ${conflicts} edited file(s) replaced by --force are saved in ${posix(relative(appDir, backup))}/\\n`,\n )\n io.stdout.write(\n `acrylblends is now ^${VERSION} in package.json${addedDependencies.length > 0 ? `; new dependencies: ${[...new Set(addedDependencies)].join(', ')}` : ''}: run npm install, then npm run check and npm test\\n`,\n )\n return 0\n } finally {\n rmSync(scratch, { recursive: true, force: true })\n }\n}\n","import { add, listPlugins, parseAddOptions } from './add'\nimport { buildClient, parseBuildClientOptions } from './build-client'\nimport { checkDeps, parseCheckDepsOptions } from './check-deps'\nimport { init, parseInitOptions, UsageError } from './init'\nimport { type Io, processIo } from './io'\nimport { kvImport, parseKvOptions } from './kv-import'\nimport { TEMPLATE_SUMMARY, TEMPLATES } from './templates'\nimport { parseUpgradeOptions, upgrade } from './upgrade'\nimport { VERSION } from './version'\n\nexport { VERSION }\n\nexport const HELP = `acrylblends ${VERSION} - scaffold Cordis apps\n\nUsage:\n acrylblends init [dir] [options] Create a Cordis app in an empty or new directory\n acrylblends add <plugin...> [--dir d] [--suite] Copy library plugins (and what they require) into an app;\n a folder path brings an external plugin into its plugins/;\n --suite also copies the port's conformance suite and vitest (add kv --suite)\n acrylblends upgrade [plugin...] [--dir d] [--dry-run] [--force] [--diff]\n Bring the library plugins an app carries (the router, the server, the door, ...) up to this\n version: untouched files are replaced, an edited file stops it (diff shown) unless --force\n acrylblends plugins List the plugin library\n acrylblends build-client [root] [out] Compile the client modules once for production (src/client to dist/client)\n acrylblends kv import <kv.json> <db> Move a JSON-file kv store into the kv table of a SQLite database [--overwrite] [--table t] [--migrations dir]\n acrylblends check-deps [dir] Fail when app code imports a database driver or opener outside the file named in\n package.json \"acryl\": { \"opener\": \"src/db.ts\" } (a port is imported, a provider is not)\n\nOptions for init:\n --template <name> one of the templates below (asked when not given); --agent means --template agent,\n --no-agent means --template blank\n --name <name> the project name (default: the directory name)\n --desktop also add the desktop shell: npm run desktop opens a window on the app\n --install run npm install after copying\n -y, --yes ask nothing; use defaults (the blank template, no install)\n\n -h, --help show this help\n -v, --version show the version\n\nTemplates (the same list as npm create acrylblends):\n${TEMPLATES.map((name) => ` ${name.padEnd(7)} ${TEMPLATE_SUMMARY[name]}`).join('\\n')}\n`\n\n/**\n * Run the CLI and return the exit code: 0 done, 1 failed or refused, 2 a usage error. Never calls `process.exit`.\n */\nexport async function runCli(argv: readonly string[], io: Io = processIo()): Promise<number> {\n const [command, ...args] = argv\n try {\n if (command === undefined || command === 'help' || command === '-h' || command === '--help') {\n io.stdout.write(HELP)\n return command === undefined ? 2 : 0\n }\n if (command === 'version' || command === '-v' || command === '--version') {\n io.stdout.write(`${VERSION}\\n`)\n return 0\n }\n if (command === 'init') return await init(parseInitOptions(args), io)\n if (command === 'add') return await add(parseAddOptions(args), io)\n if (command === 'upgrade') return await upgrade(parseUpgradeOptions(args), io)\n if (command === 'build-client') return await buildClient(parseBuildClientOptions(args), io)\n if (command === 'kv') return await kvImport(parseKv(args), io)\n if (command === 'check-deps') return checkDeps(parseCheckDeps(args), io)\n if (command === 'plugins') return listPlugins(io)\n throw new UsageError(`unknown command \"${command}\"`)\n } catch (error) {\n if (error instanceof UsageError) {\n io.stderr.write(`error: ${error.message}\\n\\n${HELP}`)\n return 2\n }\n io.stderr.write(`error: ${error instanceof Error ? error.message : String(error)}\\n`)\n return 1\n }\n}\n\nfunction parseCheckDeps(args: readonly string[]) {\n try {\n return parseCheckDepsOptions(args)\n } catch (error) {\n throw new UsageError((error as Error).message)\n }\n}\n\nfunction parseKv(args: readonly string[]) {\n return parseKvOptions(args)\n}\n"],"mappings":"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"}