pier-setup 0.1.5 → 0.2.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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/install.mjs +65 -16
  3. package/package.json +5 -2
package/README.md CHANGED
@@ -29,7 +29,7 @@ pier ships as **two halves**, installed separately:
29
29
  - **Soft write-locks**: per-pane lock tokens on write paths; cross-pane conflicts warn or block
30
30
  - **Role profiles**: built-in `master` / `worker-default`; custom roles as `.pi-herdr/roles/<name>.json`; toolset converges per role (deny rules are not bypassable)
31
31
  - **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
32
- - **Focus heat layout**: focused pane grows in place (0.72 target); blocked / ask / working / idle sized by weight; surplus panes collapse to title strips
32
+ - **Isolated worktree subagents (`isolate`)**: heavy parallel writers get a fresh git worktree (branch `pier/<slug>` from your HEAD under `~/.herdr/worktrees/<repo>/`) with commit discipline in the prompt; settlement carries a diff summary (commits since base, files changed, uncommitted count); merge with `git merge --no-ff` and the worktree auto-removes once merged and clean — the branch stays for audit
33
33
  - **Long-task lifecycle (01a03c0d review)**: observation timeout is now an inactivity budget (working slices renew it — healthy >10min tasks are no longer killed); follow_up messages deliver via steer at tool-call gaps (supplementary contracts arrive in seconds, not after the whole run); GC waits for the settlement notice to be delivered before closing panes; takeover detection attributes recent machine injections first; ledger rows carry a `via` tag, closed rows inherit their outcome, zombie running rows are swept on startup; SUBS snapshots are hash-gated. Tunables: `PI_HERDR_SUBAGENT_TIMEOUT_MS` (inactivity seconds), `PI_HERDR_INJECT_GRACE_MS`, `PI_HERDR_OBSERVE_MS`
34
34
  - **Settlement notice folding**: subagent settlements no longer flood back when a long main run ends — they inject at turn gaps, up to 3 shown, the rest folded with pointers
35
35
 
package/install.mjs CHANGED
@@ -8,17 +8,18 @@
8
8
  * node install.mjs update [--dev] [--hmr-dev] [--force] # 更新 = 卸载注册 + 重新安装(重探测路径)
9
9
  *
10
10
  * 模式:
11
- * 用户模式(默认):pi install git:github.com/July24/pier(仓库根 package.json 的 pi 字段)
11
+ * 用户模式(默认):pi install npm:pi-pier
12
12
  * + herdr plugin install July24/pier/packages/pier-workbench --yes
13
- * boot-config.json 写 herdr plugin config-dir(reinstall 不丢)。
13
+ * boot-config.json 写 herdr plugin config-dir;extPath 指向 pi 已安装的
14
+ * pi-pier(~/.pi/agent/npm/...),不是 pier-setup 包内的仓库路径。
14
15
  * --dev 开发模式:pi install <repo>/packages/pier-ext + herdr plugin link <repo>/packages/pier-workbench
15
16
  * (link 目录是活的,改码即生效;update 只重写 boot-config)。
16
- *
17
17
  * 发行规格可用 --pi-spec= / --herdr-spec= 覆盖(npm 发布或 fork 场景)。
18
18
  * 失败语义:每步给出手动等价命令;步骤失败不阻断报告(exitCode=1)。
19
19
  */
20
20
  import { execFileSync } from 'node:child_process';
21
21
  import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
22
+ import { homedir } from 'node:os';
22
23
  import { dirname, join, resolve } from 'node:path';
23
24
  import { fileURLToPath } from 'node:url';
24
25
 
@@ -121,14 +122,70 @@ function probePiRuntime() {
121
122
  return null;
122
123
  }
123
124
 
