@brainervirus/workit-pi 8.26.1 → 8.28.0

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/dist/workit.js +140 -89
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![CI](https://github.com/BrainerVirus/workit/actions/workflows/ci.yml/badge.svg)](https://github.com/BrainerVirus/workit/actions/workflows/ci.yml)
4
4
  [![license: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/BrainerVirus/workit/blob/main/LICENSE)
5
5
 
6
- [Workit](https://github.com/BrainerVirus/workit) for Pi (stock 0.85.1): a native extension with the
6
+ [Workit](https://github.com/BrainerVirus/workit) for Pi (stock 1.4.0): a native extension with the
7
7
  seven task families plus read-only `workit_context`, the eleven method
8
8
  skills, session and compaction continuity, and a coordinator that launches
9
9
  fresh reviewer/investigator processes and scoped implementers. Requires
package/dist/workit.js CHANGED
@@ -23839,6 +23839,138 @@ var standingDelta = (input) => {
23839
23839
  }
23840
23840
  };
23841
23841
  var sinceStart = new Map;
23842
+ // packages/workit-core/src/core/role-models.ts
23843
+ var MODEL_ROLES = [
23844
+ "decider",
23845
+ "implementer",
23846
+ "verifier",
23847
+ "reviewer",
23848
+ "explore",
23849
+ "babysit"
23850
+ ];
23851
+ var MODEL_TIERS = ["mundane", "standard", "hard"];
23852
+ var HOST_KEYS = new Set([
23853
+ "claude_code",
23854
+ "opencode",
23855
+ "codex",
23856
+ "codex_cli",
23857
+ "codex_desktop",
23858
+ "cursor",
23859
+ "pi",
23860
+ "default"
23861
+ ]);
23862
+ var BUILT_IN_CLAUDE_CODE = {
23863
+ decider: { model: "fable", effort: "high" },
23864
+ "implementer.hard": { model: "opus" },
23865
+ "implementer.standard": { model: "sonnet" },
23866
+ "implementer.mundane": { model: "haiku" },
23867
+ verifier: { model: "sonnet" },
23868
+ reviewer: { model: "opus" },
23869
+ explore: { model: "haiku" },
23870
+ babysit: { model: "haiku" }
23871
+ };
23872
+ var isObject7 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
23873
+ var name = (value) => typeof value === "string" && value.trim() ? value.trim() : null;
23874
+ var leaf = (value) => {
23875
+ const text = name(value);
23876
+ if (text)
23877
+ return { model: text, effort: null };
23878
+ if (!isObject7(value))
23879
+ return null;
23880
+ const model = name(value.model);
23881
+ return model ? { model, effort: name(value.effort) } : null;
23882
+ };
23883
+ var isFlat = (value) => typeof value === "string" || isObject7(value) && Object.hasOwn(value, "model");
23884
+ var forHost = (value, host) => {
23885
+ if (isFlat(value))
23886
+ return leaf(value);
23887
+ if (!isObject7(value))
23888
+ return null;
23889
+ const family = host ? hostFamily(host) : null;
23890
+ for (const key of [family, host, "default"])
23891
+ if (key && Object.hasOwn(value, key)) {
23892
+ const found = leaf(value[key]);
23893
+ if (found)
23894
+ return found;
23895
+ }
23896
+ return null;
23897
+ };
23898
+ var rolesOf = (models) => isObject7(models) && isObject7(models.roles) ? models.roles : null;
23899
+ var resolveRoleModel = (cwd, selector, host, dir) => {
23900
+ const { role, tier } = selector;
23901
+ for (const source of modelSources(cwd, dir)) {
23902
+ const where = source.global ? "the global default" : `workspace ${source.name}`;
23903
+ const roles = rolesOf(source.models);
23904
+ const configured = roles && Object.hasOwn(roles, role) ? roles[role] : undefined;
23905
+ const fromRoles = role === "implementer" ? tier && isObject7(configured) && Object.hasOwn(configured, tier) ? forHost(configured[tier], host) : null : forHost(configured, host);
23906
+ if (fromRoles)
23907
+ return { ...fromRoles, source: `models.roles in ${where}` };
23908
+ if (role === "implementer" && tier && isObject7(source.tierModels)) {
23909
+ const fromTiers = Object.hasOwn(source.tierModels, tier) ? forHost(source.tierModels[tier], host) : null;
23910
+ if (fromTiers)
23911
+ return { model: fromTiers.model, effort: null, source: `fanout.tierModels in ${where}` };
23912
+ }
23913
+ }
23914
+ if (host && hostFamily(host) === "claude_code") {
23915
+ const builtIn = BUILT_IN_CLAUDE_CODE[tier ? `${role}.${tier}` : role];
23916
+ if (builtIn)
23917
+ return { model: builtIn.model, effort: builtIn.effort ?? null, source: "built-in" };
23918
+ }
23919
+ return null;
23920
+ };
23921
+ var uniformImplementerModel = (cwd, host, dir) => {
23922
+ const tiers = MODEL_TIERS.map((tier) => resolveRoleModel(cwd, { role: "implementer", tier }, host, dir));
23923
+ const [first] = tiers;
23924
+ return first && tiers.every((t) => t?.model === first.model && t.effort === first.effort) ? first : null;
23925
+ };
23926
+ var ROLE_SELECTORS = MODEL_ROLES.flatMap((role) => role === "implementer" ? MODEL_TIERS.map((tier) => ({ role, tier })) : [{ role }]);
23927
+ var roleForAgentType = (agentType, prompt) => {
23928
+ switch (agentType) {
23929
+ case "workit:implementer": {
23930
+ const tier = typeof prompt === "string" ? /^[ \t]*TIER:[ \t]*(mundane|standard|hard)\b/im.exec(prompt)?.[1] : undefined;
23931
+ return { role: "implementer", tier: tier?.toLowerCase() ?? "standard" };
23932
+ }
23933
+ case "workit:verifier":
23934
+ return { role: "verifier" };
23935
+ case "workit:reviewer":
23936
+ return { role: "reviewer" };
23937
+ case "Explore":
23938
+ return { role: "explore" };
23939
+ default:
23940
+ return null;
23941
+ }
23942
+ };
23943
+
23944
+ // packages/workit-core/src/hooks/agent-model.ts
23945
+ var MODELS = new Set(["sonnet", "opus", "haiku", "fable"]);
23946
+ var EFFORTS = new Set(["low", "medium", "high", "xhigh", "max"]);
23947
+ var given = (value) => typeof value === "string" && value.trim() !== "";
23948
+ var agentModelDecision = (cwd, tool, env = process.env) => {
23949
+ if (given(tool.model) || env.CLAUDE_CODE_SUBAGENT_MODEL_FORCE)
23950
+ return { kind: "none" };
23951
+ const selector = roleForAgentType(tool.subagent_type, tool.prompt);
23952
+ if (!selector)
23953
+ return { kind: "none" };
23954
+ const resolved = resolveRoleModel(cwd, selector, "claude_code");
23955
+ if (!resolved)
23956
+ return { kind: "none" };
23957
+ const model = resolved.model.toLowerCase();
23958
+ const effort = resolved.effort?.toLowerCase() ?? null;
23959
+ const input = { ...tool };
23960
+ if (MODELS.has(model))
23961
+ input.model = model;
23962
+ if (effort && EFFORTS.has(effort) && !given(tool.effort))
23963
+ input.effort = effort;
23964
+ if (input.model === undefined && input.effort === tool.effort)
23965
+ return { kind: "none" };
23966
+ const label = selector.tier ? `${selector.role} ${selector.tier}` : selector.role;
23967
+ return {
23968
+ kind: "update-input",
23969
+ input,
23970
+ text: `Workit set ${String(input.model ?? "no model")}${input.effort !== tool.effort ? ` (effort ${String(input.effort)})` : ""} on this ${String(tool.subagent_type)} spawn: role ${label}, ${resolved.source}. Name a model to choose another.`
23971
+ };
23972
+ };
23973
+
23842
23974
  // packages/workit-core/src/hooks/cwd-normalize.ts
23843
23975
  var DIR = String.raw`[A-Za-z0-9_./@%+:,=-]+|'[^'$${"`"}\\\n]*'|"[^"$${"`"}\\!\n]*"`;
23844
23976
  var COMPOUND = new RegExp(String.raw`^\s*cd\s+(${DIR})\s*&&\s*(workit(?:\s[\s\S]*)?)$`, "u");
@@ -24202,7 +24334,7 @@ function handleHook(input, deps) {
24202
24334
  const delta = standingDelta(input);
24203
24335
  if (!delta)
24204
24336
  return decision;
24205
- return decision.kind === "rewrite" ? { ...decision, text: [decision.text, delta].filter(Boolean).join(`
24337
+ return decision.kind === "rewrite" || decision.kind === "update-input" ? { ...decision, text: [decision.text, delta].filter(Boolean).join(`
24206
24338
  `) } : withContextLine(decision, delta);
24207
24339
  }
24208
24340
  function decide(input, deps) {
@@ -24315,6 +24447,8 @@ function decide(input, deps) {
24315
24447
  case "tool.pre":
24316
24448
  if (event.skill)
24317
24449
  recordSkillLoad(input, event.skill, "tool");
24450
+ if (event.agentInput && input.host === "claude_code")
24451
+ return agentModelDecision(input.cwd, event.agentInput);
24318
24452
  return NONE6;
24319
24453
  case "stop":
24320
24454
  return usable2(descriptor.events.stop.support) ? stopDecision(input, descriptor) : NONE6;
@@ -24362,7 +24496,7 @@ if (false) {}
24362
24496
  var PI_DESCRIPTOR = {
24363
24497
  host: "pi",
24364
24498
  label: "Pi",
24365
- verifiedAgainst: "@earendil-works/pi-coding-agent 0.85.1",
24499
+ verifiedAgainst: "@earendil-works/pi-coding-agent 1.4.0",
24366
24500
  docs: ["https://github.com/earendil-works/pi-coding-agent"],
24367
24501
  transport: "in-process-plugin",
24368
24502
  events: {
@@ -24697,92 +24831,6 @@ var cancelHint = (workerId) => `cancel it first: workit_worker {"action":"cancel
24697
24831
  import { spawn as nodeSpawn } from "node:child_process";
24698
24832
  import { randomUUID as randomUUID4 } from "node:crypto";
24699
24833
 
24700
- // packages/workit-core/src/core/role-models.ts
24701
- var MODEL_ROLES = [
24702
- "decider",
24703
- "implementer",
24704
- "verifier",
24705
- "reviewer",
24706
- "explore",
24707
- "babysit"
24708
- ];
24709
- var MODEL_TIERS = ["mundane", "standard", "hard"];
24710
- var HOST_KEYS = new Set([
24711
- "claude_code",
24712
- "opencode",
24713
- "codex",
24714
- "codex_cli",
24715
- "codex_desktop",
24716
- "cursor",
24717
- "pi",
24718
- "default"
24719
- ]);
24720
- var BUILT_IN_CLAUDE_CODE = {
24721
- decider: { model: "fable", effort: "high" },
24722
- "implementer.hard": { model: "opus" },
24723
- "implementer.standard": { model: "sonnet" },
24724
- "implementer.mundane": { model: "haiku" },
24725
- verifier: { model: "sonnet" },
24726
- reviewer: { model: "opus" },
24727
- explore: { model: "haiku" },
24728
- babysit: { model: "haiku" }
24729
- };
24730
- var isObject7 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
24731
- var name = (value) => typeof value === "string" && value.trim() ? value.trim() : null;
24732
- var leaf = (value) => {
24733
- const text = name(value);
24734
- if (text)
24735
- return { model: text, effort: null };
24736
- if (!isObject7(value))
24737
- return null;
24738
- const model = name(value.model);
24739
- return model ? { model, effort: name(value.effort) } : null;
24740
- };
24741
- var isFlat = (value) => typeof value === "string" || isObject7(value) && Object.hasOwn(value, "model");
24742
- var forHost = (value, host) => {
24743
- if (isFlat(value))
24744
- return leaf(value);
24745
- if (!isObject7(value))
24746
- return null;
24747
- const family = host ? hostFamily(host) : null;
24748
- for (const key of [family, host, "default"])
24749
- if (key && Object.hasOwn(value, key)) {
24750
- const found = leaf(value[key]);
24751
- if (found)
24752
- return found;
24753
- }
24754
- return null;
24755
- };
24756
- var rolesOf = (models) => isObject7(models) && isObject7(models.roles) ? models.roles : null;
24757
- var resolveRoleModel = (cwd, selector, host, dir) => {
24758
- const { role, tier } = selector;
24759
- for (const source of modelSources(cwd, dir)) {
24760
- const where = source.global ? "the global default" : `workspace ${source.name}`;
24761
- const roles = rolesOf(source.models);
24762
- const configured = roles && Object.hasOwn(roles, role) ? roles[role] : undefined;
24763
- const fromRoles = role === "implementer" ? tier && isObject7(configured) && Object.hasOwn(configured, tier) ? forHost(configured[tier], host) : null : forHost(configured, host);
24764
- if (fromRoles)
24765
- return { ...fromRoles, source: `models.roles in ${where}` };
24766
- if (role === "implementer" && tier && isObject7(source.tierModels)) {
24767
- const fromTiers = Object.hasOwn(source.tierModels, tier) ? forHost(source.tierModels[tier], host) : null;
24768
- if (fromTiers)
24769
- return { model: fromTiers.model, effort: null, source: `fanout.tierModels in ${where}` };
24770
- }
24771
- }
24772
- if (host && hostFamily(host) === "claude_code") {
24773
- const builtIn = BUILT_IN_CLAUDE_CODE[tier ? `${role}.${tier}` : role];
24774
- if (builtIn)
24775
- return { model: builtIn.model, effort: builtIn.effort ?? null, source: "built-in" };
24776
- }
24777
- return null;
24778
- };
24779
- var uniformImplementerModel = (cwd, host, dir) => {
24780
- const tiers = MODEL_TIERS.map((tier) => resolveRoleModel(cwd, { role: "implementer", tier }, host, dir));
24781
- const [first] = tiers;
24782
- return first && tiers.every((t) => t?.model === first.model && t.effort === first.effort) ? first : null;
24783
- };
24784
- var ROLE_SELECTORS = MODEL_ROLES.flatMap((role) => role === "implementer" ? MODEL_TIERS.map((tier) => ({ role, tier })) : [{ role }]);
24785
-
24786
24834
  // packages/workit-pi/src/worker-protocol.ts
24787
24835
  var MAX_WORKER_LINE_BYTES = 64 * 1024;
24788
24836
  var MAX_WORKER_STDERR_BYTES = 64 * 1024;
@@ -25615,7 +25663,8 @@ function extension(pi) {
25615
25663
  handler: async (args) => {
25616
25664
  const extra = String(args ?? "").trim();
25617
25665
  pi.sendUserMessage(`/skill:${skill}${extra ? ` ${extra}` : ""}`, {
25618
- expandPromptTemplates: true
25666
+ expandPromptTemplates: true,
25667
+ deliverAs: "followUp"
25619
25668
  });
25620
25669
  }
25621
25670
  });
@@ -25631,6 +25680,8 @@ function extension(pi) {
25631
25680
  reconcileLostWorkers(ctx);
25632
25681
  });
25633
25682
  pi.on("before_agent_start", (event, ctx) => {
25683
+ if (event.messageType !== "user")
25684
+ return;
25634
25685
  const nudge = skillPromptNudge(event.prompt, ctx);
25635
25686
  const id = ctx.sessionManager.getSessionId();
25636
25687
  const trusted = ctx.isProjectTrusted();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-pi",
3
- "version": "8.26.1",
3
+ "version": "8.28.0",
4
4
  "description": "Workit native extension for Pi — tools, method skills, and session continuity",
5
5
  "keywords": [
6
6
  "agentic-coding",
@@ -31,10 +31,10 @@
31
31
  "build": "bun scripts/build.ts"
32
32
  },
33
33
  "devDependencies": {
34
- "@earendil-works/pi-coding-agent": "0.85.1"
34
+ "@earendil-works/pi-coding-agent": "1.4.0"
35
35
  },
36
36
  "peerDependencies": {
37
- "@earendil-works/pi-coding-agent": "^0.85.1"
37
+ "@earendil-works/pi-coding-agent": "^1.4.0"
38
38
  },
39
39
  "engines": {
40
40
  "node": ">=24"