@nitsan-ai/ragsuite-test 0.1.4 → 0.1.5

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
@@ -1,22 +1,30 @@
1
1
  # RAGSuite test CLI (`ragsuite-test`)
2
2
 
3
- npm-style install: **init once**, then **start / update / stop** — no `--repo-root` every time.
3
+ npm-style deploy: **init once**, then **start / update / stop** via host **npm scripts** **no Docker**.
4
4
 
5
5
  ```bash
6
6
  npm install -g @nitsan-ai/ragsuite-test
7
7
 
8
8
  # First time only
9
9
  ragsuite-test init
10
- # or without app source on disk:
11
- # ragsuite-test init --from-images
10
+ # clones ~/ragsuite-test
12
11
 
12
+ # Needs Postgres :5436 (db ragsuite_v3) and Redis :6382 on the host
13
13
  ragsuite-test start
14
- # API http://localhost:9090 · Web http://localhost:9091
14
+ # API http://localhost:9090 · Web http://localhost:9191
15
15
 
16
16
  ragsuite-test stop
17
17
  ```
18
18
 
19
- Active install is remembered in `~/.ragsuite-test/config.json` (default app dir: `~/ragsuite-test`).
19
+ Same under the hood as:
20
+
21
+ ```bash
22
+ cd ~/ragsuite-test
23
+ npm start # scripts/native-start.sh
24
+ npm run stop # scripts/native-stop.sh
25
+ ```
26
+
27
+ Active install is remembered in `~/.ragsuite-test/config.json`.
20
28
 
21
29
  ---
22
30
 
