phewsh 0.15.82 → 0.15.83

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.
Files changed (56) hide show
  1. package/README.md +117 -43
  2. package/SECURITY.md +107 -87
  3. package/bin/phewsh.js +31 -25
  4. package/commands/ambient.js +299 -145
  5. package/commands/clarify.js +2 -2
  6. package/commands/context.js +4 -4
  7. package/commands/gate.js +12 -8
  8. package/commands/hook.js +13 -9
  9. package/commands/intent.js +5 -5
  10. package/commands/ion.js +53 -1
  11. package/commands/login.js +12 -0
  12. package/commands/mcp.js +21 -4
  13. package/commands/next.js +1 -1
  14. package/commands/project.js +2 -2
  15. package/commands/receipts.js +12 -2
  16. package/commands/remember.js +3 -3
  17. package/commands/sequence.js +25 -12
  18. package/commands/serve.js +58 -4
  19. package/commands/session.js +113 -63
  20. package/commands/status.js +66 -3
  21. package/commands/task.js +20 -14
  22. package/commands/watch.js +58 -10
  23. package/docs/adapter-contract.json +122 -0
  24. package/docs/handoff-proof-fixture.json +50 -0
  25. package/docs/handoff-proof.md +41 -0
  26. package/docs/release-checklist.md +66 -0
  27. package/docs/threat-model.md +111 -0
  28. package/lib/brief.js +22 -3
  29. package/lib/continuity.js +2 -2
  30. package/lib/gate-policy.js +87 -8
  31. package/lib/handoff-receipt.js +373 -0
  32. package/lib/harnesses.js +3 -3
  33. package/lib/intent-skills.js +218 -0
  34. package/lib/intro.js +5 -4
  35. package/lib/ion-doctor.js +186 -0
  36. package/lib/local-claim.js +78 -0
  37. package/lib/mcp-token.js +61 -0
  38. package/lib/next.js +1 -1
  39. package/lib/packs.js +72 -0
  40. package/lib/receipts-data.js +87 -5
  41. package/lib/record.js +1 -1
  42. package/lib/route-coach.js +1 -1
  43. package/lib/selfheal.js +44 -17
  44. package/lib/sequencer/compressor.js +10 -1
  45. package/lib/sequencer/parsers/intent.js +6 -2
  46. package/lib/shims.js +1 -1
  47. package/lib/slash-commands.js +15 -30
  48. package/lib/suggest.js +8 -9
  49. package/lib/team-tasks.js +60 -3
  50. package/lib/truth.js +27 -6
  51. package/lib/ui.js +8 -8
  52. package/lib/verify.js +3 -2
  53. package/mcp/http-server.js +8 -66
  54. package/package.json +8 -3
  55. package/skills/intent/SKILL.md +101 -0
  56. package/skills/boat-to-shore/SKILL v1.md +0 -62
package/README.md CHANGED
@@ -1,11 +1,11 @@
1
1
  # phewsh
2
2
 
3
- **One mission. Many AI tools. No lost context.**
3
+ **The next AI starts from your files.**
4
4
 
5
5
  PHEWSH is the continuity layer for AI-assisted work: it turns what you're
6
6
  building into durable project intent (`.intent/`) and carries it across
7
7
  Claude Code, Codex, Cursor, Gemini, your terminal, and your team — so the
8
- next AI knows what the last one learned.
8
+ next AI can see what was recorded and what was not.
9
9
 
10
10
  ## Install
11
11
 
@@ -13,20 +13,35 @@ next AI knows what the last one learned.
13
13
  curl -fsSL https://phewsh.com/install.sh | sh
14
14
  ```
15
15
 
16
- No sudo, nvm-aware. (Prefer a package manager? `npm install -g phewsh`
17
- same artifact, built from this repo.)
16
+ The installer never runs npm with sudo and is nvm-aware. If an older Phewsh
17
+ install is root-owned, it discloses and requests one `sudo chown` repair first.
18
+ (Prefer a package manager? `npm install -g phewsh` installs the same npm package.)
18
19
 
19
20
  Then let it improve the AI tools you already have — without launching anything:
20
21
 
21
22
  ```bash
22
- phewsh ambient on # your .intent/ + a verified brief reach Claude Code, Codex,
23
- # Gemini, Cursor at the start of every session (reversible)
23
+ phewsh ambient on # one open intent skill + your verified .intent/ brief reach
24
+ # Claude Code, Codex, Gemini, Cursor (reversible)
24
25
  ```
25
26
 
27
+ A bare first launch keeps adapters off. `ambient on` enumerates every file it
28
+ may write before asking; choosing No changes only Phewsh's local opt-out receipt.
29
+
26
30
  phewsh isn't just a CLI — `ambient` makes every supported tool start aligned to
27
31
  what you're building. What it reads, writes, and sends is documented, factually,
28
- in [SECURITY.md](./SECURITY.md). It's local-first and MIT; this repo is an exact
29
- mirror of the published npm package.
32
+ in [SECURITY.md](./SECURITY.md), the [threat model](./docs/threat-model.md), and
33
+ the [release checklist](./docs/release-checklist.md). It's local-first and MIT;
34
+ the public source snapshot is manually synchronized today, without release
35
+ provenance yet.
36
+
37
+ `phewsh init` creates only the tool-neutral `.intent/` project record. Ambient
38
+ installs the same open `intent` skill at user scope for Codex
39
+ (`~/.agents/skills/intent/`) and Claude Code (`~/.claude/skills/intent/`), so
40
+ projects stay clean and neither harness becomes the source of truth.
41
+ If a repository already contains `.agents/skills/intent/` or
42
+ `.claude/skills/intent/`, that user-owned project override may take precedence.
43
+ Phewsh reports it through `status` and `ambient status` but never edits or
44
+ removes it; `.intent/` remains the project truth.
30
45
 
31
46
  ## Quick Start
32
47
 
@@ -38,6 +53,14 @@ phewsh next start 1
38
53
  phewsh codex # verified brief → native tool → automatic postflight
39
54
  ```
