create-ragen-app 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,8 +11,59 @@ It clones the repo, generates every secret it safely can, lets you paste a
11
11
  plain OpenAI or Anthropic API key instead of configuring an enterprise model
12
12
  provider, starts the backing services (Postgres, Qdrant, Temporal, LiteLLM,
13
13
  Redis, …) in Docker, and runs the app's own first-run setup (Prisma client,
14
- migrations, seed data) leaving `cd my-ragen-app && npm run web:dev` as the
15
- only remaining step.
14
+ migrations, seed data). What is left is starting the two apps, in separate
15
+ terminals:
16
+
17
+ ```bash
18
+ cd my-ragen-app
19
+ npm run api:dev # apps/api — the web app creates threads through it
20
+ npm run web:dev # apps/web — http://localhost:3000
21
+ ```
22
+
23
+ `apps/api` is not optional: `apps/web` delegates thread creation, the thread
24
+ sidebar and notifications to it (ADR-21), so running only the web app gets you
25
+ a panel that loads and a chat that cannot open a thread.
26
+
27
+ ## Node version
28
+
29
+ A Ragen installation needs Node 24, and the wizard refuses to create one on
30
+ anything older *before* it clones. Not because the CLI needs it — it does not,
31
+ and 0.2.0 was published and verified on Node 22 by accident — but because the
32
+ setup it runs for you (`npm install` across the monorepo, `prisma generate`,
33
+ `migrate deploy`, the seed) runs under the caller's Node and leaves a tree
34
+ that fails much later, nowhere near the cause. npm's `EBADENGINE` does warn,
35
+ as one line inside a wall of install output that does not say what breaks.
36
+
37
+ `--skip-install` turns the refusal into a warning, because then the wizard
38
+ runs nothing itself: scaffold here, run the setup on a supported Node. `--yes`
39
+ does not bypass it — that flag means "accept the defaults", not "ignore a
40
+ requirement".
41
+
42
+ ## Keep this in sync with the app
43
+
44
+ This package is the only thing that exercises the first-run path.
45
+ `.github/workflows/installer.yml` runs it on pushes to `main` and on pull
46
+ requests from this repository: it packs the package, installs the tarball,
47
+ scaffolds from the branch under review and asserts the result is configured.
48
+ That catches a broken installer, but only for the cases the assertions cover —
49
+ `AGENTS.md`'s Post-Task Workflow still asks for an update here in the same PR,
50
+ and for the PR description to say so.
51
+
52
+ What counts as install-affecting:
53
+
54
+ | Change | What to update here |
55
+ | --- | --- |
56
+ | A new or renamed env var that a fresh install must set | `src/manifest.ts` (generated secret or corrected default) |
57
+ | A default model, embedding model or `VECTOR_SIZE` change | `src/llm-provider.ts` — and the two must stay consistent, or Qdrant rejects every upsert |
58
+ | An app the web app can no longer run without | the outro in `src/cli.ts`, which tells people what to start |
59
+ | A new first-run step (migration, seed, generate) | `src/tasks.ts` and `maybeRunFirstTimeSetup` |
60
+ | A `docker-compose.yml` service, port or name change | `src/tasks.ts`, and the collision check in `ragenStackVolumeExists` |
61
+ | A gate that a brand-new install cannot pass (registration, licensing, onboarding) | usually the app, not this package — a fresh install must be able to reach a working chat without an administrator who does not exist yet |
62
+
63
+ `tests/architecture/create-ragen-app-manifest-is-current.test.ts` catches one
64
+ direction only: a key this package writes that the `.env.example` no longer
65
+ has. The opposite drift — a new required var nobody taught the manifest
66
+ about — has no textual signal, which is why the rule above is a rule.
16
67
 
17
68
  ## Flags
18
69
 
@@ -22,12 +73,24 @@ only remaining step.
22
73
  | `--skip-docker` | Write the `.env.local` files but don't start Docker |
23
74
  | `--skip-install` | Skip `npm install` / Prisma / seed |
24
75
  | `--yes` | Accept every default without prompting |
76
+ | `--provider=openai\|anthropic` | Take the API key from `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` instead of prompting |
25
77
 
26
78
  Anything the wizard doesn't ask about (S3 storage, encryption at rest,
27
79
  Stripe, email, MCP connectors) ships exactly as documented in the repo's own
28
80
  `.env.example` files — see