@@ -24,28 +32,28 @@ Active install is remembered in `~/.ragsuite-test/config.json` (default app dir:
24
32
 
25
33
  ```bash
26
34
  npm install -g @nitsan-ai/ragsuite-test@latest
27
- ragsuite-test update
35
+ ragsuite-test update # git pull only
28
36
  ragsuite-test start
29
37
  ```
30
38
 
31
- | Install type | What `update` does |
32
- |--------------|--------------------|
33
- | Git (`init`) | `git pull` in `~/ragsuite-test` |
34
- | Images (`init --from-images`) | `docker compose pull` + recreate containers |
35
-
36
39
  **Never** run `docker compose down -v` or `init --force` unless you mean to wipe data.
37
40
 
38
- If you already installed and run `init` again → it says **Already installed** and exits OK (does not wipe).
41
+ If you already installed and run `init` again → **Already installed** (exit OK).
39
42
 
40
43
  ---
41
44
 
42
- ## Which first-time install?
45
+ ## Prerequisites (host)
46
+
47
+ | Tool | Notes |
48
+ |------|--------|
49
+ | Node.js 18+ | |
50
+ | Python 3 + venv | backend |
51
+ | Yarn | Expo frontend |
52
+ | Git | `init` clone |
53
+ | Postgres | `localhost:5436`, database `ragsuite_v3` |
54
+ | Redis | `localhost:6382` |
43
55
 
44
- | | **Git source** `init` | **Images** `init --from-images` |
45
- |--|----------------------|----------------------------------|
46
- | App code on disk | Yes | No |
47
- | Docker | Optional (`--mode native`) | Required |
48
- | Best for | Dev / native | Testers / “just run it” |
56
+ Docker is **not** required for this CLI.
49
57
 
50
58
  ---
51
59
 
@@ -53,17 +61,18 @@ If you already installed and run `init` again → it says **Already installed**
53
61
 
54
62
  | Command | Purpose |
55
63
  |---------|---------|
56
- | `init` | First-time install |
57
- | `start` | Start app (uses saved install path) |
58
- | `stop` | Stop app (volumes kept) |
59
- | `update` | Upgrade code/images in place |
60
- | `doctor` | Health / prereqs |
64
+ | `init` | First-time git install |
65
+ | `start` | `scripts/native-start.sh` |
66
+ | `stop` | `scripts/native-stop.sh` (host PIDs only) |
67
+ | `update` | `git pull` in place |
68
+ | `doctor` | Native prereq checks |
69
+ | `logs` | Tail `.ragsuite/native/*.log` |
61
70
  | `version` | CLI version |
62
71
 
63
72
  ## Ports
64
73
 
65
- API **9090** · Web **9091** (Docker/images) · Web **9191** (native) · Postgres **5436** · Redis **6382**
74
+ API **9090** · Web **9191** · Postgres **5436** · Redis **6382** · Chroma **8004** (started by native-start if needed)
66
75
 
67
76
  ## Publish (maintainers)
68
77
 
69
- See [PUBLISH.md](./PUBLISH.md). Also publish GHCR images before `--from-images` works for others.
78
+ See [PUBLISH.md](./PUBLISH.md).
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@nitsan-ai/ragsuite-test",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "private": false,
5
- "description": "RAGSuite testing CLI — init once, then start/update/stop (npm-style).",
5
+ "description": "RAGSuite testing CLI — init once, then start/update/stop via native npm scripts (no Docker).",
6
6
  "main": "src/index.js",
7
7
  "bin": {
8
8
  "ragsuite-test": "./bin/ragsuite-test.js"
@@ -10,7 +10,6 @@
10
10
  "files": [
11
11
  "bin/",
12
12
  "src/",
13
- "templates/",
14
13
  "package.json",
15
14
  "README.md",
16
15
  "LICENSE"
@@ -2,20 +2,22 @@
2
2
 
3
3
  const path = require('path');
4
4
  const { resolveMode } = require('../utils/config');
5
- const { resolveRepoRoot, isImagesInstall } = require('../utils/paths');
5
+ const { resolveRepoRoot, assertNativeDeploy } = require('../utils/paths');
6
6
  const { runScript } = require('../utils/spawn');
7
+ const { error } = require('../utils/log');
7
8
 
8
9
  const name = 'doctor';
9
- const summary = 'Run doctor checks (git or images install)';
10
+ const summary = 'Check native deploy prerequisites';
10
11
 
11
12
  function help() {
12
13
  return `Usage: ragsuite-test doctor [options]
13
14
 
14
- Git install: scripts/doctor.sh
15
- Images install: scripts/docker-doctor-images.sh
15
+ Runs scripts/doctor.sh with RAGSUITE_MODE=native.
16
+
17
+ Postgres (:5436) and Redis (:6382) must be reachable for a real install.
18
+ In CI smoke, runtime TCP checks are skipped unless RAGSUITE_DOCTOR_STRICT=1.
16
19
 
17
20
  Options:
18
- --mode <docker|native> Git install gate
19
21
  --repo-root <path>
20
22
  --dry-run
21
23
  `;
@@ -26,18 +28,16 @@ function run(ctx) {
26
28
  cwd: ctx.cwd,
27
29
  repoRootFlag: ctx.globals.repoRoot,
28
30
  });
29
- const images = isImagesInstall(repoRoot);
30
- const mode = images
31
- ? 'docker'
32
- : resolveMode({
33
- flagMode: ctx.globals.mode,
34
- repoRoot,
35
- env: ctx.env,
36
- });
37
- const script = images ? 'docker-doctor-images.sh' : 'doctor.sh';
38
- return runScript(repoRoot, path.join('scripts', script), [], {
31
+ try {
32
+ assertNativeDeploy(repoRoot);
33
+ } catch (err) {
34
+ error(err.message);
35
+ return 1;
36
+ }
37
+
38
+ return runScript(repoRoot, path.join('scripts', 'doctor.sh'), [], {
39
39
  dryRun: ctx.globals.dryRun,
40
- env: { ...ctx.env, RAGSUITE_MODE: mode },
40
+ env: { ...ctx.env, RAGSUITE_MODE: resolveMode() },
41
41
  });
42
42
  }
43
43
 
@@ -5,7 +5,6 @@ const { writeConfig, CONFIG_DIR, readConfig } = require('../utils/config');
5
5
  const {
6
6
  ensureRagsuiteDir,
7
7
  resolveRepoRoot,
8
- isImagesInstall,
9
8
  looksLikeRepoRoot,
10
9
  isDirEmptyOrMissing,
11
10
  } = require('../utils/paths');
@@ -16,12 +15,8 @@ const {
16
15
  defaultInstallDir,
17
16
  cloneGitToInstallDir,
18
17
  } = require('../utils/git-install');
19
- const { materializeImagesInstall } = require('../utils/images-install');
20
18
  const { detectOs } = require('../utils/os-detect');
21
- const {
22
- printPrereqs,
23
- resolvePreferredMode,
24
- } = require('../utils/prereqs');
19
+ const { printPrereqs, resolvePreferredMode } = require('../utils/prereqs');
25
20
  const {
26
21
  generateJwtSecret,
27
22
  isPlaceholderSecret,
@@ -31,27 +26,26 @@ const { assertPortsFree } = require('../utils/port');
31
26
  const { info, warn, error } = require('../utils/log');
32
27
 
33
28
  const name = 'init';
34
- const summary = 'First-time install (git or images). Safe if already installed.';
29
+ const summary = 'First-time install (git + native npm scripts). Safe if already installed.';
35
30
 
36
- function printSuccess(repoRoot, mode, source) {
31
+ function printSuccess(repoRoot) {
37
32
  info('');
38
33
  info('=== Install complete ===');
39
34
  info(` Install dir : ${repoRoot}`);
40
- info(` Source : ${source}`);
41
- info(` Mode : ${mode}`);
35
+ info(' Mode : native (npm scripts — no Docker)');
42
36
  info('');
43
37
  info(' API http://localhost:9090');
44
- if (source === 'images' || mode === 'docker') {
45
- info(' Web http://localhost:9091');
46
- } else {
47
- info(' Web http://localhost:9191');
48
- }
38
+ info(' Web http://localhost:9191');
49
39
  info('');
50
40
  info('Next (no --repo-root needed):');
51
41
  info(' ragsuite-test start');
52
42
  info(' ragsuite-test stop');
53
43
  info(' ragsuite-test update # later upgrades, keeps data');
54
44
  info('');
45
+ info('Or in the install directory:');
46
+ info(' npm start');
47
+ info(' npm run stop');
48
+ info('');
55
49
  info(installHint());
56
50
  }
57
51
 
@@ -61,11 +55,11 @@ function printAlreadyInstalled(repoRoot) {
61
55
  info('');
62
56
  info('=== Already installed ===');
63
57
  info(` ${repoRoot}`);
64
- if (cfg) info(` source=${cfg.source} mode=${cfg.mode}`);
58
+ if (cfg) info(` source=${cfg.source} mode=native`);
65
59
  info('');
66
60
  info('Use:');
67
- info(' ragsuite-test start # run the app');
68
- info(' ragsuite-test update # upgrade code/images (keeps .env + data)');
61
+ info(' ragsuite-test start # run the app (npm scripts)');
62
+ info(' ragsuite-test update # upgrade code (keeps .env + data)');
69
63
  info(' ragsuite-test stop');
70
64
  info('');
71
65
  info('Do NOT run init --force unless you intend to wipe and reinstall.');
@@ -78,24 +72,24 @@ function isInitializedInstall(dir) {
78
72
  function help() {
79
73
  return `Usage: ragsuite-test init [options]
80
74
 
81
- First-time setup only (npm-style):
75
+ First-time setup (npm-style, no Docker):
82
76
 
83
77
  ragsuite-test init # git clone → ~/ragsuite-test
84
- ragsuite-test init --from-images # Docker images only (no app source)
78
+ ragsuite-test start # scripts/native-start.sh
85
79
 
86
80
  If already installed, init exits OK and tells you to start/update.
87
81
 
82
+ Requires host Postgres (:5436) and Redis (:6382).
83
+
88
84
  Day-to-day:
89
85
  ragsuite-test start
90
86
  ragsuite-test update
91
87
  ragsuite-test stop
92
88
 
93
89
  Options:
94
- --from-images Images-only install
95
90
  --from-git [url] Clone URL (default public repo)
96
91
  --repo-root <path> Point at an existing checkout
97
92
  --install-dir <path> Default: ~/ragsuite-test
98
- --mode <docker|native> Git install only
99
93
  --force Wipe install dir and reinstall (destructive)
100
94
  --yes, -y Non-interactive
101
95
  `;
@@ -118,10 +112,9 @@ function resolveLlmOverride(g, env) {
118
112
  return null;
119
113
  }
120
114
 
121
- function countSources(fromGit, fromImages, repoRootFlag) {
115
+ function countSources(fromGit, repoRootFlag) {
122
116
  let n = 0;
123
117
  if (fromGit !== null && fromGit !== undefined) n += 1;
124
- if (fromImages) n += 1;
125
118
  if (repoRootFlag) n += 1;
126
119
  return n;
127
120
  }
@@ -135,8 +128,30 @@ async function run(ctx) {
135
128
  return 1;
136
129
  }
137
130
 
138
- if (countSources(g.fromGit, g.fromImages, g.repoRoot) > 1) {
139
- error('Use only one of --from-images, --from-git, or --repo-root');
131
+ if (g.fromImages) {
132
+ error(
133
+ [
134
+ '--from-images was removed (Docker deployment retired).',
135
+ ' Use: ragsuite-test init',
136
+ ' Then: ragsuite-test start',
137
+ ].join('\n'),
138
+ );
139
+ return 1;
140
+ }
141
+
142
+ if (g.mode === 'docker') {
143
+ error(
144
+ [
145
+ 'Docker mode was removed from deployment.',
146
+ ' Init always uses native npm scripts (no containers).',
147
+ ' Omit --mode, or use --mode native.',
148
+ ].join('\n'),
149
+ );
150
+ return 1;
151
+ }
152
+
153
+ if (countSources(g.fromGit, g.repoRoot) > 1) {
154
+ error('Use only one of --from-git or --repo-root');
140
155
  return 1;
141
156
  }
142
157
 
@@ -144,11 +159,9 @@ async function run(ctx) {
144
159
  info(`OS: ${osInfo.label} (${osInfo.platform})`);
145
160
 
146
161
  let fromGit = g.fromGit;
147
- let fromImages = Boolean(g.fromImages);
148
162
  let repoRootFlag = g.repoRoot;
149
163
  const installDir = path.resolve(g.installDir || defaultInstallDir());
150
164
 
151
- // Existing configured install → friendly no-op (like other npm CLIs)
152
165
  if (!g.force) {
153
166
  if (repoRootFlag && isInitializedInstall(path.resolve(repoRootFlag))) {
154
167
  printAlreadyInstalled(path.resolve(repoRootFlag));
@@ -160,20 +173,15 @@ async function run(ctx) {
160
173
  }
161
174
  }
162
175
 
163
- if (!fromImages && fromGit === null && !repoRootFlag) {
176
+ if (fromGit === null && !repoRootFlag) {
164
177
  fromGit = '';
165
178
  info(`First-time install (git): ${DEFAULT_GIT_URL}`);
166
179
  info(` → ${installDir}`);
167
180
  }
168
- if (fromImages) {
169
- info(`First-time install (images, no source): → ${installDir}`);
170
- }
171
181
 
172
- // Checkout already on disk but never inited → wire config/.env, do not re-clone
173
182
  if (
174
183
  !g.force &&
175
184
  !repoRootFlag &&
176
- !fromImages &&
177
185
  looksLikeRepoRoot(installDir) &&
178
186
  !readConfig(installDir)
179
187
  ) {
@@ -194,10 +202,10 @@ async function run(ctx) {
194
202
  return 1;
195
203
  }
196
204
 
197
- let mode = fromImages ? 'docker' : g.mode || resolvePreferredMode(null);
198
- info(`Run mode: ${mode}`);
205
+ const mode = resolvePreferredMode();
206
+ info(`Run mode: ${mode} (npm scripts — Docker not used)`);
199
207
 
200
- const needGit = !fromImages && fromGit !== null && fromGit !== undefined;
208
+ const needGit = fromGit !== null && fromGit !== undefined;
201
209
  if (!printPrereqs(mode, { needGit })) {
202
210
  error('Fix prerequisites above and re-run init');
203
211
  return 1;
@@ -222,11 +230,7 @@ async function run(ctx) {
222
230
  let source = 'checkout';
223
231
 
224
232
  try {
225
- if (fromImages) {
226
- const result = materializeImagesInstall({ installDir, force: g.force });
227
- repoRoot = result.repoRoot;
228
- source = 'images';
229
- } else if (fromGit !== null && fromGit !== undefined) {
233
+ if (fromGit !== null && fromGit !== undefined) {
230
234
  const url = fromGit === '' ? DEFAULT_GIT_URL : fromGit;
231
235
  const result = cloneGitToInstallDir(url, { installDir, force: g.force });
232
236
  repoRoot = result.repoRoot;
@@ -237,7 +241,6 @@ async function run(ctx) {
237
241
  repoRootFlag,
238
242
  env: ctx.env,
239
243
  });
240
- if (isImagesInstall(repoRoot)) source = 'images';
241
244
  }
242
245
  } catch (err) {
243
246
  error(err.message || String(err));
@@ -246,7 +249,7 @@ async function run(ctx) {
246
249
 
247
250
  ensureRagsuiteDir(repoRoot);
248
251
  const cfg = writeConfig(repoRoot, {
249
- mode,
252
+ mode: 'native',
250
253
  source,
251
254
  repoRoot,
252
255
  installDir: repoRoot,
@@ -273,7 +276,7 @@ async function run(ctx) {
273
276
  }
274
277
 
275
278
  info(`Config: mode=${cfg.mode} source=${cfg.source}`);
276
- printSuccess(repoRoot, mode, source);
279
+ printSuccess(repoRoot);
277
280
  return 0;
278
281
  }
279
282
 
@@ -2,23 +2,20 @@
2
2
 
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
- const { resolveMode } = require('../utils/config');
6
- const { resolveRepoRoot, nativeLogDir } = require('../utils/paths');
5
+ const { resolveRepoRoot, nativeLogDir, assertNativeDeploy } = require('../utils/paths');
7
6
  const { runCommand } = require('../utils/spawn');
8
7
  const { error, info } = require('../utils/log');
9
8
 
10
9
  const name = 'logs';
11
- const summary = 'Follow Docker compose or native process logs';
10
+ const summary = 'Follow native process logs';
12
11
 
13
12
  function help() {
14
13
  return `Usage: ragsuite-test logs [options]
15
14
 
16
- Docker mode: docker compose logs -f (same as root npm run logs).
17
- Native mode: tail -f .ragsuite/native/*.log when present.
15
+ Tails .ragsuite/native/*.log (host processes no Docker).
18
16
 
19
17
  Options:
20
- --mode <docker|native> Override config / RAGSUITE_MODE
21
- --repo-root <path> Monorepo root
18
+ --repo-root <path> Install root
22
19
  --dry-run Print the command and exit 0
23
20
  `;
24
21
  }
@@ -28,36 +25,27 @@ function run(ctx) {
28
25
  cwd: ctx.cwd,
29
26
  repoRootFlag: ctx.globals.repoRoot,
30
27
  });
31
- const mode = resolveMode({
32
- flagMode: ctx.globals.mode,
33
- repoRoot,
34
- env: ctx.env,
35
- });
36
-
37
- if (mode === 'native') {
38
- const dir = nativeLogDir(repoRoot);
39
- let logs = [];
40
- if (fs.existsSync(dir)) {
41
- logs = fs
42
- .readdirSync(dir)
43
- .filter((f) => f.endsWith('.log'))
44
- .map((f) => path.join(dir, f));
45
- }
46
- if (logs.length === 0) {
47
- error(
48
- `No native log files under ${dir}. Start with mode=native first, or use --mode docker.`,
49
- );
50
- return 1;
51
- }
52
- info(`Following ${logs.length} native log file(s)…`);
53
- return runCommand('tail', ['-f', ...logs], {
54
- cwd: repoRoot,
55
- dryRun: ctx.globals.dryRun,
56
- env: ctx.env,
57
- });
28
+ try {
29
+ assertNativeDeploy(repoRoot);
30
+ } catch (err) {
31
+ error(err.message);
32
+ return 1;
58
33
  }
59
34
 
60
- return runCommand('docker', ['compose', 'logs', '-f'], {
35
+ const dir = nativeLogDir(repoRoot);
36
+ let logs = [];
37
+ if (fs.existsSync(dir)) {
38
+ logs = fs
39
+ .readdirSync(dir)
40
+ .filter((f) => f.endsWith('.log'))
41
+ .map((f) => path.join(dir, f));
42
+ }
43
+ if (logs.length === 0) {
44
+ error(`No native log files under ${dir}. Start with: ragsuite-test start`);
45
+ return 1;
46
+ }
47
+ info(`Following ${logs.length} native log file(s)…`);
48
+ return runCommand('tail', ['-f', ...logs], {
61
49
  cwd: repoRoot,
62
50
  dryRun: ctx.globals.dryRun,
63
51
  env: ctx.env,
@@ -2,25 +2,23 @@
2
2
 
3
3
  const path = require('path');
4
4
  const { resolveMode } = require('../utils/config');
5
- const { resolveRepoRoot, isImagesInstall } = require('../utils/paths');
5
+ const { resolveRepoRoot, assertNativeDeploy } = require('../utils/paths');
6
6
  const { runScript } = require('../utils/spawn');
7
7
  const { assertApiPortFree } = require('../utils/port');
8
8
  const { error } = require('../utils/log');
9
9
 
10
10
  const name = 'start';
11
- const summary = 'Start stack (git scripts or images pull-only)';
11
+ const summary = 'Start app via npm scripts (native no Docker)';
12
12
 
13
13
  function help() {
14
14
  return `Usage: ragsuite-test start [options]
15
15
 
16
- Git install: scripts/docker-start.sh or native-start.sh
17
- Images install (--from-images): scripts/docker-start-images.sh (pull, no build)
16
+ Runs scripts/native-start.sh (same as \`npm start\` in the install dir).
17
+ Does not use Docker — no containers, no volume risk.
18
18
 
19
19
  Options:
20
- --mode <docker|native> Override (git install; images always docker)
21
- --repo-root <path> Install root
20
+ --repo-root <path> Override active install
22
21
  --dry-run Print script path and exit 0
23
- --detach, -d Detached start
24
22
  `;
25
23
  }
26
24
 
@@ -29,24 +27,14 @@ async function run(ctx) {
29
27
  cwd: ctx.cwd,
30
28
  repoRootFlag: ctx.globals.repoRoot,
31
29
  });
32
- const images = isImagesInstall(repoRoot);
33
- const mode = images
34
- ? 'docker'
35
- : resolveMode({
36
- flagMode: ctx.globals.mode,
37
- repoRoot,
38
- env: ctx.env,
39
- });
40
-
41
- let scriptName;
42
- if (images) {
43
- scriptName = 'docker-start-images.sh';
44
- } else {
45
- scriptName = mode === 'native' ? 'native-start.sh' : 'docker-start.sh';
30
+ try {
31
+ assertNativeDeploy(repoRoot);
32
+ } catch (err) {
33
+ error(err.message);
34
+ return 1;
46
35
  }
47
36
 
48
- const forward = normalizeStartArgs(ctx.commandArgs);
49
-
37
+ const mode = resolveMode();
50
38
  if (!ctx.globals.dryRun) {
51
39
  try {
52
40
  await assertApiPortFree(ctx.env);
@@ -56,23 +44,10 @@ async function run(ctx) {
56
44
  }
57
45
  }
58
46
 
59
- return runScript(repoRoot, path.join('scripts', scriptName), forward, {
47
+ return runScript(repoRoot, path.join('scripts', 'native-start.sh'), [], {
60
48
  dryRun: ctx.globals.dryRun,
61
49
  env: { ...ctx.env, RAGSUITE_MODE: mode },
62
50
  });
63
51
  }
64
52
 
65
- function normalizeStartArgs(args) {
66
- const out = [];
67
- for (const a of args) {
68
- if (a === '--detach' || a === '-d') {
69
- out.push('--detach');
70
- continue;
71
- }
72
- if (a === '--') continue;
73
- out.push(a);
74
- }
75
- return out;
76
- }
77
-
78
53
  module.exports = { name, summary, help, run };
@@ -2,22 +2,21 @@
2
2
 
3
3
  const path = require('path');
4
4
  const { resolveMode } = require('../utils/config');
5
- const { resolveRepoRoot, isImagesInstall } = require('../utils/paths');
5
+ const { resolveRepoRoot, assertNativeDeploy } = require('../utils/paths');
6
6
  const { runScript } = require('../utils/spawn');
7
+ const { error } = require('../utils/log');
7
8
 
8
9
  const name = 'stop';
9
- const summary = 'Stop stack (git scripts or images pull-only)';
10
+ const summary = 'Stop native app processes (does not touch Docker volumes)';
10
11
 
11
12
  function help() {
12
13
  return `Usage: ragsuite-test stop [options]
13
14
 
14
- Git install: docker-stop.sh / native-stop.sh
15
- Images install: docker-stop-images.sh
16
- Never wipes Docker volumes.
15
+ Runs scripts/native-stop.sh (same as \`npm run stop\` in the install dir).
16
+ Stops host processes only — never runs docker compose down.
17
17
 
18
18
  Options:
19
- --mode <docker|native> Override (git install)
20
- --repo-root <path> Install root
19
+ --repo-root <path> Override active install
21
20
  --dry-run Print script path and exit 0
22
21
  `;
23
22
  }
@@ -27,24 +26,16 @@ function run(ctx) {
27
26
  cwd: ctx.cwd,
28
27
  repoRootFlag: ctx.globals.repoRoot,
29
28
  });
30
- const images = isImagesInstall(repoRoot);
31
- const mode = images
32
- ? 'docker'
33
- : resolveMode({
34
- flagMode: ctx.globals.mode,
35
- repoRoot,
36
- env: ctx.env,
37
- });
38
-
39
- const scriptName = images
40
- ? 'docker-stop-images.sh'
41
- : mode === 'native'
42
- ? 'native-stop.sh'
43
- : 'docker-stop.sh';
44
-
45
- return runScript(repoRoot, path.join('scripts', scriptName), [], {
29
+ try {
30
+ assertNativeDeploy(repoRoot);
31
+ } catch (err) {
32
+ error(err.message);
33
+ return 1;
34
+ }
35
+
36
+ return runScript(repoRoot, path.join('scripts', 'native-stop.sh'), [], {
46
37
  dryRun: ctx.globals.dryRun,
47
- env: { ...ctx.env, RAGSUITE_MODE: mode },
38
+ env: { ...ctx.env, RAGSUITE_MODE: resolveMode() },
48
39
  });
49
40
  }
50
41