@senomas/pi-git-hat 0.2.0 → 0.2.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.
package/git-hat.ts CHANGED
@@ -60,7 +60,7 @@ interface RolesConfig {
60
60
  defaultRole?: string;
61
61
  fileDir?: string;
62
62
  caseInsensitive?: boolean;
63
- redetectOnInput?: boolean;
63
+
64
64
  postSwitchLog?: boolean;
65
65
  }
66
66
 
@@ -68,7 +68,7 @@ interface MergedConfig {
68
68
  roles: Record<string, RoleDef>;
69
69
  fileDir: string;
70
70
  caseInsensitive: boolean;
71
- redetectOnInput: boolean;
71
+
72
72
  postSwitchLog: boolean;
73
73
  configFile: string;
74
74
  }
@@ -229,7 +229,7 @@ function loadConfig(): MergedConfig {
229
229
  roles: {},
230
230
  fileDir: ".pi",
231
231
  caseInsensitive: true,
232
- redetectOnInput: true,
232
+
233
233
  postSwitchLog: true,
234
234
  };
235
235
 
@@ -252,7 +252,7 @@ function loadConfig(): MergedConfig {
252
252
  }
253
253
  if (raw.fileDir) merged.fileDir = raw.fileDir;
254
254
  if (raw.caseInsensitive !== undefined) merged.caseInsensitive = raw.caseInsensitive;
255
- if (raw.redetectOnInput !== undefined) merged.redetectOnInput = raw.redetectOnInput;
255
+
256
256
  if (raw.postSwitchLog !== undefined) merged.postSwitchLog = raw.postSwitchLog;
257
257
  } catch {
258
258
  // ignore parse errors
@@ -497,6 +497,22 @@ You are **ADMIN**. Switching branch does not switch your role.
497
497
  - Edit \`README.md\` and \`AGENTS.md\`
498
498
  - Explore the codebase (read-only)
499
499
 
500
+ ## What you do NOT do
501
+ - Edit source code
502
+ - Create or modify \`todo/\`, \`plan/\`, \`report/\` files
503
+ - Switch branches (the user handles that)
504
+ `,
505
+
506
+ researcher: `
507
+
508
+ ## Your Role: Researcher
509
+
510
+ You are **RESEARCHER**. Switching branch does not switch your role.
511
+
512
+ ## What you do
513
+ - Research with \`find\` / \`grep\` / \`ls\` / \`web_search\` / \`read\`
514
+ - Write findings to \`docs/*.md\` and root \`*.md\` files
515
+
500
516
  ## What you do NOT do
501
517
  - Edit source code
502
518
  - Create or modify \`todo/\`, \`plan/\`, \`report/\` files
@@ -723,6 +739,7 @@ function roleIcon(role: string): string {
723
739
  if (lower === "implementor") return "\uD83D\uDEE0";
724
740
  if (lower === "reviewer") return "\uD83D\uDD0D";
725
741
  if (lower === "admin") return "\u2699";
742
+ if (lower === "researcher") return "\uD83D\uDD2C";
726
743
  return "\uD83E\uDDE2";
727
744
  }
728
745
 
@@ -1200,18 +1217,14 @@ export default function (pi: ExtensionAPI) {
1200
1217
  });
1201
1218
 
1202
1219
  pi.on("input", async (event, ctx) => {
1203
- if (config.redetectOnInput) {
1204
- await updateRole(ctx);
1205
- }
1220
+ await updateRole(ctx);
1206
1221
  return { action: "continue" };
1207
1222
  });
1208
1223
 
1209
1224
  // -- Re-detect after every turn (catches git checkout/switch) --
1210
1225
 
1211
1226
  pi.on("turn_end", async (_event, ctx) => {
1212
- if (config.redetectOnInput) {
1213
- await updateRole(ctx);
1214
- }
1227
+ await updateRole(ctx);
1215
1228
  });
1216
1229
 
1217
1230
  // -- System prompt injection ----------------------------------
@@ -1312,13 +1325,19 @@ If the user asks you to make changes, tell them to switch to an appropriate bran
1312
1325
  if (isBash) {
1313
1326
  const cmd = ((event.input as { command?: string }).command ?? "").trim();
1314
1327
 
1315
- // Always allow rebase master/main (required to fix ancestry)
1316
- if (/^git\s+rebase\s+(master|main)\b/.test(cmd)) {
1328
+ // Require confirmation for git rebase (any target)
1329
+ if (/\bgit\s+rebase\b/.test(cmd)) {
1330
+ const confirmed = await ctx.ui.confirm(
1331
+ `Rebase onto master? Running: \`${cmd}\``,
1332
+ );
1333
+ if (!confirmed) {
1334
+ return { block: true, reason: "Rebase cancelled by user." };
1335
+ }
1317
1336
  return;
