@nitsan-ai/ragsuite-test 0.1.4 → 0.1.6

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,33 @@
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 + Redis :6382 (auto-started via data-only compose if Docker is available)
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
+ # stops host app + leftover Docker app containers; keeps DB volumes
17
18
  ```
18
19
 
19
- Active install is remembered in `~/.ragsuite-test/config.json` (default app dir: `~/ragsuite-test`).
20
+ Same under the hood as:
21
+
22
+ ```bash
23
+ cd ~/ragsuite-test
24
+ npm start # scripts/native-start.sh
25
+ npm run stop # scripts/native-stop.sh
26
+ ```
27
+
28
+ Active install is remembered in `~/.ragsuite-test/config.json`.
29
+
30
+ **Data safety:** `start` may run `docker compose up -d postgres redis` only (existing volumes). It never runs `down -v`. App code always runs natively.
20
31
 
21
32
  ---
22
33
 
@@ -24,28 +35,28 @@ Active install is remembered in `~/.ragsuite-test/config.json` (default app dir:
24
35
 
25
36
  ```bash
26
37
  npm install -g @nitsan-ai/ragsuite-test@latest
27
- ragsuite-test update
38
+ ragsuite-test update # git pull only
28
39
  ragsuite-test start
29
40
  ```
30
41
 
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
42
  **Never** run `docker compose down -v` or `init --force` unless you mean to wipe data.
37
43
 
38
- If you already installed and run `init` again → it says **Already installed** and exits OK (does not wipe).
44
+ If you already installed and run `init` again → **Already installed** (exit OK).
39
45
 
40
46
  ---
41
47
 
42
- ## Which first-time install?
48
+ ## Prerequisites (host)
49
+
50
+ | Tool | Notes |
51
+ |------|--------|
52
+ | Node.js 18+ | |
53
+ | Python 3 + venv | backend |
54
+ | Yarn | Expo frontend |
55
+ | Git | `init` clone |
56
+ | Postgres + Redis | Host brew **or** data-only compose (`postgres`/`redis` services) on :5436 / :6382 |
57
+ | Docker (optional) | Only to auto-start/reuse existing postgres/redis volumes |
43
58
 
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” |
59
+ Docker is **not** required to run the API/UI (those are native).
49
60
 
50
61
  ---
51
62
 
@@ -53,17 +64,18 @@ If you already installed and run `init` again → it says **Already installed**
53
64
 
54
65
  | Command | Purpose |
55
66
  |---------|---------|
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 |
67
+ | `init` | First-time git install (no port checks) |
68
+ | `start` | `scripts/native-start.sh` (+ data services if needed) |
69
+ | `stop` | Native PIDs + leftover app containers (DB kept) |
70
+ | `update` | `git pull` in place |
71
+ | `doctor` | Native prereq checks |
72
+ | `logs` | Tail `.ragsuite/native/*.log` |
61
73
  | `version` | CLI version |
62
74
 
63
75
  ## Ports
64
76
 
65
- API **9090** · Web **9091** (Docker/images) · Web **9191** (native) · Postgres **5436** · Redis **6382**
77
+ API **9090** · Web **9191** · Postgres **5436** · Redis **6382** · Chroma **8004** (started by native-start if needed)
66
78
 
67
79
  ## Publish (maintainers)
68
80
 
69
- See [PUBLISH.md](./PUBLISH.md). Also publish GHCR images before `--from-images` works for others.
81
+ 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.6",
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.",
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,42 +15,36 @@ 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');
20
+ const { info, warn, error } = require('../utils/log');
25
21
  const {
26
22
  generateJwtSecret,
27
23
  isPlaceholderSecret,
28
24
  writeInstallEnv,
29
25
  } = require('../utils/env-file');
30
- const { assertPortsFree } = require('../utils/port');
31
- const { info, warn, error } = require('../utils/log');
32
26
 
33
27
  const name = 'init';
34
- const summary = 'First-time install (git or images). Safe if already installed.';
28
+ const summary = 'First-time install (git + native npm scripts). Safe if already installed.';
35
29
 
36
- function printSuccess(repoRoot, mode, source) {
30
+ function printSuccess(repoRoot) {
37
31
  info('');
38
32
  info('=== Install complete ===');
39
33
  info(` Install dir : ${repoRoot}`);
40
- info(` Source : ${source}`);
41
- info(` Mode : ${mode}`);
34
+ info(' Mode : native (npm scripts — no Docker)');
42
35
  info('');
43
36
  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
- }
37
+ info(' Web http://localhost:9191');
49
38
  info('');
50
39
  info('Next (no --repo-root needed):');
51
40
  info(' ragsuite-test start');
52
41
  info(' ragsuite-test stop');
53
42
  info(' ragsuite-test update # later upgrades, keeps data');
54
43
  info('');
44
+ info('Or in the install directory:');
45
+ info(' npm start');
46
+ info(' npm run stop');
47
+ info('');
55
48
  info(installHint());
56
49
  }
57
50
 
@@ -61,11 +54,11 @@ function printAlreadyInstalled(repoRoot) {
61
54
  info('');
62
55
  info('=== Already installed ===');
63
56
  info(` ${repoRoot}`);
64
- if (cfg) info(` source=${cfg.source} mode=${cfg.mode}`);
57
+ if (cfg) info(` source=${cfg.source} mode=native`);
65
58
  info('');
66
59
  info('Use:');
67
- info(' ragsuite-test start # run the app');
68
- info(' ragsuite-test update # upgrade code/images (keeps .env + data)');
60
+ info(' ragsuite-test start # run the app (npm scripts)');
61
+ info(' ragsuite-test update # upgrade code (keeps .env + data)');
69
62
  info(' ragsuite-test stop');
70
63
  info('');
71
64
  info('Do NOT run init --force unless you intend to wipe and reinstall.');
@@ -78,24 +71,24 @@ function isInitializedInstall(dir) {
78
71
  function help() {
79
72
  return `Usage: ragsuite-test init [options]
80
73
 
81
- First-time setup only (npm-style):
74
+ First-time setup (npm-style, no Docker):
82
75
 
83
76
  ragsuite-test init # git clone → ~/ragsuite-test
84
- ragsuite-test init --from-images # Docker images only (no app source)
77
+ ragsuite-test start # scripts/native-start.sh
85
78
 
86
79
  If already installed, init exits OK and tells you to start/update.
87
80
 
81
+ Requires host Postgres (:5436) and Redis (:6382).
82
+
88
83
  Day-to-day:
89
84
  ragsuite-test start
90
85
  ragsuite-test update
91
86
  ragsuite-test stop
92
87
 
93
88
  Options:
94
- --from-images Images-only install
95
89
  --from-git [url] Clone URL (default public repo)
96
90
  --repo-root <path> Point at an existing checkout
97
91
  --install-dir <path> Default: ~/ragsuite-test
98
- --mode <docker|native> Git install only
99
92
  --force Wipe install dir and reinstall (destructive)
100
93
  --yes, -y Non-interactive
101
94
  `;
@@ -118,10 +111,9 @@ function resolveLlmOverride(g, env) {
118
111
  return null;
119
112
  }
120
113
 
121
- function countSources(fromGit, fromImages, repoRootFlag) {
114
+ function countSources(fromGit, repoRootFlag) {
122
115
  let n = 0;
123
116
  if (fromGit !== null && fromGit !== undefined) n += 1;
124
- if (fromImages) n += 1;
125
117
  if (repoRootFlag) n += 1;
126
118
  return n;
127
119
  }
@@ -135,8 +127,30 @@ async function run(ctx) {
135
127
  return 1;
136
128
  }
137
129
 
138
- if (countSources(g.fromGit, g.fromImages, g.repoRoot) > 1) {
139
- error('Use only one of --from-images, --from-git, or --repo-root');
130
+ if (g.fromImages) {
131
+ error(
132
+ [
133
+ '--from-images was removed (Docker deployment retired).',
134
+ ' Use: ragsuite-test init',
135
+ ' Then: ragsuite-test start',
136
+ ].join('\n'),
137
+ );
138
+ return 1;
139
+ }
140
+
141
+ if (g.mode === 'docker') {
142
+ error(
143
+ [
144
+ 'Docker mode was removed from deployment.',
145
+ ' Init always uses native npm scripts (no containers).',
146
+ ' Omit --mode, or use --mode native.',
147
+ ].join('\n'),
148
+ );
149
+ return 1;
150
+ }
151
+
152
+ if (countSources(g.fromGit, g.repoRoot) > 1) {
153
+ error('Use only one of --from-git or --repo-root');
140
154
  return 1;
141
155
  }
142
156
 
@@ -144,11 +158,9 @@ async function run(ctx) {
144
158
  info(`OS: ${osInfo.label} (${osInfo.platform})`);
145
159
 
146
160
  let fromGit = g.fromGit;
147
- let fromImages = Boolean(g.fromImages);
148
161
  let repoRootFlag = g.repoRoot;
149
162
  const installDir = path.resolve(g.installDir || defaultInstallDir());
150
163
 
151
- // Existing configured install → friendly no-op (like other npm CLIs)
152
164
  if (!g.force) {
153
165
  if (repoRootFlag && isInitializedInstall(path.resolve(repoRootFlag))) {
154
166
  printAlreadyInstalled(path.resolve(repoRootFlag));
@@ -160,20 +172,15 @@ async function run(ctx) {
160
172
  }
161
173
  }
162
174
 
163
- if (!fromImages && fromGit === null && !repoRootFlag) {
175
+ if (fromGit === null && !repoRootFlag) {
164
176
  fromGit = '';
165
177
  info(`First-time install (git): ${DEFAULT_GIT_URL}`);
166
178
  info(` → ${installDir}`);
167
179
  }
168
- if (fromImages) {
169
- info(`First-time install (images, no source): → ${installDir}`);
170
- }
171
180
 
172
- // Checkout already on disk but never inited → wire config/.env, do not re-clone
173
181
  if (
174
182
  !g.force &&
175
183
  !repoRootFlag &&
176
- !fromImages &&
177
184
  looksLikeRepoRoot(installDir) &&
178
185
  !readConfig(installDir)
179
186
  ) {
@@ -194,10 +201,10 @@ async function run(ctx) {
194
201
  return 1;
195
202
  }
196
203
 
197
- let mode = fromImages ? 'docker' : g.mode || resolvePreferredMode(null);
198
- info(`Run mode: ${mode}`);
204
+ const mode = resolvePreferredMode();
205
+ info(`Run mode: ${mode} (npm scripts — Docker not used)`);
199
206
 
200
- const needGit = !fromImages && fromGit !== null && fromGit !== undefined;
207
+ const needGit = fromGit !== null && fromGit !== undefined;
201
208
  if (!printPrereqs(mode, { needGit })) {
202
209
  error('Fix prerequisites above and re-run init');
203
210
  return 1;
@@ -209,24 +216,14 @@ async function run(ctx) {
209
216
  const llmKey = resolveLlmOverride(g, ctx.env);
210
217
  const smtp = optionalSmtpOverrides(g, ctx.env);
211
218
 
212
- if (ctx.env.RAGSUITE_TEST_SKIP_PORT_CHECK !== '1') {
213
- try {
214
- await assertPortsFree();
215
- } catch (err) {
216
- error(err.message);
217
- return 1;
218
- }
219
- }
219
+ // Init only installs files — do not require ports free.
220
+ // (Postgres/Redis being "in use" is good; API busy is a start-time concern.)
220
221
 
221
222
  let repoRoot;
222
223
  let source = 'checkout';
223
224
 
224
225
  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) {
226
+ if (fromGit !== null && fromGit !== undefined) {
230
227
  const url = fromGit === '' ? DEFAULT_GIT_URL : fromGit;
231
228
  const result = cloneGitToInstallDir(url, { installDir, force: g.force });
232
229
  repoRoot = result.repoRoot;
@@ -237,7 +234,6 @@ async function run(ctx) {
237
234
  repoRootFlag,
238
235
  env: ctx.env,
239
236
  });
240
- if (isImagesInstall(repoRoot)) source = 'images';
241
237
  }
242
238
  } catch (err) {
243
239
  error(err.message || String(err));
@@ -246,7 +242,7 @@ async function run(ctx) {
246
242
 
247
243
  ensureRagsuiteDir(repoRoot);
248
244
  const cfg = writeConfig(repoRoot, {
249
- mode,
245
+ mode: 'native',
250
246
  source,
251
247
  repoRoot,
252
248
  installDir: repoRoot,
@@ -273,7 +269,7 @@ async function run(ctx) {
273
269
  }
274
270
 
275
271
  info(`Config: mode=${cfg.mode} source=${cfg.source}`);
276
- printSuccess(repoRoot, mode, source);
272
+ printSuccess(repoRoot);
277
273
  return 0;
278
274
  }
279
275
 
@@ -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,26 @@
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
- const { error } = require('../utils/log');
8
+ const { error, info } = 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); auto-starts DB containers if needed';
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
+
18
+ App runs on the host. If Postgres/Redis are down, start may bring up
19
+ data-only compose services (postgres + redis) using existing volumes —
20
+ never \`down -v\`. Backend/frontend Docker containers are not started.
18
21
 
19
22
  Options:
20
- --mode <docker|native> Override (git install; images always docker)
21
- --repo-root <path> Install root
23
+ --repo-root <path> Override active install
22
24
  --dry-run Print script path and exit 0
23
- --detach, -d Detached start
24
25
  `;
25
26
  }
26
27
 
@@ -29,24 +30,14 @@ async function run(ctx) {
29
30
  cwd: ctx.cwd,
30
31
  repoRootFlag: ctx.globals.repoRoot,
31
32
  });
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';
33
+ try {
34
+ assertNativeDeploy(repoRoot);
35
+ } catch (err) {
36
+ error(err.message);
37
+ return 1;
46
38
  }
47
39
 
48
- const forward = normalizeStartArgs(ctx.commandArgs);
49
-
40
+ const mode = resolveMode();
50
41
  if (!ctx.globals.dryRun) {
51
42
  try {
52
43
  await assertApiPortFree(ctx.env);
@@ -54,25 +45,14 @@ async function run(ctx) {
54
45
  error(err.message);
55
46
  return 1;
56
47
  }
48
+ } else {
49
+ info('[dry-run] would run scripts/native-start.sh');
57
50
  }
58
51
 
59
- return runScript(repoRoot, path.join('scripts', scriptName), forward, {
52
+ return runScript(repoRoot, path.join('scripts', 'native-start.sh'), [], {
60
53
  dryRun: ctx.globals.dryRun,
61
54
  env: { ...ctx.env, RAGSUITE_MODE: mode },
62
55
  });
63
56
  }
64
57
 
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
58
  module.exports = { name, summary, help, run };
@@ -2,22 +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
+ 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 + leftover Docker app containers (keeps DB 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:
16
+ Stops host API / Expo / chroma PIDs
17
+ Stops leftover Docker backend/frontend/worker if present
18
+ • Leaves postgres/redis running (and never uses down -v)
17
19
 
18
20
  Options:
19
- --mode <docker|native> Override (git install)
20
- --repo-root <path> Install root
21
+ --repo-root <path> Override active install
21
22
  --dry-run Print script path and exit 0
22
23
  `;
23
24
  }
@@ -27,24 +28,16 @@ function run(ctx) {
27
28
  cwd: ctx.cwd,
28
29
  repoRootFlag: ctx.globals.repoRoot,
29
30
  });
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), [], {
31
+ try {
32
+ assertNativeDeploy(repoRoot);
33
+ } catch (err) {
34
+ error(err.message);
35
+ return 1;
36
+ }
37
+
38
+ return runScript(repoRoot, path.join('scripts', 'native-stop.sh'), [], {
46
39
  dryRun: ctx.globals.dryRun,
47
- env: { ...ctx.env, RAGSUITE_MODE: mode },
40
+ env: { ...ctx.env, RAGSUITE_MODE: resolveMode() },
48
41
  });
49
42
  }
50
43