prjct-cli 2.23.1 → 2.23.3
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/CHANGELOG.md +17 -92
- package/README.md +220 -9
- package/dist/bin/prjct-core.mjs +323 -318
- package/dist/daemon/entry.mjs +214 -209
- package/dist/mcp/server.mjs +39 -39
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,15 +35,39 @@ curl -sSL https://raw.githubusercontent.com/jlopezlira/prjct-cli/main/scripts/in
|
|
|
35
35
|
|
|
36
36
|
The script auto-detects platform (mac arm64/intel + linux x64), downloads the right binary from GitHub Releases, sets up `~/.local/bin/prjct` on your PATH, runs `prjct setup` + `prjct sync`, and warns you if a stale package-manager install is shadowing the new binary.
|
|
37
37
|
|
|
38
|
-
###
|
|
38
|
+
### Updating prjct (built-in)
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
prjct updates itself. The canonical command is **`prjct update`**, with
|
|
41
|
+
**`prjct upgrade`** as an identical alias:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
prjct update # = prjct upgrade
|
|
45
|
+
prjct update --dry-run # show exactly what would change, touch nothing
|
|
46
|
+
prjct upgrade --yes # non-interactive (skip the consolidation prompt)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
What it does, in three phases (`core/commands/update.ts`):
|
|
45
50
|
|
|
46
|
-
|
|
51
|
+
1. **Package update** — auto-detects the package manager that owns your install
|
|
52
|
+
(npm / pnpm / bun / yarn / homebrew), resolves the **true registry-latest**
|
|
53
|
+
version and pins it exactly (so a stale `@latest` cache can't downgrade you),
|
|
54
|
+
and migrates a homebrew install to your detected PM if needed.
|
|
55
|
+
2. **Global cleanup & consolidation** — migrates legacy state to SQLite,
|
|
56
|
+
reinstalls editor commands/config, and **consolidates parallel installs** so
|
|
57
|
+
you don't end up with shadowing copies in different PM bin dirs.
|
|
58
|
+
3. **Daemon restart** — stops the stale background daemon and respawns it from
|
|
59
|
+
the freshly installed code.
|
|
60
|
+
|
|
61
|
+
Flags: `--dry-run`, `--yes`/`-y`, `--cleanup` / `--no-cleanup` (default `auto`),
|
|
62
|
+
`--md` (machine-readable output for agents/CI).
|
|
63
|
+
|
|
64
|
+
**Knowing an update exists:** prjct checks at most once every 24h (cached, fully
|
|
65
|
+
non-blocking — never delays a command) and, after the command's own output,
|
|
66
|
+
prints a one-line banner: `Update available! x.y.z → a.b.c — Run: prjct upgrade`.
|
|
67
|
+
Or set it and forget it: `prjct config set auto-update on` (throttled background
|
|
68
|
+
check, logs to `~/.prjct-cli/state/auto-update.log`).
|
|
69
|
+
|
|
70
|
+
Full install + upgrade paths: [INSTALL_PROMPT.md](./INSTALL_PROMPT.md).
|
|
47
71
|
|
|
48
72
|
## What you get
|
|
49
73
|
|
|
@@ -86,6 +110,85 @@ Claude Code session prjct
|
|
|
86
110
|
|
|
87
111
|
State is the source of truth; the vault is recall. New knowledge enters via `prjct remember <type>`, `prjct capture`, or — automatically — the Stop hook's transcript scan.
|
|
88
112
|
|
|
113
|
+
### Where data actually lives
|
|
114
|
+
|
|
115
|
+
Not "all in a local `.prjct/` folder" — that's the pre-v1.24.1 model. Three tiers:
|
|
116
|
+
|
|
117
|
+
| Tier | Location | Commit it? |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| Config / identity | `<repo>/.prjct/prjct.config.json` (`projectId`, persona) | **Yes** — small, machine-independent |
|
|
120
|
+
| State (source of truth) | `~/.prjct-cli/projects/<projectId>/prjct.db` (SQLite) | No — per-device |
|
|
121
|
+
| Vault (recall snapshot) | `~/Documents/prjct/<slug>/_generated/` (Markdown) | No — regenerated |
|
|
122
|
+
|
|
123
|
+
Find a project's data: read `projectId` from `.prjct/prjct.config.json`, then the
|
|
124
|
+
DB is `~/.prjct-cli/projects/<projectId>/`, the vault is
|
|
125
|
+
`~/Documents/prjct/<slug>/` (`<slug>` = repo dir name lowercased; `PRJCT_CLI_HOME`
|
|
126
|
+
relocates the global store). Teammates share knowledge via optional cloud sync
|
|
127
|
+
(`prjct login` + `prjct sync`), **not** git — git never carries state. Full
|
|
128
|
+
detail, worktrees, monorepos: **[docs/storage-and-paths.md](./docs/storage-and-paths.md)**.
|
|
129
|
+
|
|
130
|
+
## Execution environments (zero-config)
|
|
131
|
+
|
|
132
|
+
The same binary runs in a plain shell, inside Claude Code, in an OpenAI Codex
|
|
133
|
+
sandbox, or in CI — and **detects which, with no configuration**, then adapts
|
|
134
|
+
output accordingly. Here is the actual *how*.
|
|
135
|
+
|
|
136
|
+
**Mechanism 1 — agent detection** (`core/infrastructure/agent-detector.ts`,
|
|
137
|
+
`isClaudeEnvironment()`). prjct concludes it's inside **Claude** if *any* of
|
|
138
|
+
these is true, evaluated **in this order** (first match wins, result cached for
|
|
139
|
+
the process):
|
|
140
|
+
|
|
141
|
+
1. env var `CLAUDE_AGENT` or `ANTHROPIC_CLAUDE` is set (Claude's runtime sets it);
|
|
142
|
+
2. `global.mcp` is present **or** `MCP_AVAILABLE` is set (MCP is available);
|
|
143
|
+
3. a `CLAUDE.md` file exists in the current working directory;
|
|
144
|
+
4. a `~/.claude/` directory exists;
|
|
145
|
+
5. the cwd path contains `/.claude/` or `/claude-workspace/`.
|
|
146
|
+
|
|
147
|
+
If **none** match, prjct falls back to the **Terminal/CLI** profile — that *is*
|
|
148
|
+
the plain-terminal detection: it's the default when no Claude signal is present.
|
|
149
|
+
**OpenAI Codex** is detected separately (`ai-provider.ts`, `detectCodex()`) by
|
|
150
|
+
the **`codex` CLI binary being on `PATH`** (a stray `~/.codex/` alone is not
|
|
151
|
+
enough); Codex's context file is `AGENTS.md`, skills under `~/.codex/skills/`.
|
|
152
|
+
|
|
153
|
+
**Mechanism 2 — output adaptation** (no flag needed; three independent signals):
|
|
154
|
+
|
|
155
|
+
- **TTY** (`core/utils/output.ts`, `spin()`): `process.stdout.isTTY` decides the
|
|
156
|
+
spinner — `true` (human terminal) → animated branded spinner redrawn with `\r`;
|
|
157
|
+
`false` (Claude Code, Codex, CI, a pipe) → a **single static** `⚡ prjct …`
|
|
158
|
+
line, no animation.
|
|
159
|
+
- **LLM-context gate** (`core/index.ts`):
|
|
160
|
+
`isLlmContext = !process.stdin.isTTY || options.md === true || options.json === true`.
|
|
161
|
+
Commands declared `requiresLlm` refuse to run in a *raw human terminal* unless
|
|
162
|
+
`--md`/`--json` is passed — inside an agent `stdin.isTTY` is already false, so
|
|
163
|
+
they run transparently with no flag.
|
|
164
|
+
- **`--md` / `--json`** (any env): an explicit override — strips the branding
|
|
165
|
+
header/footer, emits machine-structured markdown/JSON.
|
|
166
|
+
|
|
167
|
+
Every signal (env var, `PATH`, TTY, piped stdio) is something the **host sets on
|
|
168
|
+
its own** — prjct reads those ambient facts instead of asking you to declare
|
|
169
|
+
anything. Full per-environment output table:
|
|
170
|
+
**[docs/environments.md](./docs/environments.md)**.
|
|
171
|
+
|
|
172
|
+
### What it looks like
|
|
173
|
+
|
|
174
|
+
In a real terminal — branded, animated, colored:
|
|
175
|
+
|
|
176
|
+
```text
|
|
177
|
+
$ prjct task "add OAuth refresh"
|
|
178
|
+
⚡ prjct ✓ Task started: add OAuth refresh
|
|
179
|
+
branch: task/add-oauth-refresh · status: active
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Inside Claude Code / Codex / CI (non-TTY) — the same line, **static** (no
|
|
183
|
+
animation), so logs stay clean. With `--md`, output is plain markdown an agent
|
|
184
|
+
can consume directly:
|
|
185
|
+
|
|
186
|
+
```text
|
|
187
|
+
$ prjct task "add OAuth refresh" --md
|
|
188
|
+
> Task started: **add OAuth refresh**
|
|
189
|
+
> branch `task/add-oauth-refresh` · status `active`
|
|
190
|
+
```
|
|
191
|
+
|
|
89
192
|
## Quick start (post-install)
|
|
90
193
|
|
|
91
194
|
```bash
|
|
@@ -206,12 +309,12 @@ prjct regen Full vault rebuild from SQLite
|
|
|
206
309
|
prjct watch Auto-sync on file changes
|
|
207
310
|
prjct doctor Check system health
|
|
208
311
|
prjct hooks <install|uninstall|status> Git hooks for auto-sync
|
|
209
|
-
prjct context <
|
|
312
|
+
prjct context <memory|learnings|wiki> Recall memory / sync the vault
|
|
210
313
|
prjct review-risk Advisory change-size + delivery-geometry hint (read-only)
|
|
211
314
|
prjct workflow ["config"] Configure hooks via natural language
|
|
212
315
|
prjct stop / restart Background daemon control
|
|
213
316
|
prjct login / logout / auth Cloud sync authentication
|
|
214
|
-
prjct update Update CLI system-wide
|
|
317
|
+
prjct update Update CLI system-wide (alias: prjct upgrade)
|
|
215
318
|
prjct --version / --help
|
|
216
319
|
```
|
|
217
320
|
|
|
@@ -311,12 +414,120 @@ prjct-cli/
|
|
|
311
414
|
- Node.js 22.22.2+ or Bun 1.0+
|
|
312
415
|
- One of: Claude Code, Gemini CLI, Cursor IDE, Windsurf, OpenAI Codex, Antigravity
|
|
313
416
|
|
|
417
|
+
## Common questions
|
|
418
|
+
|
|
419
|
+
**How do I initialize / register a new project?**
|
|
420
|
+
In any git repo, run `prjct sync` (it auto-runs on the first prjct command) or
|
|
421
|
+
`prjct init`. This creates `.prjct/prjct.config.json` with a `projectId`, builds
|
|
422
|
+
the SQLite store at `~/.prjct-cli/projects/<projectId>/`, and generates the vault.
|
|
423
|
+
|
|
424
|
+
**How do I add a development task?**
|
|
425
|
+
Run `prjct task "<description>"` from the repo. It registers the task in SQLite,
|
|
426
|
+
creates a branch, and marks it active — worked example:
|
|
427
|
+
|
|
428
|
+
```bash
|
|
429
|
+
$ prjct task "add OAuth refresh"
|
|
430
|
+
⚡ prjct ✓ Task started: add OAuth refresh
|
|
431
|
+
branch: task/add-oauth-refresh · status: active
|
|
432
|
+
|
|
433
|
+
$ prjct tag type:feature domain:auth # optional: categorize it
|
|
434
|
+
$ prjct status done # close it when finished
|
|
435
|
+
$ prjct ship # bump version, commit, PR
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
Inside an agent you don't type the command — say it: `p. task "add OAuth
|
|
439
|
+
refresh"` in Claude Code, `/task "…"` in Cursor/Windsurf. `prjct task` with no
|
|
440
|
+
argument prints the currently active task.
|
|
441
|
+
|
|
442
|
+
**How do I get AI assistance for a coding problem?**
|
|
443
|
+
Inside Claude Code (or any wired agent) describe the problem in natural
|
|
444
|
+
language — prjct maps the intent to a quality workflow and runs its methodology,
|
|
445
|
+
persisting findings to memory. Concrete examples:
|
|
446
|
+
|
|
447
|
+
| You say… | Workflow activated | What it does |
|
|
448
|
+
|---|---|---|
|
|
449
|
+
| "review my changes" | `review` | Production Bug Hunt + Completeness Gate over the diff |
|
|
450
|
+
| "investigate why tests flake" | `investigate` | Iron Law — no fix without a root cause first |
|
|
451
|
+
| "is this safe to ship?" | `security` | OWASP Top 10 + STRIDE, concrete exploit per finding |
|
|
452
|
+
| "qa the checkout page" | `qa` | Real browser, atomic fixes, regression tests |
|
|
453
|
+
|
|
454
|
+
You can also pull project knowledge directly: ask "what patterns does this
|
|
455
|
+
project use?" and the agent reads `~/Documents/prjct/<slug>/_generated/patterns.md`
|
|
456
|
+
instead of grepping source (the lookup-first protocol). Outside an agent, every
|
|
457
|
+
command takes `--md` to emit agent-ready markdown.
|
|
458
|
+
|
|
459
|
+
**What does prjct output look like in a normal terminal?**
|
|
460
|
+
A branded, **animated** spinner with full colors and interactive prompts (the
|
|
461
|
+
native human experience). See [What it looks like](#what-it-looks-like).
|
|
462
|
+
|
|
463
|
+
**How do I check for and apply updates?**
|
|
464
|
+
`prjct update` (alias `prjct upgrade`) — auto-detects your package manager, pins
|
|
465
|
+
the true registry-latest, consolidates parallel installs, restarts the daemon.
|
|
466
|
+
A non-blocking 24h-cached banner tells you when one is available. See
|
|
467
|
+
[Updating prjct](#updating-prjct-built-in).
|
|
468
|
+
|
|
469
|
+
**How does prjct tailor its output for Claude Code specifically?**
|
|
470
|
+
Once it detects Claude (env vars / MCP / `CLAUDE.md` / `~/.claude/`) and sees
|
|
471
|
+
piped stdio (non-TTY), it adapts on every axis, with no flag:
|
|
472
|
+
|
|
473
|
+
- **Status line** — a single **static** `⚡ prjct …` line instead of the
|
|
474
|
+
animated, carriage-return-redrawn spinner, so the transcript stays clean.
|
|
475
|
+
- **Prompts** — interactive confirmations are suppressed (nothing blocks on
|
|
476
|
+
stdin that the agent can't answer).
|
|
477
|
+
- **`requiresLlm` commands** — run transparently (piped stdin means
|
|
478
|
+
`isLlmContext` is already true; in a raw human terminal they'd refuse without
|
|
479
|
+
`--md`).
|
|
480
|
+
- **`--md`** — when passed, the branding header/footer is stripped and output is
|
|
481
|
+
structured markdown the model consumes directly.
|
|
482
|
+
- **Context injection** — the installed hooks feed Claude persona + active task
|
|
483
|
+
+ topical memory at `SessionStart`/`UserPromptSubmit`, and the lookup-first
|
|
484
|
+
protocol points it at the regenerated vault before it re-reads source.
|
|
485
|
+
|
|
486
|
+
Full per-environment table: [docs/environments.md](./docs/environments.md).
|
|
487
|
+
|
|
488
|
+
**What's the output in an OpenAI Codex sandbox?**
|
|
489
|
+
Codex is detected by the `codex` CLI on PATH (context file `AGENTS.md`). The
|
|
490
|
+
sandbox is non-interactive/non-TTY, so prjct emits the same static, prompt-free
|
|
491
|
+
status line as any agent; add `--md` for fully markdown-structured output.
|
|
492
|
+
|
|
493
|
+
**How do I quickly find the local `.prjct/` directory?**
|
|
494
|
+
It's in your **project repo root** (created by `prjct init` / first `prjct`
|
|
495
|
+
command) and is `.gitignore`d — that's why `git status` never shows it. Find it:
|
|
496
|
+
|
|
497
|
+
```bash
|
|
498
|
+
ls -la .prjct/ # from the repo root
|
|
499
|
+
cat .prjct/prjct.config.json # projectId + persona
|
|
500
|
+
ls -la "$(git rev-parse --show-toplevel)/.prjct/" # from any subdirectory
|
|
501
|
+
git check-ignore -v .prjct # why git ignores it
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
The path is always `<repoRoot>/.prjct/` (strictly relative to the project — no
|
|
505
|
+
env var, no global lookup). Read `projectId` from `prjct.config.json` to reach
|
|
506
|
+
the *other* tiers: DB at `~/.prjct-cli/projects/<projectId>/prjct.db`, vault at
|
|
507
|
+
`~/Documents/prjct/<slug>/_generated/` (`PRJCT_CLI_HOME` overrides the global
|
|
508
|
+
base). The in-repo `.prjct/` holds only config, not state — full detail in
|
|
509
|
+
[docs/storage-and-paths.md](./docs/storage-and-paths.md).
|
|
510
|
+
|
|
511
|
+
**How does prjct detect its environment with no configuration?**
|
|
512
|
+
Every signal is something the host sets itself — Claude exports env vars and
|
|
513
|
+
pipes stdio, Codex puts `codex` on PATH, a real terminal has a TTY, CI doesn't.
|
|
514
|
+
prjct reads those ambient facts (precedence in
|
|
515
|
+
[docs/environments.md](./docs/environments.md)) rather than asking you to declare
|
|
516
|
+
anything.
|
|
517
|
+
|
|
518
|
+
**Is all project data really in a local `.prjct/` directory? Team/VCS implications?**
|
|
519
|
+
No — only `.prjct/prjct.config.json` (small, **committable** identity) is in the
|
|
520
|
+
repo. State is per-device SQLite under `~/.prjct-cli` (never committed); the
|
|
521
|
+
vault is regenerated. Teams coordinate via optional cloud sync, not git. Full
|
|
522
|
+
tradeoffs: [docs/storage-and-paths.md](./docs/storage-and-paths.md).
|
|
523
|
+
|
|
314
524
|
## Links
|
|
315
525
|
|
|
316
526
|
- [Website](https://prjct.app)
|
|
317
527
|
- [GitHub](https://github.com/jlopezlira/prjct-cli)
|
|
318
528
|
- [npm](https://www.npmjs.com/package/prjct-cli)
|
|
319
529
|
- [Changelog](CHANGELOG.md)
|
|
530
|
+
- [Architecture](./docs/architecture.md) · [Execution environments](./docs/environments.md) · [Storage & paths](./docs/storage-and-paths.md) · [SQLite migration](./docs/sqlite-migration.md)
|
|
320
531
|
|
|
321
532
|
## License
|
|
322
533
|
|