@iamsaroj/replicax 0.0.3 → 0.0.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 +199 -73
- package/dist/index.js +1590 -205
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,23 +5,25 @@
|
|
|
5
5
|
<h3><em>Copy the setup, not the code.</em></h3>
|
|
6
6
|
|
|
7
7
|
<p>
|
|
8
|
-
Extract a project's entire development environment
|
|
8
|
+
Extract a project's entire development environment - <strong>tooling, folder structure, and conventions</strong>
|
|
9
9
|
into a portable profile, then recreate it anywhere in seconds.<br/>
|
|
10
10
|
None of your business code. None of your secrets. Just the setup.
|
|
11
11
|
</p>
|
|
12
12
|
|
|
13
13
|
[](https://www.npmjs.com/package/@iamsaroj/replicax)
|
|
14
|
+
[](https://github.com/khanalsaroj/replicaX/actions/workflows/ci.yml)
|
|
15
|
+
[](https://github.com/khanalsaroj/replicaX/actions/workflows/release.yml)
|
|
14
16
|
[](https://nodejs.org)
|
|
15
17
|
[](https://www.typescriptlang.org)
|
|
16
18
|

|
|
17
19
|
[](LICENSE)
|
|
18
20
|
|
|
19
21
|
<sub>
|
|
20
|
-
<a href="#quick-start"><b>Quick start</b></a>  
|
|
21
|
-
<a href="#commands"><b>Commands</b></a>  
|
|
22
|
-
<a href="#what-gets-captured"><b>What gets captured</b></a>  
|
|
23
|
-
<a href="#security"><b>Security</b></a>  
|
|
24
|
-
<a href="#how-it-works"><b>How it works</b></a>  
|
|
22
|
+
<a href="#quick-start"><b>Quick start</b></a> |
|
|
23
|
+
<a href="#commands"><b>Commands</b></a> |
|
|
24
|
+
<a href="#what-gets-captured"><b>What gets captured</b></a> |
|
|
25
|
+
<a href="#security"><b>Security</b></a> |
|
|
26
|
+
<a href="#how-it-works"><b>How it works</b></a> |
|
|
25
27
|
<a href="#faq"><b>FAQ</b></a>
|
|
26
28
|
</sub>
|
|
27
29
|
|
|
@@ -29,14 +31,14 @@
|
|
|
29
31
|
|
|
30
32
|
---
|
|
31
33
|
|
|
32
|
-
> **ReplicaX captures the _setup_ of a project
|
|
33
|
-
the _implementation_ behind.**
|
|
34
|
+
> **ReplicaX captures the _setup_ of a project - the parts you copy-paste between every new repo - and leaves
|
|
35
|
+
> the _implementation_ behind.**
|
|
34
36
|
|
|
35
37
|
Every new project starts the same way: copy `tsconfig.json`, port the ESLint and Prettier config, recreate the
|
|
36
|
-
Dockerfiles, re
|
|
38
|
+
Dockerfiles, re-add the CI workflow, rebuild `src/`'s folder layout. It's slow, error-prone, and quietly drifts out of
|
|
37
39
|
sync across a team.
|
|
38
40
|
|
|
39
|
-
ReplicaX captures that ritual **once** and replays it **on demand**
|
|
41
|
+
ReplicaX captures that ritual **once** and replays it **on demand** - locally, or straight from any GitHub repo.
|
|
40
42
|
|
|
41
43
|
> It is **not** a code generator, a project cloner, or a backup tool.
|
|
42
44
|
|
|
@@ -46,7 +48,7 @@ ReplicaX captures that ritual **once** and replays it **on demand** — locally,
|
|
|
46
48
|
|
|
47
49
|
| | Without ReplicaX | With ReplicaX |
|
|
48
50
|
|-----------------------|--------------------------------------------|---------------------------------|
|
|
49
|
-
| **New project setup** | 30+ minutes of copy
|
|
51
|
+
| **New project setup** | 30+ minutes of copy-paste from an old repo | `replicax create my-app` |
|
|
50
52
|
| **What you copy** | Whatever you remember to grab | A complete, validated profile |
|
|
51
53
|
| **Secrets** | One stray `.env` away from a leak | Blocked unconditionally |
|
|
52
54
|
| **Team consistency** | Drifts repo to repo | One shareable `.tar.gz` profile |
|
|
@@ -58,16 +60,16 @@ ReplicaX captures that ritual **once** and replays it **on demand** — locally,
|
|
|
58
60
|
|
|
59
61
|
| | |
|
|
60
62
|
|-------------------------------|------------------------------------------------------------------------------------------------------------------|
|
|
61
|
-
| **One
|
|
62
|
-
| **Capture any GitHub repo** | `extract owner/repo` profiles a remote repo
|
|
63
|
-
| **One
|
|
64
|
-
| **AI assistant skills** | `init-skill` uses your own AI (Claude
|
|
65
|
-
| **`.ts` _and_ `.js` configs** | Copied byte
|
|
66
|
-
| **Secret
|
|
63
|
+
| **One-command capture** | `init` scans the current project into a reusable profile. |
|
|
64
|
+
| **Capture any GitHub repo** | `extract owner/repo` profiles a remote repo - no clone, no `git` required. |
|
|
65
|
+
| **One-command scaffold** | `create` reproduces the setup in a fresh directory. |
|
|
66
|
+
| **AI assistant skills** | `init-skill` uses your own AI (Claude / Codex / Gemini) to author a ready-to-use skill for agentic coding tools. |
|
|
67
|
+
| **`.ts` _and_ `.js` configs** | Copied byte-for-byte - never compiled, never executed. |
|
|
68
|
+
| **Secret-safe by design** | `.env`, keys, and certs can never enter a profile; `.npmrc` tokens are stripped automatically. |
|
|
67
69
|
| **No business code** | Folders are recreated empty; source files are never read. |
|
|
68
|
-
| **Stays in sync** | `sync --diff` shows what drifted; `validate` verifies integrity via SHA
|
|
70
|
+
| **Stays in sync** | `sync --diff` shows what drifted; `validate` verifies integrity via SHA-256. |
|
|
69
71
|
| **Portable & shareable** | `export` / `import` a whole profile as a single `.tar.gz`. |
|
|
70
|
-
| **`.replicaxignore`** | gitignore
|
|
72
|
+
| **`.replicaxignore`** | gitignore-style control over exactly what gets captured. |
|
|
71
73
|
|
|
72
74
|
---
|
|
73
75
|
|
|
@@ -86,15 +88,15 @@ pnpm add -g @iamsaroj/replicax
|
|
|
86
88
|
## Quick start
|
|
87
89
|
|
|
88
90
|
```bash
|
|
89
|
-
# 1
|
|
91
|
+
# 1 In an existing, well-configured project
|
|
90
92
|
cd my-project
|
|
91
|
-
replicax init #
|
|
93
|
+
replicax init # -> writes a profile to .replicax/
|
|
92
94
|
|
|
93
|
-
# 2
|
|
94
|
-
replicax create my-new-app #
|
|
95
|
+
# 2 Anywhere the profile lives, scaffold a fresh project
|
|
96
|
+
replicax create my-new-app # -> same setup, none of the code
|
|
95
97
|
```
|
|
96
98
|
|
|
97
|
-
|
|
99
|
+
...and here's what `init` actually shows you:
|
|
98
100
|
|
|
99
101
|
```console
|
|
100
102
|
$ replicax init
|
|
@@ -136,14 +138,14 @@ my-app/
|
|
|
136
138
|
Create a project from it with: replicax create <project-name>
|
|
137
139
|
```
|
|
138
140
|
|
|
139
|
-
> 💡 **Tip:** run `replicax init --dry-run` first to preview exactly what would be captured
|
|
141
|
+
> 💡 **Tip:** run `replicax init --dry-run` first to preview exactly what would be captured - nothing is written.
|
|
140
142
|
|
|
141
143
|
---
|
|
142
144
|
|
|
143
145
|
## Before & After
|
|
144
146
|
|
|
145
147
|
Starting from a typical **Vite + React + TypeScript** project, `replicax init && replicax create my-new-app` produces a
|
|
146
|
-
clean skeleton
|
|
148
|
+
clean skeleton - same tooling, zero application code, zero secrets.
|
|
147
149
|
|
|
148
150
|
<table>
|
|
149
151
|
<tr>
|
|
@@ -164,14 +166,14 @@ my-project/
|
|
|
164
166
|
├── docker-compose.yml
|
|
165
167
|
├── .github/workflows/ci.yml
|
|
166
168
|
├── .husky/pre-commit
|
|
167
|
-
├── .env
|
|
168
|
-
├── package.json
|
|
169
|
+
├── .env <- secret
|
|
170
|
+
├── package.json <- runtime deps
|
|
169
171
|
└── src/
|
|
170
172
|
├── components/
|
|
171
|
-
│ └── Button.tsx
|
|
173
|
+
│ └── Button.tsx <- business code
|
|
172
174
|
├── hooks/
|
|
173
175
|
├── services/
|
|
174
|
-
│ └── UserService.ts
|
|
176
|
+
│ └── UserService.ts <- business code
|
|
175
177
|
└── pages/
|
|
176
178
|
</pre>
|
|
177
179
|
|
|
@@ -211,14 +213,17 @@ No `.env`. No `Button.tsx`. No `UserService.ts`. No `react` runtime dependency.
|
|
|
211
213
|
|
|
212
214
|
| Command | What it does |
|
|
213
215
|
|--------------------------------------------------------------------------------------|----------------------------------------------------|
|
|
214
|
-
| [`replicax init`](#replicax-init) | Scan the current project
|
|
216
|
+
| [`replicax init`](#replicax-init) | Scan the current project -> profile in `.replicax/` |
|
|
215
217
|
| [`replicax extract <repo>`](#replicax-extract-repo) | Profile a **remote GitHub repo** (no clone) |
|
|
216
218
|
| [`replicax create <name>`](#replicax-create-project-name) | Scaffold a new project from a profile |
|
|
217
219
|
| [`replicax sync`](#replicax-sync) | Update the profile from the current project |
|
|
218
220
|
| [`replicax inspect`](#replicax-inspect) | Display captured config & structure |
|
|
219
|
-
| [`replicax validate`](#replicax-validate) | Schema + integrity (SHA
|
|
221
|
+
| [`replicax validate`](#replicax-validate) | Schema + integrity (SHA-256) check CI-friendly |
|
|
220
222
|
| [`replicax export`](#replicax-export--import) / [`import`](#replicax-export--import) | Portable `.tar.gz` profile in/out |
|
|
221
|
-
| [`replicax init-skill`](#replicax-init-skill) | Author an AI
|
|
223
|
+
| [`replicax init-skill`](#replicax-init-skill) | Author an AI-assistant skill from your stack |
|
|
224
|
+
| [`replicax doctor`](#replicax-doctor) | Check which dev tools are installed locally |
|
|
225
|
+
| [`replicax compare <a> <b>`](#replicax-compare-source-target) | Diff two profiles/projects: tooling, config, ... |
|
|
226
|
+
| [`replicax audit`](#replicax-audit) | Score a setup vs best practices + recommendations |
|
|
222
227
|
|
|
223
228
|
> Every write operation accepts `--dry-run` (preview, touch nothing) and `--verbose` (list every file).
|
|
224
229
|
|
|
@@ -234,7 +239,7 @@ replicax init --verbose # list every detected file
|
|
|
234
239
|
|
|
235
240
|
### `replicax extract <repo>`
|
|
236
241
|
|
|
237
|
-
Capture a profile from a **remote GitHub repository** instead of the current directory
|
|
242
|
+
Capture a profile from a **remote GitHub repository** instead of the current directory - the same scan as `init`,
|
|
238
243
|
pointed at a repo you don't even have checked out. The repo is downloaded as a tarball over the GitHub API (no `git`
|
|
239
244
|
required) into a temp directory, scanned, then discarded; only the profile is kept.
|
|
240
245
|
|
|
@@ -251,27 +256,36 @@ replicax extract owner/repo --dry-run # preview, write not
|
|
|
251
256
|
Accepts `owner/repo`, a `github.com` URL (including `/tree/<branch>` links), an ssh remote, or a `#branch` / `@tag`
|
|
252
257
|
suffix.
|
|
253
258
|
|
|
254
|
-
> **Private repos & rate limits:** set `GITHUB_TOKEN` (or `GH_TOKEN`) in your environment
|
|
259
|
+
> **Private repos & rate limits:** set `GITHUB_TOKEN` (or `GH_TOKEN`) in your environment - it's read from the
|
|
255
260
|
> environment, used for the one request, and **never stored**. The same secret guard applies, so a remote repo's
|
|
256
261
|
`.env` /
|
|
257
262
|
> keys are never captured.
|
|
258
263
|
|
|
259
264
|
### `replicax create <project-name>`
|
|
260
265
|
|
|
261
|
-
Create a new project from a profile. Existing files trigger an interactive overwrite/skip prompt (auto
|
|
262
|
-
non
|
|
266
|
+
Create a new project from a profile. Existing files trigger an interactive overwrite/skip prompt (auto-skips when
|
|
267
|
+
non-interactive).
|
|
263
268
|
|
|
264
269
|
```bash
|
|
265
270
|
replicax create my-app
|
|
266
271
|
replicax create my-app --profile ./shared/.replicax # use a profile elsewhere
|
|
267
|
-
replicax create my-app --skip-install #
|
|
272
|
+
replicax create my-app --skip-install # never run the package manager
|
|
273
|
+
replicax create my-app --install # install even for untrusted profiles
|
|
268
274
|
replicax create my-app --force # overwrite conflicts, no prompt
|
|
269
275
|
replicax create my-app --dry-run # preview the file plan
|
|
270
276
|
```
|
|
271
277
|
|
|
278
|
+
> **Dependency install is a trust boundary.** Running the package manager executes
|
|
279
|
+
> any `preinstall`/`postinstall` lifecycle scripts declared by the captured
|
|
280
|
+
> `devDependencies`. Profiles you made locally (`init`/`sync`) install by default.
|
|
281
|
+
> Profiles from **`extract` (remote)** or **`import` (an archive someone sent you)**
|
|
282
|
+
> are marked untrusted: `create` prints the package manager and the exact
|
|
283
|
+
> dependency list, then **stops** without installing. Review it, then run the
|
|
284
|
+
> install yourself or re-run with `--install`.
|
|
285
|
+
|
|
272
286
|
### `replicax sync`
|
|
273
287
|
|
|
274
|
-
Re
|
|
288
|
+
Re-scan and update the profile to match the current project.
|
|
275
289
|
|
|
276
290
|
```bash
|
|
277
291
|
replicax sync # update, print a change summary
|
|
@@ -297,13 +311,13 @@ Tooling (14 file(s))
|
|
|
297
311
|
│ Language & Type Checking │ tsconfig.json │ json │ 226 B │
|
|
298
312
|
│ Build Tools │ vite.config.ts │ ts │ 98 B │
|
|
299
313
|
│ Formatting │ .prettierrc │ other │ 63 B │
|
|
300
|
-
│
|
|
314
|
+
│ ... │ ... │ ... │ ... │
|
|
301
315
|
└────────────────────────────────┴──────────────────────────┴─────────┴──────────┘
|
|
302
316
|
```
|
|
303
317
|
|
|
304
318
|
### `replicax validate`
|
|
305
319
|
|
|
306
|
-
Check the profile's schema and integrity (SHA
|
|
320
|
+
Check the profile's schema and integrity (SHA-256 checksums + path safety). Exits non-zero on failure - handy in CI.
|
|
307
321
|
|
|
308
322
|
```bash
|
|
309
323
|
replicax validate
|
|
@@ -321,12 +335,12 @@ replicax import ./react-enterprise.tar.gz --force # overwrite an existing profi
|
|
|
321
335
|
|
|
322
336
|
### `replicax init-skill`
|
|
323
337
|
|
|
324
|
-
Generate an AI
|
|
338
|
+
Generate an AI-assistant **skill** from the current project - a ready-to-use bundle (an entry `SKILL.md` plus optional
|
|
325
339
|
`references/`) that teaches an assistant the tech stack, the install/build/test/lint commands, the tooling, and the
|
|
326
340
|
folder layout, written where your assistant looks for skills.
|
|
327
341
|
|
|
328
342
|
It uses **whatever AI you already have configured**. ReplicaX prefers a locally installed CLI (reusing its login) and
|
|
329
|
-
falls back to a provider API key from your environment
|
|
343
|
+
falls back to a provider API key from your environment - it never stores credentials:
|
|
330
344
|
|
|
331
345
|
| Provider | CLI (preferred) | API key (fallback) | API model default |
|
|
332
346
|
|----------|-----------------|-------------------------------------|--------------------|
|
|
@@ -343,14 +357,96 @@ replicax init-skill --target claude --dry-run # preview (no AI
|
|
|
343
357
|
replicax init-skill --target claude --force # overwrite existing skill files
|
|
344
358
|
```
|
|
345
359
|
|
|
346
|
-
**Targets** (`--target`, required) control the on
|
|
347
|
-
`codex`
|
|
348
|
-
or forced with `--provider`) is the AI that _authors_ it
|
|
360
|
+
**Targets** (`--target`, required) control the on-disk _format/location_: `claude` -> `.claude/skills/<name>/SKILL.md`,
|
|
361
|
+
`codex` -> `.codex/skills/<name>/SKILL.md`, `antigravity` -> `.agents/skills/<name>.md`. The **provider** (auto-detected,
|
|
362
|
+
or forced with `--provider`) is the AI that _authors_ it - the two are independent.
|
|
363
|
+
|
|
364
|
+
> **Bring your own template.** If the project root has a `SKILL.md`, `init-skill` hands it to the AI as the **base** to
|
|
365
|
+
> refine - the model preserves your headings, structure, and instructions and fills them in from the detected setup,
|
|
366
|
+
> instead of starting from scratch.
|
|
349
367
|
|
|
350
|
-
> **Privacy:** only the project's _setup_ is sent to the provider
|
|
368
|
+
> **Privacy:** only the project's _setup_ is sent to the provider - the same safe surface ReplicaX captures (config
|
|
351
369
|
> files, structure, `package.json` scripts/deps). Source code and secrets are never sent. With `--no-ai` (or no provider
|
|
352
370
|
> configured), ReplicaX falls back to a deterministic, fully offline template.
|
|
353
371
|
|
|
372
|
+
### `replicax doctor`
|
|
373
|
+
|
|
374
|
+
Report which developer tools are installed locally - runtimes, package managers, Docker, and editors - with versions.
|
|
375
|
+
Cross-platform and read-only; a missing tool is a finding, not an error.
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
replicax doctor
|
|
379
|
+
replicax doctor --json # machine-readable
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
```console
|
|
383
|
+
$ replicax doctor
|
|
384
|
+
Developer environment
|
|
385
|
+
|
|
386
|
+
✓ Node.js 22.17.1
|
|
387
|
+
✓ Git 2.45.1
|
|
388
|
+
✓ npm 10.2.0
|
|
389
|
+
✗ Docker not found
|
|
390
|
+
✓ Claude Code 2.1.0
|
|
391
|
+
|
|
392
|
+
8/11 tools found
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### `replicax compare <source> <target>`
|
|
396
|
+
|
|
397
|
+
Diff two profiles - or two project directories - across tooling, configuration files, `package.json`, structure, and
|
|
398
|
+
metadata. Each argument may be a `.replicax` profile, a directory containing one, or a plain project folder (scanned on
|
|
399
|
+
the fly), so you can compare anything against anything.
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
replicax compare ./examples/react-vite ./examples/nextjs-enterprise
|
|
403
|
+
replicax compare ./my-app ./other-app --json
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
```text
|
|
407
|
+
Added:
|
|
408
|
+
+ Docker (Tooling)
|
|
409
|
+
+ src/api (Structure)
|
|
410
|
+
Removed:
|
|
411
|
+
- Jest (Tooling)
|
|
412
|
+
Changed:
|
|
413
|
+
~ eslint.config.js (Configuration files)
|
|
414
|
+
~ language: javascript -> typescript (Metadata)
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### `replicax audit`
|
|
418
|
+
|
|
419
|
+
Score a project's setup against best-practice rules - linting, formatting, testing, git hooks, CI/CD, containerization
|
|
420
|
+
and get concrete recommendations for what's missing. Scans the current directory by default, or evaluates a stored
|
|
421
|
+
profile with `--profile`.
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
replicax audit
|
|
425
|
+
replicax audit --path ./some/project
|
|
426
|
+
replicax audit --profile ./examples/nextjs-enterprise/.replicax --json
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
```text
|
|
430
|
+
Project Score: 60/100
|
|
431
|
+
|
|
432
|
+
✓ Formatting
|
|
433
|
+
✓ Testing
|
|
434
|
+
✗ Git hooks
|
|
435
|
+
✗ Containerization
|
|
436
|
+
|
|
437
|
+
Missing:
|
|
438
|
+
- Git hooks
|
|
439
|
+
- Containerization
|
|
440
|
+
|
|
441
|
+
Recommendations:
|
|
442
|
+
- Add Husky to run checks before each commit.
|
|
443
|
+
- Add a Dockerfile to containerize the application.
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
> `compare` and `audit` build on the detection engine: every scan now reports the **detected stack** (React, TypeScript,
|
|
447
|
+
> Docker, GitHub Actions, ...) with a confidence score, persisted in the profile and viewable via `inspect --section
|
|
448
|
+
> detections`.
|
|
449
|
+
|
|
354
450
|
---
|
|
355
451
|
|
|
356
452
|
## What gets captured
|
|
@@ -360,17 +456,18 @@ or forced with `--provider`) is the AI that _authors_ it — the two are indepen
|
|
|
360
456
|
| TS/JS configs, ESLint, Prettier | Application source (components, services, controllers) |
|
|
361
457
|
| Vite / Webpack / Rollup / esbuild | Runtime `dependencies` in `package.json` |
|
|
362
458
|
| Tailwind / PostCSS | `.env*`, `*.pem`, `*.key`, certificates |
|
|
363
|
-
| Docker, CI/CD (Actions, GitLab, CircleCI, Jenkins) | `node_modules/`, `dist/`, `build/`, `coverage/`, `.next/`,
|
|
459
|
+
| Docker, CI/CD (Actions, GitLab, CircleCI, Jenkins) | `node_modules/`, `dist/`, `build/`, `coverage/`, `.next/`, ... |
|
|
364
460
|
| `.editorconfig`, Husky hooks | IDE folders (`.vscode/`, `.idea/`, `.vs/`, `.fleet/`, `.zed/`) |
|
|
365
461
|
| Test configs (Vitest/Jest/Playwright/Cypress) | Anything matched by `.replicaxignore` |
|
|
366
|
-
| Monorepo files, commitlint/lint
|
|
462
|
+
| Monorepo files, commitlint/lint-staged/release/knip | |
|
|
463
|
+
| JVM build (Maven/Gradle) + Spring `application.*` | Compiled output (`target/`, `*.class`), the gradle wrapper JAR |
|
|
367
464
|
| Folder hierarchy (directories only) | Folder _contents_ |
|
|
368
465
|
|
|
369
466
|
**`package.json` is curated, not copied.** Only `scripts`, `devDependencies`, `engines`, `type`, `packageManager`, and
|
|
370
467
|
config blocks like `lint-staged` are kept. Runtime `dependencies` are deliberately dropped (that's your application),
|
|
371
468
|
and the new project's name is stamped in on `create`.
|
|
372
469
|
|
|
373
|
-
Both `.ts` and `.js` config variants work because ReplicaX copies them **verbatim**
|
|
470
|
+
Both `.ts` and `.js` config variants work because ReplicaX copies them **verbatim** it never needs to compile or
|
|
374
471
|
execute a config to capture it.
|
|
375
472
|
|
|
376
473
|
---
|
|
@@ -380,23 +477,32 @@ execute a config to capture it.
|
|
|
380
477
|
ReplicaX treats secret exclusion as a **hard guarantee, not a best effort.**
|
|
381
478
|
|
|
382
479
|
> 🛡️ **Secrets are never captured.** `.env`, `.env.*`, `*.pem`, `*.key`, `*.crt`, SSH keys, and friends are blocked *
|
|
383
|
-
*unconditionally**
|
|
480
|
+
*unconditionally** - this cannot be overridden by configuration.
|
|
384
481
|
|
|
385
|
-
> 🧼 **`.npmrc` is sanitized.** It's a legitimate setup file, but auth tokens (`_authToken`, `_password`,
|
|
482
|
+
> 🧼 **`.npmrc` is sanitized.** It's a legitimate setup file, but auth tokens (`_authToken`, `_password`, ...) are stripped
|
|
386
483
|
> out before it enters a profile.
|
|
387
484
|
|
|
388
485
|
> 🚧 **No path escapes.** Every path read from a profile (or from an AI response) is validated against traversal (`..`)
|
|
389
486
|
> and absolute paths before anything is written, so a malicious profile can never write outside its target directory.
|
|
390
|
-
`validate` re
|
|
487
|
+
> `validate` re-checks this.
|
|
488
|
+
|
|
489
|
+
> 📦 **Archive extraction is a trust boundary.** An imported `.tar.gz` is validated before a single byte is written:
|
|
490
|
+
> entries that escape the target (`..`, absolute paths), symlinks/hardlinks, and device entries are rejected, and the
|
|
491
|
+
> archive is capped on compressed size, uncompressed size, file count, and per-file size, so a tar bomb is aborted up
|
|
492
|
+
> front. The same guard (with links skipped) protects the GitHub tarball that `extract` downloads.
|
|
391
493
|
|
|
392
|
-
|
|
494
|
+
> 🧯 **Install is opt-in for untrusted profiles.** Because `npm install` runs dependency lifecycle scripts, `create`
|
|
495
|
+
> will not auto-install for an `extract`ed or `import`ed profile - it prints the dependency list and waits for you to
|
|
496
|
+
> review and pass `--install`. See [`replicax create`](#replicax-create-project-name).
|
|
497
|
+
|
|
498
|
+
The same guarantees apply to `extract` - a remote repo's secrets are filtered exactly as a local project's are.
|
|
393
499
|
|
|
394
500
|
---
|
|
395
501
|
|
|
396
|
-
## Configuration
|
|
502
|
+
## Configuration - `.replicaxignore` and `.replicaxinclude`
|
|
397
503
|
|
|
398
|
-
|
|
399
|
-
from the profile
|
|
504
|
+
**`.replicaxignore`** controls what gets *excluded*, with **gitignore syntax**. `init` can scaffold a starter for you.
|
|
505
|
+
Ignored files are excluded from the profile - but their parent directories are still captured for structure.
|
|
400
506
|
|
|
401
507
|
```gitignore
|
|
402
508
|
# Business logic (folders kept, contents dropped)
|
|
@@ -408,22 +514,42 @@ src/**/*.ts
|
|
|
408
514
|
*.log
|
|
409
515
|
```
|
|
410
516
|
|
|
517
|
+
**`.replicaxinclude`** is the opposite: a list of **glob patterns** (one per line, `#` comments) for *extra* files to
|
|
518
|
+
capture verbatim, on top of the auto-detected catalogue. Use it for config ReplicaX doesn't recognize by default
|
|
519
|
+
(`*.toml`, a `config/` directory, an IDE file you do want shared, ...). A trailing `/` means "the whole directory".
|
|
520
|
+
|
|
521
|
+
```gitignore
|
|
522
|
+
# Capture these in addition to the auto-detected setup
|
|
523
|
+
app.config.toml
|
|
524
|
+
config/**
|
|
525
|
+
.vscode/extensions.json
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
**Precedence** (highest first): the **secret guard** always wins (a secret can never be included) ->
|
|
529
|
+
**`.replicaxignore`** (your excludes beat your includes) -> **`.replicaxinclude`** (overrides the default prune/ignore
|
|
530
|
+
lists, so it can reach normally-skipped locations) -> the **built-in catalogue**.
|
|
531
|
+
|
|
411
532
|
---
|
|
412
533
|
|
|
413
534
|
## Profile format
|
|
414
535
|
|
|
415
|
-
A profile is five JSON files under `.replicax
|
|
536
|
+
A profile is five required JSON files under `.replicax/`, plus an optional manifest:
|
|
416
537
|
|
|
417
538
|
```text
|
|
418
539
|
.replicax/
|
|
419
540
|
├── profile.json # identity & metadata (name, version, timestamps)
|
|
420
541
|
├── tooling.json # every captured config file (verbatim) + the package.json template
|
|
421
542
|
├── structure.json # folder hierarchy (sorted POSIX directory paths)
|
|
422
|
-
├── metadata.json # node version, package manager, framework, language
|
|
423
|
-
|
|
543
|
+
├── metadata.json # node version, package manager, framework, language + detected stack
|
|
544
|
+
├── checksum.json # SHA-256 integrity hashes
|
|
545
|
+
└── manifest.json # content-free index of artifacts (path, category, size, hash)
|
|
424
546
|
```
|
|
425
547
|
|
|
426
|
-
All
|
|
548
|
+
All files are schema-validated (zod) on load; `validate` additionally re-checks checksums and rejects unsafe paths.
|
|
549
|
+
|
|
550
|
+
**Schema version 2.1.0** added the detected stack (`metadata.detections`), an optional `registry` block (for future
|
|
551
|
+
registry support), and `manifest.json` - all backward-compatible. Profiles written by older ReplicaX (2.0.0) are
|
|
552
|
+
**migrated automatically on load** and the manifest is synthesized when absent, so existing profiles keep working.
|
|
427
553
|
|
|
428
554
|
---
|
|
429
555
|
|
|
@@ -446,7 +572,7 @@ flowchart LR
|
|
|
446
572
|
|
|
447
573
|
- **Scanner** detects config files (via a glob catalogue), the folder hierarchy, and project metadata (package manager,
|
|
448
574
|
framework, language).
|
|
449
|
-
- **Ignore engine** layers default ignores + `.replicaxignore`, with a separate, **non
|
|
575
|
+
- **Ignore engine** layers default ignores + `.replicaxignore`, with a separate, **non-overridable secret guard**.
|
|
450
576
|
- **Profile generator** assembles the bundle and computes checksums.
|
|
451
577
|
- **Project generator** reproduces the setup, adapting names/paths, with a **conflict resolver** for existing files.
|
|
452
578
|
|
|
@@ -456,7 +582,7 @@ flowchart LR
|
|
|
456
582
|
|
|
457
583
|
```bash
|
|
458
584
|
npm install
|
|
459
|
-
npm run build # tsup
|
|
585
|
+
npm run build # tsup -> dist/index.js (single ESM file, with shebang)
|
|
460
586
|
npm run typecheck # tsc --noEmit (covers src AND tests)
|
|
461
587
|
npm test # vitest (real temp-dir fixtures, no mocks)
|
|
462
588
|
npm run format # prettier --write .
|
|
@@ -475,15 +601,15 @@ npx vitest run -t "sanitizes a captured .npmrc"
|
|
|
475
601
|
<br/>
|
|
476
602
|
|
|
477
603
|
**Lockfile.** `package-lock.json` is maintained with **npm 10** (what CI's Node 20/22 ship with). On npm 11+, regenerate
|
|
478
|
-
with `npx npm@10 install` when changing dependencies
|
|
604
|
+
with `npx npm@10 install` when changing dependencies - npm 11 resolves a different tree and will desync `npm ci`.
|
|
479
605
|
|
|
480
|
-
**Path alias.** Imports use a `@/*`
|
|
606
|
+
**Path alias.** Imports use a `@/*` -> `src/*` alias resolved by tsc, tsup/esbuild, and the `vite-tsconfig-paths` vitest
|
|
481
607
|
plugin. The build bundles to one file, so the alias never reaches the published output.
|
|
482
608
|
|
|
483
|
-
**Stack.** TypeScript 5
|
|
484
|
-
@inquirer/prompts
|
|
609
|
+
**Stack.** TypeScript 5 / Node 20+ / ESM / commander / fast-glob / fs-extra / ignore / zod / tar / picocolors / ora /
|
|
610
|
+
@inquirer/prompts / cli-table3 / vitest / tsup / prettier.
|
|
485
611
|
|
|
486
|
-
**Audit note.** `npm audit` flags `esbuild` (a build
|
|
612
|
+
**Audit note.** `npm audit` flags `esbuild` (a build-time transitive of `tsup`). The advisory concerns esbuild's dev
|
|
487
613
|
server, which ReplicaX never runs, and esbuild is not part of the published runtime (`dist/`). Fixing it requires a
|
|
488
614
|
breaking tsup downgrade, so the toolchain is left intact.
|
|
489
615
|
|
|
@@ -502,7 +628,7 @@ No. Only configuration files and the empty folder hierarchy. Application code is
|
|
|
502
628
|
<details>
|
|
503
629
|
<summary><b>What about <code>.ts</code> config files like <code>vite.config.ts</code>?</b></summary>
|
|
504
630
|
<br/>
|
|
505
|
-
Fully supported
|
|
631
|
+
Fully supported - they're copied as text, so both <code>.ts</code> and <code>.js</code> variants work without any compile step.
|
|
506
632
|
</details>
|
|
507
633
|
|
|
508
634
|
<details>
|
|
@@ -520,22 +646,22 @@ They're part of your application, not your setup. <code>devDependencies</code>,
|
|
|
520
646
|
<details>
|
|
521
647
|
<summary><b>Does <code>extract</code> need <code>git</code> installed?</b></summary>
|
|
522
648
|
<br/>
|
|
523
|
-
No. It downloads the repo as a tarball over the GitHub API using Node's built-in <code>fetch</code>
|
|
649
|
+
No. It downloads the repo as a tarball over the GitHub API using Node's built-in <code>fetch</code> no <code>git</code> binary, no full clone.
|
|
524
650
|
</details>
|
|
525
651
|
|
|
526
652
|
<details>
|
|
527
653
|
<summary><b>Is it cross-platform?</b></summary>
|
|
528
654
|
<br/>
|
|
529
|
-
Yes
|
|
655
|
+
Yes Windows (native + WSL), macOS, and Linux.
|
|
530
656
|
</details>
|
|
531
657
|
|
|
532
658
|
---
|
|
533
659
|
|
|
534
660
|
## License
|
|
535
661
|
|
|
536
|
-
**MIT**
|
|
662
|
+
**MIT** see [LICENSE](LICENSE).
|
|
537
663
|
|
|
538
664
|
<div align="center">
|
|
539
665
|
<br/>
|
|
540
|
-
<sub><i>ReplicaX
|
|
666
|
+
<sub><i>ReplicaX - copy the setup, not the code.</i></sub>
|
|
541
667
|
</div>
|