40
55
 
56
+ Every native handoff now leaves an integrity-checksummed local receipt. The next tool sees the
57
+ exact `.intent/` and repository state that crossed the boundary, plus an
58
+ explicit list of what did not: transcripts, model reasoning, editor buffers,
59
+ harness-local memory, and unrecorded decisions. `phewsh status` re-hashes the
60
+ current state and says **verified**, **moved**, **partial**, or **invalid**
61
+ instead of silently claiming continuity. Dirty evidence means Git tracked,
62
+ staged, and untracked-unignored files; ignored files are never hashed or named.
63
+
41
64
  ## No API key needed
42
65
 
43
66
  phewsh is not another agent — it's the layer that uses the ones you already
@@ -54,17 +77,20 @@ phewsh ai providers # see what's installed
54
77
  API keys (OpenRouter, Anthropic, Groq, …) and PHEWSH pooled credits remain
55
78
  available as alternatives — `phewsh login --set-key`.
56
79
 
57
- ## One package, one system
80
+ ## One package, modular adapters
58
81
 
59
- Everything ships in `phewsh` — the CLI (intent authoring, sync, bridges,
60
- receipts, dispatch) *and* the MCP server. `phewsh mcp setup` wires the
61
- bundled server into Claude Code / Cursor / any MCP client via
62
- `phewsh mcp serve --stdio`: an *interactive* agent session gets your
63
- project's briefing, task queue, and enforcement gate over stdio, and shares
64
- state with the bridges (`~/.phewsh/`). No second install.
82
+ The package includes the CLI plus optional native skills, hooks, projections,
83
+ MCP capabilities, and bridges. They all adapt tools around `.intent/`; none is
84
+ a second project record.
65
85
 
66
- Rule of thumb: `phewsh serve` = dispatch tasks *to* your agents.
67
- `phewsh mcp setup` = your agents pull tasks *from* PHEWSH mid-session.
86
+ `phewsh mcp setup` adds the bundled stdio adapter to a supported client. That
87
+ client can receive bounded Project, Next, constraints, and task capabilities.
88
+ MCP access does not claim work, transfer private model memory, or grant remote
89
+ execution authority.
90
+
91
+ Rule of thumb: `phewsh serve` is the same-machine, project-bound worker used
92
+ after a human claim. `phewsh mcp setup` lets a configured client read and report
93
+ through bounded capabilities during its own session.
68
94
 
69
95
  ## Ambient — continuity without launching phewsh
70
96
 
@@ -72,23 +98,41 @@ Rule of thumb: `phewsh serve` = dispatch tasks *to* your agents.
72
98
  phewsh ambient on
73
99
  ```
74
100
 
75
- A consent screen shows exactly what changes. Phewsh then keeps one canonical
76
- generated core aligned across `CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, and
77
- `.cursorrules`, while preserving human-authored content outside its managed
78
- blocks. Claude Code also receives a session-start brief and leaves a one-line
79
- metadata breadcrumb (never transcript contents) in
80
- `~/.phewsh/ambient-sessions.jsonl`. `phewsh ambient status` shows the ledger;
81
- `phewsh ambient off` removes Phewsh-managed blocks without deleting your notes.
101
+ A consent screen shows exactly what changes. The layers stay independent:
102
+
103
+ - one byte-identical open Intent skill installs natively for Claude Code and Codex;
104
+ - generated blocks align `CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, and
105
+ `.cursorrules` while preserving human-authored content;
106
+ - Claude Code session hooks add a bounded start brief and a metadata-only end
107
+ breadcrumb; safety/receipt hooks for Claude and Codex are controlled by the
108
+ separate `phewsh gate enforce on|off|status` toggle.
82
109
 
83
- ## Live Execution
110
+ `phewsh ambient status` reports those layers separately. `phewsh ambient off`
111
+ removes only unchanged Phewsh-managed additions and preserves user-owned skills,
112
+ hooks, and notes. It does not disable the independent safety/receipt layer.
84
113
 
85
- Connect the web app to your local machine for real-time task execution:
114
+ ## Ion work with people and agents
115
+
116
+ [Phewsh Ion](https://phewsh.com/ion) is the shared project room. A person
117
+ requests work, a human deliberately claims it for a local agent, and the
118
+ branch, pull request, evidence, review, and accepted Record return to the same
119
+ room.
120
+
121
+ Make a repository available to **your own machine's** worker:
86
122
 
87
123
  ```bash
