pier-setup 0.3.0 → 0.3.1
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 +13 -23
- package/install.mjs +15 -97
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ pier ships as **two halves**, installed separately:
|
|
|
19
19
|
| Half | Package | Role |
|
|
20
20
|
|---|---|---|
|
|
21
21
|
| **pi extension** | `packages/pier-ext` (npm: [`pi-pier`](https://www.npmjs.com/package/pi-pier), [pi.dev gallery](https://pi.dev/packages/pi-pier)) | Injects `todo_write` / `subagent` / `terminal` / `ask_user_question` tools into a pi session, and reports pane state over the herdr socket API |
|
|
22
|
-
| **herdr plugin** | `packages/pier-workbench` (`pier.workbench`) |
|
|
22
|
+
| **herdr plugin** | `packages/pier-workbench` (`pier.workbench`) | Blocked human-gate notifications, focus heat layout (focused pane grows in place), ops dashboard + sidebar agent view |
|
|
23
23
|
|
|
24
24
|
### Highlights
|
|
25
25
|
|
|
@@ -30,7 +30,7 @@ pier ships as **two halves**, installed separately:
|
|
|
30
30
|
- **Soft write-locks**: per-pane lock beacons on `write`/`edit` paths; cross-pane conflicts warn (default) or block (`PI_HERDR_WRITE_LOCK=1`). The warning lists every holder; `/locks` is the human view of the same table (`herdr agent list` exposes the raw tokens to agents)
|
|
31
31
|
- **Role profiles**: built-in `master` / `worker-default`; custom roles as `.pi-herdr/roles/<name>.json`; toolset converges per role (deny rules are not bypassable)
|
|
32
32
|
- **Human gate**: subagent `ask_user_question` → sidebar blocked marker + notification; manual takeover (ESC-interrupt then typing) is heuristically detected so the master pauses/returns management automatically
|
|
33
|
-
- **Ask picker**:
|
|
33
|
+
- **Ask picker**: every choice question renders through one pier-owned picker in the TUI — single-select (arrows + enter/space pick the highlighted row) and `multi: true` toggle list (checkboxes: space toggles, `a` toggles all, live selection count) share the same framed chrome, `recommended` seeds the cursor (and pre-checks in multi), and the free-text row stays last; `allowOther: false` gives pure choice. The host select dialog and typed-index prompts remain the fallbacks for RPC mode and older pi
|
|
34
34
|
- **Blocking dialogs mark the pane**: pi's `ui_prompt_start` / `ui_prompt_end` events cover the inherently blocking `ctx.ui` dialogs (`select` / `confirm` / `input` / `editor`), so a dialog from *any* extension marks the pane blocked and emits the `herdr:blocked` edge; nested gates coalesce, and the ask tool no longer needs its 5s refresh heartbeat. `custom` is deliberately excluded — pi routes resident overlays through it too (pier's own slim-frame overlay never calls `done()`), which used to leave a working pane marked blocked for the whole session
|
|
35
35
|
- **Role gate stops early**: a denied worker tool call returns `terminate`, so a batch whose results are all terminating ends without another model round trip
|
|
36
36
|
- **Transcript cards**: pier's own session entries (todo edits, subagent/terminal registries, role manifests, soft approvals) and its reminder messages render as compact cards instead of raw JSON — entry/message renderers, no pi-tui dependency
|
|
@@ -45,7 +45,7 @@ pier ships as **two halves**, installed separately:
|
|
|
45
45
|
### Requirements
|
|
46
46
|
|
|
47
47
|
- Node ≥ 22
|
|
48
|
-
- pi ≥ 0.
|
|
48
|
+
- pi ≥ 0.86.0 (`@earendil-works/pi-coding-agent`) — dynamic toolset (transcript-backed `setActiveTools` deltas) and role switching require it
|
|
49
49
|
- herdr ≥ 0.9.0 (macOS / Linux / Windows; Windows is preview beta)
|
|
50
50
|
|
|
51
51
|
### One-shot install (recommended)
|
|
@@ -56,7 +56,7 @@ No clone needed — run the npm package directly:
|
|
|
56
56
|
npx pier-setup@latest # user mode: pi install npm:pi-pier + herdr plugin install
|
|
57
57
|
npx pier-setup@latest version # local vs npm latest (installer / pi-pier / herdr plugin)
|
|
58
58
|
npx pier-setup@latest update # refresh both halves in place (does not uninstall first)
|
|
59
|
-
npx pier-setup@latest uninstall
|
|
59
|
+
npx pier-setup@latest uninstall
|
|
60
60
|
|
|
61
61
|
npm i -g pier-setup # or install globally, then: pier-setup / version / update
|
|
62
62
|
```
|
|
@@ -70,15 +70,13 @@ Dev mode still requires cloning the repo:
|
|
|
70
70
|
git clone https://github.com/July24/pier && cd pier
|
|
71
71
|
node install.mjs install --dev # local-path pi install + herdr plugin link; code changes are live
|
|
72
72
|
node install.mjs version --dev
|
|
73
|
-
node install.mjs update --dev #
|
|
73
|
+
node install.mjs update --dev # re-check env + versions; pull the repo yourself
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
The script verifies the environment (node / pi / herdr versions)
|
|
77
|
-
and cli.js absolute paths, generates boot-config.json (user mode stores it in the
|
|
78
|
-
herdr plugin config dir, so reinstalls don't lose it), and registers both halves.
|
|
76
|
+
The script verifies the environment (node / pi / herdr versions) and registers both halves.
|
|
79
77
|
|
|
80
78
|
`update` re-runs `pi update npm:pi-pier` (falls back to `pi install`) and
|
|
81
|
-
`herdr plugin install … --yes
|
|
79
|
+
`herdr plugin install … --yes`. Override sources with
|
|
82
80
|
`--pi-spec=` / `--herdr-spec=` (npm publishing or forks). `pier-setup --help`
|
|
83
81
|
lists every command.
|
|
84
82
|
|
|
@@ -131,15 +129,7 @@ pi overwrites tools/commands by name; event listeners stack. Two todo or subagen
|
|
|
131
129
|
**Designed coexistence:** herdr’s official `herdr:pi` reporter. Keep it. pier emits `herdr:blocked` so that plugin remains lifecycle authority.
|
|
132
130
|
|
|
133
131
|
- **other agents inside herdr (claude code / codex etc.)**: tabs without a pi pane
|
|
134
|
-
are excluded from heat reflow; blocked notifications are pi-only
|
|
135
|
-
auto-bootstrap can be disabled with `autoBootstrap: false` in boot-config.
|
|
136
|
-
|
|
137
|
-
### Bootstrap config (workbench half)
|
|
138
|
-
|
|
139
|
-
Master-tab bootstrap needs local node / pi paths: `pier-setup` generates
|
|
140
|
-
them automatically; manually, copy `packages/pier-workbench/scripts/boot-config.example.json`
|
|
141
|
-
(placeholders for both macOS and Windows). User mode reads it from
|
|
142
|
-
`herdr plugin config-dir pier.workbench`; dev mode from `packages/pier-workbench/scripts/boot-config.json`.
|
|
132
|
+
are excluded from heat reflow; blocked notifications are pi-only.
|
|
143
133
|
|
|
144
134
|
### Usage
|
|
145
135
|
|
|
@@ -153,7 +143,7 @@ them automatically; manually, copy `packages/pier-workbench/scripts/boot-config.
|
|
|
153
143
|
```
|
|
154
144
|
packages/
|
|
155
145
|
pier-ext/ # pi extension (npm: pi-pier): todo/subagent tools, herdr client, vocab authority, skill
|
|
156
|
-
pier-workbench/ # herdr plugin (pier.workbench):
|
|
146
|
+
pier-workbench/ # herdr plugin (pier.workbench): blocked notify + heat layout + ops dashboard
|
|
157
147
|
docs/ # install guide, configuration overview, role profile docs, sidebar role config
|
|
158
148
|
```
|
|
159
149
|
|
|
@@ -161,7 +151,7 @@ docs/ # install guide, configuration overview, role profile docs, s
|
|
|
161
151
|
|
|
162
152
|
```sh
|
|
163
153
|
npm install --ignore-scripts
|
|
164
|
-
npm test # node --test,
|
|
154
|
+
npm test # node --test, 733 unit tests (planner / todo replay / anti-freeze staleness / session tail / GC / lifecycle / renderers / ask picker / subagent output / jev decision layer: diagnostic gate, notice ranking, excerpt windows)
|
|
165
155
|
```
|
|
166
156
|
|
|
167
157
|
## Configuration
|
|
@@ -218,10 +208,10 @@ PI_HERDR_OBS_PACK_ENABLE=1 PI_HERDR_OBS_PACK_LOG=1 pi # start here
|
|
|
218
208
|
|
|
219
209
|
Full quick start, what to watch in `efficiency-logs/*.jsonl`, rollback steps and a feedback template: **[docs/efficiency-trial.md](docs/efficiency-trial.md)**.
|
|
220
210
|
|
|
221
|
-
Everything above (plus roles, pi settings
|
|
211
|
+
Everything above (plus roles, pi settings and the `PIER_*`/`PI_HERDR_*` env knobs) is also inspectable in-session:
|
|
222
212
|
|
|
223
213
|
```text
|
|
224
|
-
/pier-config #
|
|
214
|
+
/pier-config # 4-plane index; hands a guided change to the agent
|
|
225
215
|
/pier-config show all # effective value + source (env > workspace > user > default) per key
|
|
226
216
|
/pier-config check # validation across planes · /pier-config doc → written report
|
|
227
217
|
```
|
|
@@ -241,6 +231,6 @@ MIT
|
|
|
241
231
|
|
|
242
232
|
---
|
|
243
233
|
|
|
244
|
-
> 💡 **For contributors**: `.gitignore` is tracked in the repository.
|
|
234
|
+
> 💡 **For contributors**: `.gitignore` is tracked in the repository. `docs/research/` contains local research notes ignored by `.gitignore`.
|
|
245
235
|
>
|
|
246
236
|
> **Naming convention**: the brand is **pier** (repo/packages/plugin); runtime protocol identifiers keep the **`pi-herdr`** prefix (`.pi-herdr/roles/` dir, `pi-herdr.subs` session custom entries, `~/.pi/agent/herdr-pi/roles/` user dir) — they persist with user sessions/config files, renaming would break existing data, so they are the compatibility layer.
|
package/install.mjs
CHANGED
|
@@ -3,25 +3,23 @@
|
|
|
3
3
|
* pier one-shot installer / uninstaller / updater / version inspector (cross-platform: macOS / Linux / Windows).
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
|
-
* node install.mjs install [--dev]
|
|
7
|
-
* node install.mjs update [--dev]
|
|
8
|
-
* node install.mjs version [--json]
|
|
9
|
-
* node install.mjs uninstall [--dev]
|
|
6
|
+
* node install.mjs install [--dev] # Install (default command, 'install' can be omitted)
|
|
7
|
+
* node install.mjs update [--dev] # Refresh both halves in place to latest release (no prior uninstall)
|
|
8
|
+
* node install.mjs version [--json] # Local vs npm latest
|
|
9
|
+
* node install.mjs uninstall [--dev] # Uninstall both halves
|
|
10
10
|
* node install.mjs --prepare # npm prepare: hooksPath + repo root bin link
|
|
11
11
|
* node install.mjs --help
|
|
12
12
|
*
|
|
13
13
|
* Modes:
|
|
14
14
|
* User mode (default): pi install npm:pi-pier
|
|
15
15
|
* + herdr plugin install July24/pier/packages/pier-workbench --yes
|
|
16
|
-
* boot-config.json written to herdr plugin config-dir; extPath points to pi-installed
|
|
17
|
-
* pi-pier (~/.pi/agent/npm/...), not the repo path inside pier-setup package.
|
|
18
16
|
* --dev Development mode: pi install <repo>/packages/pier-ext + herdr plugin link <repo>/packages/pier-workbench
|
|
19
|
-
* (linked directory is live; code edits take effect immediately
|
|
17
|
+
* (linked directory is live; code edits take effect immediately).
|
|
20
18
|
* Distribution specs can be overridden via --pi-spec= / --herdr-spec= (for npm publish or fork scenarios).
|
|
21
19
|
* Failure semantics: Each step provides manual equivalent command; step failure does not abort reporting (exitCode=1).
|
|
22
20
|
*/
|
|
23
21
|
import { execFileSync } from 'node:child_process';
|
|
24
|
-
import { chmodSync, existsSync, mkdirSync, readFileSync,
|
|
22
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
|
|
25
23
|
import { homedir } from 'node:os';
|
|
26
24
|
import { dirname, join, resolve } from 'node:path';
|
|
27
25
|
import { fileURLToPath } from 'node:url';
|
|
@@ -29,7 +27,6 @@ import { fileURLToPath } from 'node:url';
|
|
|
29
27
|
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)));
|
|
30
28
|
const EXT_DIR = join(ROOT, 'packages', 'pier-ext');
|
|
31
29
|
const WB_DIR = join(ROOT, 'packages', 'pier-workbench');
|
|
32
|
-
const DEV_BOOT_CONFIG = join(WB_DIR, 'scripts', 'boot-config.json');
|
|
33
30
|
const EXT_PATH = join(EXT_DIR, 'src', 'index.ts');
|
|
34
31
|
const IS_WIN = process.platform === 'win32';
|
|
35
32
|
const COMMANDS = ['install', 'uninstall', 'update', 'version', 'help'];
|
|
@@ -141,10 +138,6 @@ function npmLatest(name) {
|
|
|
141
138
|
}
|
|
142
139
|
}
|
|
143
140
|
|
|
144
|
-
/** Herdr plugin config directory (boot-config destination in user mode; semantic path exists once plugin is registered). */
|
|
145
|
-
function herdrConfigDir() {
|
|
146
|
-
try { return run('herdr', ['plugin', 'config-dir', 'pier.workbench']); } catch { return null; }
|
|
147
|
-
}
|
|
148
141
|
|
|
149
142
|
/* ── Environment check (pre-install) ────────────────────────────────── */
|
|
150
143
|
function checkEnv() {
|
|
@@ -152,8 +145,8 @@ function checkEnv() {
|
|
|
152
145
|
if (major < 22) die(`node ≥ 22 required, found ${process.versions.node}`);
|
|
153
146
|
log(`✓ node ${process.versions.node}`);
|
|
154
147
|
const piVersion = (() => { try { return parseVersion(run('pi', ['--version'])); } catch { return null; } })();
|
|
155
|
-
if (!piVersion || !geVersion(piVersion, [0,
|
|
156
|
-
die(`pi ≥ 0.
|
|
148
|
+
if (!piVersion || !geVersion(piVersion, [0, 86, 0])) {
|
|
149
|
+
die(`pi ≥ 0.86.0 required${piVersion ? `, found ${piVersion.join('.')}` : ' (pi not found or not runnable)'}. Install: npm i -g @earendil-works/pi-coding-agent`);
|
|
157
150
|
}
|
|
158
151
|
log(`✓ pi ${piVersion.join('.')}`);
|
|
159
152
|
const herdrVersion = (() => { try { return parseVersion(run('herdr', ['--version'])); } catch { return null; } })();
|
|
@@ -167,26 +160,6 @@ function checkEnv() {
|
|
|
167
160
|
/** pi extension source: user mode uses git/npm spec, dev mode uses local directory. */
|
|
168
161
|
const piSource = () => (dev ? EXT_DIR : PI_SPEC);
|
|
169
162
|
|
|
170
|
-
/* ── boot-config detection and writing ────────────────────────────── */
|
|
171
|
-
function probePiRuntime() {
|
|
172
|
-
const piBin = which('pi');
|
|
173
|
-
// bin is a node shim: realpath resolves to .../pi-coding-agent/dist/cli.js (npm layout, isomorphic win/posix)
|
|
174
|
-
if (piBin) {
|
|
175
|
-
try {
|
|
176
|
-
const real = realpathSync(piBin);
|
|
177
|
-
if (real.endsWith('cli.js') && existsSync(real)) {
|
|
178
|
-
return { piCli: real, piNode: process.execPath };
|
|
179
|
-
}
|
|
180
|
-
} catch { /* fall back to fallback */ }
|
|
181
|
-
}
|
|
182
|
-
// npm root -g fallback: when pi is not in PATH (e.g. nvm shim), construct from global npm layout
|
|
183
|
-
try {
|
|
184
|
-
const gRoot = run('npm', ['root', '-g']);
|
|
185
|
-
const cand = join(gRoot, '@earendil-works', 'pi-coding-agent', 'dist', 'cli.js');
|
|
186
|
-
if (existsSync(cand)) return { piCli: cand, piNode: process.execPath };
|
|
187
|
-
} catch { /* npm unavailable */ }
|
|
188
|
-
return null;
|
|
189
|
-
}
|
|
190
163
|
|
|
191
164
|
function piAgentDir() {
|
|
192
165
|
return process.env.PI_CODING_AGENT_DIR || join(homedir(), '.pi', 'agent');
|
|
@@ -260,47 +233,6 @@ function resolveUserExtPath() {
|
|
|
260
233
|
return extPathFromPiList();
|
|
261
234
|
}
|
|
262
235
|
|
|
263
|
-
function writeBootConfig(hmrDev, force) {
|
|
264
|
-
const probed = probePiRuntime();
|
|
265
|
-
if (!probed) die('cannot locate pi cli.js (tried: pi shim realpath, npm root -g). Fill boot-config.json manually.');
|
|
266
|
-
let extPath;
|
|
267
|
-
if (dev) {
|
|
268
|
-
if (!existsSync(EXT_PATH)) die(`pier-ext entry missing: ${EXT_PATH} (repo layout broken?)`);
|
|
269
|
-
extPath = EXT_PATH;
|
|
270
|
-
} else {
|
|
271
|
-
extPath = resolveUserExtPath();
|
|
272
|
-
if (!extPath) die(`cannot locate installed pier-ext (npm:pi-pier / git clone). Did \`pi install ${piSource()}\` succeed?`);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
const config = {
|
|
276
|
-
mainTabLabel: 'main',
|
|
277
|
-
piNode: probed.piNode,
|
|
278
|
-
piCli: probed.piCli,
|
|
279
|
-
extPath,
|
|
280
|
-
workbenchPluginId: 'pier.workbench',
|
|
281
|
-
hmrDev,
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
const target = dev ? DEV_BOOT_CONFIG : join(herdrConfigDir() ?? die('cannot resolve herdr plugin config-dir (is pier.workbench installed?)'), 'boot-config.json');
|
|
285
|
-
if (existsSync(target) && !force) {
|
|
286
|
-
let existing = null;
|
|
287
|
-
try { existing = JSON.parse(readFileSync(target, 'utf8')); } catch { /* treated as corrupted */ }
|
|
288
|
-
if (existing) {
|
|
289
|
-
log(`• ${target} exists, diff (existing → new):`);
|
|
290
|
-
for (const k of Object.keys(config)) {
|
|
291
|
-
if (existing[k] !== config[k]) log(` ${k}: ${JSON.stringify(existing[k])} → ${JSON.stringify(config[k])}`);
|
|
292
|
-
}
|
|
293
|
-
log(' kept existing (use --force to overwrite)');
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
mkdirSync(dirname(target), { recursive: true });
|
|
298
|
-
writeFileSync(target, JSON.stringify(config, null, 2) + '\n');
|
|
299
|
-
log(`✓ boot-config.json ${force ? 'overwritten (--force)' : 'written'} → ${target}`);
|
|
300
|
-
log(` piNode = ${config.piNode}`);
|
|
301
|
-
log(` piCli = ${config.piCli}`);
|
|
302
|
-
log(` extPath = ${config.extPath}`);
|
|
303
|
-
}
|
|
304
236
|
|
|
305
237
|
function pkgDirFromExtPath(extPath) {
|
|
306
238
|
let d = dirname(extPath);
|
|
@@ -344,17 +276,17 @@ function usage() {
|
|
|
344
276
|
log(`pier-setup — install / update / inspect pier (pi-pier + pier.workbench)
|
|
345
277
|
|
|
346
278
|
Usage:
|
|
347
|
-
pier-setup [install] [--dev]
|
|
348
|
-
pier-setup update [--dev]
|
|
279
|
+
pier-setup [install] [--dev]
|
|
280
|
+
pier-setup update [--dev]
|
|
349
281
|
pier-setup version [--json]
|
|
350
|
-
pier-setup uninstall [--dev]
|
|
282
|
+
pier-setup uninstall [--dev]
|
|
351
283
|
|
|
352
284
|
npx pier-setup@latest # recommended user install
|
|
353
285
|
npx pier-setup@latest update # refresh both halves to newest release
|
|
354
286
|
npx pier-setup@latest version # local vs npm latest
|
|
355
287
|
|
|
356
288
|
--pi-spec= / --herdr-spec= override distribution sources
|
|
357
|
-
--dev local link (clone);
|
|
289
|
+
--dev local link (clone); the linked directories are live`);
|
|
358
290
|
}
|
|
359
291
|
|
|
360
292
|
function version() {
|
|
@@ -390,25 +322,20 @@ function update() {
|
|
|
390
322
|
if (latestSetup && me && cmpSemver(me, latestSetup) < 0) {
|
|
391
323
|
log(`⚠ installer ${me} < latest ${latestSetup} — re-run: npx pier-setup@latest update`);
|
|
392
324
|
}
|
|
393
|
-
const hmrDev = flags.has('--hmr-dev');
|
|
394
325
|
if (dev) {
|
|
395
|
-
log('dev mode: local link is live; pull the repo yourself
|
|
396
|
-
writeBootConfig(hmrDev, true);
|
|
326
|
+
log('dev mode: local link is live; pull the repo yourself (no installer-managed files to refresh).');
|
|
397
327
|
} else {
|
|
398
328
|
if (tryRun('pi', ['update', piSource()])) log(`✓ pi extension updated (${piSource()})`);
|
|
399
329
|
else if (tryRun('pi', ['install', piSource()])) log(`✓ pi extension installed (${piSource()})`);
|
|
400
330
|
else { console.error('✗ pi update/install failed'); log(` manual: pi update ${piSource()}`); process.exitCode = 1; }
|
|
401
331
|
if (tryRun('herdr', ['plugin', 'install', HERDR_SPEC, '--yes'])) log(`✓ herdr plugin updated (${HERDR_SPEC})`);
|
|
402
332
|
else { console.error('✗ herdr plugin update failed'); log(` manual: herdr plugin install ${HERDR_SPEC} --yes`); process.exitCode = 1; }
|
|
403
|
-
writeBootConfig(hmrDev, true);
|
|
404
333
|
}
|
|
405
334
|
log('');
|
|
406
335
|
version();
|
|
407
336
|
}
|
|
408
337
|
|
|
409
338
|
function install() {
|
|
410
|
-
const hmrDev = flags.has('--hmr-dev');
|
|
411
|
-
const force = flags.has('--force');
|
|
412
339
|
checkEnv();
|
|
413
340
|
removeLegacyGitRegistration();
|
|
414
341
|
|
|
@@ -417,40 +344,31 @@ function install() {
|
|
|
417
344
|
else { console.error('✗ pi install failed'); log(` manual: pi install ${EXT_DIR}`); process.exitCode = 1; }
|
|
418
345
|
if (tryRun('herdr', ['plugin', 'link', WB_DIR])) log('✓ herdr plugin linked (packages/pier-workbench, local)');
|
|
419
346
|
else { console.error('✗ herdr plugin link failed'); log(` manual: herdr plugin link ${WB_DIR}`); process.exitCode = 1; }
|
|
420
|
-
writeBootConfig(hmrDev, force);
|
|
421
347
|
} else {
|
|
422
348
|
if (tryRun('pi', ['install', piSource()])) log(`✓ pi extension installed (${PI_SPEC})`);
|
|
423
349
|
else { console.error('✗ pi install failed'); log(` manual: pi install ${PI_SPEC}`); process.exitCode = 1; }
|
|
424
350
|
if (tryRun('herdr', ['plugin', 'install', HERDR_SPEC, '--yes'])) log(`✓ herdr plugin installed (${HERDR_SPEC})`);
|
|
425
351
|
else { console.error('✗ herdr plugin install failed'); log(` manual: herdr plugin install ${HERDR_SPEC}`); process.exitCode = 1; }
|
|
426
|
-
writeBootConfig(hmrDev, force);
|
|
427
352
|
}
|
|
428
353
|
|
|
429
354
|
log(`
|
|
430
355
|
pier installed (${dev ? 'dev mode: local paths, code changes are live' : 'user mode: managed checkouts'}). Next:
|
|
431
|
-
1. start herdr, open/create a workspace
|
|
356
|
+
1. start herdr, open/create a workspace and run \`pi\` inside a pane
|
|
432
357
|
2. inside pi, ask the model to use todo_write / subagent tools`);
|
|
433
358
|
}
|
|
434
359
|
|
|
435
360
|
function uninstall() {
|
|
436
|
-
const purge = flags.has('--purge');
|
|
437
361
|
if (tryRun('pi', ['remove', piSource()])) log('✓ pi extension removed');
|
|
438
362
|
else { console.error('✗ pi remove failed'); log(` manual: pi remove ${piSource()}`); process.exitCode = 1; }
|
|
439
363
|
|
|
440
364
|
if (dev) {
|
|
441
365
|
if (tryRun('herdr', ['plugin', 'unlink', 'pier.workbench'])) log('✓ herdr plugin unlinked (files kept)');
|
|
442
366
|
else { console.error('✗ herdr plugin unlink failed'); log(' manual: herdr plugin unlink pier.workbench'); process.exitCode = 1; }
|
|
443
|
-
if (purge && existsSync(DEV_BOOT_CONFIG)) { rmSync(DEV_BOOT_CONFIG); log('✓ dev boot-config.json purged'); }
|
|
444
367
|
} else {
|
|
445
368
|
if (tryRun('herdr', ['plugin', 'uninstall', 'pier.workbench'])) log('✓ herdr plugin uninstalled (managed checkout removed)');
|
|
446
369
|
else { console.error('✗ herdr plugin uninstall failed'); log(' manual: herdr plugin uninstall pier.workbench'); process.exitCode = 1; }
|
|
447
|
-
if (purge) {
|
|
448
|
-
const dir = herdrConfigDir();
|
|
449
|
-
const f = dir ? join(dir, 'boot-config.json') : null;
|
|
450
|
-
if (f && existsSync(f)) { rmSync(f); log('✓ boot-config.json purged'); }
|
|
451
|
-
}
|
|
452
370
|
}
|
|
453
|
-
log(
|
|
371
|
+
log('\npier uninstalled.');
|
|
454
372
|
}
|
|
455
373
|
|
|
456
374
|
if (command === 'help' || flags.has('--help') || flags.has('-h')) usage();
|