@nitsan-ai/ragsuite-test 0.1.0 → 0.1.2
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 +47 -49
- package/package.json +2 -2
- package/src/commands/init.js +83 -128
- package/src/commands/update.js +7 -20
- package/src/index.js +11 -7
- package/src/utils/args.js +91 -30
- package/src/utils/distribution.js +14 -11
- package/src/utils/env-file.js +124 -21
- package/src/utils/git-install.js +93 -0
- package/src/utils/paths.js +1 -1
- package/src/utils/port.js +15 -1
- package/src/utils/prereqs.js +78 -16
- package/src/utils/zip-install.js +0 -213
package/README.md
CHANGED
|
@@ -1,85 +1,83 @@
|
|
|
1
1
|
# RAGSuite test CLI (`ragsuite-test`)
|
|
2
2
|
|
|
3
|
-
> **TESTING PACKAGE** —
|
|
4
|
-
> **Not** the final production `@nitsan-ai/ragsuite` / `ragsuite` CLI (later release).
|
|
5
|
-
> Do **not** treat this as the long-term npm identity.
|
|
3
|
+
> **TESTING PACKAGE** — temporary. Final public CLI will be `ragsuite` later.
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
**One-command public install** (GitHub repo must be public):
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|-----------|------|---------|
|
|
15
|
-
| You have Docker | `docker` (default) | `ragsuite-test init … --mode docker` then `start` |
|
|
16
|
-
| No Docker | `native` | Need Postgres **:5436** + Redis **:6382** on the host, then `ragsuite-test init … --mode native` then `start` |
|
|
17
|
-
|
|
18
|
-
Docker is **not** mandatory — choose native in the wizard or pass `--mode native`.
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @nitsan-ai/ragsuite-test
|
|
9
|
+
ragsuite-test init
|
|
10
|
+
ragsuite-test start --repo-root ~/ragsuite-test --detach
|
|
11
|
+
```
|
|
19
12
|
|
|
20
|
-
|
|
13
|
+
That clones `https://github.com/nitsan-ai/RAGSUITE.git` into `~/ragsuite-test`, writes `.env` (no SMTP/LLM questions), and picks **Docker** if the daemon is up, otherwise **native**.
|
|
21
14
|
|
|
22
|
-
|
|
15
|
+
- API: http://localhost:9090
|
|
16
|
+
- Web (Docker): http://localhost:9091
|
|
17
|
+
- Web (native): http://localhost:9191
|
|
23
18
|
|
|
24
19
|
```bash
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
ragsuite-test stop --repo-root ~/ragsuite-test
|
|
21
|
+
```
|
|
27
22
|
|
|
28
|
-
|
|
29
|
-
ragsuite-test init
|
|
23
|
+
## Prerequisites
|
|
30
24
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
--llm-api-key 'your-key'
|
|
25
|
+
| Need | Required? | How |
|
|
26
|
+
|------|-----------|-----|
|
|
27
|
+
| Node.js 18+ | Yes | https://nodejs.org · `brew install node` |
|
|
28
|
+
| git | Yes | `xcode-select --install` · `brew install git` |
|
|
29
|
+
| Docker | No | Optional; without it init uses native (needs Postgres `:5436` + Redis `:6382`) |
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
# API http://localhost:9090 · Web http://localhost:9091
|
|
40
|
-
```
|
|
31
|
+
Real SMTP belongs only in local `.env` (gitignored). Init never asks for it.
|
|
41
32
|
|
|
42
|
-
|
|
33
|
+
## Advanced (optional)
|
|
43
34
|
|
|
44
|
-
|
|
35
|
+
```bash
|
|
36
|
+
# Force native / docker
|
|
37
|
+
ragsuite-test init --mode native
|
|
38
|
+
ragsuite-test init --mode docker
|
|
39
|
+
|
|
40
|
+
# Custom install dir
|
|
41
|
+
ragsuite-test init --install-dir ~/my-ragsuite
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
| Existing checkout | `--repo-root` |
|
|
50
|
-
| GitHub Release | `--from-release` — not implemented yet |
|
|
43
|
+
# Existing checkout (CI / developers)
|
|
44
|
+
ragsuite-test init --repo-root /path/to/RAGSUITE
|
|
45
|
+
```
|
|
51
46
|
|
|
52
|
-
|
|
47
|
+
## Ports
|
|
53
48
|
|
|
54
|
-
|
|
49
|
+
| Service | Port |
|
|
50
|
+
|---------|------|
|
|
51
|
+
| API | 9090 |
|
|
52
|
+
| Web (Docker) | 9091 |
|
|
53
|
+
| Web (native Expo) | 9191 |
|
|
54
|
+
| Postgres | 5436 |
|
|
55
|
+
| Redis | 6382 |
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
- Native PID/logs: `<install>/.ragsuite/native/` (Phase 4 scripts)
|
|
57
|
+
Busy ports: `ragsuite-test stop --repo-root ~/ragsuite-test` · `lsof -nP -iTCP:9090 -sTCP:LISTEN`
|
|
58
58
|
|
|
59
59
|
## Commands
|
|
60
60
|
|
|
61
61
|
| Command | Behavior |
|
|
62
62
|
|---------|----------|
|
|
63
|
-
| `init` |
|
|
64
|
-
| `start` / `stop` |
|
|
65
|
-
| `doctor` |
|
|
63
|
+
| `init` | Clone public repo → `.env` + config (default) |
|
|
64
|
+
| `start` / `stop` | Docker or native scripts |
|
|
65
|
+
| `doctor` | Health / prereq hints |
|
|
66
66
|
| `logs` / `update` / `version` | As before |
|
|
67
67
|
|
|
68
|
-
## Publish
|
|
68
|
+
## Publish
|
|
69
69
|
|
|
70
|
-
See [PUBLISH.md](./PUBLISH.md)
|
|
70
|
+
See [PUBLISH.md](./PUBLISH.md).
|
|
71
71
|
|
|
72
72
|
```bash
|
|
73
73
|
cd cli && npm run prepublish:check
|
|
74
|
-
# Only when
|
|
74
|
+
# Only when approved:
|
|
75
75
|
RAGSUITE_TEST_ALLOW_PUBLISH=1 npm publish --access public
|
|
76
|
-
# Or: GitHub Actions → CLI publish (workflow_dispatch, NPM_TOKEN)
|
|
77
|
-
# Optional app ZIP: Actions → Release app ZIP
|
|
78
76
|
```
|
|
79
77
|
|
|
80
78
|
## Windows
|
|
81
79
|
|
|
82
|
-
Use WSL or Git Bash
|
|
80
|
+
Use WSL or Git Bash.
|
|
83
81
|
|
|
84
82
|
## Tests
|
|
85
83
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nitsan-ai/ragsuite-test",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "RAGSuite testing CLI (ragsuite-test) — install
|
|
5
|
+
"description": "RAGSuite testing CLI (ragsuite-test) — public install: npm i -g && ragsuite-test init (clones GitHub). Temporary name before public ragsuite release.",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"ragsuite-test": "./bin/ragsuite-test.js"
|
package/src/commands/init.js
CHANGED
|
@@ -1,51 +1,29 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const fs = require('fs');
|
|
4
3
|
const path = require('path');
|
|
5
4
|
const { writeConfig, CONFIG_DIR } = require('../utils/config');
|
|
6
|
-
const { ensureRagsuiteDir, resolveRepoRoot
|
|
5
|
+
const { ensureRagsuiteDir, resolveRepoRoot } = require('../utils/paths');
|
|
7
6
|
const { assertSupportedInstall, installHint } = require('../utils/distribution');
|
|
8
7
|
const {
|
|
8
|
+
DEFAULT_GIT_URL,
|
|
9
9
|
defaultInstallDir,
|
|
10
|
-
|
|
11
|
-
} = require('../utils/
|
|
10
|
+
cloneGitToInstallDir,
|
|
11
|
+
} = require('../utils/git-install');
|
|
12
12
|
const { detectOs } = require('../utils/os-detect');
|
|
13
|
-
const {
|
|
14
|
-
|
|
13
|
+
const {
|
|
14
|
+
printPrereqs,
|
|
15
|
+
resolvePreferredMode,
|
|
16
|
+
} = require('../utils/prereqs');
|
|
15
17
|
const {
|
|
16
18
|
generateJwtSecret,
|
|
17
|
-
generateCiLlmKey,
|
|
18
19
|
isPlaceholderSecret,
|
|
19
20
|
writeInstallEnv,
|
|
20
21
|
} = require('../utils/env-file');
|
|
21
22
|
const { assertPortsFree } = require('../utils/port');
|
|
22
|
-
const { info,
|
|
23
|
+
const { info, error } = require('../utils/log');
|
|
23
24
|
|
|
24
25
|
const name = 'init';
|
|
25
|
-
const summary = '
|
|
26
|
-
|
|
27
|
-
function help() {
|
|
28
|
-
return `Usage: ragsuite-test init [options]
|
|
29
|
-
|
|
30
|
-
Interactive installer (or --yes for CI) that:
|
|
31
|
-
- detects OS / prerequisites
|
|
32
|
-
- installs from ZIP or configures a checkout
|
|
33
|
-
- writes .ragsuite-test/config.json and .env (JWT auto-generated)
|
|
34
|
-
- checks ports 9090, 9091, 5436, 6382
|
|
35
|
-
|
|
36
|
-
Install sources:
|
|
37
|
-
--from-zip <path> Extract app ZIP into --install-dir
|
|
38
|
-
--repo-root <path> Use an existing monorepo checkout
|
|
39
|
-
--from-release <tag> Not implemented (download ZIP manually)
|
|
40
|
-
|
|
41
|
-
Options:
|
|
42
|
-
--install-dir <path> ZIP target (default: ~/ragsuite-test)
|
|
43
|
-
--mode <docker|native> docker = Docker stack; native = no Docker (needs host Postgres/Redis)
|
|
44
|
-
--llm-api-key <key> CUSTOM_LLM_INTERNAL_API_KEY (--yes)
|
|
45
|
-
--force Overwrite non-empty install dir / existing .env
|
|
46
|
-
--yes, -y Non-interactive (requires --from-zip or --repo-root)
|
|
47
|
-
`;
|
|
48
|
-
}
|
|
26
|
+
const summary = 'One-command install: clone public GitHub repo → .env + config';
|
|
49
27
|
|
|
50
28
|
function printSuccess(repoRoot, mode) {
|
|
51
29
|
info('');
|
|
@@ -61,9 +39,6 @@ function printSuccess(repoRoot, mode) {
|
|
|
61
39
|
info(' Web http://localhost:9091 (Docker nginx)');
|
|
62
40
|
}
|
|
63
41
|
info('');
|
|
64
|
-
info(' Mode reminder: docker needs Docker; native needs host Postgres/Redis (no Docker required).');
|
|
65
|
-
info(' Each install directory is one deployment / one organization.');
|
|
66
|
-
info('');
|
|
67
42
|
info('Next steps:');
|
|
68
43
|
info(` 1. ragsuite-test start --repo-root ${repoRoot}${mode === 'docker' ? ' --detach' : ''}`);
|
|
69
44
|
if (mode === 'native') {
|
|
@@ -76,139 +51,119 @@ function printSuccess(repoRoot, mode) {
|
|
|
76
51
|
info(installHint());
|
|
77
52
|
}
|
|
78
53
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
54
|
+
function help() {
|
|
55
|
+
return `Usage: ragsuite-test init [options]
|
|
56
|
+
|
|
57
|
+
Simple public install (default — no questions):
|
|
58
|
+
clones ${DEFAULT_GIT_URL}
|
|
59
|
+
into ~/ragsuite-test
|
|
60
|
+
picks docker mode if Docker is running, otherwise native
|
|
61
|
+
writes .env (JWT auto; SMTP/LLM from .env.example — no prompts)
|
|
62
|
+
|
|
63
|
+
ragsuite-test init
|
|
64
|
+
ragsuite-test start --repo-root ~/ragsuite-test --detach
|
|
65
|
+
|
|
66
|
+
Advanced (optional):
|
|
67
|
+
--from-git [url] Clone this URL instead of the default
|
|
68
|
+
--repo-root <path> Use an existing checkout (no clone)
|
|
69
|
+
--install-dir <path> Clone target (default: ~/ragsuite-test)
|
|
70
|
+
--mode <docker|native> Force run mode
|
|
71
|
+
--force Overwrite non-empty install dir / existing .env
|
|
72
|
+
--yes, -y Same defaults; for scripts/CI
|
|
73
|
+
--llm-api-key / --smtp-* Optional overrides (usually not needed)
|
|
74
|
+
`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function optionalSmtpOverrides(g, env) {
|
|
78
|
+
const host = g.smtpHost || env.RAGSUITE_TEST_SMTP_HOST || null;
|
|
79
|
+
const user = g.smtpUser || env.RAGSUITE_TEST_SMTP_USER || null;
|
|
80
|
+
const password = g.smtpPassword || env.RAGSUITE_TEST_SMTP_PASSWORD || null;
|
|
81
|
+
const emailFrom = g.emailFrom || env.RAGSUITE_TEST_EMAIL_FROM || null;
|
|
82
|
+
if (!host && !user && !password && !emailFrom) return null;
|
|
83
|
+
return { host, user, password, emailFrom };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function resolveLlmOverride(g, env) {
|
|
87
|
+
if (g.llmApiKey && !isPlaceholderSecret(g.llmApiKey)) return g.llmApiKey;
|
|
83
88
|
if (env.RAGSUITE_TEST_LLM_API_KEY && !isPlaceholderSecret(env.RAGSUITE_TEST_LLM_API_KEY)) {
|
|
84
89
|
return env.RAGSUITE_TEST_LLM_API_KEY;
|
|
85
90
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
error('Key required and must not start with change-me');
|
|
95
|
-
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function countSources(fromGit, repoRootFlag) {
|
|
95
|
+
let n = 0;
|
|
96
|
+
if (fromGit !== null && fromGit !== undefined) n += 1;
|
|
97
|
+
if (repoRootFlag) n += 1;
|
|
98
|
+
return n;
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
async function run(ctx) {
|
|
99
102
|
assertSupportedInstall();
|
|
100
103
|
const g = ctx.globals;
|
|
101
|
-
const interactive = Boolean(process.stdin.isTTY) && !g.yes;
|
|
102
104
|
|
|
103
105
|
if (g.fromRelease) {
|
|
104
|
-
error(
|
|
105
|
-
`--from-release is not implemented. Download a ZIP (private Release asset or local file), then: ragsuite-test init --from-zip <file.zip>`,
|
|
106
|
-
);
|
|
106
|
+
error('--from-release is not supported. Use default init, --from-git, or --repo-root.');
|
|
107
107
|
return 1;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
if (g.
|
|
111
|
-
error('Use
|
|
110
|
+
if (countSources(g.fromGit, g.repoRoot) > 1) {
|
|
111
|
+
error('Use only one of --from-git or --repo-root');
|
|
112
112
|
return 1;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
const osInfo = detectOs();
|
|
116
116
|
info(`OS: ${osInfo.label} (${osInfo.platform})`);
|
|
117
117
|
|
|
118
|
-
let
|
|
119
|
-
let fromZip = g.fromZip;
|
|
118
|
+
let fromGit = g.fromGit;
|
|
120
119
|
let repoRootFlag = g.repoRoot;
|
|
121
|
-
|
|
120
|
+
const installDir = g.installDir || defaultInstallDir();
|
|
122
121
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
} else if (interactive && !fromZip && !repoRootFlag) {
|
|
129
|
-
const method = await choose(
|
|
130
|
-
'Install method:',
|
|
131
|
-
[
|
|
132
|
-
{ id: 'zip', label: 'Local ZIP file (--from-zip)' },
|
|
133
|
-
{ id: 'checkout', label: 'Existing checkout (--repo-root)' },
|
|
134
|
-
],
|
|
135
|
-
{ defaultIndex: 0 },
|
|
136
|
-
);
|
|
137
|
-
if (method.id === 'zip') {
|
|
138
|
-
fromZip = await ask('Path to app ZIP', { yesMode: false });
|
|
139
|
-
if (!fromZip) {
|
|
140
|
-
error('ZIP path required');
|
|
141
|
-
return 1;
|
|
142
|
-
}
|
|
143
|
-
installDir = await ask('Install directory', {
|
|
144
|
-
defaultValue: defaultInstallDir(),
|
|
145
|
-
yesMode: false,
|
|
146
|
-
});
|
|
147
|
-
} else {
|
|
148
|
-
repoRootFlag = await ask('Path to existing RAGSUITE checkout', { yesMode: false });
|
|
149
|
-
if (!repoRootFlag || !looksLikeRepoRoot(path.resolve(repoRootFlag))) {
|
|
150
|
-
error('Not a valid checkout (need scripts/docker-start.sh)');
|
|
151
|
-
return 1;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const modeChoice = await choose(
|
|
156
|
-
'Run mode (Docker is optional):',
|
|
157
|
-
[
|
|
158
|
-
{ id: 'docker', label: 'Docker — if you have Docker Desktop / daemon (default)' },
|
|
159
|
-
{ id: 'native', label: 'Native — no Docker; needs Postgres :5436 + Redis :6382 on this machine' },
|
|
160
|
-
],
|
|
161
|
-
{ defaultIndex: 0 },
|
|
162
|
-
);
|
|
163
|
-
mode = modeChoice.id;
|
|
164
|
-
} else if (!fromZip && !repoRootFlag) {
|
|
165
|
-
error('Pass --from-zip / --repo-root, or run in a TTY for the interactive wizard');
|
|
166
|
-
return 1;
|
|
122
|
+
// Default public path: no menus, no path prompts — clone GitHub → ~/ragsuite-test
|
|
123
|
+
if (fromGit === null && !repoRootFlag) {
|
|
124
|
+
fromGit = '';
|
|
125
|
+
info(`Install: clone ${DEFAULT_GIT_URL}`);
|
|
126
|
+
info(`Target: ${path.resolve(installDir)}`);
|
|
167
127
|
}
|
|
168
128
|
|
|
169
|
-
|
|
129
|
+
const mode = g.mode || resolvePreferredMode(null);
|
|
130
|
+
info(`Run mode: ${mode} (Docker optional — pass --mode docker|native to force)`);
|
|
131
|
+
|
|
132
|
+
const needGit = fromGit !== null && fromGit !== undefined;
|
|
133
|
+
if (!printPrereqs(mode, { needGit })) {
|
|
170
134
|
error('Fix prerequisites above and re-run init');
|
|
171
135
|
return 1;
|
|
172
136
|
}
|
|
173
137
|
|
|
174
138
|
const jwtSecret = generateJwtSecret();
|
|
175
139
|
info(`JWT_SECRET_KEY will be auto-generated (…${jwtSecret.slice(-8)})`);
|
|
140
|
+
info('SMTP + LLM: from .env.example into .env (no prompts).');
|
|
176
141
|
|
|
177
|
-
const llmKey =
|
|
142
|
+
const llmKey = resolveLlmOverride(g, ctx.env);
|
|
143
|
+
const smtp = optionalSmtpOverrides(g, ctx.env);
|
|
178
144
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if (!smtpSkipped) {
|
|
186
|
-
info('After init, edit SMTP_* in .env (SMTP_HOST, SMTP_USER, SMTP_PASSWORD, EMAIL_FROM).');
|
|
145
|
+
if (ctx.env.RAGSUITE_TEST_SKIP_PORT_CHECK !== '1') {
|
|
146
|
+
try {
|
|
147
|
+
await assertPortsFree();
|
|
148
|
+
} catch (err) {
|
|
149
|
+
error(err.message);
|
|
150
|
+
return 1;
|
|
187
151
|
}
|
|
188
|
-
} else {
|
|
189
|
-
warn('SMTP skipped (--yes / noninteractive). Invites/email may fail until SMTP_* is set.');
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Port checks before mutating install (clearer UX)
|
|
193
|
-
try {
|
|
194
|
-
await assertPortsFree();
|
|
195
|
-
} catch (err) {
|
|
196
|
-
error(err.message);
|
|
197
|
-
return 1;
|
|
198
152
|
}
|
|
199
153
|
|
|
200
154
|
let repoRoot;
|
|
201
155
|
let source = 'checkout';
|
|
202
156
|
|
|
203
157
|
try {
|
|
204
|
-
if (
|
|
205
|
-
|
|
206
|
-
|
|
158
|
+
if (fromGit !== null && fromGit !== undefined) {
|
|
159
|
+
const url = fromGit === '' ? DEFAULT_GIT_URL : fromGit;
|
|
160
|
+
info(`Cloning ${url} → ${path.resolve(installDir)}`);
|
|
161
|
+
const result = cloneGitToInstallDir(url, {
|
|
207
162
|
installDir,
|
|
208
163
|
force: g.force,
|
|
209
164
|
});
|
|
210
165
|
repoRoot = result.repoRoot;
|
|
211
|
-
source = '
|
|
166
|
+
source = 'git';
|
|
212
167
|
info(`Installed app at ${repoRoot}`);
|
|
213
168
|
} else {
|
|
214
169
|
repoRoot = resolveRepoRoot({
|
|
@@ -235,10 +190,10 @@ async function run(ctx) {
|
|
|
235
190
|
force: g.force,
|
|
236
191
|
jwtSecret,
|
|
237
192
|
llmApiKey: llmKey,
|
|
238
|
-
|
|
193
|
+
smtp,
|
|
239
194
|
});
|
|
240
195
|
} catch (err) {
|
|
241
|
-
if (err.code === 'ENV_EXISTS') {
|
|
196
|
+
if (err.code === 'ENV_EXISTS' || err.code === 'ENV_INCOMPLETE') {
|
|
242
197
|
error(err.message);
|
|
243
198
|
return 1;
|
|
244
199
|
}
|
package/src/commands/update.js
CHANGED
|
@@ -14,8 +14,7 @@ function help() {
|
|
|
14
14
|
return `Usage: ragsuite-test update [options]
|
|
15
15
|
|
|
16
16
|
Verifies the install/repo path and prints safe update steps.
|
|
17
|
-
|
|
18
|
-
Checkout installs: optional git fetch + status (no reset).
|
|
17
|
+
Git installs: git fetch + pull guidance (no destructive reset).
|
|
19
18
|
|
|
20
19
|
Never runs docker compose down -v.
|
|
21
20
|
|
|
@@ -32,38 +31,26 @@ function run(ctx) {
|
|
|
32
31
|
});
|
|
33
32
|
|
|
34
33
|
const cfg = readConfig(repoRoot);
|
|
35
|
-
const source = cfg && cfg.source
|
|
34
|
+
const source = (cfg && cfg.source) || 'checkout';
|
|
36
35
|
|
|
37
36
|
info(`Install path OK: ${repoRoot}`);
|
|
38
37
|
info(` source=${source}`);
|
|
39
38
|
info('');
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
info('This install came from a ZIP. Safe update steps:');
|
|
43
|
-
info(' 1. ragsuite-test stop --repo-root ' + repoRoot);
|
|
44
|
-
info(' 2. Download a newer release ZIP (do not wipe Docker volumes)');
|
|
45
|
-
info(' 3. Extract to a NEW directory, e.g. --install-dir ~/ragsuite-test-v2');
|
|
46
|
-
info(' or: backup this dir, then init --from-zip … --force');
|
|
47
|
-
info(' 4. Copy your .env into the new install (do not commit secrets)');
|
|
48
|
-
info(' 5. ragsuite-test doctor --repo-root <new-dir>');
|
|
49
|
-
info(' 6. ragsuite-test start --repo-root <new-dir>');
|
|
50
|
-
info('');
|
|
51
|
-
info('Never: docker compose down -v (destroys Postgres/Chroma data).');
|
|
52
|
-
return 0;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
info('Safe update steps (checkout install):');
|
|
40
|
+
info('Safe update steps:');
|
|
56
41
|
info(' 1. Stop the stack (ragsuite-test stop --repo-root …)');
|
|
57
|
-
info(' 2. Update sources (git pull
|
|
42
|
+
info(' 2. Update sources (git pull)');
|
|
58
43
|
info(' 3. Docker: npm run rebuild or docker compose build');
|
|
59
44
|
info(' 4. Native: re-run backend/scripts/setup.sh if Python deps changed');
|
|
60
45
|
info(' 5. Start again (ragsuite-test start --repo-root …)');
|
|
61
46
|
info(' 6. Run doctor after upgrades');
|
|
62
47
|
info('');
|
|
48
|
+
info('Never: docker compose down -v (destroys Postgres/Chroma data).');
|
|
49
|
+
info('');
|
|
63
50
|
|
|
64
51
|
const gitDir = path.join(repoRoot, '.git');
|
|
65
52
|
if (!fs.existsSync(gitDir)) {
|
|
66
|
-
warn('No .git directory — skip fetch/status
|
|
53
|
+
warn('No .git directory — skip fetch/status. Re-init with --from-git if needed.');
|
|
67
54
|
return 0;
|
|
68
55
|
}
|
|
69
56
|
|
package/src/index.js
CHANGED
|
@@ -31,16 +31,20 @@ function globalHelp() {
|
|
|
31
31
|
'Global options:',
|
|
32
32
|
' --help, -h Show help',
|
|
33
33
|
' --repo-root <path> Monorepo / install root',
|
|
34
|
-
' --from-
|
|
35
|
-
' --install-dir <path> init:
|
|
36
|
-
' --
|
|
37
|
-
' --
|
|
34
|
+
' --from-git [url] init: clone this URL (default: public nitsan-ai/RAGSUITE)',
|
|
35
|
+
' --install-dir <path> init: clone target (default ~/ragsuite-test)',
|
|
36
|
+
' --llm-api-key <key> init: optional override for CUSTOM_LLM_INTERNAL_API_KEY',
|
|
37
|
+
' --smtp-host <host> init: optional SMTP override',
|
|
38
|
+
' --smtp-user <user> init: optional SMTP override',
|
|
39
|
+
' --smtp-password <pass> init: optional SMTP override',
|
|
40
|
+
' --email-from <email> init: optional SMTP override',
|
|
38
41
|
' --force init: overwrite non-empty install dir / .env',
|
|
39
|
-
' --yes, -y Non-interactive',
|
|
40
|
-
' --mode <docker|native> Override
|
|
42
|
+
' --yes, -y Non-interactive (same defaults as plain init)',
|
|
43
|
+
' --mode <docker|native> Override config (Docker optional)',
|
|
41
44
|
' --dry-run Print actions without running (start/stop/doctor/logs)',
|
|
42
45
|
'',
|
|
43
46
|
'Env: RAGSUITE_REPO_ROOT or RAGSUITE_INSTALL_DIR',
|
|
47
|
+
' RAGSUITE_TEST_LLM_API_KEY, RAGSUITE_TEST_SMTP_* , RAGSUITE_TEST_EMAIL_FROM',
|
|
44
48
|
'',
|
|
45
49
|
'Run ragsuite-test <command> --help for command details.',
|
|
46
50
|
);
|
|
@@ -88,7 +92,7 @@ async function main(argv = process.argv) {
|
|
|
88
92
|
const code = typeof result?.then === 'function' ? await result : result;
|
|
89
93
|
return typeof code === 'number' ? code : 0;
|
|
90
94
|
} catch (err) {
|
|
91
|
-
if (err && (err.code === 'NOT_REPO_ROOT' || err.code === 'USAGE' || err.code === '
|
|
95
|
+
if (err && (err.code === 'NOT_REPO_ROOT' || err.code === 'USAGE' || err.code === 'INSTALL_DIR_NONEMPTY' || err.code === 'ENV_EXISTS' || err.code === 'ENV_INCOMPLETE' || err.code === 'PORT_IN_USE' || err.code === 'LLM_KEY_INVALID' || err.code === 'SMTP_REQUIRED' || err.code === 'GIT_CLONE_FAILED' || err.code === 'MISSING_GIT')) {
|
|
92
96
|
error(err.message);
|
|
93
97
|
return 1;
|
|
94
98
|
}
|