88
- phewsh serve
124
+ phewsh project add # once inside each repo you explicitly allow
125
+ phewsh serve # one loopback worker for the whole machine
126
+ phewsh ion doctor # read-only two-person preflight
89
127
  ```
90
128
 
91
- This starts a bridge on `localhost:7483`. Open [phewsh.com/intent](https://phewsh.com/intent) and go to the Work tab — you'll see a green "Live" indicator. Agent tasks get a "Run Live" button that executes on your machine through whichever agent CLIs you have installed: **Claude Code, Codex, Gemini, Cursor Agent, OpenCode**. PHEWSH detects them automatically and every run leaves a receipt (`phewsh receipts`).
129
+ The bridge listens on `localhost:7483`. Registration does not execute work,
130
+ teammates cannot reach your localhost, and Ion does not grant remote execution
131
+ authority. Work begins only after a human clicks **Run on this machine** in
132
+ their browser or runs `phewsh ion claim <task-id>`. The claim runs in an
133
+ isolated Git worktree, opens a PR through your authenticated `gh`, and returns
134
+ bounded evidence to Ion; accepted work becomes project truth only through
135
+ normal review, merge, and Record reconciliation.
92
136
 
93
137
  ## Interactive Shell
94
138
 
@@ -120,7 +164,7 @@ cancel an in-flight provider turn.
120
164
 
121
165
  ## The four answers
122
166
 
123
- Phewsh keeps the same four answers available to you and every harness:
167
+ Phewsh records four answers that supported harness adapters can read:
124
168
 
125
169
  - **Project** — what you are building and why (`.intent/`)
126
170
  - **Next** — the current task and accepted success criteria (`.intent/next.json`)
@@ -128,8 +172,14 @@ Phewsh keeps the same four answers available to you and every harness:
128
172
  - **Record** — what happened, what was kept, and what was learned
129
173
 
130
174
  The lifecycle is explicit: intent → criteria → verified brief → native tool →
131
- observed evidence → verdict → approved reconciliation → every other tool
132
- inherits the updated truth.
175
+ observed evidence → verdict → approved reconciliation → supported adapters can
176
+ read the updated project record. Native transcripts and hidden tool memory do
177
+ not cross that boundary.
178
+
179
+ Want to falsify that claim without an AI subscription? Run the exact public
180
+ [Claude Code → Codex handoff fixture](./docs/handoff-proof.md). It writes the
181
+ receipt before any destination-model output and verifies the checkout using the
182
+ same receipt code as the CLI.
133
183
 
134
184
  ## All Commands
135
185
 
@@ -141,10 +191,11 @@ phewsh next # Queue work and define success criteria
141
191
  phewsh work # Current work + verification + human review
142
192
  phewsh truth # Read-only source-of-truth audit
143
193
  phewsh brief # Verified state + accepted work contract
144
- phewsh watch # Sync native harness files + optional cloud mirror
145
- phewsh ambient on # Automatic cross-tool continuity, with consent
194
+ phewsh seq --write # One-shot .intent/ refresh into all native project files
195
+ phewsh watch # Deliberately running native refresh + optional cloud push
196
+ phewsh ambient on # Preview + install reversible native adapters
146
197
  phewsh outcomes # Decision record — what was kept, reverted, or failed
147
- phewsh serve # Live execution bridge for web app
198
+ phewsh serve # Same-machine worker; human-initiated, project-bound claims
148
199
  phewsh clarify # AI-assisted artifact generation
149
200
  phewsh intent --init # Create .intent/ without entering the shell
150
201
  phewsh intent --status # Check artifact state
@@ -152,8 +203,8 @@ phewsh ai run "prompt" # One-shot AI with .intent/ context
152
203
  phewsh login # Authenticate + set API key
153
204
  phewsh push # Sync local .intent/ to cloud
154
205
  phewsh pull # Sync cloud to local
155
- phewsh mcp setup # Configure MCP server for agent connectivity
156
- phewsh mcp serve # Coordination bridge route work to live agents
206
+ phewsh mcp setup # Configure the optional bounded MCP adapter
207
+ phewsh mcp serve # Serve bounded capabilities over stdio/HTTP
157
208
  phewsh receipts # Proof trail — what agents actually did, with evidence
158
209
  phewsh update # Update phewsh to the latest version
159
210
  phewsh style # Build your style identity
@@ -161,8 +212,9 @@ phewsh style # Build your style identity
161
212
 
162
213
  ## Receipts
163
214
 
164
- Every task that runs through PHEWSH leaves evidence on your machine —
165
- sessions, results, blockers, gate checks, spend in `~/.phewsh/`. See it:
215
+ Every task and native tool handoff that runs through PHEWSH leaves evidence on
216
+ your machine — sessions, results, blockers, gate checks, handoff receipts, spend
217
+ — in `~/.phewsh/`. See it:
166
218
 
167
219
  ```bash