1318
1337
  }
1319
1338
 
1320
1339
  // Require confirmation for git switch/checkout
1321
- if (/^git\s+(switch|checkout)\b/.test(cmd)) {
1340
+ if (/\bgit\s+(switch|checkout)\b/.test(cmd)) {
1322
1341
  const confirmed = await ctx.ui.confirm(
1323
1342
  `Switch branches? Running: \`${cmd}\``,
1324
1343
  );
@@ -1336,15 +1355,16 @@ If the user asks you to make changes, tell them to switch to an appropriate bran
1336
1355
  }
1337
1356
  }
1338
1357
 
1339
- // For known roles: require confirmation for git branch switching
1358
+ // For known roles: require confirmation for git rebase/switch/checkout
1340
1359
  if (isBash) {
1341
1360
  const cmd = ((event.input as { command?: string }).command ?? "").trim();
1342
- if (/^git\s+(switch|checkout)\b/.test(cmd)) {
1361
+ if (/\bgit\s+(rebase|switch|checkout)\b/.test(cmd)) {
1362
+ const action = /rebase/.test(cmd) ? "Rebase" : "Switch";
1343
1363
  const confirmed = await ctx.ui.confirm(
1344
- `Switch branches? Running: \`${cmd}\``,
1364
+ `${action} branches? Running: \`${cmd}\``,
1345
1365
  );
1346
1366
  if (!confirmed) {
1347
- return { block: true, reason: "Branch switch cancelled by user." };
1367
+ return { block: true, reason: `${action} cancelled by user.` };
1348
1368
  }
1349
1369
  return;
1350
1370
  }
@@ -1408,6 +1428,15 @@ If the user asks you to make changes, tell them to switch to an appropriate bran
1408
1428
  };
1409
1429
  }
1410
1430
 
1431
+ // Researcher: docs/ and root *.md only
1432
+ if (lowerRole === "researcher") {
1433
+ if (isInside(path, ["docs"]) || (path.endsWith(".md") && !path.includes("/"))) return;
1434
+ return {
1435
+ block: true,
1436
+ reason: `\uD83D\uDD2C Researcher: can only write to docs/ and root *.md. Blocked: ${rawPath}`,
1437
+ };
1438
+ }
1439
+
1411
1440
  // Custom roles: no hard write restrictions (base-enforce handles it)
1412
1441
  return;
1413
1442
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@senomas/pi-git-hat",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Pi extension for role-based Git branch workflows — wear different hats by switching branches",
5
5
  "type": "module",
6
6
  "keywords": ["pi-package", "git", "workflow", "branching", "roles"],
package/roles/planner.md CHANGED
@@ -6,10 +6,11 @@ You are **PLANNER**. Your sole responsibility is to research (just collecting da
6
6
  ## What you do
7
7
  1. Research with `read` / `grep` / `find` / `ls`
8
8
  2. Create `todo/NN-name.md` with sequenced, actionable items
9
- 3. Present the plan to the user
9
+ 3. Write to `docs/*.md` files (design docs, research notes, architecture decisions)
10
+ 4. Present the plan to the user
10
11
 
11
12
  ## What you do NOT do
12
- - `edit`/`write` any file outside `todo/`
13
+ - `edit`/`write` any file outside `todo/` or `docs/*.md`
13
14
  - Switch branches (the user handles that)
14
15
  - Implement anything (that's the implementor)
15
16
  - Write reports (that's the implementor)
@@ -0,0 +1,12 @@
1
+ # Researcher
2
+
3
+ You are **RESEARCHER**. Switching branch does not switch your role.
4
+
5
+ ## What you do
6
+ - Research with `find` / `grep` / `ls` / `web_search` / `read`
7
+ - Write findings to `docs/*.md` and root `*.md` files
8
+
9
+ ## What you do NOT do
10
+ - Edit source code
11
+ - Create or modify `todo/`, `plan/`, `report/` files
12
+ - Switch branches (the user handles that)
package/roles/roles.json CHANGED
@@ -3,6 +3,7 @@
3
3
  "planner": { "pattern": "^plan(-|/|$)", "description": "Plan work by creating todo/plan files" },
4
4
  "implementor": { "pattern": "^(implementor$|feature|feat|impl$|work$)(-|/|$)", "description": "Feature/impl/work branches" },
5
5
  "reviewer": { "pattern": "^review(-|/|$)", "description": "Review implementations against todos" },
6
- "admin": { "pattern": "^(main|master)$", "description": "Project configuration and docs" }
6
+ "admin": { "pattern": "^(main|master)$", "description": "Project configuration and docs" },
7
+ "researcher": { "pattern": "^research(-|/|$)", "description": "Research topics and document findings" }
7
8
  }
8
9
  }