125
+ function piAgentDir() {
126
+ return process.env.PI_CODING_AGENT_DIR || join(homedir(), '.pi', 'agent');
127
+ }
128
+
129
+ function npmNameFromSpec(spec) {
130
+ if (!spec.startsWith('npm:')) return null;
131
+ const rest = spec.slice(4);
132
+ if (rest.startsWith('@')) {
133
+ const slash = rest.indexOf('/');
134
+ if (slash < 0) return rest;
135
+ return `${rest.slice(0, slash)}/${rest.slice(slash + 1).split('@')[0]}`;
136
+ }
137
+ return rest.split('@')[0];
138
+ }
139
+
140
+ function extPathFromPiList() {
141
+ let out;
142
+ try { out = run('pi', ['list']); } catch { return null; }
143
+ const lines = out.split(/\r?\n/);
144
+ for (let i = 0; i < lines.length; i++) {
145
+ const spec = lines[i].trim();
146
+ const loc = lines[i + 1]?.trim();
147
+ if (!loc) continue;
148
+ if (!/pi-pier|pier-ext|july24\/pier/i.test(spec)) continue;
149
+ for (const c of [join(loc, 'src', 'index.ts'), join(loc, 'packages', 'pier-ext', 'src', 'index.ts')]) {
150
+ if (existsSync(c)) return c;
151
+ }
152
+ }
153
+ return null;
154
+ }
155
+
156
+ /** User-mode extPath: pi's installed package, never the pier-setup npx cache. */
157
+ function resolveUserExtPath() {
158
+ const candidates = [];
159
+ const npmName = npmNameFromSpec(PI_SPEC);
160
+ if (npmName) candidates.push(join(piAgentDir(), 'npm', 'node_modules', npmName, 'src', 'index.ts'));
161
+ if (PI_SPEC.startsWith('git:')) {
162
+ const hostPath = PI_SPEC.slice(4).replace(/^git@/, '').replace(/:/g, '/');
163
+ candidates.push(
164
+ join(piAgentDir(), 'git', hostPath, 'packages', 'pier-ext', 'src', 'index.ts'),
165
+ join(piAgentDir(), 'git', hostPath, 'src', 'index.ts'),
166
+ );
167
+ }
168
+ candidates.push(
169
+ join(piAgentDir(), 'npm', 'node_modules', 'pi-pier', 'src', 'index.ts'),
170
+ join(piAgentDir(), 'git', 'github.com', 'July24', 'pier', 'packages', 'pier-ext', 'src', 'index.ts'),
171
+ );
172
+ for (const p of candidates) {
173
+ if (p && existsSync(p)) return p;
174
+ }
175
+ return extPathFromPiList();
176
+ }
177
+
124
178
  function writeBootConfig(hmrDev, force) {
125
179
  const probed = probePiRuntime();
126
180
  if (!probed) die('cannot locate pi cli.js (tried: pi shim realpath, npm root -g). Fill boot-config.json manually.');
127
- if (!existsSync(EXT_PATH)) die(`pier-ext entry missing: ${EXT_PATH} (repo layout broken?)`);
128
- // 用户模式 extPath 必须指向 herdr 管理的 checkout 内的扩展(安装 herdr 半区后才知道);
129
- // git 安装布局与本地同构:packages/pier-ext/src/index.ts。
130
- const extPath = dev ? EXT_PATH
131
- : join(herdrManagedRootGuess(), 'packages', 'pier-ext', 'src', 'index.ts');
181
+ let extPath;
182
+ if (dev) {
183
+ if (!existsSync(EXT_PATH)) die(`pier-ext entry missing: ${EXT_PATH} (repo layout broken?)`);
184
+ extPath = EXT_PATH;
185
+ } else {
186
+ extPath = resolveUserExtPath();
187
+ if (!extPath) die(`cannot locate installed pier-ext (npm:pi-pier / git clone). Did \`pi install ${piSource()}\` succeed?`);
188
+ }
132
189
 
133
190
  const config = {
134
191
  mainTabLabel: 'main',
@@ -160,14 +217,6 @@ function writeBootConfig(hmrDev, force) {
160
217
  log(` extPath = ${config.extPath}`);
161
218
  }
162
219
 
163
- /** herdr 管理的插件 checkout 根(GitHub 安装布局:…/plugins/<owner>-<repo>/…)。 */
164
- function herdrManagedRootGuess() {
165
- const dir = herdrConfigDir();
166
- if (!dir) return '';
167
- // config-dir 形如 <plugins-root>/<plugin-id>/config → checkout 在 <plugins-root>/<plugin-id>/
168
- return resolve(dir, '..');
169
- }
170
-
171
220
  /* ── 三命令 ──────────────────────────────────────────────────────── */
172
221
  function install() {
173
222
  const hmrDev = flags.has('--hmr-dev');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pier-setup",
3
- "version": "0.1.5",
3
+ "version": "0.2.1",
4
4
  "description": "One-shot installer for pier: registers the pi-pier extension with pi and the pier.workbench plugin with herdr (install / uninstall / update)",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -32,13 +32,16 @@
32
32
  ],
33
33
  "scripts": {
34
34
  "test": "node --test \"packages/*/test/*.test.ts\"",
35
+ "test:mutation": "stryker run",
35
36
  "prepare": "git config core.hooksPath .githooks"
36
37
  },
37
38
  "devDependencies": {
38
39
  "@deepseek-ai/cordis-plugin-group": "^1.0.1",
39
40
  "@deepseek-ai/cordis-plugin-hmr": "^1.0.16",
40
41
  "@deepseek-ai/cordis-plugin-loader": "^1.0.2",
41
- "@deepseek-ai/cordis-plugin-timer": "^1.1.3"
42
+ "@deepseek-ai/cordis-plugin-timer": "^1.1.3",
43
+ "@stryker-mutator/core": "^10.0.0",
44
+ "@stryker-mutator/typescript-checker": "^10.0.0"
42
45
  },
43
46
  "pi": {
44
47
  "extensions": [