168
220
  phewsh receipts # merged timeline, newest first
@@ -170,9 +222,14 @@ phewsh receipts --json # machine-readable, for agents and scripts
170
222
  ```
171
223
 
172
224
  The same trail is visible at [phewsh.com/intent/receipts](https://phewsh.com/intent/receipts)
173
- while a local bridge is running (`phewsh serve` or `phewsh mcp serve` the
174
- first executes tasks directly via Claude Code, the second routes them to
175
- live connected agents; both record identical receipts).
225
+ only while this browser can reach a local bridge. `phewsh serve` supports the
226
+ same-machine manual-claim path; `phewsh mcp serve` exposes the optional adapter.
227
+ Neither makes a teammate's browser able to reach your localhost or grants
228
+ cross-machine execution authority.
229
+
230
+ Handoff receipts live in `~/.phewsh/handoffs/`. They contain paths and SHA-256
231
+ fingerprints, never file contents or transcripts. A hash detects corruption or
232
+ an unrecomputed edit; it is integrity evidence, not authenticated identity.
176
233
 
177
234
  ## Outcomes
178
235
 
@@ -202,8 +259,25 @@ phewsh push # upload .intent/ to cloud
202
259
  phewsh pull # download from cloud
203
260
  ```
204
261
 
205
- Cloud sync is manual. Local harness projections self-heal automatically from
206
- the same canonical `.intent/` source.
262
+ Cloud sync is never triggered by `init`, `ambient`, or `seq`. `phewsh push` is
263
+ the explicit one-shot upload. Deliberately starting `phewsh watch` opts into
264
+ automatic push while that process runs for a signed-in user; use
265
+ `phewsh watch --no-push` for local projections only. Local harness projections
266
+ self-heal from the same canonical `.intent/` source.
267
+
268
+ ## Environment variables
269
+
270
+ All optional; phewsh needs no configuration to run. None of these hold secrets.
271
+
272
+ | Variable | Effect |
273
+ |---|---|
274
+ | `PHEWSH_DEBUG` | Verbose diagnostics for session handling |
275
+ | `PHEWSH_OFFLINE` | Skip network checks in the truth audit (`phewsh truth`) |
276
+ | `PHEWSH_WIDTH` | Override terminal width when the terminal misreports it |
277
+ | `PHEWSH_AUTOWORK` | Auto-run `/work` on session start (used by the `phewsh <harness>` shortcut) |
278
+ | `PHEWSH_MCP_PORT` / `PHEWSH_MCP_HOST` | Bind address for the local MCP HTTP bridge |
279
+ | `PHEWSH_ALLOWED_ORIGINS` | Extra CORS origins for the local serve bridge (loopback by default) |
280
+ | `PHEWSH_PROJECT_INDEX` | Override the path of the local project index |
207
281
 
208
282
  ## Web app
209
283
 
package/SECURITY.md CHANGED
@@ -1,97 +1,117 @@
1
1
  # Security & Data Flow — phewsh CLI
2
2
 
