@archme/cli 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +64 -285
  2. package/SKILL.md +3 -4
  3. package/dist/cli.js +13 -12
  4. package/package.json +16 -2
package/README.md CHANGED
@@ -1,308 +1,87 @@
1
- # archme-cli
1
+ # @archme/cli
2
2
 
3
- Multi-subcommand CLI for ArchitectMe. The daemon (original purpose of this
4
- package) is one subcommand; the others cover code analysis, OAuth login, and
5
- MCP API key management.
6
-
7
- See also:
8
- - Proposal: `../future-proposals/26-05-12-archme-cli-and-component-anchors.md`
9
- - Analyze methodology: `./SKILL.md`
10
- - Daemon commit-driven flow: `../future-proposals/26-04-29-github-app-commit-driven-updates.md`
11
- - Release runbook (bump → distribute → set floor): `./RELEASE.md`
12
-
13
- ## Subcommands at a glance
14
-
15
- | Subcommand | Purpose |
16
- |---|---|
17
- | `archme daemon` | Local job runner — claims `archme_jobs` rows and runs Claude to update architecture |
18
- | `archme analyze outline\|repo\|diff\|match\|prefetch` | Code analysis primitives (tree-sitter) for keeping architecture in sync with code |
19
- | `archme login \| logout` | OAuth flow — authenticate this machine against ArchitectMe |
20
- | `archme keys list\|create\|revoke` | Manage MCP API keys for headless/CI use |
21
-
22
- ## Installation
3
+ Command-line companion for [ArchMe](https://archme.io) — maps your codebase into
4
+ a living architecture diagram and keeps it current as you commit.
23
5
 
24
6
  ```bash
25
7
  npm install -g @archme/cli
26
8
  ```
27
9
 
28
- Requires Node 20+. `keytar` is an *optional* dependency — if its native build
29
- fails, credentials fall back to `~/.archme/credentials.json` (0600) and
30
- everything else keeps working.
31
-
32
- ### Developing on the CLI
33
-
34
- **For iterating on sources, use tsx directly** — it always runs current code:
35
-
36
- ```bash
37
- cd archme-cli
38
- npm install
39
- npx tsx src/bin.ts <subcommand> [args]
40
- ```
41
-
42
- `npm link` also works, but note the published `bin` is the *built bundle*
43
- (`dist/cli.js`), so linking without building leaves a dangling symlink, and a
44
- stale `dist/` silently shadows your edits. Build first, and rebuild after
45
- changes:
46
-
47
- ```bash
48
- npm install
49
- npm run build # required — bin points at dist/cli.js
50
- npm link
51
-
52
- which archme # → <your-npm-prefix>/bin/archme
53
- ```
54
-
55
- To uninstall: `cd archme-cli && npm unlink` (or `npm rm -g @archme/cli`).
56
-
57
- `npm run build` uses esbuild to inline the repo's top-level `shared/` modules,
58
- which do not exist inside the package. `npm run build:check` builds and then
59
- executes the artifact — that is what CI and `prepublishOnly` run.
60
-
61
- `bin/archme` (the dev shim, used by an unbuilt clone and by service units when
62
- `dist/` is absent) runs `src/bin.ts` via tsx. It must point at `bin.ts`, not
63
- `cli.ts` — `cli.ts` exports `main` without invoking it, so pointing at it makes
64
- every command a silent exit 0. `src/binShim.test.ts` pins this by executing it.
65
-
66
- ### Do you need env config?
67
-
68
- | Goal | Env setup |
69
- |---|---|
70
- | `archme analyze` (outline / repo / diff / match / prefetch) against local files | **None.** Analyze doesn't talk to Supabase. |
71
- | `archme login` / `archme daemon` / `archme scan` against **prod** | **None.** Defaults are hardcoded; just `archme login && archme daemon`. |
72
- | Same commands against **local Supabase** | `ARCHME_ENV=local`. The per-developer OAuth client id is set up once via `npm run setup:local-daemon-oauth` from the repo root (after `supabase start`) — that writes `~/.archme/local-config.json`, which the CLI auto-reads when `ARCHME_ENV=local`. |
73
- | Self-hosted ArchitectMe deployment | Override individual env vars: `SUPABASE_URL=... SUPABASE_ANON_KEY=... ARCHME_DAEMON_CLIENT_ID=... ARCHME_MCP_BASE_URL=... archme daemon`. |
74
-
75
- The CLI never reads `.env` files. Configuration comes from (in order of precedence): explicit env vars > `~/.archme/local-config.json` (when `ARCHME_ENV=local`) > built-in preset for `ARCHME_ENV` (`prod` by default). The full set of overrideable vars is `SUPABASE_URL`, `SUPABASE_ANON_KEY`, `ARCHME_DAEMON_CLIENT_ID`, `ARCHME_MCP_BASE_URL`, plus `CLONE_BASE_DIR` (daemon only, defaults to `~/.archme-job-runner/clones`).
76
-
77
- ---
78
-
79
- ## archme daemon
80
-
81
- Local daemon that consumes `archme_jobs` rows from Supabase and runs Claude
82
- on this machine to update the architecture diagram. It is the local worker
83
- for the GitHub-App → Supabase → laptop-daemon flow
84
- (see `../future-proposals/26-04-29-github-app-commit-driven-updates.md`).
85
-
86
- ### How it works
87
-
88
- 1. Subscribes to Supabase Realtime `INSERT` events on `archme_jobs` filtered
89
- to `status = 'pending'`. On startup and reconnect, also runs a sweep over
90
- any pending rows.
91
- 2. Atomically claims a row through the `claim_archme_job` RPC using its
92
- registered org device id.
93
- 3. Requests short-lived GitHub App installation credentials for the claimed
94
- job's repo, then uses the repo under `CLONE_BASE_DIR/<owner>/<repo>` as a
95
- shared Git object cache.
96
- 4. Creates a temporary detached worktree at the job's `after_sha`.
97
- 5. Generates a temp `mcp.json` pointing at the archme MCP with
98
- `?project=<slug>&branch=<branch>` from the job row.
99
- 6. Shells out to `claude -p <prompt> --mcp-config <path>` with its working
100
- directory set to that temporary worktree. Claude reads the architecture,
101
- reasons about the diff, and calls `update_architecture`.
102
- 7. Calls the `archme-job-complete` edge function to mark the row
103
- `completed` (with the model's summary) or `failed` (with the error) and
104
- post the GitHub check run.
105
- 8. Runs a safety sweep every 30 seconds so pending rows are still picked up if
106
- Realtime misses an event.
107
-
108
- ### Setup
109
-
110
- ```bash
111
- cd archme-cli
112
- npm install
113
- ```
114
-
115
- That's it for the prod target — config defaults live in `src/config/defaults.ts`. For local-Supabase development, see "Do you need env config?" above.
116
-
117
- ### Auth
118
-
119
- The daemon always uses one-time browser enrollment:
120
-
121
- ```bash
122
- cd archme-cli
123
- npm run enroll
124
- ```
125
-
126
- The command prints a code and opens `/agents/pair` in your browser. Pick the
127
- org this daemon should work for, then confirm the matching code while signed
128
- in to ArchitectMe. Pairing creates an enabled `agent_devices` row for that
129
- org. The daemon stores the resulting refresh token, org id, and device id in
130
- macOS Keychain under service `archme-daemon`, using `SUPABASE_URL` as the
131
- account. If Keychain is unavailable, it falls back to
132
- `~/.archme/credentials.json` with mode `0600`.
133
-
134
- On every token refresh the daemon persists the rotated refresh token. If the
135
- stored token is revoked, invalid, or missing org/device identity, startup
136
- exits with re-enrollment instructions.
137
-
138
- The web app must be configured with `VITE_ARCHME_DAEMON_CLIENT_ID` matching
139
- the pre-registered Supabase OAuth client for the daemon. That client needs
140
- `<app-origin>/agents/pair/callback` as an allowed redirect URI.
141
-
142
- For local Supabase, run this from the repo root after `supabase start`:
143
-
144
- ```bash
145
- npm run setup:local-daemon-oauth
146
- ```
147
-
148
- That creates or updates the local daemon OAuth client and writes:
10
+ Requires Node 20+ and [Claude Code](https://claude.com/claude-code) installed and
11
+ signed in — scans and updates run on **your** Claude subscription, on your
12
+ machine. Your code is never sent to ArchMe's servers; only the resulting
13
+ architecture is.
149
14
 
150
- - `.env.local` for the Vite app (so `/agents/pair` knows the client id)
151
- - `~/.archme/local-config.json` for the CLI (auto-loaded when `ARCHME_ENV=local`)
15
+ ## 1. Scan your repo
152
16
 
153
- After that:
17
+ `cd` into the repository you want mapped, then:
154
18
 
155
19
  ```bash
156
- ARCHME_ENV=local archme login
157
- ARCHME_ENV=local archme daemon
20
+ archme init
158
21
  ```
159
22
 
160
- To complete the browser step locally, the local app still needs a normal
161
- ArchitectMe web session. If your browser is not already signed in, configure
162
- the local Supabase sign-in provider before starting Supabase.
23
+ This signs you in, creates a project named after the repo, writes the agent
24
+ config (`.mcp.json`, a `CLAUDE.md` block, the architecture skill), tells you
25
+ what the scan will cost before spending it, and runs the scan. It prints a link
26
+ to your board — components appear on it as they're written.
163
27
 
164
- ### Run
28
+ ## 2. Keep it up to date
165
29
 
166
- ```bash
167
- npm run dev
168
- ```
169
-
170
- Logs prefixed with `[<job-id>]` per job.
171
-
172
- ### Enrollment Verification
173
-
174
- ```bash
175
- cd archme-cli
176
- npm run enroll
177
- # confirm the browser prompt
178
- npm run dev
179
- ```
180
-
181
- On macOS, the credential should be visible with:
182
-
183
- ```bash
184
- security find-generic-password -s archme-daemon -a "$SUPABASE_URL"
185
- ```
186
-
187
- If Keychain was unavailable, check `~/.archme/credentials.json` exists with
188
- mode `0600`.
189
-
190
- ### Job Verification
191
-
192
- With the daemon running, enqueue a job for a watched repo/project. The watched
193
- repo must have a valid GitHub App `installation_id`; the daemon uses that
194
- installation to mint short-lived HTTPS clone/fetch credentials.
195
-
196
- ```sql
197
- select enqueue_archme_job(
198
- '<watched_repo_id>',
199
- '<org_id>',
200
- '<user_id>',
201
- '<project_id>',
202
- '<repo_owner>',
203
- '<repo_name>',
204
- '<repo_branch>',
205
- '<archme_branch>',
206
- '<before_sha>',
207
- '<after_sha>',
208
- false,
209
- null
210
- );
211
- ```
212
-
213
- Within one safety sweep the daemon should claim the row, set
214
- `claimed_by_device_id`, fetch the repo without persisting tokenized remotes,
215
- run Claude, call the completion edge function, and mark the row
216
- `completed`. Open the project in the web app on the same branch; the diagram
217
- should reflect the change, or the row's `result.summary` should explain why
218
- no update was needed.
219
-
220
- ---
221
-
222
- ## archme analyze
223
-
224
- Code analysis primitives that power keeping ArchitectMe architecture in sync
225
- with actual source code. Parses files with
226
- [web-tree-sitter](https://github.com/tree-sitter/tree-sitter/tree/master/lib/binding_web)
227
- and emits structured JSON that the MCP server and agents consume.
228
-
229
- Grammars are fetched on demand to `~/.archme/tools/grammars/` (override with
230
- `ARCHME_TOOLS_DIR`). No build step required — grammars are downloaded the
231
- first time a language is encountered.
232
-
233
- **Supported languages:** TypeScript, TSX, JavaScript, Python, Go, Java, Ruby,
234
- Rust, Swift, Kotlin.
235
-
236
- For the full agent methodology (how to run a repo scan, match anchors, and
237
- write architecture updates) see `./SKILL.md`.
238
-
239
- ### Commands
240
-
241
- ```
242
- archme analyze outline <file> Emit a JSON symbol outline for a single file
243
- archme analyze repo Walk the repo and outline every supported file
244
- archme analyze diff <range> Outline only files changed in a git range (e.g. HEAD~3..HEAD)
245
- archme analyze match <anchor-spec> Match anchor specs (JSON file) against current symbol outlines
246
- archme analyze prefetch [langs...] Pre-download grammars so first analysis is instant
247
- ```
248
-
249
- ### Example
30
+ `archme init` also starts watching the repo, so every push queues an architecture
31
+ update — but nothing processes that queue until you run the agent:
250
32
 
251
33
  ```bash
252
- archme analyze outline src/api/upload.ts
34
+ archme daemon start
253
35
  ```
254
36
 
255
- Output is a JSON envelope:
37
+ Installs the daemon as a background service (launchd/systemd), enables it at
38
+ login, and starts it. Run it on a machine that stays on. Each update counts
39
+ tokens against your Claude account, the same way the scan did.
256
40
 
257
- ```json
258
- {
259
- "file": "src/api/upload.ts",
260
- "lang": "typescript",
261
- "symbols": [
262
- { "kind": "function", "name": "handleUpload", "line": 12, "exported": true },
263
- { "kind": "class", "name": "UploadService", "line": 34, "exported": true }
264
- ]
265
- }
266
- ```
267
-
268
- `archme analyze repo` emits one envelope per file (newline-delimited JSON) and
269
- is the starting point for a full codebase scan.
270
-
271
- `archme analyze match <anchor-spec.json>` takes a JSON file describing named
272
- anchors (component → expected symbols) and reports which anchors still resolve
273
- and which have drifted, enabling the MCP server to flag stale architecture
274
- nodes.
41
+ Watching a repo needs the ArchMe GitHub App installed on it; `archme init` tells
42
+ you if that step is still missing. Not up for hosting the agent yourself? Get in
43
+ touch at [archme.io](https://archme.io) and we'll run it for you.
275
44
 
276
45
  ---
277
46
 
278
- ## Auth & keys
47
+ ## Other commands
279
48
 
280
- ### archme login / logout
281
-
282
- ```bash
283
- archme login # Opens browser OAuth flow; stores token in macOS Keychain
284
- # (falls back to ~/.archme/credentials.json with mode 0600)
285
- archme logout # Clears stored credentials
286
- ```
287
-
288
- OAuth flow uses the same Supabase OAuth 2.1 / PKCE mechanism as the daemon
289
- enrollment. Intended for interactive use; the daemon uses its own enrollment
290
- flow (`npm run enroll`) instead.
291
-
292
- ### archme keys list | create | revoke
293
-
294
- ```bash
295
- archme keys list # List MCP API keys for the authenticated user
296
- archme keys create <name> # Mint a new am_* key for CI / headless use
297
- archme keys revoke <key-id> # Revoke a key
298
- ```
299
-
300
- > **Currently stub** — these commands print placeholder messages. Full
301
- > implementation (Unkey integration, org-scoped key listing) is pending.
302
-
303
- ---
304
-
305
- ## Privacy / sync
306
-
307
- This directory is excluded from the work-repo sync
308
- (`scripts/sync-to-on-prem.sh`).
49
+ | Command | Purpose |
50
+ |---|---|
51
+ | `archme init [repo-path]` | Guided setup + scan (see above); `--force` re-scans |
52
+ | `archme scan <repo-path>` | Low-level single-pass scan into an explicit `--project` / `--branch` |
53
+ | `archme daemon <sub>` | `start` · `stop` · `restart` · `status` · `logs` · `enable` · `disable` · `install` · `uninstall` · `run` |
54
+ | `archme analyze <sub>` | Tree-sitter code analysis: `outline` · `repo` · `diff` · `match` · `prefetch` |
55
+ | `archme login` / `archme logout` | Authenticate this machine against ArchMe |
56
+
57
+ Every command takes `--help`. Useful flags:
58
+
59
+ - `archme init --skip-scan` — wire up the repo without scanning; `--force`
60
+ re-scans a project that already has an architecture; `--yes` runs unattended
61
+ (scans are interactive by default, so you can steer them as they go).
62
+ - `archme daemon status` — is it installed, running, and signed in?
63
+ `archme daemon logs -f` follows the log.
64
+ - `archme analyze outline <file>` — JSON symbol outline for one file; `repo`
65
+ outlines everything, `diff <range>` only what a git range touched. Supports
66
+ TypeScript, TSX, JavaScript, Python, Go, Java, Ruby, Rust, Swift, and Kotlin.
67
+ Grammars download on first use to `~/.archme/tools/grammars/`.
68
+
69
+ ### Notes
70
+
71
+ - **Credentials**: stored in the macOS Keychain when available, otherwise
72
+ `~/.archme/credentials.json` (mode `0600`). `keytar` is an *optional*
73
+ dependency — if its native build fails, everything still works via the file
74
+ store.
75
+ - **Configuration**: no env setup needed against archme.io; the CLI never reads
76
+ `.env` files. Self-hosted deployments can override `SUPABASE_URL`,
77
+ `SUPABASE_ANON_KEY`, `ARCHME_DAEMON_CLIENT_ID`, `ARCHME_MCP_BASE_URL`, and
78
+ `CLONE_BASE_DIR` (daemon only, defaults to
79
+ `~/.archme-job-runner/clones`).
80
+ - **Agent methodology** — how an agent scans a repo, anchors components to code,
81
+ and writes architecture updates — is in the `SKILL.md` bundled with this
82
+ package. `archme init` installs it into your repo for you.
83
+
84
+ ## License
85
+
86
+ Proprietary — see the bundled `LICENSE`. Use is granted against the archme.io
87
+ service; bundled open-source components keep their own terms.
package/SKILL.md CHANGED
@@ -237,7 +237,6 @@ own code.
237
237
 
238
238
  ## Where to look
239
239
 
240
- - Spec (this skill's source of truth):
241
- `future-proposals/26-05-12-archme-cli-and-component-anchors.md`
242
- - Tool descriptions live in the MCP server (`supabase/functions/mcp/index.ts`).
243
- - CLI source: `archme-cli/src/analyze/`.
240
+ - Every archme MCP tool documents its own arguments and constraints — list the
241
+ tools and read the description before guessing at a payload shape.
242
+ - `archme <command> --help` documents the CLI side.
package/dist/cli.js CHANGED
@@ -18312,18 +18312,19 @@ async function main(argv) {
18312
18312
  }
18313
18313
  }
18314
18314
  function printHelp() {
18315
- console.log(`archme \u2014 architecture-aware code analysis and daemon
18316
-
18317
- Usage:
18318
- archme init [repo-path] Guided first-time setup (login, project,
18319
- agent config, scan)
18320
- archme daemon <subcommand> Manage the local daemon as a service
18321
- (start|stop|status|logs|restart|enable|
18322
- disable|install|uninstall|run)
18323
- archme analyze <subcommand> Code analysis (outline|repo|diff|match|prefetch)
18324
- archme scan <repo-path> Run a single-pass brownfield scan
18325
- archme login | logout Authenticate with archme
18326
- archme keys list|create|revoke Manage MCP API keys
18315
+ console.log(`archme \u2014 map your codebase into a living architecture diagram
18316
+
18317
+ Start here:
18318
+ cd <your-repo> && archme init Set up this repo and scan it
18319
+ archme daemon start Run the agent that keeps it current
18320
+
18321
+ Other commands:
18322
+ archme daemon <subcommand> Manage the local daemon as a service
18323
+ (start|stop|status|logs|restart|enable|
18324
+ disable|install|uninstall|run)
18325
+ archme analyze <subcommand> Code analysis (outline|repo|diff|match|prefetch)
18326
+ archme scan <repo-path> Single-pass scan into an explicit project/branch
18327
+ archme login | logout Authenticate with archme
18327
18328
 
18328
18329
  Run 'archme init --help', 'archme daemon --help', 'archme analyze --help', or
18329
18330
  'archme scan --help' for subcommand help.`);
package/package.json CHANGED
@@ -1,9 +1,23 @@
1
1
  {
2
2
  "name": "@archme/cli",
3
- "version": "0.4.1",
4
- "description": "archme command-line interface: daemon, analyze, auth, key management",
3
+ "version": "0.4.2",
4
+ "description": "Map your codebase into a living architecture diagram: run `archme init` in a repo to scan it, `archme daemon start` to keep it current on every commit.",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",
7
+ "homepage": "https://archme.io",
8
+ "bugs": {
9
+ "url": "https://archme.io"
10
+ },
11
+ "keywords": [
12
+ "architecture",
13
+ "architecture-diagram",
14
+ "codebase-map",
15
+ "mcp",
16
+ "claude-code",
17
+ "coding-agents",
18
+ "tree-sitter",
19
+ "static-analysis"
20
+ ],
7
21
  "bin": {
8
22
  "archme": "dist/cli.js"
9
23
  },