@nitsan-ai/ragsuite-test 0.1.3 → 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 +46 -71
- package/package.json +2 -3
- package/src/commands/doctor.js +16 -16
- package/src/commands/init.js +129 -85
- package/src/commands/logs.js +23 -35
- package/src/commands/start.js +12 -37
- package/src/commands/stop.js +15 -24
- package/src/commands/update.js +55 -52
- package/src/index.js +7 -7
- package/src/utils/args.js +10 -3
- package/src/utils/config.js +11 -26
- package/src/utils/distribution.js +10 -16
- package/src/utils/git-install.js +13 -8
- package/src/utils/global-config.js +61 -0
- package/src/utils/paths.js +81 -22
- package/src/utils/port.js +3 -4
- package/src/utils/prereqs.js +25 -65
- package/src/utils/images-install.js +0 -100
- package/templates/images/.env.example +0 -76
- package/templates/images/docker-compose.yml +0 -165
- package/templates/images/scripts/docker-doctor-images.sh +0 -48
- package/templates/images/scripts/docker-start-images.sh +0 -107
- package/templates/images/scripts/docker-stop-images.sh +0 -22
package/README.md
CHANGED
|
@@ -1,103 +1,78 @@
|
|
|
1
1
|
# RAGSuite test CLI (`ragsuite-test`)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Two ways to run. Pick one:
|
|
6
|
-
|
|
7
|
-
| | **A) Git source** | **B) Docker images only** |
|
|
8
|
-
|--|-------------------|---------------------------|
|
|
9
|
-
| Command | `ragsuite-test init` | `ragsuite-test init --from-images` |
|
|
10
|
-
| On disk | Full monorepo clone | Tiny compose bundle only |
|
|
11
|
-
| App code visible? | Yes | **No** (runs in containers) |
|
|
12
|
-
| Needs | git + Node; Docker *or* native Postgres/Redis | Node + **Docker** |
|
|
13
|
-
| Best for | Dev, debugging, native mode, reading code | Testers / “just run the app” |
|
|
14
|
-
| Pros | Native mode; full scripts; offline rebuild from source | No source leak; faster to start; smaller disk |
|
|
15
|
-
| Cons | Source on disk; larger checkout | Needs published GHCR images; Docker required; no native mode |
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## A) Git source (clone)
|
|
3
|
+
npm-style deploy: **init once**, then **start / update / stop** via host **npm scripts** — **no Docker**.
|
|
20
4
|
|
|
21
5
|
```bash
|
|
22
6
|
npm install -g @nitsan-ai/ragsuite-test
|
|
7
|
+
|
|
8
|
+
# First time only
|
|
23
9
|
ragsuite-test init
|
|
24
|
-
# clones
|
|
25
|
-
# auto: docker if daemon up, else native
|
|
10
|
+
# clones → ~/ragsuite-test
|
|
26
11
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
#
|
|
12
|
+
# Needs Postgres :5436 (db ragsuite_v3) and Redis :6382 on the host
|
|
13
|
+
ragsuite-test start
|
|
14
|
+
# API http://localhost:9090 · Web http://localhost:9191
|
|
30
15
|
|
|
31
|
-
|
|
32
|
-
# Web http://localhost:9091 (docker) or :9191 (native)
|
|
33
|
-
ragsuite-test stop --repo-root ~/ragsuite-test
|
|
16
|
+
ragsuite-test stop
|
|
34
17
|
```
|
|
35
18
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
Needs Postgres `:5436` (`ragsuite_v3`) and Redis `:6382`:
|
|
19
|
+
Same under the hood as:
|
|
39
20
|
|
|
40
21
|
```bash
|
|
41
|
-
ragsuite-test
|
|
42
|
-
|
|
22
|
+
cd ~/ragsuite-test
|
|
23
|
+
npm start # scripts/native-start.sh
|
|
24
|
+
npm run stop # scripts/native-stop.sh
|
|
43
25
|
```
|
|
44
26
|
|
|
45
|
-
|
|
27
|
+
Active install is remembered in `~/.ragsuite-test/config.json`.
|
|
46
28
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
**Maintainer (once):** publish images — Actions → **Publish images (GHCR)**
|
|
50
|
-
(packages: `ghcr.io/nitsan-ai/ragsuite-backend`, `…/ragsuite-frontend`)
|
|
29
|
+
---
|
|
51
30
|
|
|
52
|
-
|
|
31
|
+
## Upgrade (keeps data & `.env`)
|
|
53
32
|
|
|
54
33
|
```bash
|
|
55
|
-
npm install -g @nitsan-ai/ragsuite-test
|
|
56
|
-
ragsuite-test
|
|
57
|
-
ragsuite-test start
|
|
58
|
-
# pulls images — does NOT clone app source
|
|
59
|
-
ragsuite-test stop --repo-root ~/ragsuite-test
|
|
34
|
+
npm install -g @nitsan-ai/ragsuite-test@latest
|
|
35
|
+
ragsuite-test update # git pull only
|
|
36
|
+
ragsuite-test start
|
|
60
37
|
```
|
|
61
38
|
|
|
62
|
-
|
|
39
|
+
**Never** run `docker compose down -v` or `init --force` unless you mean to wipe data.
|
|
63
40
|
|
|
64
|
-
|
|
65
|
-
# in ~/ragsuite-test/.env
|
|
66
|
-
IMAGE_TAG=1.0.0
|
|
67
|
-
IMAGE_REGISTRY=ghcr.io/nitsan-ai
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
If images are private on GHCR, make packages public or `docker login ghcr.io`.
|
|
41
|
+
If you already installed and run `init` again → **Already installed** (exit OK).
|
|
71
42
|
|
|
72
43
|
---
|
|
73
44
|
|
|
74
|
-
## Prerequisites
|
|
45
|
+
## Prerequisites (host)
|
|
75
46
|
|
|
76
|
-
|
|
|
77
|
-
|
|
78
|
-
| Node 18+ |
|
|
79
|
-
|
|
|
80
|
-
|
|
|
81
|
-
|
|
|
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` |
|
|
82
55
|
|
|
83
|
-
|
|
56
|
+
Docker is **not** required for this CLI.
|
|
84
57
|
|
|
85
|
-
|
|
58
|
+
---
|
|
86
59
|
|
|
87
|
-
|
|
88
|
-
|---------|------|
|
|
89
|
-
| API | 9090 |
|
|
90
|
-
| Web (Docker/images) | 9091 |
|
|
91
|
-
| Web (native Expo) | 9191 |
|
|
92
|
-
| Postgres | 5436 |
|
|
93
|
-
| Redis | 6382 |
|
|
60
|
+
## Commands
|
|
94
61
|
|
|
95
|
-
|
|
62
|
+
| Command | Purpose |
|
|
63
|
+
|---------|---------|
|
|
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` |
|
|
70
|
+
| `version` | CLI version |
|
|
96
71
|
|
|
97
|
-
|
|
72
|
+
## Ports
|
|
98
73
|
|
|
99
|
-
|
|
74
|
+
API **9090** · Web **9191** · Postgres **5436** · Redis **6382** · Chroma **8004** (started by native-start if needed)
|
|
100
75
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
76
|
+
## Publish (maintainers)
|
|
77
|
+
|
|
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.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "RAGSuite testing CLI — init
|
|
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"
|
package/src/commands/doctor.js
CHANGED
|
@@ -2,20 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const { resolveMode } = require('../utils/config');
|
|
5
|
-
const { resolveRepoRoot,
|
|
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 = '
|
|
10
|
+
const summary = 'Check native deploy prerequisites';
|
|
10
11
|
|
|
11
12
|
function help() {
|
|
12
13
|
return `Usage: ragsuite-test doctor [options]
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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:
|
|
40
|
+
env: { ...ctx.env, RAGSUITE_MODE: resolveMode() },
|
|
41
41
|
});
|
|
42
42
|
}
|
|
43
43
|
|
package/src/commands/init.js
CHANGED
|
@@ -1,85 +1,97 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const path = require('path');
|
|
4
|
-
const { writeConfig, CONFIG_DIR } = require('../utils/config');
|
|
4
|
+
const { writeConfig, CONFIG_DIR, readConfig } = require('../utils/config');
|
|
5
5
|
const {
|
|
6
6
|
ensureRagsuiteDir,
|
|
7
7
|
resolveRepoRoot,
|
|
8
|
-
|
|
8
|
+
looksLikeRepoRoot,
|
|
9
|
+
isDirEmptyOrMissing,
|
|
9
10
|
} = require('../utils/paths');
|
|
11
|
+
const { setActiveInstall } = require('../utils/global-config');
|
|
10
12
|
const { assertSupportedInstall, installHint } = require('../utils/distribution');
|
|
11
13
|
const {
|
|
12
14
|
DEFAULT_GIT_URL,
|
|
13
15
|
defaultInstallDir,
|
|
14
16
|
cloneGitToInstallDir,
|
|
15
17
|
} = require('../utils/git-install');
|
|
16
|
-
const { materializeImagesInstall } = require('../utils/images-install');
|
|
17
18
|
const { detectOs } = require('../utils/os-detect');
|
|
18
|
-
const {
|
|
19
|
-
printPrereqs,
|
|
20
|
-
resolvePreferredMode,
|
|
21
|
-
} = require('../utils/prereqs');
|
|
19
|
+
const { printPrereqs, resolvePreferredMode } = require('../utils/prereqs');
|
|
22
20
|
const {
|
|
23
21
|
generateJwtSecret,
|
|
24
22
|
isPlaceholderSecret,
|
|
25
23
|
writeInstallEnv,
|
|
26
24
|
} = require('../utils/env-file');
|
|
27
25
|
const { assertPortsFree } = require('../utils/port');
|
|
28
|
-
const { info, error } = require('../utils/log');
|
|
26
|
+
const { info, warn, error } = require('../utils/log');
|
|
29
27
|
|
|
30
28
|
const name = 'init';
|
|
31
|
-
const summary = '
|
|
29
|
+
const summary = 'First-time install (git + native npm scripts). Safe if already installed.';
|
|
32
30
|
|
|
33
|
-
function printSuccess(repoRoot
|
|
31
|
+
function printSuccess(repoRoot) {
|
|
34
32
|
info('');
|
|
35
33
|
info('=== Install complete ===');
|
|
36
34
|
info(` Install dir : ${repoRoot}`);
|
|
37
|
-
info(
|
|
38
|
-
info(` Mode : ${mode}`);
|
|
39
|
-
info(` Config : ${path.join(repoRoot, CONFIG_DIR, 'config.json')}`);
|
|
35
|
+
info(' Mode : native (npm scripts — no Docker)');
|
|
40
36
|
info('');
|
|
41
37
|
info(' API http://localhost:9090');
|
|
42
|
-
|
|
43
|
-
info(' Web http://localhost:9091 (images / Docker nginx)');
|
|
44
|
-
} else if (mode === 'native') {
|
|
45
|
-
info(' Web http://localhost:9191 (Expo web — native mode)');
|
|
46
|
-
} else {
|
|
47
|
-
info(' Web http://localhost:9091 (Docker nginx)');
|
|
48
|
-
}
|
|
38
|
+
info(' Web http://localhost:9191');
|
|
49
39
|
info('');
|
|
50
|
-
info('Next
|
|
51
|
-
|
|
52
|
-
info(
|
|
53
|
-
info('
|
|
54
|
-
info(
|
|
40
|
+
info('Next (no --repo-root needed):');
|
|
41
|
+
info(' ragsuite-test start');
|
|
42
|
+
info(' ragsuite-test stop');
|
|
43
|
+
info(' ragsuite-test update # later upgrades, keeps data');
|
|
44
|
+
info('');
|
|
45
|
+
info('Or in the install directory:');
|
|
46
|
+
info(' npm start');
|
|
47
|
+
info(' npm run stop');
|
|
55
48
|
info('');
|
|
56
49
|
info(installHint());
|
|
57
50
|
}
|
|
58
51
|
|
|
52
|
+
function printAlreadyInstalled(repoRoot) {
|
|
53
|
+
const cfg = readConfig(repoRoot);
|
|
54
|
+
setActiveInstall(repoRoot);
|
|
55
|
+
info('');
|
|
56
|
+
info('=== Already installed ===');
|
|
57
|
+
info(` ${repoRoot}`);
|
|
58
|
+
if (cfg) info(` source=${cfg.source} mode=native`);
|
|
59
|
+
info('');
|
|
60
|
+
info('Use:');
|
|
61
|
+
info(' ragsuite-test start # run the app (npm scripts)');
|
|
62
|
+
info(' ragsuite-test update # upgrade code (keeps .env + data)');
|
|
63
|
+
info(' ragsuite-test stop');
|
|
64
|
+
info('');
|
|
65
|
+
info('Do NOT run init --force unless you intend to wipe and reinstall.');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function isInitializedInstall(dir) {
|
|
69
|
+
return looksLikeRepoRoot(dir) && Boolean(readConfig(dir));
|
|
70
|
+
}
|
|
71
|
+
|
|
59
72
|
function help() {
|
|
60
73
|
return `Usage: ragsuite-test init [options]
|
|
61
74
|
|
|
62
|
-
|
|
75
|
+
First-time setup (npm-style, no Docker):
|
|
76
|
+
|
|
77
|
+
ragsuite-test init # git clone → ~/ragsuite-test
|
|
78
|
+
ragsuite-test start # scripts/native-start.sh
|
|
79
|
+
|
|
80
|
+
If already installed, init exits OK and tells you to start/update.
|
|
63
81
|
|
|
64
|
-
|
|
65
|
-
ragsuite-test init
|
|
66
|
-
Clones ${DEFAULT_GIT_URL} → ~/ragsuite-test
|
|
67
|
-
Supports --mode docker|native
|
|
82
|
+
Requires host Postgres (:5436) and Redis (:6382).
|
|
68
83
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
84
|
+
Day-to-day:
|
|
85
|
+
ragsuite-test start
|
|
86
|
+
ragsuite-test update
|
|
87
|
+
ragsuite-test stop
|
|
73
88
|
|
|
74
89
|
Options:
|
|
75
|
-
--from-
|
|
76
|
-
--
|
|
77
|
-
--
|
|
78
|
-
--install
|
|
79
|
-
--mode <docker|native> Git install only (images install is always docker)
|
|
80
|
-
--force Overwrite non-empty install dir / existing .env
|
|
90
|
+
--from-git [url] Clone URL (default public repo)
|
|
91
|
+
--repo-root <path> Point at an existing checkout
|
|
92
|
+
--install-dir <path> Default: ~/ragsuite-test
|
|
93
|
+
--force Wipe install dir and reinstall (destructive)
|
|
81
94
|
--yes, -y Non-interactive
|
|
82
|
-
--llm-api-key / --smtp-* Optional overrides
|
|
83
95
|
`;
|
|
84
96
|
}
|
|
85
97
|
|
|
@@ -100,10 +112,9 @@ function resolveLlmOverride(g, env) {
|
|
|
100
112
|
return null;
|
|
101
113
|
}
|
|
102
114
|
|
|
103
|
-
function countSources(fromGit,
|
|
115
|
+
function countSources(fromGit, repoRootFlag) {
|
|
104
116
|
let n = 0;
|
|
105
117
|
if (fromGit !== null && fromGit !== undefined) n += 1;
|
|
106
|
-
if (fromImages) n += 1;
|
|
107
118
|
if (repoRootFlag) n += 1;
|
|
108
119
|
return n;
|
|
109
120
|
}
|
|
@@ -113,12 +124,34 @@ async function run(ctx) {
|
|
|
113
124
|
const g = ctx.globals;
|
|
114
125
|
|
|
115
126
|
if (g.fromRelease) {
|
|
116
|
-
error('--from-release is not supported.
|
|
127
|
+
error('--from-release is not supported.');
|
|
117
128
|
return 1;
|
|
118
129
|
}
|
|
119
130
|
|
|
120
|
-
if (
|
|
121
|
-
error(
|
|
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');
|
|
122
155
|
return 1;
|
|
123
156
|
}
|
|
124
157
|
|
|
@@ -126,30 +159,53 @@ async function run(ctx) {
|
|
|
126
159
|
info(`OS: ${osInfo.label} (${osInfo.platform})`);
|
|
127
160
|
|
|
128
161
|
let fromGit = g.fromGit;
|
|
129
|
-
let fromImages = Boolean(g.fromImages);
|
|
130
162
|
let repoRootFlag = g.repoRoot;
|
|
131
|
-
const installDir = g.installDir || defaultInstallDir();
|
|
163
|
+
const installDir = path.resolve(g.installDir || defaultInstallDir());
|
|
164
|
+
|
|
165
|
+
if (!g.force) {
|
|
166
|
+
if (repoRootFlag && isInitializedInstall(path.resolve(repoRootFlag))) {
|
|
167
|
+
printAlreadyInstalled(path.resolve(repoRootFlag));
|
|
168
|
+
return 0;
|
|
169
|
+
}
|
|
170
|
+
if (!repoRootFlag && isInitializedInstall(installDir)) {
|
|
171
|
+
printAlreadyInstalled(installDir);
|
|
172
|
+
return 0;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
132
175
|
|
|
133
|
-
if (
|
|
176
|
+
if (fromGit === null && !repoRootFlag) {
|
|
134
177
|
fromGit = '';
|
|
135
|
-
info(`
|
|
136
|
-
info(`
|
|
178
|
+
info(`First-time install (git): ${DEFAULT_GIT_URL}`);
|
|
179
|
+
info(` → ${installDir}`);
|
|
137
180
|
}
|
|
138
181
|
|
|
139
|
-
if (
|
|
140
|
-
|
|
141
|
-
|
|
182
|
+
if (
|
|
183
|
+
!g.force &&
|
|
184
|
+
!repoRootFlag &&
|
|
185
|
+
looksLikeRepoRoot(installDir) &&
|
|
186
|
+
!readConfig(installDir)
|
|
187
|
+
) {
|
|
188
|
+
info(`Found existing source at ${installDir} — finishing setup (no re-clone).`);
|
|
189
|
+
repoRootFlag = installDir;
|
|
190
|
+
fromGit = null;
|
|
142
191
|
}
|
|
143
192
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
193
|
+
if (!g.force && !isDirEmptyOrMissing(installDir) && !looksLikeRepoRoot(installDir) && !repoRootFlag) {
|
|
194
|
+
error(
|
|
195
|
+
[
|
|
196
|
+
`Directory exists but is not a RAGSuite install: ${installDir}`,
|
|
197
|
+
' Fix leftover files, or:',
|
|
198
|
+
' ragsuite-test init --force # wipe & reinstall (destructive)',
|
|
199
|
+
' ragsuite-test init --install-dir ~/ragsuite-test-2',
|
|
200
|
+
].join('\n'),
|
|
201
|
+
);
|
|
202
|
+
return 1;
|
|
149
203
|
}
|
|
150
|
-
info(`Run mode: ${mode}`);
|
|
151
204
|
|
|
152
|
-
const
|
|
205
|
+
const mode = resolvePreferredMode();
|
|
206
|
+
info(`Run mode: ${mode} (npm scripts — Docker not used)`);
|
|
207
|
+
|
|
208
|
+
const needGit = fromGit !== null && fromGit !== undefined;
|
|
153
209
|
if (!printPrereqs(mode, { needGit })) {
|
|
154
210
|
error('Fix prerequisites above and re-run init');
|
|
155
211
|
return 1;
|
|
@@ -157,7 +213,6 @@ async function run(ctx) {
|
|
|
157
213
|
|
|
158
214
|
const jwtSecret = generateJwtSecret();
|
|
159
215
|
info(`JWT_SECRET_KEY will be auto-generated (…${jwtSecret.slice(-8)})`);
|
|
160
|
-
info('SMTP + LLM: from .env.example into .env (no prompts).');
|
|
161
216
|
|
|
162
217
|
const llmKey = resolveLlmOverride(g, ctx.env);
|
|
163
218
|
const smtp = optionalSmtpOverrides(g, ctx.env);
|
|
@@ -175,31 +230,17 @@ async function run(ctx) {
|
|
|
175
230
|
let source = 'checkout';
|
|
176
231
|
|
|
177
232
|
try {
|
|
178
|
-
if (
|
|
179
|
-
const result = materializeImagesInstall({
|
|
180
|
-
installDir,
|
|
181
|
-
force: g.force,
|
|
182
|
-
});
|
|
183
|
-
repoRoot = result.repoRoot;
|
|
184
|
-
source = 'images';
|
|
185
|
-
info(`Images bundle installed at ${repoRoot}`);
|
|
186
|
-
} else if (fromGit !== null && fromGit !== undefined) {
|
|
233
|
+
if (fromGit !== null && fromGit !== undefined) {
|
|
187
234
|
const url = fromGit === '' ? DEFAULT_GIT_URL : fromGit;
|
|
188
|
-
|
|
189
|
-
const result = cloneGitToInstallDir(url, {
|
|
190
|
-
installDir,
|
|
191
|
-
force: g.force,
|
|
192
|
-
});
|
|
235
|
+
const result = cloneGitToInstallDir(url, { installDir, force: g.force });
|
|
193
236
|
repoRoot = result.repoRoot;
|
|
194
237
|
source = 'git';
|
|
195
|
-
info(`Installed app at ${repoRoot}`);
|
|
196
238
|
} else {
|
|
197
239
|
repoRoot = resolveRepoRoot({
|
|
198
240
|
cwd: ctx.cwd,
|
|
199
241
|
repoRootFlag,
|
|
200
242
|
env: ctx.env,
|
|
201
243
|
});
|
|
202
|
-
if (isImagesInstall(repoRoot)) source = 'images';
|
|
203
244
|
}
|
|
204
245
|
} catch (err) {
|
|
205
246
|
error(err.message || String(err));
|
|
@@ -208,11 +249,12 @@ async function run(ctx) {
|
|
|
208
249
|
|
|
209
250
|
ensureRagsuiteDir(repoRoot);
|
|
210
251
|
const cfg = writeConfig(repoRoot, {
|
|
211
|
-
mode,
|
|
252
|
+
mode: 'native',
|
|
212
253
|
source,
|
|
213
254
|
repoRoot,
|
|
214
255
|
installDir: repoRoot,
|
|
215
256
|
});
|
|
257
|
+
setActiveInstall(repoRoot);
|
|
216
258
|
|
|
217
259
|
try {
|
|
218
260
|
writeInstallEnv(repoRoot, {
|
|
@@ -222,17 +264,19 @@ async function run(ctx) {
|
|
|
222
264
|
smtp,
|
|
223
265
|
});
|
|
224
266
|
} catch (err) {
|
|
225
|
-
if (err.code === 'ENV_EXISTS'
|
|
267
|
+
if (err.code === 'ENV_EXISTS') {
|
|
268
|
+
warn('.env already present — keeping it (use --force only if you want to regenerate).');
|
|
269
|
+
} else if (err.code === 'ENV_INCOMPLETE') {
|
|
226
270
|
error(err.message);
|
|
227
271
|
return 1;
|
|
272
|
+
} else {
|
|
273
|
+
error(err.message || String(err));
|
|
274
|
+
return 1;
|
|
228
275
|
}
|
|
229
|
-
error(err.message || String(err));
|
|
230
|
-
return 1;
|
|
231
276
|
}
|
|
232
277
|
|
|
233
|
-
info(`
|
|
234
|
-
|
|
235
|
-
printSuccess(repoRoot, mode, source);
|
|
278
|
+
info(`Config: mode=${cfg.mode} source=${cfg.source}`);
|
|
279
|
+
printSuccess(repoRoot);
|
|
236
280
|
return 0;
|
|
237
281
|
}
|
|
238
282
|
|
package/src/commands/logs.js
CHANGED
|
@@ -2,23 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
|
-
const {
|
|
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
|
|
10
|
+
const summary = 'Follow native process logs';
|
|
12
11
|
|
|
13
12
|
function help() {
|
|
14
13
|
return `Usage: ragsuite-test logs [options]
|
|
15
14
|
|
|
16
|
-
|
|
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
|
-
--
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
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,
|