29
81
  [docs/self-hosting](https://docs.ragen.ai/docs/self-hosting).
30
82
 
83
+ ## Declining to paste a key
84
+
85
+ Typing a provider API key into someone else's CLI is a reasonable thing to
86
+ refuse, so the provider step is skippable — pick *"I'll configure LiteLLM
87
+ myself"*, or press enter on an empty key. The install still completes, and
88
+ `SETUP-LLM.md` is written into the new directory with the exact `.env.local`
89
+ values and `model_list` entries for OpenAI and Anthropic, plus the one
90
+ ordering constraint that matters (`VECTOR_SIZE` has to be right *before* the
91
+ first document is indexed). `src/manual-setup.ts` generates that file from
92
+ `LLM_PROVIDERS`, so it cannot drift from what the wizard would have done.
93
+
31
94
  ## What it changes, and how it decides
32
95
 
33
96
  `src/manifest.ts` is the single list of which env vars get a generated
@@ -37,13 +100,94 @@ cloned repo's own `.env.example` already has it. See the file's own comments
37
100
  for the sharing rules (some secrets are the same value in two files, most are
38
101
  independent).
39
102
 
103
+ ## Testing a change before publishing
104
+
105
+ `npm pack` reproduces exactly what npm would serve — it honours `files`,
106
+ `bin` and `prepare` — so the published artifact can be exercised without a
107
+ registry:
108
+
109
+ ```bash
110
+ pack=$(mktemp -d)
111
+ npm pack --workspace=create-ragen-app --pack-destination="$pack"
112
+ npm install --prefix "$pack" "$pack"/create-ragen-app-*.tgz
113
+ "$pack"/node_modules/.bin/create-ragen-app /tmp/try-ragen \
114
+ --ref=my-branch --provider=openai --skip-docker --skip-install
115
+ ```
116
+
117
+ Three details, each of which this file previously got wrong:
118
+
119
+ - **Install the tarball, do not hand it to `npx`.** `npx ./thing.tgz` does not
120
+ install and run a local package — it tries to *execute* the file, and fails
121
+ with `Permission denied`. `.github/workflows/installer.yml` installs it,
122
+ which is why CI passed while the command written here never ran.
123
+ - **Glob the filename.** `npm pack` names the tarball after the version in
124
+ `package.json`, so writing one here goes stale at the next release.
125
+ - **Pack into an empty directory.** That is what keeps the glob honest: a
126
+ shared `/tmp` accumulates one tarball per version ever built, the glob then
127
+ expands to several paths, and `npm install` would be handed all of them.
128
+
129
+ `--ref` is the part people forget: the CLI clones the repository from GitHub,
130
+ so testing a change to the *app* needs that branch pushed. Without it you are
131
+ testing new installer code against old repository content.
132
+
133
+ `prepare` runs `clean` before `build` deliberately. `files` publishes `dist`
134
+ wholesale and `tsc` does not remove the output of a source file that no
135
+ longer exists, so without the clean a renamed or deleted module ships as a
136
+ stale `.js` that nothing in the repo can explain.
137
+
40
138
  ## Publishing (manual for now)
41
139
 
42
- There is no CI job wired up yet (see the project plan's non-goals). To cut a
43
- new version:
140
+ There is no publish job in CI (see the project plan's non-goals), so this is a
141
+ checklist rather than one command:
44
142
 
45
143
  ```bash
46
144
  npm version <patch|minor|major> --workspace=create-ragen-app
47
- npm run build --workspace=create-ragen-app
145
+ npm install --package-lock-only
146
+ git add packages/create-ragen-app/package.json package-lock.json
147
+ git commit -m "chore(release): create-ragen-app <version>"
148
+ ```
149
+
150
+ **Land that on `main` before publishing.** `main` is protected, so it goes
151
+ through a pull request like anything else — and publishing first is precisely
152
+ how the registry ended up ahead of the repository last time. npm versions are
153
+ immutable: once `0.2.0` exists, a repository that still says `0.1.0` cannot be
154
+ corrected by re-publishing, only by pushing the commit that should have gone
155
+ first.
156
+
157
+ ```bash
158
+ git checkout main && git pull
48
159
  npm publish --workspace=create-ragen-app
49
160
  ```
161
+
162
+ Publishing from a merged `main` also means the tarball is built from the tree
163
+ everyone else can see, rather than from whatever happens to be in the working
164
+ directory.
165
+
166
+ The two middle lines of the first block are there because of what `npm
167
+ version` does *not* do for a workspace. Both have already cost this package a
168
+ release:
169
+
170
+ - **It does not commit, and does not tag.** In a single-package repository it
171
+ does both; with `--workspace` it rewrites `package.json` and leaves the
172
+ change unstaged, printing only the new version. 0.2.0 went to npm from a
173
+ bump that then sat uncommitted on a laptop, so the registry served 0.2.0
174
+ while `main` still said 0.1.0 — and `npm publish` from `main` would have
175
+ been rejected as an existing version.
176
+ - **It does not touch `package-lock.json`.** The lockfile keeps its own copy
177
+ of every workspace's version, so it stayed on `0.1.0`. That is why
178
+ `git add package-lock.json` staged nothing in that release commit: there was
179
+ nothing to stage. `npm install --package-lock-only` fixes it and leaves
180
+ `node_modules` alone.
181
+
182
+ `npm run build` is deliberately absent: `prepare` already runs `clean &&
183
+ build` on publish, and it has to clean — `files` publishes `dist` wholesale
184
+ and `tsc` does not remove the output of a source file that no longer exists.
185
+
186
+ Then exercise what was actually published, not just what was packed — from
187
+ the repository root:
188
+
189
+ ```bash
190
+ OPENAI_API_KEY=dummy npx create-ragen-app@latest /tmp/verify-release \
191
+ --provider=openai --skip-docker --skip-install
192
+ node scripts/ci/assert-scaffolded-install.mjs /tmp/verify-release
193
+ ```
package/dist/args.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { LlmProviderChoice } from './llm-provider';
1
2
  export interface CliArgs {
2
3
  /** Undefined when the user gave no positional argument — the CLI prompts. */
3
4
  targetDir: string | undefined;
@@ -5,6 +6,13 @@ export interface CliArgs {
5
6
  skipDocker: boolean;
6
7
  skipInstall: boolean;
7
8
  yes: boolean;
9
+ /**
10
+ * Undefined when the CLI should ask. Set by `--provider=`, which takes the
11
+ * API key from the environment instead of a prompt — for anyone who would
12
+ * rather not put a provider key in their shell history, and for CI, which
13
+ * has no way to answer a prompt at all.
14
+ */
15
+ provider: LlmProviderChoice | undefined;
8
16
  }
9
17
  export declare const DEFAULT_TARGET_DIR = "./ragen-app";
10
18
  export declare function parseArgs(argv: string[]): CliArgs;
@@ -1 +1 @@
1
- {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACtB,6EAA6E;IAC7E,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,OAAO,CAAC;CACd;AAED,eAAO,MAAM,kBAAkB,gBAAgB,CAAC;AAGhD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CA4BjD"}
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,WAAW,OAAO;IACtB,6EAA6E;IAC7E,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,OAAO,CAAC;IACb;;;;;OAKG;IACH,QAAQ,EAAE,iBAAiB,GAAG,SAAS,CAAC;CACzC;AAED,eAAO,MAAM,kBAAkB,gBAAgB,CAAC;AAKhD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAsCjD"}
package/dist/args.js CHANGED
@@ -4,6 +4,7 @@ exports.DEFAULT_TARGET_DIR = void 0;
4
4
  exports.parseArgs = parseArgs;
5
5
  exports.DEFAULT_TARGET_DIR = './ragen-app';
6
6
  const DEFAULT_REF = 'main';
7
+ const PROVIDERS = ['openai', 'anthropic'];
7
8
  function parseArgs(argv) {
8
9
  const positionals = argv.filter((arg) => !arg.startsWith('--'));
9
10
  if (positionals.length > 1) {
@@ -20,12 +21,19 @@ function parseArgs(argv) {
20
21
  ?.slice(prefix.length);
21
22
  return value || undefined;
22
23
  };
24
+ const provider = valueOf('provider');
25
+ if (provider && !PROVIDERS.includes(provider)) {
26
+ // Rejected rather than ignored: silently falling back to "ask me" turns a
27
+ // typo in a CI job into a hang on a prompt nothing can answer.
28
+ throw new Error(`Unknown --provider=${provider}. Expected one of: ${PROVIDERS.join(', ')}.`);
29
+ }
23
30
  return {
24
31
  targetDir: positionals[0],
25
32
  ref: valueOf('ref') ?? DEFAULT_REF,
26
33
  skipDocker: hasFlag('skip-docker'),
27
34
  skipInstall: hasFlag('skip-install'),
28
35
  yes: hasFlag('yes'),
36
+ provider: provider,
29
37
  };
30
38
  }
31
39
  //# sourceMappingURL=args.js.map
package/dist/args.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":";;;AAYA,8BA4BC;AA/BY,QAAA,kBAAkB,GAAG,aAAa,CAAC;AAChD,MAAM,WAAW,GAAG,MAAM,CAAC;AAE3B,SAAgB,SAAS,CAAC,IAAc;IACtC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,wEAAwE;QACxE,iEAAiE;QACjE,iCAAiC;QACjC,MAAM,IAAI,KAAK,CACb,+BAA+B,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,sCAAsC,CACpG,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAEtE,MAAM,OAAO,GAAG,CAAC,IAAY,EAAsB,EAAE;QACnD,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI;aACf,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YACtC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzB,OAAO,KAAK,IAAI,SAAS,CAAC;IAC5B,CAAC,CAAC;IAEF,OAAO;QACL,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;QACzB,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,WAAW;QAClC,UAAU,EAAE,OAAO,CAAC,aAAa,CAAC;QAClC,WAAW,EAAE,OAAO,CAAC,cAAc,CAAC;QACpC,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC;KACpB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":";;;AAuBA,8BAsCC;AA3CY,QAAA,kBAAkB,GAAG,aAAa,CAAC;AAChD,MAAM,WAAW,GAAG,MAAM,CAAC;AAE3B,MAAM,SAAS,GAAwB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAE/D,SAAgB,SAAS,CAAC,IAAc;IACtC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,wEAAwE;QACxE,iEAAiE;QACjE,iCAAiC;QACjC,MAAM,IAAI,KAAK,CACb,+BAA+B,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,sCAAsC,CACpG,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAEtE,MAAM,OAAO,GAAG,CAAC,IAAY,EAAsB,EAAE;QACnD,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI;aACf,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YACtC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzB,OAAO,KAAK,IAAI,SAAS,CAAC;IAC5B,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,IAAI,QAAQ,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAA6B,CAAC,EAAE,CAAC;QACnE,0EAA0E;QAC1E,+DAA+D;QAC/D,MAAM,IAAI,KAAK,CACb,sBAAsB,QAAQ,sBAAsB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC5E,CAAC;IACJ,CAAC;IAED,OAAO;QACL,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;QACzB,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,WAAW;QAClC,UAAU,EAAE,OAAO,CAAC,aAAa,CAAC;QAClC,WAAW,EAAE,OAAO,CAAC,cAAc,CAAC;QACpC,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC;QACnB,QAAQ,EAAE,QAAyC;KACpD,CAAC;AACJ,CAAC"}
package/dist/cli.d.ts CHANGED
@@ -1,2 +1,9 @@
1
- export declare function run(argv: string[]): Promise<void>;
1
+ /**
2
+ * Returns whether the install ran to completion, so `index.ts` can exit
3
+ * non-zero when it did not. Every `clack.cancel()` above used to `return`
4
+ * into a resolved promise and a zero exit code — an aborted install looked
5
+ * like a successful one to anything reading `$?`, which is a shell `&&`, a
6
+ * Dockerfile, and the CI job that exists to catch exactly this.
7
+ */
8
+ export declare function run(argv: string[]): Promise<boolean>;
2
9
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAuDA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8FvD"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AA6DA;;;;;;GAMG;AACH,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAgJ1D"}
package/dist/cli.js CHANGED
@@ -42,20 +42,44 @@ const args_1 = require("./args");
42
42
  const clone_1 = require("./clone");
43
43
  const env_file_1 = require("./env-file");
44
44
  const litellm_config_1 = require("./litellm-config");
45
+ const manual_setup_1 = require("./manual-setup");
46
+ const node_version_1 = require("./node-version");
45
47
  const llm_provider_1 = require("./llm-provider");
46
48
  const manifest_1 = require("./manifest");
47
49
  const secrets_1 = require("./secrets");
48
50
  const tasks_1 = require("./tasks");
51
+ /** Written into the new install whenever a model still has to be wired by hand. */
52
+ const MANUAL_SETUP_FILENAME = 'SETUP-LLM.md';
49
53
  const ENV_PATHS = {
50
54
  root: { example: '.env.example', local: '.env.local' },
51
55
  admin: { example: 'apps/admin/.env.example', local: 'apps/admin/.env.local' },
52
56
  };
57
+ /**
58
+ * Returns whether the install ran to completion, so `index.ts` can exit
59
+ * non-zero when it did not. Every `clack.cancel()` above used to `return`
60
+ * into a resolved promise and a zero exit code — an aborted install looked
61
+ * like a successful one to anything reading `$?`, which is a shell `&&`, a
62
+ * Dockerfile, and the CI job that exists to catch exactly this.
63
+ */
53
64
  async function run(argv) {
54
65
  const args = (0, args_1.parseArgs)(argv);
55
66
  clack.intro('create-ragen-app');
67
+ // Before the target directory, and well before the clone: the point of the
68
+ // check is to cost nothing when it fails.
69
+ const nodeVersion = (0, node_version_1.checkNodeVersion)({
70
+ version: process.version,
71
+ willRunSetup: !args.skipInstall,
72
+ });
73
+ if (nodeVersion.kind === 'refuse') {
74
+ clack.cancel(nodeVersion.message);
75
+ return false;
76
+ }
77
+ if (nodeVersion.kind === 'warn') {
78
+ clack.log.warn(nodeVersion.message);
79
+ }
56
80
  const targetDir = await resolveTargetDir(args.targetDir, args.yes);
57
81
  if (!targetDir) {
58
- return;
82
+ return false;
59
83
  }
60
84
  const cloneSpinner = clack.spinner();
61
85
  cloneSpinner.start(`Cloning Ragen into ${targetDir}`);
@@ -65,18 +89,16 @@ async function run(argv) {
65
89
  catch (error) {
66
90
  cloneSpinner.stop('Clone failed.', 1);
67
91
  clack.cancel(`Could not download ${args.ref} from the Ragen repository: ${String(error)}`);
68
- return;
92
+ return false;
69
93
  }
70
94
  cloneSpinner.stop('Cloned.');
71
95
  const resolvedValues = resolveManifestValues();
72
96
  const rootOverrides = overridesForTarget('root', resolvedValues);
73
97
  const adminOverrides = overridesForTarget('admin', resolvedValues);
74
- const llmPrompt = args.yes
75
- ? { cancelled: false, choice: undefined }
76
- : await promptLlmProvider();
98
+ const llmPrompt = await resolveLlmProvider(args);
77
99
  if (llmPrompt.cancelled) {
78
100
  clack.cancel('Cancelled.');
79
- return;
101
+ return false;
80
102
  }
81
103
  const llmChoice = llmPrompt.choice;
82
104
  if (llmChoice) {
@@ -90,17 +112,38 @@ async function run(argv) {
90
112
  `Wrote what could be matched, but these keys have no line in the cloned repo's .env.example: ${missingKeys.join(', ')}.`,
91
113
  "That usually means create-ragen-app's manifest and the repo have drifted — fix them by hand in .env.local before starting the app. Stopping before Docker/migrations, since they'd run against an incomplete config.",
92
114
  ].join('\n'));
93
- return;
115
+ return false;
94
116
  }
95
117
  if (llmChoice) {
96
- patchLiteLLMConfig(targetDir, llmChoice.liteLLMEntry);
118
+ patchLiteLLMConfig(targetDir, llmChoice.liteLLMEntries);
119
+ if (!llmChoice.embeddingsConfigured) {
120
+ clack.log.warn([
121
+ 'Chat is configured, but this provider has no embeddings API — the',
122
+ 'knowledge base will not work until you add one. See',
123
+ `${MANUAL_SETUP_FILENAME} in the new directory.`,
124
+ ].join(' '));
125
+ writeManualSetupGuide(targetDir);
126
+ }
97
127
  }
98
128
  else {
99
- clack.log.warn('No LLM provider configured — chat will not work until infra/litellm/config.yaml has a model and a matching API key. See docs/model-routing.md.');
129
+ // Declining to paste a provider key into someone else's CLI is
130
+ // reasonable, so this path has to leave a person able to finish by hand
131
+ // rather than just telling them something is broken.
132
+ const guidePath = writeManualSetupGuide(targetDir);
133
+ clack.note([
134
+ 'No LLM provider configured, so chat and the knowledge base are off.',
135
+ '',
136
+ 'Two files to edit, then `docker compose restart litellm`:',
137
+ ' .env.local — your key, DEFAULT_MODEL, REPHRASE_MODEL,',
138
+ ' EMBEDDINGS_MODEL, VECTOR_SIZE',
139
+ ' infra/litellm/config.yaml — a model_list entry per model',
140
+ '',
141
+ `Exact values for OpenAI and Anthropic are written to ${guidePath}.`,
142
+ ].join('\n'), 'Configure a model later');
100
143
  }
101
144
  if (!args.skipDocker) {
102
145
  if (!(await maybeStartDocker(targetDir, args.yes))) {
103
- return;
146
+ return false;
104
147
  }
105
148
  }
106
149
  if (!args.skipInstall) {
@@ -111,20 +154,30 @@ async function run(argv) {
111
154
  // through explicitly.
112
155
  const rootEnv = (0, dotenv_1.parse)(rootWrite.content);
113
156
  if (!(await maybeRunFirstTimeSetup(targetDir, args.yes, rootEnv))) {
114
- return;
157
+ return false;
115
158
  }
116
159
  }
117
160
  clack.outro([
118
161
  'Done. Next steps:',
119
162
  ` cd ${targetDir}`,
120
- ' npm run web:dev',
163
+ ' npm run api:dev # in one terminal',
164
+ ' npm run web:dev # in another',
165
+ '',
166
+ // Both, not just web: apps/web delegates thread creation, the thread
167
+ // sidebar and notifications to apps/api (ADR-21), so starting only the
168
+ // web app gets you a panel that loads and a chat that cannot open a
169
+ // thread.
170
+ 'apps/api is not optional — the web app creates threads through it,',
171
+ 'so chat fails without it.',
121
172
  '',
122
173
  'App: http://localhost:3000',
174
+ 'API: http://localhost:3001',
123
175
  'Admin: http://localhost:3200 (npm run admin:dev)',
124
176
  '',
125
177
  'Anything skipped above (S3 storage, encryption, Stripe, email, MCP',
126
178
  'connectors) is documented in docs/self-hosting.',
127
179
  ].join('\n'));
180
+ return true;
128
181
  }
129
182
  async function resolveTargetDir(given, yes) {
130
183
  let targetDir = given;
@@ -188,6 +241,43 @@ function writeEnvFile(targetDir, target, overrides) {
188
241
  (0, node_fs_1.writeFileSync)(localPath, content, { mode: 0o600 });
189
242
  return { content, missingKeys };
190
243
  }
244
+ /**
245
+ * Three ways to arrive at a provider, in precedence order: named on the
246
+ * command line with the key in the environment, declined wholesale by
247
+ * `--yes`, or asked for.
248
+ */
249
+ async function resolveLlmProvider(args) {
250
+ if (args.provider) {
251
+ return providerFromEnvironment(args.provider);
252
+ }
253
+ if (args.yes) {
254
+ return { cancelled: false, choice: undefined };
255
+ }
256
+ return promptLlmProvider();
257
+ }
258
+ /**
259
+ * `--provider=` takes the key from the environment rather than a prompt.
260
+ *
261
+ * Two callers want this. Someone who would rather not type a provider key
262
+ * into another project's CLI — it lands in shell history and in whatever
263
+ * records the terminal — can export it instead. And CI cannot answer a
264
+ * prompt at all, which is why nothing has ever exercised the configured-
265
+ * provider path automatically.
266
+ *
267
+ * A missing variable stops the install instead of quietly falling through to
268
+ * the unconfigured path: `--provider` is an explicit statement that a model
269
+ * should be wired, so silently not wiring one would be the wrong answer to
270
+ * a typo'd variable name in a CI job.
271
+ */
272
+ function providerFromEnvironment(choice) {
273
+ const { apiKeyEnvVar, label } = llm_provider_1.LLM_PROVIDERS[choice];
274
+ const apiKey = process.env[apiKeyEnvVar]?.trim();
275
+ if (!apiKey) {
276
+ clack.cancel(`--provider=${choice} needs the ${label} key in ${apiKeyEnvVar}, and that variable is empty. Export it and run again, or drop the flag to be asked for it.`);
277
+ return { cancelled: true };
278
+ }
279
+ return { cancelled: false, choice: (0, llm_provider_1.resolveLlmProviderChoice)(choice, apiKey) };
280
+ }
191
281
  async function promptLlmProvider() {
192
282
  const choice = await clack.select({
193
283
  message: 'Which LLM provider should power chat?',
@@ -217,10 +307,26 @@ async function promptLlmProvider() {
217
307
  choice: (0, llm_provider_1.resolveLlmProviderChoice)(choice, apiKey),
218
308
  };
219
309
  }
220
- function patchLiteLLMConfig(targetDir, entry) {
310
+ function patchLiteLLMConfig(targetDir, entries) {
221
311
  const configPath = (0, node_path_1.join)(targetDir, 'infra/litellm/config.yaml');
222
- const original = (0, node_fs_1.readFileSync)(configPath, 'utf8');
223
- (0, node_fs_1.writeFileSync)(configPath, (0, litellm_config_1.addLiteLLMModel)(original, entry));
312
+ // Reversed because each insert goes directly under `model_list:`, so the
313
+ // last one applied ends up on top. Reading the file afterwards should show
314
+ // the chat model first and the embedding model under it, in the order the
315
+ // wizard asked about them.
316
+ const patched = [...entries]
317
+ .reverse()
318
+ .reduce((config, entry) => (0, litellm_config_1.addLiteLLMModel)(config, entry), (0, node_fs_1.readFileSync)(configPath, 'utf8'));
319
+ (0, node_fs_1.writeFileSync)(configPath, patched);
320
+ }
321
+ /**
322
+ * Leaves the manual instructions on disk as well as on screen. A terminal
323
+ * that has just scrolled a `docker compose` build past them is exactly the
324
+ * moment someone needs them, and a file survives that.
325
+ */
326
+ function writeManualSetupGuide(targetDir) {
327
+ const path = (0, node_path_1.join)(targetDir, MANUAL_SETUP_FILENAME);
328
+ (0, node_fs_1.writeFileSync)(path, (0, manual_setup_1.manualLlmSetupInstructions)());
329
+ return path;
224
330
  }
225
331
  async function confirmOrSkip(message, yes) {
226
332
  if (yes) {
@@ -250,6 +356,34 @@ async function runStep(spinner, label, successMessage, task) {
250
356
  return true;
251
357
  }
252
358
  async function maybeStartDocker(targetDir, yes) {
359
+ // Before the confirm, not after: sharing a database with an install you
360
+ // already depend on is the kind of thing to decline, and you can only
361
+ // decline it if you are told first.
362
+ if (await (0, tasks_1.ragenStackVolumeExists)()) {
363
+ clack.log.warn([
364
+ 'This machine already runs a Ragen stack, and docker-compose.yml pins',
365
+ 'container, volume and network names globally — so starting this one',
366
+ 'would reuse the existing Postgres and Qdrant data, not create its own.',
367
+ '',
368
+ 'To keep them apart, answer no here and start the stack yourself under a',
369
+ 'distinct name *and* distinct host ports — the name only moves the',
370
+ 'containers and volumes, while the published ports would still collide',
371
+ 'with the running stack:',
372
+ '',
373
+ ` cd ${targetDir} \\`,
374
+ ' && RAGEN_STACK_NAME=my-ragen \\',
375
+ ' POSTGRES_PORT=55532 QDRANT_PORT=6343 QDRANT_GRPC_PORT=6344 \\',
376
+ ' TEMPORAL_PORT=7243 TEMPORAL_UI_PORT=8090 \\',
377
+ ' LITELLM_PORT=4010 LITELLM_DB_PORT=55533 \\',
378
+ ' DOCLING_PORT=5011 REDIS_PORT=56479 \\',
379
+ ' PRESIDIO_ANALYZER_PORT=5012 PRESIDIO_ANONYMIZER_PORT=5013 \\',
380
+ ' docker compose up -d',
381
+ '',
382
+ 'Then update .env.local to match: DATABASE_URL, QDRANT_URL,',
383
+ 'LITELLM_PROXY_URL, REDIS_URL, DOCLING_URL, TEMPORAL_SERVER_ADDRESS and',
384
+ 'the two PRESIDIO_* URLs all name a host port.',
385
+ ].join('\n'));
386
+ }
253
387
  const proceed = await confirmOrSkip('Start the backing services now? (Postgres, Qdrant, Temporal, LiteLLM, Redis, …)', yes);
254
388
  if (!proceed) {
255
389
  return true;
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -2,7 +2,13 @@
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const cli_1 = require("./cli");
5
- (0, cli_1.run)(process.argv.slice(2)).catch((error) => {
5
+ (0, cli_1.run)(process.argv.slice(2))
6
+ .then((completed) => {
7
+ if (!completed) {
8
+ process.exitCode = 1;
9
+ }
10
+ })
11
+ .catch((error) => {
6
12
  console.error(error instanceof Error ? error.message : error);
7
13
  process.exitCode = 1;
8
14
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,+BAA4B;AAE5B,IAAA,SAAG,EAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAClD,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC9D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,+BAA4B;AAE5B,IAAA,SAAG,EAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KACvB,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE;IAClB,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC,CAAC;KACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IACxB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC9D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
@@ -6,16 +6,32 @@ import type { LiteLLMModelEntry } from './litellm-config';
6
6
  * paste a plain OpenAI or Anthropic key and get a working model instead.
7
7
  */
8
8
  export type LlmProviderChoice = 'openai' | 'anthropic';
9
+ export interface LlmEmbeddingsConfig {
10
+ modelName: string;
11
+ litellmModel: string;
12
+ /** Output dimensionality — must match `VECTOR_SIZE`, see rag-core's vector contract. */
13
+ vectorSize: number;
14
+ }
9
15
  export interface LlmProviderConfig {
10
16
  label: string;
11
17
  apiKeyEnvVar: string;
12
18
  modelName: string;
13
19
  litellmModel: string;
20
+ /**
21
+ * Undefined for a provider with no embeddings API of its own. Chat still
22
+ * works; the knowledge base does not, because retrieval has nothing to
23
+ * embed a query with. The wizard says so rather than leaving the shipped
24
+ * Scaleway default in place and letting the first upload fail with a 404
25
+ * for a model the install has no credentials for.
26
+ */
27
+ embeddings?: LlmEmbeddingsConfig;
14
28
  }
15
29
  export declare const LLM_PROVIDERS: Record<LlmProviderChoice, LlmProviderConfig>;
16
30
  export interface LlmProviderChoiceResult {
17
31
  envUpdates: Record<string, string>;
18
- liteLLMEntry: LiteLLMModelEntry;
32
+ liteLLMEntries: LiteLLMModelEntry[];
33
+ /** False when the picked provider cannot serve embeddings — the caller warns. */
34
+ embeddingsConfigured: boolean;
19
35
  }
20
36
  export declare function resolveLlmProviderChoice(choice: LlmProviderChoice, apiKey: string): LlmProviderChoiceResult;
21
37
  //# sourceMappingURL=llm-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"llm-provider.d.ts","sourceRoot":"","sources":["../src/llm-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEvD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,iBAAiB,EAAE,iBAAiB,CAkBtE,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,YAAY,EAAE,iBAAiB,CAAC;CACjC;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,MAAM,GACb,uBAAuB,CAezB"}
1
+ {"version":3,"file":"llm-provider.d.ts","sourceRoot":"","sources":["../src/llm-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,wFAAwF;IACxF,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAClC;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,iBAAiB,EAAE,iBAAiB,CAyBtE,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,cAAc,EAAE,iBAAiB,EAAE,CAAC;IACpC,iFAAiF;IACjF,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,MAAM,GACb,uBAAuB,CAwCzB"}
@@ -8,6 +8,11 @@ exports.LLM_PROVIDERS = {
8
8
  apiKeyEnvVar: 'OPENAI_API_KEY',
9
9
  modelName: 'gpt-4o-mini',
10
10
  litellmModel: 'openai/gpt-4o-mini',
11
+ embeddings: {
12
+ modelName: 'text-embedding-3-small',
13
+ litellmModel: 'openai/text-embedding-3-small',
14
+ vectorSize: 1536,
15
+ },
11
16
  },
12
17
  anthropic: {
13
18
  label: 'Anthropic',
@@ -19,21 +24,45 @@ exports.LLM_PROVIDERS = {
19
24
  // Bedrock traffic under Bedrock's catalog metadata.
20
25
  modelName: 'claude-haiku-4-5-direct',
21
26
  litellmModel: 'anthropic/claude-haiku-4-5-20251001',
27
+ // Anthropic ships no embeddings endpoint, so there is nothing to point
28
+ // EMBEDDINGS_MODEL at with this key alone.
22
29
  },
23
30
  };
24
31
  function resolveLlmProviderChoice(choice, apiKey) {
25
32
  const config = exports.LLM_PROVIDERS[choice];
26
- return {
27
- envUpdates: {
28
- [config.apiKeyEnvVar]: apiKey,
29
- DEFAULT_MODEL: config.modelName,
30
- DEFAULT_MODEL_PROVIDER: 'litellm',
31
- },
32
- liteLLMEntry: {
33
+ const envUpdates = {
34
+ [config.apiKeyEnvVar]: apiKey,
35
+ DEFAULT_MODEL: config.modelName,
36
+ DEFAULT_MODEL_PROVIDER: 'litellm',
37
+ // .env.example ships gemini-2.5-flash here, which needs Vertex
38
+ // credentials. Multi-query expansion is on by default (ADR-15), so
39
+ // leaving it would fail the RAG chain on its *first* step — before the
40
+ // model the user just configured is ever reached.
41
+ REPHRASE_MODEL: config.modelName,
42
+ };
43
+ const liteLLMEntries = [
44
+ {
33
45
  modelName: config.modelName,
34
46
  model: config.litellmModel,
35
47
  apiKeyEnvVar: config.apiKeyEnvVar,
36
48
  },
49
+ ];
50
+ if (config.embeddings) {
51
+ envUpdates.EMBEDDINGS_MODEL = config.embeddings.modelName;
52
+ // VECTOR_SIZE and EMBEDDINGS_MODEL have to agree or Qdrant rejects every
53
+ // upsert — rag-core's vector contract says so, and its default (3584)
54
+ // belongs to the Scaleway model being replaced here.
55
+ envUpdates.VECTOR_SIZE = String(config.embeddings.vectorSize);
56
+ liteLLMEntries.push({
57
+ modelName: config.embeddings.modelName,
58
+ model: config.embeddings.litellmModel,
59
+ apiKeyEnvVar: config.apiKeyEnvVar,
60
+ });
61
+ }
62
+ return {
63
+ envUpdates,
64
+ liteLLMEntries,
65
+ embeddingsConfigured: Boolean(config.embeddings),
37
66
  };
38
67
  }
39
68
  //# sourceMappingURL=llm-provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"llm-provider.js","sourceRoot":"","sources":["../src/llm-provider.ts"],"names":[],"mappings":";;;AA0CA,4DAkBC;AA3CY,QAAA,aAAa,GAAiD;IACzE,MAAM,EAAE;QACN,KAAK,EAAE,QAAQ;QACf,YAAY,EAAE,gBAAgB;QAC9B,SAAS,EAAE,aAAa;QACxB,YAAY,EAAE,oBAAoB;KACnC;IACD,SAAS,EAAE;QACT,KAAK,EAAE,WAAW;QAClB,YAAY,EAAE,mBAAmB;QACjC,gFAAgF;QAChF,uEAAuE;QACvE,qEAAqE;QACrE,sEAAsE;QACtE,oDAAoD;QACpD,SAAS,EAAE,yBAAyB;QACpC,YAAY,EAAE,qCAAqC;KACpD;CACF,CAAC;AAOF,SAAgB,wBAAwB,CACtC,MAAyB,EACzB,MAAc;IAEd,MAAM,MAAM,GAAG,qBAAa,CAAC,MAAM,CAAC,CAAC;IAErC,OAAO;QACL,UAAU,EAAE;YACV,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM;YAC7B,aAAa,EAAE,MAAM,CAAC,SAAS;YAC/B,sBAAsB,EAAE,SAAS;SAClC;QACD,YAAY,EAAE;YACZ,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,KAAK,EAAE,MAAM,CAAC,YAAY;YAC1B,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"llm-provider.js","sourceRoot":"","sources":["../src/llm-provider.ts"],"names":[],"mappings":";;;AAkEA,4DA2CC;AA7EY,QAAA,aAAa,GAAiD;IACzE,MAAM,EAAE;QACN,KAAK,EAAE,QAAQ;QACf,YAAY,EAAE,gBAAgB;QAC9B,SAAS,EAAE,aAAa;QACxB,YAAY,EAAE,oBAAoB;QAClC,UAAU,EAAE;YACV,SAAS,EAAE,wBAAwB;YACnC,YAAY,EAAE,+BAA+B;YAC7C,UAAU,EAAE,IAAI;SACjB;KACF;IACD,SAAS,EAAE;QACT,KAAK,EAAE,WAAW;QAClB,YAAY,EAAE,mBAAmB;QACjC,gFAAgF;QAChF,uEAAuE;QACvE,qEAAqE;QACrE,sEAAsE;QACtE,oDAAoD;QACpD,SAAS,EAAE,yBAAyB;QACpC,YAAY,EAAE,qCAAqC;QACnD,uEAAuE;QACvE,2CAA2C;KAC5C;CACF,CAAC;AASF,SAAgB,wBAAwB,CACtC,MAAyB,EACzB,MAAc;IAEd,MAAM,MAAM,GAAG,qBAAa,CAAC,MAAM,CAAC,CAAC;IAErC,MAAM,UAAU,GAA2B;QACzC,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM;QAC7B,aAAa,EAAE,MAAM,CAAC,SAAS;QAC/B,sBAAsB,EAAE,SAAS;QACjC,+DAA+D;QAC/D,mEAAmE;QACnE,uEAAuE;QACvE,kDAAkD;QAClD,cAAc,EAAE,MAAM,CAAC,SAAS;KACjC,CAAC;IAEF,MAAM,cAAc,GAAwB;QAC1C;YACE,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,KAAK,EAAE,MAAM,CAAC,YAAY;YAC1B,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC;KACF,CAAC;IAEF,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,UAAU,CAAC,gBAAgB,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC;QAC1D,yEAAyE;QACzE,sEAAsE;QACtE,qDAAqD;QACrD,UAAU,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC9D,cAAc,CAAC,IAAI,CAAC;YAClB,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,SAAS;YACtC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,YAAY;YACrC,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,UAAU;QACV,cAAc;QACd,oBAAoB,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;KACjD,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAEzC,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAEpE,eAAO,MAAM,QAAQ,EAAE,aAAa,EAmDnC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,aAAa,EAAE,CAEnE"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAEzC,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAEpE,eAAO,MAAM,QAAQ,EAAE,aAAa,EAqEnC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,aAAa,EAAE,CAEnE"}
package/dist/manifest.js CHANGED
@@ -63,6 +63,24 @@ exports.MANIFEST = [
63
63
  targets: ['root', 'admin'],
64
64
  },
65
65
  // --- Local-dev defaults that correct a stale example value ---
66
+ {
67
+ // Ships commented out, which leaves apps/web sending no Authorization
68
+ // header while docker-compose.yml starts the proxy *with* a master key
69
+ // (`${LITELLM_MASTER_KEY:-sk-litellm-dev-key}`) — so every call to the
70
+ // proxy came back 401 and the model picker silently fell back to a
71
+ // static list.
72
+ //
73
+ // This is deliberately the same literal as the compose default rather
74
+ // than a generated secret: Compose interpolates `${LITELLM_MASTER_KEY}`
75
+ // from the shell or a root `.env`, and never from `.env.local`. A
76
+ // generated value here would land in the app and not in the container,
77
+ // which is the 401 again with a harder-to-see cause. It is a local-dev
78
+ // credential on a loopback port; a deployed install sets its own.
79
+ key: 'LITELLM_MASTER_KEY',
80
+ strategy: 'local-default',
81
+ targets: ['root'],
82
+ value: 'sk-litellm-dev-key',
83
+ },
66
84
  {
67
85
  // docker-compose.yml maps Postgres to host port 55432, not the 5432 that
68
86
  // both .env.example files show — a native/other Postgres on 5432 would
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;;AAwEH,4CAEC;AAvDY,QAAA,QAAQ,GAAoB;IACvC,oDAAoD;IACpD,EAAE,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE;IACrE,EAAE,GAAG,EAAE,oBAAoB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE;IAC7E;QACE,GAAG,EAAE,0BAA0B;QAC/B,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB;IACD;QACE,GAAG,EAAE,qBAAqB;QAC1B,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB;IACD;QACE,6DAA6D;QAC7D,sEAAsE;QACtE,0DAA0D;QAC1D,GAAG,EAAE,mBAAmB;QACxB,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB;IACD;QACE,GAAG,EAAE,oBAAoB;QACzB,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,OAAO,CAAC;KACnB;IAED,yDAAyD;IACzD;QACE,yEAAyE;QACzE,mDAAmD;QACnD,oEAAoE;QACpE,0EAA0E;QAC1E,0BAA0B;QAC1B,GAAG,EAAE,qBAAqB;QAC1B,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;KAC3B;IAED,gEAAgE;IAChE;QACE,yEAAyE;QACzE,uEAAuE;QACvE,0DAA0D;QAC1D,mBAAmB;QACnB,GAAG,EAAE,cAAc;QACnB,QAAQ,EAAE,eAAe;QACzB,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;QAC1B,KAAK,EAAE,qDAAqD;KAC7D;CACF,CAAC;AAEF,SAAgB,gBAAgB,CAAC,MAAiB;IAChD,OAAO,gBAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACpE,CAAC"}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;;AA0FH,4CAEC;AAzEY,QAAA,QAAQ,GAAoB;IACvC,oDAAoD;IACpD,EAAE,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE;IACrE,EAAE,GAAG,EAAE,oBAAoB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE;IAC7E;QACE,GAAG,EAAE,0BAA0B;QAC/B,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB;IACD;QACE,GAAG,EAAE,qBAAqB;QAC1B,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB;IACD;QACE,6DAA6D;QAC7D,sEAAsE;QACtE,0DAA0D;QAC1D,GAAG,EAAE,mBAAmB;QACxB,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,CAAC;KAClB;IACD;QACE,GAAG,EAAE,oBAAoB;QACzB,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,OAAO,CAAC;KACnB;IAED,yDAAyD;IACzD;QACE,yEAAyE;QACzE,mDAAmD;QACnD,oEAAoE;QACpE,0EAA0E;QAC1E,0BAA0B;QAC1B,GAAG,EAAE,qBAAqB;QAC1B,QAAQ,EAAE,iBAAiB;QAC3B,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;KAC3B;IAED,gEAAgE;IAChE;QACE,sEAAsE;QACtE,uEAAuE;QACvE,uEAAuE;QACvE,mEAAmE;QACnE,eAAe;QACf,EAAE;QACF,sEAAsE;QACtE,wEAAwE;QACxE,kEAAkE;QAClE,uEAAuE;QACvE,uEAAuE;QACvE,kEAAkE;QAClE,GAAG,EAAE,oBAAoB;QACzB,QAAQ,EAAE,eAAe;QACzB,OAAO,EAAE,CAAC,MAAM,CAAC;QACjB,KAAK,EAAE,oBAAoB;KAC5B;IACD;QACE,yEAAyE;QACzE,uEAAuE;QACvE,0DAA0D;QAC1D,mBAAmB;QACnB,GAAG,EAAE,cAAc;QACnB,QAAQ,EAAE,eAAe;QACzB,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;QAC1B,KAAK,EAAE,qDAAqD;KAC7D;CACF,CAAC;AAEF,SAAgB,gBAAgB,CAAC,MAAiB;IAChD,OAAO,gBAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACpE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function manualLlmSetupInstructions(): string;
2
+ //# sourceMappingURL=manual-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manual-setup.d.ts","sourceRoot":"","sources":["../src/manual-setup.ts"],"names":[],"mappings":"AAsEA,wBAAgB,0BAA0B,IAAI,MAAM,CAkCnD"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.manualLlmSetupInstructions = manualLlmSetupInstructions;
4
+ const llm_provider_1 = require("./llm-provider");
5
+ /**
6
+ * What to write by hand when the wizard did not take an API key.
7
+ *
8
+ * Pasting a provider key into someone else's CLI is a reasonable thing to
9
+ * refuse, so skipping has to leave a person able to finish the job rather
10
+ * than a one-line "chat will not work". The text is generated from
11
+ * `LLM_PROVIDERS`, not written out twice, so the instructions cannot drift
12
+ * from what the wizard itself would have configured.
13
+ */
14
+ const SELF_HOSTING_DOCS = 'https://docs.ragen.ai/docs/self-hosting';
15
+ function providerSection(choice) {
16
+ const config = llm_provider_1.LLM_PROVIDERS[choice];
17
+ const envLines = [
18
+ `${config.apiKeyEnvVar}=<your ${config.label} key>`,
19
+ 'DEFAULT_MODEL_PROVIDER=litellm',
20
+ `DEFAULT_MODEL=${config.modelName}`,
21
+ `REPHRASE_MODEL=${config.modelName}`,
22
+ ];
23
+ const yamlLines = [
24
+ ` - model_name: ${config.modelName}`,
25
+ ' litellm_params:',
26
+ ` model: ${config.litellmModel}`,
27
+ ` api_key: os.environ/${config.apiKeyEnvVar}`,
28
+ ];
29
+ if (config.embeddings) {
30
+ envLines.push(`EMBEDDINGS_MODEL=${config.embeddings.modelName}`, `VECTOR_SIZE=${config.embeddings.vectorSize}`);
31
+ yamlLines.push(` - model_name: ${config.embeddings.modelName}`, ' litellm_params:', ` model: ${config.embeddings.litellmModel}`, ` api_key: os.environ/${config.apiKeyEnvVar}`);
32
+ }
33
+ return [
34
+ `### ${config.label}`,
35
+ '',
36
+ '`.env.local` (repository root):',
37
+ '',
38
+ '```',
39
+ ...envLines,
40
+ '```',
41
+ '',
42
+ '`infra/litellm/config.yaml`, under the existing `model_list:` key:',
43
+ '',
44
+ '```yaml',
45
+ ...yamlLines,
46
+ '```',
47
+ ...(config.embeddings
48
+ ? []
49
+ : [
50
+ '',
51
+ `${config.label} has no embeddings API, so the knowledge base needs a`,
52
+ 'second provider. Leave `EMBEDDINGS_MODEL` and `VECTOR_SIZE` alone and',
53
+ 'add one (OpenAI, Scaleway or Cohere) before uploading documents.',
54
+ ]),
55
+ '',
56
+ ];
57
+ }
58
+ function manualLlmSetupInstructions() {
59
+ return [
60
+ '# Configure a chat model',
61
+ '',
62
+ 'This installation has no LLM provider yet, so chat and the knowledge',
63
+ 'base will not work until one is configured. Nothing here needs to go',
64
+ 'through a CLI — edit the two files below yourself.',
65
+ '',
66
+ 'Pick one provider, apply both edits, then restart the proxy:',
67
+ '',
68
+ '```bash',
69
+ 'docker compose restart litellm',
70
+ '```',
71
+ '',
72
+ ...providerSection('openai'),
73
+ ...providerSection('anthropic'),
74
+ '## Before you upload anything',
75
+ '',
76
+ '`VECTOR_SIZE` must match the embedding model **before** the first',
77
+ "document is indexed. Qdrant fixes a collection's dimensionality when it",
78
+ 'is created, so changing it later means deleting the collections and',
79
+ 're-indexing everything.',
80
+ '',
81
+ '## Check it worked',
82
+ '',
83
+ '```bash',
84
+ 'curl -s -H "Authorization: Bearer $LITELLM_MASTER_KEY" \\',
85
+ ' http://localhost:4000/v1/models',
86
+ '```',
87
+ '',
88
+ `Anything else — S3 storage, encryption at rest, Stripe, email, MCP`,
89
+ `connectors — is documented at ${SELF_HOSTING_DOCS}.`,
90
+ '',
91
+ ].join('\n');
92
+ }
93
+ //# sourceMappingURL=manual-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manual-setup.js","sourceRoot":"","sources":["../src/manual-setup.ts"],"names":[],"mappings":";;AAsEA,gEAkCC;AAxGD,iDAAuE;AAEvE;;;;;;;;GAQG;AAEH,MAAM,iBAAiB,GAAG,yCAAyC,CAAC;AAEpE,SAAS,eAAe,CAAC,MAAyB;IAChD,MAAM,MAAM,GAAG,4BAAa,CAAC,MAAM,CAAC,CAAC;IAErC,MAAM,QAAQ,GAAG;QACf,GAAG,MAAM,CAAC,YAAY,UAAU,MAAM,CAAC,KAAK,OAAO;QACnD,gCAAgC;QAChC,iBAAiB,MAAM,CAAC,SAAS,EAAE;QACnC,kBAAkB,MAAM,CAAC,SAAS,EAAE;KACrC,CAAC;IAEF,MAAM,SAAS,GAAG;QAChB,mBAAmB,MAAM,CAAC,SAAS,EAAE;QACrC,qBAAqB;QACrB,gBAAgB,MAAM,CAAC,YAAY,EAAE;QACrC,6BAA6B,MAAM,CAAC,YAAY,EAAE;KACnD,CAAC;IAEF,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,QAAQ,CAAC,IAAI,CACX,oBAAoB,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,EACjD,eAAe,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAC9C,CAAC;QACF,SAAS,CAAC,IAAI,CACZ,mBAAmB,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,EAChD,qBAAqB,EACrB,gBAAgB,MAAM,CAAC,UAAU,CAAC,YAAY,EAAE,EAChD,6BAA6B,MAAM,CAAC,YAAY,EAAE,CACnD,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,MAAM,CAAC,KAAK,EAAE;QACrB,EAAE;QACF,iCAAiC;QACjC,EAAE;QACF,KAAK;QACL,GAAG,QAAQ;QACX,KAAK;QACL,EAAE;QACF,oEAAoE;QACpE,EAAE;QACF,SAAS;QACT,GAAG,SAAS;QACZ,KAAK;QACL,GAAG,CAAC,MAAM,CAAC,UAAU;YACnB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,EAAE;gBACF,GAAG,MAAM,CAAC,KAAK,uDAAuD;gBACtE,uEAAuE;gBACvE,kEAAkE;aACnE,CAAC;QACN,EAAE;KACH,CAAC;AACJ,CAAC;AAED,SAAgB,0BAA0B;IACxC,OAAO;QACL,0BAA0B;QAC1B,EAAE;QACF,sEAAsE;QACtE,sEAAsE;QACtE,oDAAoD;QACpD,EAAE;QACF,8DAA8D;QAC9D,EAAE;QACF,SAAS;QACT,gCAAgC;QAChC,KAAK;QACL,EAAE;QACF,GAAG,eAAe,CAAC,QAAQ,CAAC;QAC5B,GAAG,eAAe,CAAC,WAAW,CAAC;QAC/B,+BAA+B;QAC/B,EAAE;QACF,mEAAmE;QACnE,yEAAyE;QACzE,qEAAqE;QACrE,yBAAyB;QACzB,EAAE;QACF,oBAAoB;QACpB,EAAE;QACF,SAAS;QACT,2DAA2D;QAC3D,mCAAmC;QACnC,KAAK;QACL,EAAE;QACF,oEAAoE;QACpE,iCAAiC,iBAAiB,GAAG;QACrD,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Whether this Node can be used to create a Ragen installation.
3
+ *
4
+ * The distinction that matters: **the installation** needs Node 24, not this
5
+ * CLI. The CLI itself runs happily on older majors — it was published and
6
+ * verified on Node 22 by accident — so refusing on the grounds that "this
7
+ * tool requires Node 24" would be both untrue and unhelpfully broad.
8
+ *
9
+ * What genuinely breaks is the first-run setup the wizard performs on the
10
+ * caller's behalf: `npm install` across the monorepo, `prisma generate`,
11
+ * `migrate deploy` and the seed all run under whatever Node invoked the
12
+ * wizard. Getting a half-built `node_modules` out of that is the expensive
13
+ * failure, because it surfaces much later and nowhere near its cause. npm's
14
+ * own `EBADENGINE` warning does fire, but as one line inside a wall of
15
+ * install output, and it does not say what will break.
16
+ *
17
+ * So the check is gated on what the wizard is about to *do*:
18
+ *
19
+ * - running the setup steps → refuse, before anything is cloned
20
+ * - `--skip-install` → proceed, because nothing runs here; warn instead,
21
+ * since the scaffolded app still needs Node 24 to start
22
+ *
23
+ * `--yes` deliberately does not bypass it. That flag means "accept the
24
+ * defaults", not "ignore a requirement".
25
+ */
26
+ /**
27
+ * Kept in step with this package's `engines.node` by
28
+ * `src/__tests__/node-version.test.ts`, and with the repository's own Node
29
+ * version documented in AGENTS.md ("Node.js 24.x (Active LTS)").
30
+ */
31
+ export declare const REQUIRED_NODE_MAJOR = 24;
32
+ export type NodeVersionVerdict = {
33
+ kind: 'ok';
34
+ } | {
35
+ kind: 'warn';
36
+ message: string;
37
+ } | {
38
+ kind: 'refuse';
39
+ message: string;
40
+ };
41
+ export interface NodeVersionCheck {
42
+ /** As `process.version` gives it, e.g. `v22.22.3`. */
43
+ version: string;
44
+ /** False when `--skip-install` means the wizard runs nothing itself. */
45
+ willRunSetup: boolean;
46
+ }
47
+ /**
48
+ * Returns undefined for anything that is not a recognisable Node version, so
49
+ * an unexpected format cannot be read as "too old" and block an install that
50
+ * would have worked.
51
+ */
52
+ export declare function parseNodeMajor(version: string): number | undefined;
53
+ export declare function checkNodeVersion({ version, willRunSetup, }: NodeVersionCheck): NodeVersionVerdict;
54
+ //# sourceMappingURL=node-version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-version.d.ts","sourceRoot":"","sources":["../src/node-version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMlE;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,YAAY,GACb,EAAE,gBAAgB,GAAG,kBAAkB,CAkCvC"}
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ /**
3
+ * Whether this Node can be used to create a Ragen installation.
4
+ *
5
+ * The distinction that matters: **the installation** needs Node 24, not this
6
+ * CLI. The CLI itself runs happily on older majors — it was published and
7
+ * verified on Node 22 by accident — so refusing on the grounds that "this
8
+ * tool requires Node 24" would be both untrue and unhelpfully broad.
9
+ *
10
+ * What genuinely breaks is the first-run setup the wizard performs on the
11
+ * caller's behalf: `npm install` across the monorepo, `prisma generate`,
12
+ * `migrate deploy` and the seed all run under whatever Node invoked the
13
+ * wizard. Getting a half-built `node_modules` out of that is the expensive
14
+ * failure, because it surfaces much later and nowhere near its cause. npm's
15
+ * own `EBADENGINE` warning does fire, but as one line inside a wall of
16
+ * install output, and it does not say what will break.
17
+ *
18
+ * So the check is gated on what the wizard is about to *do*:
19
+ *
20
+ * - running the setup steps → refuse, before anything is cloned
21
+ * - `--skip-install` → proceed, because nothing runs here; warn instead,
22
+ * since the scaffolded app still needs Node 24 to start
23
+ *
24
+ * `--yes` deliberately does not bypass it. That flag means "accept the
25
+ * defaults", not "ignore a requirement".
26
+ */
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.REQUIRED_NODE_MAJOR = void 0;
29
+ exports.parseNodeMajor = parseNodeMajor;
30
+ exports.checkNodeVersion = checkNodeVersion;
31
+ /**
32
+ * Kept in step with this package's `engines.node` by
33
+ * `src/__tests__/node-version.test.ts`, and with the repository's own Node
34
+ * version documented in AGENTS.md ("Node.js 24.x (Active LTS)").
35
+ */
36
+ exports.REQUIRED_NODE_MAJOR = 24;
37
+ /**
38
+ * Returns undefined for anything that is not a recognisable Node version, so
39
+ * an unexpected format cannot be read as "too old" and block an install that
40
+ * would have worked.
41
+ */
42
+ function parseNodeMajor(version) {
43
+ const match = /^v?(\d+)\./.exec(version.trim());
44
+ if (!match) {
45
+ return undefined;
46
+ }
47
+ return Number(match[1]);
48
+ }
49
+ function checkNodeVersion({ version, willRunSetup, }) {
50
+ const major = parseNodeMajor(version);
51
+ if (major === undefined || major >= exports.REQUIRED_NODE_MAJOR) {
52
+ return { kind: 'ok' };
53
+ }
54
+ if (!willRunSetup) {
55
+ return {
56
+ kind: 'warn',
57
+ message: [
58
+ `You are on Node ${major}, and a Ragen installation needs Node ${exports.REQUIRED_NODE_MAJOR}.`,
59
+ 'Nothing is being installed here, so the files will be written anyway —',
60
+ 'but switch before running npm install or the app in the new directory.',
61
+ ].join(' '),
62
+ };
63
+ }
64
+ return {
65
+ kind: 'refuse',
66
+ message: [
67
+ `A Ragen installation needs Node ${exports.REQUIRED_NODE_MAJOR}, and this is Node ${major}.`,
68
+ '',
69
+ 'Stopping before anything is written: the setup this runs for you —',
70
+ 'npm install, prisma generate, migrate and seed — would run under this',
71
+ 'Node and leave a tree that fails later, somewhere that does not point',
72
+ 'back here.',
73
+ '',
74
+ ` nvm use ${exports.REQUIRED_NODE_MAJOR} # or fnm, volta, asdf, …`,
75
+ '',
76
+ 'Or pass --skip-install to write the files now and run the setup',
77
+ 'yourself on a supported Node.',
78
+ ].join('\n'),
79
+ };
80
+ }
81
+ //# sourceMappingURL=node-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-version.js","sourceRoot":"","sources":["../src/node-version.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;;;AA0BH,wCAMC;AAED,4CAqCC;AArED;;;;GAIG;AACU,QAAA,mBAAmB,GAAG,EAAE,CAAC;AActC;;;;GAIG;AACH,SAAgB,cAAc,CAAC,OAAe;IAC5C,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1B,CAAC;AAED,SAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,YAAY,GACK;IACjB,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAEtC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,IAAI,2BAAmB,EAAE,CAAC;QACxD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,CAAC;IAED,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE;gBACP,mBAAmB,KAAK,yCAAyC,2BAAmB,GAAG;gBACvF,wEAAwE;gBACxE,wEAAwE;aACzE,CAAC,IAAI,CAAC,GAAG,CAAC;SACZ,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP,mCAAmC,2BAAmB,sBAAsB,KAAK,GAAG;YACpF,EAAE;YACF,oEAAoE;YACpE,uEAAuE;YACvE,uEAAuE;YACvE,YAAY;YACZ,EAAE;YACF,aAAa,2BAAmB,6BAA6B;YAC7D,EAAE;YACF,iEAAiE;YACjE,+BAA+B;SAChC,CAAC,IAAI,CAAC,IAAI,CAAC;KACb,CAAC;AACJ,CAAC"}
package/dist/tasks.d.ts CHANGED
@@ -14,6 +14,21 @@ export interface MigrateOptions {
14
14
  retryDelayMs?: number;
15
15
  }
16
16
  export declare function isDockerAvailable(): Promise<boolean>;
17
+ /**
18
+ * Whether this Docker daemon already runs a Ragen stack.
19
+ *
20
+ * docker-compose.yml pins container, volume and network names instead of
21
+ * letting Compose prefix them per project, so a second install does not just
22
+ * collide on the container names — it silently attaches to the *same*
23
+ * postgres and qdrant volumes as the first one. Checking the volume rather
24
+ * than a container catches a stack that is merely stopped, which is the
25
+ * case that looks safest and is not.
26
+ *
27
+ * Reads RAGEN_STACK_NAME for the same reason compose does: someone already
28
+ * running a stack under a name of their own would otherwise be told their
29
+ * machine is clear, and collide with it.
30
+ */
31
+ export declare function ragenStackVolumeExists(): Promise<boolean>;
17
32
  export declare function startDockerServices({ cwd }: RunOptions): Promise<void>;
18
33
  export declare function installDependencies({ cwd }: RunOptions): Promise<void>;
19
34
  export declare function generatePrismaClient({ cwd, env, }: RunOptions): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAU1D;AAED,wBAAsB,mBAAmB,CAAC,EAAE,GAAG,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED,wBAAsB,mBAAmB,CAAC,EAAE,GAAG,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED,wBAAsB,oBAAoB,CAAC,EACzC,GAAG,EACH,GAAG,GACJ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5B;AAED,wBAAsB,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1E;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,UAAU,EACxB,EAAE,OAAW,EAAE,YAAmB,EAAE,GAAE,cAAmB,GACxD,OAAO,CAAC,IAAI,CAAC,CAsBf"}
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAU1D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,OAAO,CAAC,CAgB/D;AAED,wBAAsB,mBAAmB,CAAC,EAAE,GAAG,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED,wBAAsB,mBAAmB,CAAC,EAAE,GAAG,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED,wBAAsB,oBAAoB,CAAC,EACzC,GAAG,EACH,GAAG,GACJ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5B;AAED,wBAAsB,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1E;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,UAAU,EACxB,EAAE,OAAW,EAAE,YAAmB,EAAE,GAAE,cAAmB,GACxD,OAAO,CAAC,IAAI,CAAC,CAsBf"}
package/dist/tasks.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isDockerAvailable = isDockerAvailable;
4
+ exports.ragenStackVolumeExists = ragenStackVolumeExists;
4
5
  exports.startDockerServices = startDockerServices;
5
6
  exports.installDependencies = installDependencies;
6
7
  exports.generatePrismaClient = generatePrismaClient;
@@ -19,6 +20,33 @@ async function isDockerAvailable() {
19
20
  return false;
20
21
  }
21
22
  }
23
+ /**
24
+ * Whether this Docker daemon already runs a Ragen stack.
25
+ *
26
+ * docker-compose.yml pins container, volume and network names instead of
27
+ * letting Compose prefix them per project, so a second install does not just
28
+ * collide on the container names — it silently attaches to the *same*
29
+ * postgres and qdrant volumes as the first one. Checking the volume rather
30
+ * than a container catches a stack that is merely stopped, which is the
31
+ * case that looks safest and is not.
32
+ *
33
+ * Reads RAGEN_STACK_NAME for the same reason compose does: someone already
34
+ * running a stack under a name of their own would otherwise be told their
35
+ * machine is clear, and collide with it.
36
+ */
37
+ async function ragenStackVolumeExists() {
38
+ const stackName = process.env.RAGEN_STACK_NAME?.trim() || 'ragen';
39
+ const postgresVolume = `${stackName}-postgres-data`;
40
+ try {
41
+ const { stdout } = await (0, execa_1.execa)('docker', ['volume', 'ls', '--format', '{{.Name}}'], { timeout: 10_000 });
42
+ return stdout.split('\n').some((name) => name.trim() === postgresVolume);
43
+ }
44
+ catch {
45
+ // Same reasoning as isDockerAvailable: an unreachable daemon is not a
46
+ // reason to fail, the caller is about to find that out anyway.
47
+ return false;
48
+ }
49
+ }
22
50
  async function startDockerServices({ cwd }) {
23
51
  await (0, execa_1.execa)('docker', ['compose', 'up', '-d'], { cwd, stdio: 'inherit' });
24
52
  }
package/dist/tasks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":";;AAmBA,8CAUC;AAED,kDAEC;AAED,kDAEC;AAED,oDAKC;AAED,oCAEC;AAOD,0CAyBC;AAhFD,iCAA8B;AAmBvB,KAAK,UAAU,iBAAiB;IACrC,IAAI,CAAC;QACH,sEAAsE;QACtE,wEAAwE;QACxE,mBAAmB;QACnB,MAAM,IAAA,aAAK,EAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,mBAAmB,CAAC,EAAE,GAAG,EAAc;IAC3D,MAAM,IAAA,aAAK,EAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AAC5E,CAAC;AAEM,KAAK,UAAU,mBAAmB,CAAC,EAAE,GAAG,EAAc;IAC3D,MAAM,IAAA,aAAK,EAAC,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AAC7D,CAAC;AAEM,KAAK,UAAU,oBAAoB,CAAC,EACzC,GAAG,EACH,GAAG,GACQ;IACX,MAAM,IAAA,aAAK,EAAC,KAAK,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AAChF,CAAC;AAEM,KAAK,UAAU,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,EAAc;IACzD,MAAM,IAAA,aAAK,EAAC,KAAK,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AACzE,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,eAAe,CACnC,EAAE,GAAG,EAAE,GAAG,EAAc,EACxB,EAAE,OAAO,GAAG,CAAC,EAAE,YAAY,GAAG,IAAI,KAAqB,EAAE;IAEzD,IAAI,SAAkB,CAAC;IAEvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,OAAO,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,MAAM,IAAA,aAAK,EAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE;gBAClD,GAAG;gBACH,GAAG;gBACH,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,GAAG,KAAK,CAAC;YAClB,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;gBACtB,MAAM,KAAK,CAAC,YAAY,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CACb,sCAAsC,OAAO,sCAAsC,MAAM,CAAC,SAAS,CAAC,EAAE,CACvG,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-ragen-app",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "private": false,
5
5
  "description": "Scaffold a self-hosted Ragen AI installation with one command",
6
6
  "license": "Apache-2.0",
@@ -22,7 +22,7 @@
22
22
  "scripts": {
23
23
  "build": "tsc -p tsconfig.json",
24
24
  "clean": "rm -rf dist",
25
- "prepare": "npm run build",
25
+ "prepare": "npm run clean && npm run build",
26
26
  "lint": "eslint",
27
27
  "typecheck": "tsc --noEmit --incremental --tsBuildInfoFile ./typecheck.tsbuildinfo"
28
28
  },