3
- phewsh is a **local-first** tool. It runs on your machine, reads your project's
4
- `.intent/` and your installed AI tools' config, and helps you carry context
5
- between those tools. This document states factually, traceable to source
6
- what it reads, writes, and sends. No vague claims; if something here is wrong,
7
- it's a bug: **hello@phewsh.com**.
8
-
9
- > Status: this is an honest self-documented inventory, **not** an independent
10
- > audit. The CLI source is **public and MIT-licensed** at
11
- > **github.com/cleverIdeaz/phewsh-cli** an exact mirror of the published npm
12
- > package, so you can read exactly what you install (`bin/ commands/ lib/ mcp/`).
13
- > An independent review is still planned (see "Roadmap").
3
+ Phewsh is a **local-first continuity layer**, not a sandbox. It reads project
4
+ records, projects bounded context into supported AI tools, and can launch tools
5
+ that run with your user account's authority. This page is a source-backed
6
+ inventory of what the CLI reads, writes, and sends.
7
+
8
+ > **Status:** self-documented and tested, **not independently audited**. The
9
+ > MIT-licensed source snapshot is public at
10
+ > [cleverIdeaz/phewsh-cli](https://github.com/cleverIdeaz/phewsh-cli). The npm
11
+ > artifact is manually published today and is not yet cryptographically linked
12
+ > to that repository. See the [threat model](./docs/threat-model.md) and
13
+ > [release integrity checklist](./docs/release-checklist.md).
14
14
 
15
15
  ## What phewsh reads
16
- - **`.intent/`** in your project (`vision.md`, `plan.md`, `status.md`, `next.md`,
17
- `project.json`, `next.json`). This is the source of truth it projects.
18
- - **Your tools' context files** when present: `CLAUDE.md`, `AGENTS.md`,
19
- `GEMINI.md`, `.cursorrules`, `.github/copilot-instructions.md`, `README.md`.
20
- - **Your Claude project memory** (`~/.claude/projects/<cwd>/memory/MEMORY.md` and
21
- files it links) and **global per-user memory** (`~/.claude/CLAUDE.md`,
22
- `~/.codex/AGENTS.md`, `~/.gemini/GEMINI.md`) read-only, used to enrich the
23
- `phewsh seq` summary. Global memory is **never** written into a project file
24
- unless you pass `--include-global` (`lib/sequencer/index.js`).
25
- - **Git status** of the current repo (read-only: `git status`, HEAD, diff stats).
26
-
27
- ## What phewsh writes (and where)
28
- Every generated block is wrapped in `<!-- PHEWSH:START -->` / `<!-- PHEWSH:END -->`
29
- markers; **content outside the markers is preserved byte-for-byte** (tested).
30
- - **Project context files** — the canonical `.intent/` projection into
31
- `CLAUDE.md` / `AGENTS.md` / `GEMINI.md` / `.cursorrules` (only files that
32
- already exist, unless you create them). One canonical projector
33
- (`lib/selfheal.js`) is the single writer.
34
- - **`~/.phewsh/`** `config.json` (your settings/keys, mode **0600**, dir 0700),
35
- `briefs/` (saved handoff briefs), `sessions/`, `receipts/`, ledger files.
36
- - **Shell rc** only if you run `phewsh shim on` (adds one PATH line; reversible
37
- with `phewsh shim off`).
38
- - **Global base files** only if you run `phewsh ambient on`: a marker-wrapped
39
- block in `~/.claude/CLAUDE.md` etc. for tools you already have. Reversible with
40
- `phewsh ambient off`.
41
- - **Claude Code hook** `phewsh ambient on` registers `SessionStart`/`SessionEnd`
42
- hooks (context injection + a metadata breadcrumb; **never your transcript**).
43
-
44
- ## Network calls (exactly these)
45
- phewsh makes **no network calls for its core local features** (sequencing,
46
- projection, briefs, status). Calls happen only for these named actions:
47
- - **`api.anthropic.com` / `openrouter.ai` / `api.together.xyz`** only if you set
48
- a BYOK key and use `/run` or the API route. Your key goes **directly** to the
49
- provider; it is **not** proxied through phewsh servers.
50
- - **`registry.npmjs.org`** — version check for `phewsh update` (notify-only by
51
- default).
52
- - **`<project>.supabase.co`** only if you `/login`: auth + optional cloud sync
53
- of your `.intent/` (you initiate `push`/`pull`).
54
- - **`phewsh.com`** — only for `phewsh serve`/cloud-bridge actions you start.
55
- - **Sustainability telemetry** (`trackSap`, `lib/supabase.js`) sends **model
56
- name, token counts, and a kWh estimate only**. No prompts, no responses, no
57
- file contents. Tied to your account id only when logged in.
16
+
17
+ - Project truth in `.intent/`, plus Git status, HEAD, and diff statistics.
18
+ - Existing native context files such as `CLAUDE.md`, `AGENTS.md`, `GEMINI.md`,
19
+ `.cursorrules`, Copilot instructions, and `README.md`.
20
+ - Claude project/global memory and other supported tools' global context files
21
+ when building a `phewsh seq` summary. Global content is not copied into a
22
+ project unless you pass `--include-global`.
23
+ - Local Phewsh configuration, receipts, decisions, and session metadata.
24
+
25
+ Phewsh does not read or store native tool transcripts through its ambient
26
+ hooks. A native tool may still read files or send prompts under that tool's own
27
+ permissions and policy.
28
+
29
+ ## What phewsh writes
30
+
31
+ - Marker-wrapped projections in supported native context files. Content outside
32
+ `<!-- PHEWSH:START -->` / `<!-- PHEWSH:END -->` is preserved.
33
+ - Local state under `~/.phewsh/`: configuration, briefs, handoff receipts,
34
+ session metadata, and ledgers. `config.json` and handoff receipt paths are
35
+ explicitly owner-only (`0600` files, `0700` directories) on POSIX systems.
36
+ Other local ledgers rely on the owning account and process umask today; treat
37
+ the whole directory as sensitive.
38
+ - A reversible PATH line only after `phewsh shim on`.
39
+ - Reversible, marker-wrapped global adapter blocks and unmodified Phewsh-owned
40
+ intent-skill copies only after `phewsh ambient on`.
41
+ - Claude Code and Codex lifecycle/safety hooks after `phewsh ambient on`.
42
+
43
+ Handoff receipts contain paths, fingerprints, Git state, route labels, and a
44
+ brief hash—not file contents, prompts, responses, transcripts, or model
45
+ reasoning. Gitignored files are not named or hashed. Browser-facing receipt
46
+ views are redacted. A SHA-256 match detects later change; it is **not a
47
+ signature** and does not prove who created the receipt.
48
+
49
+ ## Network boundaries
50
+
51
+ Core projection, status, local brief generation, and receipt verification can
52
+ run without network access. Network calls occur when a user selects a feature
53
+ that needs them, including:
54
+
55
+ - npm registry version checks and optional updates;
56
+ - direct requests to configured model providers, a configured custom endpoint,
57
+ local Ollama, or Phewsh's pooled provider route;
58
+ - Supabase authentication, cloud sync, Ion/team features, and sustainability
59
+ telemetry;
60
+ - user-requested URL browsing, YouTube captions, GitHub API feedback/listing,
61
+ and OAuth flows;
62
+ - same-machine HTTP bridges started by the user.
63
+
64
+ BYOK requests go to the selected provider or configured endpoint. The endpoint
65
+ receives the prompt supplied to that provider. Sustainability telemetry sends
66
+ the model, prompt/completion token counts, estimated kWh/CO2/water, a session
67
+ identifier, and an account identifier when logged in—never prompt or response
68
+ content. A user-requested browse sends a request to the supplied URL.
58
69
 
59
70
  ## Credentials
60
- - A bring-your-own key lives in `~/.phewsh/config.json` at mode **0600**
61
- (`lib/config-file.js`) and is sent **directly to the provider**, never to us.
62
- - phewsh routes through your installed tools on **their own login** (your Claude
63
- subscription, your ChatGPT plan) it does not see or store those credentials.
64
-
65
- ## The local bridge
66
- `phewsh serve` binds **`127.0.0.1` only** (loopback), with an origin allowlist,
67
- and runs only while you run it.
68
-
69
- ## Known issues / hardening backlog (honest)
70
- - **Local shell-injection surface (medium, local-only):** a few call sites build
71
- shell strings from REPL input via `execSync` (e.g. `commands/session.js` gate /
72
- outcomes arg passthrough). Inputs are your own typed/pasted text on your own
73
- machine, but crafted args could execute. Fix: convert to argument-safe
74
- `execFileSync`/`spawnSync`. Tracked as a Next item.
75
- - **No release provenance yet** npm provenance, signed tags, and a public
76
- source repo are planned (Roadmap) so the published artifact is verifiable.
71
+
72
+ Phewsh stores its own Supabase tokens and BYOK values in
73
+ `~/.phewsh/config.json`, hardened to mode `0600` inside a `0700` directory on
74
+ POSIX systems. Phewsh does not read Claude Code, Codex, Gemini, or Cursor
75
+ credentials; spawned tools authenticate themselves.
76
+
77
+ ## Local bridges
78
+
79
+ `phewsh serve` binds IPv4 and IPv6 loopback (`127.0.0.1` and `::1`) and applies
80
+ a browser-origin allowlist. Project claims are rechecked against registration,
81
+ cloud project identity, and Git origin. The legacy local dispatch surface is
82
+ broader and should be treated as local-user authority.
83
+
84
+ **Loopback is not authentication.** Another process running as your user may
85
+ be able to call a local service, and non-browser clients do not supply a browser
86
+ Origin header. The optional MCP HTTP transport is also unauthenticated. Never
87
+ set `PHEWSH_MCP_HOST` to a non-loopback interface on an untrusted network.
88
+
89
+ ## Safety gate
90
+
91
+ The pre-tool gate blocks a narrow set of catastrophic command shapes and may
92
+ ask about high-blast-radius operations depending on autonomy. It is deliberately
93
+ **fail-open** if hook input cannot be understood, uses pattern/segment matching
94
+ rather than a complete shell parser, and covers known tool names. It is a
95
+ last-line safety aid, **not a sandbox or authorization system**.
96
+
97
+ ## Supply chain status
98
+
99
+ The npm release and public source mirror are synchronized manually. There is
100
+ currently **no release provenance**, signed tag, or registry attestation tying
101
+ an installed tarball to a public commit. Users can inspect `npm pack`, the
102
+ public source snapshot, or the installer before running it, but similarity is
103
+ not cryptographic proof. The required release procedure and promotion gate are
104
+ in the [release integrity checklist](./docs/release-checklist.md).
77
105
 
78
106
  ## Disable / uninstall
79
- - `phewsh ambient off` — removes injected hooks and global base files; restores
80
- your files.
81
- - `phewsh shim off` — removes the PATH line.
82
- - `npm uninstall -g phewsh` removes the CLI. `rm -rf ~/.phewsh` removes local
83
- state. Generated `PHEWSH:START/END` blocks can be deleted by hand; everything
84
- outside them is yours and untouched.
85
-
86
- ## Roadmap to verifiable trust
87
- Done: this doc, exec hardening, telemetry stays counts-only and explicit, and a
88
- **public MIT source repo** (`cleverIdeaz/phewsh-cli`) mirroring the npm package.
89
- Before broad promotion: npm provenance, signed tags, and dependency/secret
90
- scanning so the published artifact is cryptographically verifiable from the
91
- public source. For enterprise: a documented threat model and an independent
92
- security assessment. We will not call phewsh "audited" until an independent
93
- audit has actually occurred.
107
+
108
+ - `phewsh ambient off` removes injected hooks, global blocks, and unchanged
109
+ Phewsh-owned intent-skill copies.
110
+ - `phewsh shim off` removes the PATH line.
111
+ - `npm uninstall -g phewsh` removes the CLI. Local `~/.phewsh/` state and
112
+ project `.intent/` files remain yours and can be removed separately.
94
113
 
95
114
  ## Reporting
96
- Security issues: **hello@phewsh.com**. Please allow reasonable time to remediate
97
- before public disclosure.
115
+
116
+ Security issues: **hello@phewsh.com**. Please allow reasonable time to
117
+ remediate before public disclosure.
package/bin/phewsh.js CHANGED
@@ -7,10 +7,15 @@ const command = args[0];
7
7
  // Must be instant and side-effect-free: print the banner, exit. No update
8
8
  // check, no network, no session. Intercepted before anything else loads.
9
9
  if (command === 'shim-preflight') {
10
- try {
11
- const bin = args[1] || 'tool';
12
- process.stdout.write(require('../lib/shims').preflightBanner(bin) + '\n');
13
- } catch { /* a broken banner must never delay the real tool */ }
10
+ // Machine-readable launches (Codex app-server JSONL, anything spawned with
11
+ // piped stdio) must get NOTHING on stdout — a banner corrupts the stream
12
+ // the parent parses. A human terminal has a TTY; everything else stays silent.
13
+ if (process.stdout.isTTY) {
14
+ try {
15
+ const bin = args[1] || 'tool';
16
+ process.stdout.write(require('../lib/shims').preflightBanner(bin) + '\n');
17
+ } catch { /* a broken banner must never delay the real tool */ }
18
+ }
14
19
  process.exit(0);
15
20
  }
16
21
 
@@ -58,7 +63,7 @@ function showBrand() {
58
63
  console.log('');
59
64
  console.log(` ${b(w('█▀█ █░█ █▀▀ █░█░█ █▀ █░█'))}`);
60
65
  console.log(` ${b(w('█▀▀ █▀█ ██▄ ▀▄▀▄▀ ▄█ █▀█'))}`);
61
- console.log(` ${g('Keep all your AI tools. phewsh is the one memory they share.')}`);
66
+ console.log(` ${g('Keep all your AI tools. phewsh briefs them from one .intent/ folder you own.')}`);
62
67
  console.log('');
63
68
 
64
69
  // Context-aware hint
@@ -86,6 +91,8 @@ const COMMANDS = {
86
91
  link: () => require('../commands/link'),
87
92
  sync: () => require('../commands/sync').main('status'),
88
93
  login: () => require('../commands/login'),
94
+ // `phewsh logout` = `phewsh login --logout` — the universal spelling.
95
+ logout: () => { process.argv.splice(3, 0, '--logout'); return require('../commands/login'); },
89
96
  ai: () => require('../commands/ai'),
90
97
  style: () => require('../commands/style'),
91
98
  mbhd: () => require('../commands/mbhd'),
@@ -133,13 +140,13 @@ function showHelp() {
133
140
  const pkg = require('../package.json');
134
141
  showBrand();
135
142
  console.log(` ${g('v' + pkg.version)} · ${g('phewsh.com/cli')}\n`);
136
- console.log(` ${g('Phewsh keeps work from getting lost for you, and every AI tool you use.')}`);
143
+ console.log(` ${g('Carry forward what was recorded. See exactly what was not.')}`);
137
144
  console.log('');
138
145
  console.log(` ${b(w('the whole idea — four plain words'))}`);
139
146
  console.log(` ${cyan('intent')} ${g('PROJECT what you\'re building & why')}`);
140
147
  console.log(` ${cyan('next')} ${g('NEXT what should happen next — a zero-AI list')}`);
141
148
  console.log(` ${cyan('work')} ${g('WORK what\'s happening now — at a glance')}`);
142
- console.log(` ${cyan('remember')} ${g('RECORD jot a decision so it sticks & travels')}`);
149
+ console.log(` ${cyan('remember')} ${g('RECORD jot a decision so it stays in .intent/')}`);
143
150
  console.log(` ${cyan('status')} ${g('see all four at a glance')}`);
144
151
  console.log('');
145
152
  console.log(` ${b(w('get started'))}`);
@@ -152,38 +159,38 @@ function showHelp() {
152
159
  console.log(` ${cyan('gate')} ${g('Set constraints (budget, time, skill, urgency)')}`);
153
160
  console.log(` ${cyan('context')} ${g('Export .intent/ for any AI tool')}`);
154
161
  console.log(` ${cyan('status')} ${g('git status for AI continuity — truth, record, drift, what\'s wired')}`);
155
- console.log(` ${cyan('next')} ${g('What should happen next — a zero-AI list every tool reads')}`);
162
+ console.log(` ${cyan('next')} ${g('What should happen next — a zero-AI list compatible adapters read')}`);
156
163
  console.log(` ${cyan('truth')} ${g('Read-only audit: versions, Git, intent, projections, conflicts')}`);
157
164
  console.log(` ${cyan('brief')} ${g('Provider-ready briefing built from verified project truth')}`);
158
165
  console.log(` ${cyan('ai')} ${g('One-shot prompt with .intent/ context')}
159
166
  ${cyan('browse')} ${g('Read any URL — AI summary in your terminal')}`);
160
167
  console.log('');
161
- console.log(` ${b(w('sync everywhere'))}`);
162
- console.log(` ${cyan('seq')} ${g('Sequence all memoryoptimal context for any agent')}`);
163
- console.log(` ${cyan('watch')} ${g('Auto-sync .intent/ native harness files + cloud')}`);
168
+ console.log(` ${b(w('connect your tools'))}`);
169
+ console.log(` ${cyan('seq')} ${g('Compile project truthnative context for a chosen tool')}`);
170
+ console.log(` ${cyan('watch')} ${g('Auto-sync while running; signed-in cloud push unless --no-push')}`);
164
171
  console.log(` ${cyan('push/pull')} ${g('Manual sync to/from phewsh.com/intent')}`);
165
- console.log(` ${cyan('serve')} ${g('Execution bridgerun from phewsh.com/ion or /intent')}`);
172
+ console.log(` ${cyan('serve')} ${g('Same-machine workerproject-bound, human-initiated claims')}`);
166
173
  console.log(` ${cyan('project')} ${g('Choose which projects this machine\'s worker shows on /ion')}`);
167
- console.log(` ${cyan('ion')} ${g('Shared visual room for humans + local agents')}`);
168
- console.log(` ${cyan('mcp')} ${g('Connect AI agents via MCP protocol')}`);
169
- console.log(` ${cyan('ambient')} ${g('Continuity without launching phewsh enhance your other tools')}`);
174
+ console.log(` ${cyan('ion')} ${g('Shared project room for humans + agents; request → review → Record')}`);
175
+ console.log(` ${cyan('mcp')} ${g('Optional bounded MCP adapter no project truth or execution authority')}`);
176
+ console.log(` ${cyan('ambient')} ${g('Inspect or install reversible skills, hooks, and context adapters')}`);
170
177
  console.log(` ${cyan('shim')} ${g('Guaranteed launch banner — phewsh prints status before each tool')}`);
171
178
  console.log(` ${cyan('pack')} ${g('Opt-in workflow packs (Karpathy guidelines, GSD…) — attributed, reversible')}`);
172
179
  console.log(` ${cyan('task')} ${g('Shared tasks — request, claim, and ship teammate work via branch + PR')}
173
180
  ${cyan('dispatch')} ${g('Friendly verb over task: dispatch "<title>" to request, <id>|next to claim')}
174
- ${cyan('receipts')} ${g('Proof trail — what agents actually did, with evidence')}`);
175
- console.log(` ${cyan('remember')} ${g('Jot a decision to .intent/decisions.md — every tool inherits it')}`);
181
+ ${cyan('receipts')} ${g('Proof trail — task evidence + cross-tool handoff receipts')}`);
182
+ console.log(` ${cyan('remember')} ${g('Jot a decision to .intent/decisions.md — supported tools can read it')}`);
176
183
  console.log(` ${cyan('outcomes')} ${g('Decision record — what was kept, reverted, or failed')}`);
177
184
  console.log(` ${cyan('bypass')} ${g('Went around phewsh? Record why — 10 seconds, no guilt')}`);
178
185
  console.log('');
179
186
  console.log(` ${b(w('configure'))}`);
180
187
  console.log(` ${cyan('feedback')} ${g('Tell us what you need — prefilled GitHub issue; `feedback list` shows the queue')}`);
181
- console.log(` ${cyan('login')} ${g('Identity + API key + cloud sync')}`);
188
+ console.log(` ${cyan('login')} ${g('Identity + API key + cloud sync — `logout` to sign out')}`);
182
189
  console.log(` ${cyan('link')} ${g('Link local .intent/ to cloud project')}`);
183
190
  console.log(` ${cyan('update')} ${g('Update phewsh — or `phewsh update auto on` to stay current automatically')}`);
184
191
  console.log('');
185
- console.log(` ${g('Works in: Claude Code · Cursor · ChatGPT · any MCP agent')}`);
186
- console.log(` ${g('No account needed. Account adds sync + sharing.')}`);
192
+ console.log(` ${g('Works with: Claude Code · Codex · Cursor · Gemini · compatible MCP clients')}`);
193
+ console.log(` ${g('No account needed for local truth. An account adds explicit cloud sync + Ion rooms.')}`);
187
194
  console.log('');
188
195
  }
189
196
 
@@ -249,12 +256,11 @@ async function maybeFirstRunIntro() {
249
256
  } catch { /* the intro is a nicety — never let it block the session */ }
250
257
  }
251
258
 
252
- // Always-on, frictionless: on the first interactive use, auto-enable ambient
253
- // across every installed harness (unless the user opted out); on every run
254
- // after, self-heal so each tool's context files are present and fresh. All
255
- // best-effort and non-blocking a launch must never wait on or fail from this.
259
+ // Once a user has explicitly enabled native adapters, keep their existing
260
+ // marked context blocks fresh. A bare launch never installs skills or hooks;
261
+ // first-run setup is offered by the intro and `phewsh ambient on` previews the
262
+ // exact files before asking for consent.
256
263
  async function ambientSelfHeal() {
257
- try { await require('../commands/ambient').ensureAuto(); } catch { /* never block launch */ }
258
264
  // Refresh-only: keep already-present context files fresh, but never CREATE
259
265
  // them just because phewsh was opened here — that would dirty a clean repo.
260
266
  try { require('../lib/selfheal').syncContextFiles({ createMissing: false }); } catch { /* never block launch */ }