pi-umbra 0.3.0 → 0.4.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 (99) hide show
  1. package/README.md +3 -4
  2. package/node_modules/@shikijs/cli/dist/cli.d.mts +13 -6
  3. package/node_modules/@shikijs/cli/dist/cli.mjs +32 -27
  4. package/node_modules/@shikijs/cli/dist/{code-to-ansi-BNrZay-4.mjs → code-to-ansi-Dmm_CuZ9.mjs} +15 -7
  5. package/node_modules/@shikijs/cli/dist/index.d.mts +24 -3
  6. package/node_modules/@shikijs/cli/dist/index.mjs +1 -1
  7. package/node_modules/@shikijs/cli/package.json +3 -3
  8. package/node_modules/@shikijs/core/dist/index.d.mts +28 -28
  9. package/node_modules/@shikijs/core/dist/index.mjs +15 -12
  10. package/node_modules/@shikijs/core/package.json +4 -4
  11. package/node_modules/@shikijs/engine-javascript/dist/{engine-compile-Bdn9ihA2.d.mts → engine-compile-CtqiSkRk.d.mts} +5 -0
  12. package/node_modules/@shikijs/engine-javascript/dist/engine-compile.d.mts +1 -1
  13. package/node_modules/@shikijs/engine-javascript/dist/engine-compile.mjs +2 -4
  14. package/node_modules/@shikijs/engine-javascript/dist/engine-raw.d.mts +2 -3
  15. package/node_modules/@shikijs/engine-javascript/dist/engine-raw.mjs +2 -4
  16. package/node_modules/@shikijs/engine-javascript/dist/index.d.mts +1 -1
  17. package/node_modules/@shikijs/engine-javascript/dist/index.mjs +1 -1
  18. package/node_modules/@shikijs/engine-javascript/dist/string-TLTPtCPs.mjs +115 -0
  19. package/node_modules/@shikijs/engine-javascript/package.json +3 -3
  20. package/node_modules/@shikijs/engine-oniguruma/package.json +3 -3
  21. package/node_modules/@shikijs/langs/dist/ada.mjs +1 -1
  22. package/node_modules/@shikijs/langs/dist/ahk.mjs +1 -1
  23. package/node_modules/@shikijs/langs/dist/beancount.mjs +1 -1
  24. package/node_modules/@shikijs/langs/dist/coq.mjs +1 -1
  25. package/node_modules/@shikijs/langs/dist/csharp.mjs +1 -1
  26. package/node_modules/@shikijs/langs/dist/css.mjs +1 -1
  27. package/node_modules/@shikijs/langs/dist/dart.mjs +1 -1
  28. package/node_modules/@shikijs/langs/dist/dotenv.mjs +1 -1
  29. package/node_modules/@shikijs/langs/dist/emacs-lisp.mjs +1 -1
  30. package/node_modules/@shikijs/langs/dist/gn.mjs +1 -1
  31. package/node_modules/@shikijs/langs/dist/handlebars.mjs +1 -1
  32. package/node_modules/@shikijs/langs/dist/julia.mjs +1 -1
  33. package/node_modules/@shikijs/langs/dist/latex.mjs +1 -1
  34. package/node_modules/@shikijs/langs/dist/luau.mjs +1 -1
  35. package/node_modules/@shikijs/langs/dist/marko.mjs +1 -1
  36. package/node_modules/@shikijs/langs/dist/moonbit.mjs +1 -1
  37. package/node_modules/@shikijs/langs/dist/nextflow-groovy.mjs +1 -1
  38. package/node_modules/@shikijs/langs/dist/nextflow.mjs +1 -1
  39. package/node_modules/@shikijs/langs/dist/nushell.mjs +1 -1
  40. package/node_modules/@shikijs/langs/dist/php.mjs +1 -1
  41. package/node_modules/@shikijs/langs/dist/powershell.mjs +1 -1
  42. package/node_modules/@shikijs/langs/dist/ruby.mjs +1 -1
  43. package/node_modules/@shikijs/langs/dist/rust.mjs +1 -1
  44. package/node_modules/@shikijs/langs/dist/sql.mjs +1 -1
  45. package/node_modules/@shikijs/langs/dist/svelte.mjs +1 -1
  46. package/node_modules/@shikijs/langs/dist/twig.mjs +3 -3
  47. package/node_modules/@shikijs/langs/dist/typespec.mjs +1 -1
  48. package/node_modules/@shikijs/langs/package.json +3 -3
  49. package/node_modules/@shikijs/primitive/dist/index.d.mts +31 -32
  50. package/node_modules/@shikijs/primitive/dist/index.mjs +2 -1
  51. package/node_modules/@shikijs/primitive/package.json +3 -3
  52. package/node_modules/@shikijs/themes/dist/monokai.mjs +1 -1
  53. package/node_modules/@shikijs/themes/dist/one-dark-pro.mjs +1 -1
  54. package/node_modules/@shikijs/themes/dist/red.mjs +1 -1
  55. package/node_modules/@shikijs/themes/dist/solarized-dark.mjs +1 -1
  56. package/node_modules/@shikijs/themes/dist/solarized-light.mjs +1 -1
  57. package/node_modules/@shikijs/themes/package.json +3 -3
  58. package/node_modules/@shikijs/types/dist/index.d.mts +76 -76
  59. package/node_modules/@shikijs/types/package.json +1 -1
  60. package/node_modules/pi-umbra-copy-chat/README.md +4 -7
  61. package/node_modules/pi-umbra-copy-chat/extensions/umbra-copy-chat.ts +16 -54
  62. package/node_modules/pi-umbra-copy-chat/package.json +1 -1
  63. package/node_modules/pi-umbra-help/checks/umbra-help.check.ts +10 -1
  64. package/node_modules/pi-umbra-help/extensions/umbra-help.ts +31 -0
  65. package/node_modules/pi-umbra-help/package.json +1 -1
  66. package/node_modules/pi-umbra-inputbar/README.md +1 -1
  67. package/node_modules/pi-umbra-inputbar/extensions/umbra-inputbar.ts +1 -1
  68. package/node_modules/pi-umbra-inputbar/package.json +2 -2
  69. package/node_modules/pi-umbra-shimmer/package.json +1 -1
  70. package/node_modules/pi-umbra-shimmer/patch.mjs +23 -21
  71. package/node_modules/pi-umbra-skill-matcher/package.json +1 -1
  72. package/node_modules/pi-umbra-skill-matcher/patch.mjs +7 -0
  73. package/node_modules/pi-umbra-subagents/README.md +24 -6
  74. package/node_modules/pi-umbra-subagents/extensions/umbra-subagents/bar/bar-line.ts +250 -102
  75. package/node_modules/pi-umbra-subagents/extensions/umbra-subagents/bar.check.ts +133 -66
  76. package/node_modules/pi-umbra-subagents/extensions/umbra-subagents/bar.ts +59 -27
  77. package/node_modules/pi-umbra-subagents/extensions/umbra-subagents/fan/index.ts +53 -8
  78. package/node_modules/pi-umbra-subagents/extensions/umbra-subagents/fan/spec.ts +24 -14
  79. package/node_modules/pi-umbra-subagents/extensions/umbra-subagents/fan/store.check.ts +132 -5
  80. package/node_modules/pi-umbra-subagents/extensions/umbra-subagents/fan/store.ts +156 -64
  81. package/node_modules/pi-umbra-subagents/extensions/umbra-subagents/fan/worktree.ts +156 -0
  82. package/node_modules/pi-umbra-subagents/extensions/umbra-subagents/panel.ts +1 -1
  83. package/node_modules/pi-umbra-subagents/extensions/umbra-subagents/skills/delegate/state.ts +19 -0
  84. package/node_modules/pi-umbra-subagents/extensions/umbra-subagents/skills/fan/SKILL.md +25 -4
  85. package/node_modules/pi-umbra-subagents/package.json +2 -2
  86. package/node_modules/pi-umbra-theme/checks/umbra-background.check.ts +7 -1
  87. package/node_modules/pi-umbra-theme/extensions/umbra-background.ts +2 -1
  88. package/node_modules/pi-umbra-theme/package.json +3 -3
  89. package/node_modules/shiki/dist/bundle-full.d.mts +4 -4
  90. package/node_modules/shiki/dist/bundle-web.d.mts +9 -9
  91. package/node_modules/shiki/dist/types.d.mts +3 -3
  92. package/node_modules/shiki/package.json +10 -10
  93. package/package.json +9 -12
  94. package/node_modules/@shikijs/engine-javascript/dist/scanner-DX8LRFGE.mjs +0 -77
  95. package/node_modules/pi-umbra-rename/LICENSE +0 -21
  96. package/node_modules/pi-umbra-rename/README.md +0 -18
  97. package/node_modules/pi-umbra-rename/checks/umbra-rename.check.ts +0 -55
  98. package/node_modules/pi-umbra-rename/extensions/umbra-rename.ts +0 -22
  99. package/node_modules/pi-umbra-rename/package.json +0 -36
@@ -1,7 +1,7 @@
1
1
  // The input bar: the session name on its top border (right side) and /umb-color for its border
2
2
  // colour. Both ride on pi's own extension point - ctx.ui.setEditorComponent with a subclass of
3
3
  // CustomEditor - so no bundle patch is involved. The name is read from pi.getSessionName() at
4
- // every render, so /umb-rename shows on the next repaint; /umb-color persists in
4
+ // every render, so /name shows on the next repaint; /umb-color persists in
5
5
  // ~/.pi/agent/input-color.
6
6
  import { CustomEditor, type ExtensionAPI, type ExtensionContext, type KeybindingsManager } from "@earendil-works/pi-coding-agent";
7
7
  import { isKeyRepeat, visibleWidth, type TuiMouseEvent, type TuiMouseEventResult } from "@earendil-works/pi-tui";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-umbra-inputbar",
3
- "version": "0.1.4",
4
- "description": "pi's input bar, rebuilt: a chevron prompt, the session name on the border, a colour you pick, and a command to rename the session.",
3
+ "version": "0.1.5",
4
+ "description": "pi's input bar, rebuilt: a chevron prompt, the session name on the border, a colour you pick.",
5
5
  "keywords": [
6
6
  "pi-package",
7
7
  "pi",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-umbra-shimmer",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "A wave of colour running through pi's working indicator, over both the spinner and the text. Needs the umbra bundle patches; without them it does nothing.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -60,8 +60,11 @@ const PATCHES = [
60
60
  // wave: the spinner colour function was skipped for them while the message kept being
61
61
  // repainted every frame. Verbatim still holds when no shimmer is installed.
62
62
  reason: "and paints the custom frames too",
63
- from: `return this.renderIndicatorVerbatim?frame2:this.spinnerColorFn(frame2)`,
64
- to: `return this.renderIndicatorVerbatim&&!globalThis.__umbraShimmer?frame2:this.spinnerColorFn(frame2)`,
63
+ // pi 1.0 bundles the same line with the local named `frame` rather than `frame2`.
64
+ variants: ["frame2", "frame"].map((name) => ({
65
+ from: `return this.renderIndicatorVerbatim?${name}:this.spinnerColorFn(${name})`,
66
+ to: `return this.renderIndicatorVerbatim&&!globalThis.__umbraShimmer?${name}:this.spinnerColorFn(${name})`,
67
+ })),
65
68
  },
66
69
  {
67
70
  // The working indicator paints its spinner with `accent` and its message with `muted`, both
@@ -79,33 +82,32 @@ const CHECK = process.argv.includes("--check");
79
82
  const unapplied = [];
80
83
  const gone = [];
81
84
 
82
- for (const patch of PATCHES) {
83
- let done = false;
85
+ // One patch, every file read once: "applied", "unapplied" (--check), or undefined when gone.
86
+ const apply = (patch) => {
84
87
  for (const path of files) {
85
88
  const source = readFileSync(path, "utf8");
86
89
  // A multi-line patch is written with newline escapes; match whatever line ending the file uses.
87
90
  const eol = source.includes("\r\n") ? "\r\n" : "\n";
88
- const from = patch.from.split("\n").join(eol);
89
- const to = patch.to.split("\n").join(eol);
90
- if (source.includes(to)) {
91
- if (!CHECK) console.log(`already patched: ${patch.reason}`);
92
- done = true;
93
- break;
94
- }
95
- if (!source.includes(from)) continue;
96
- if (CHECK) {
97
- unapplied.push(patch.reason);
98
- done = true;
99
- break;
91
+ for (const variant of patch.variants ?? [patch]) {
92
+ const from = variant.from.split("\n").join(eol);
93
+ const to = variant.to.split("\n").join(eol);
94
+ if (source.includes(to)) return "applied";
95
+ if (!source.includes(from)) continue;
96
+ if (CHECK) return "unapplied";
97
+ writeFileSync(path, source.replace(from, to));
98
+ console.log(`patched: ${patch.reason}`);
99
+ return "applied";
100
100
  }
101
- writeFileSync(path, source.replace(from, to));
102
- console.log(`patched: ${patch.reason}`);
103
- done = true;
104
- break;
105
101
  }
102
+ return undefined;
103
+ };
104
+
105
+ for (const patch of PATCHES) {
106
+ const result = apply(patch);
107
+ if (result === "unapplied") unapplied.push(patch.reason);
106
108
  // Neither the original text nor the patched text is there, so pi changed the code this
107
109
  // patch names. Report it rather than force anything.
108
- if (!done) gone.push(patch.reason);
110
+ else if (!result) gone.push(patch.reason);
109
111
  }
110
112
 
111
113
  for (const reason of unapplied) console.log(`NOT APPLIED: ${reason}`);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-umbra-skill-matcher",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Type /huh and reach skill:huh. pi lists every skill under its bare name, which is not the name that dispatches.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -58,6 +58,7 @@ const PATCHES = [
58
58
  },
59
59
  {
60
60
  reason: "the command list names skills without the prefix too",
61
+ needs: "/huh instead of /skill:huh",
61
62
  from: "skills=this._resourceLoader.getSkills().skills.map(skill=>({name:`skill:${skill.name}`,",
62
63
  to: "skills=this._resourceLoader.getSkills().skills.map(skill=>({name:skill.name,",
63
64
  },
@@ -83,6 +84,7 @@ const PATCHES = [
83
84
  // `isAtStartOfMessage`. At that moment the token after the slash is still empty, which is
84
85
  // exactly the shape `umbraMidSlash` accepts.
85
86
  reason: "typing a mid-sentence slash opens the menu on the slash",
87
+ needs: "a mid-sentence /name opens the slash menu",
86
88
  from: `char==="/"&&this.isAtStartOfMessage()`,
87
89
  to: `char==="/"&&(this.isAtStartOfMessage()||this.umbraMidSlash((this.state.lines[this.state.cursorLine]||"").slice(0,this.state.cursorCol)))`,
88
90
  },
@@ -94,6 +96,11 @@ const unapplied = [];
94
96
  const gone = [];
95
97
 
96
98
  for (const patch of PATCHES) {
99
+ // It would call a method, or offer a name, that only the patch it needs provides.
100
+ if (gone.includes(patch.needs)) {
101
+ gone.push(`${patch.reason} (held back: needs "${patch.needs}")`);
102
+ continue;
103
+ }
97
104
  let done = false;
98
105
  for (const path of files) {
99
106
  const source = readFileSync(path, "utf8");
@@ -1,8 +1,10 @@
1
1
  # pi-umbra-subagents
2
2
 
3
- Parallel, read-only pi branches you can watch while they work. A branch is a separate `pi -p`
4
- process with an empty context; a live list above the input box shows what each one is doing,
5
- and their answers come back to the session when the last one ends. Also `/umb-loop`, which
3
+ Parallel pi branches you can watch while they work. A branch is a separate `pi -p` process with
4
+ an empty context; a live tree under the input box shows what each one is doing, and their answers
5
+ come back to the session when the last one ends. Branches are read-only, unless one is marked
6
+ `[write]`: that one works in its own git worktree, and its changes wait on a git branch until you
7
+ say whether to merge them. Also `/umb-loop`, which
6
8
  sends a prompt again after every reply, on a count or a timer.
7
9
 
8
10
  ![Three branches running under the input box](https://raw.githubusercontent.com/grknbyk/pi-umbra/main/assets/subagents.webp)
@@ -33,14 +35,30 @@ design: Given the Map results, propose the change.
33
35
  `label@provider/model: task` picks a model for one branch, otherwise it runs on the session's
34
36
  model. The results arrive as a follow-up message at the start of the next turn.
35
37
 
38
+ `label [write]: task` gives one branch `edit`, `write` and `bash`, in its own git worktree on a
39
+ new `fan/<run>/<branch>` branch that starts from your working tree, uncommitted work included.
40
+ Its changes are committed to that branch when it ends and its row reads `Changed +12 −3 · 2 files
41
+ on fan/...`; nothing is merged until the session asks you and you say yes. It needs a git
42
+ repository, and pi has no sandbox: bash can still reach outside the worktree, and only the
43
+ branch's instructions forbid it.
44
+
45
+ The worktree lives under `.git/fan-worktrees/`, where test runners, linters and `git clean` do not
46
+ look. A write branch cannot stop on a question, because its worktree closes when it ends, so its
47
+ task has to carry every decision. Every write branch starts from the tree as it was when the run started, so a later
48
+ phase does not see an earlier phase's changes. A run you start with `/umb-fan` tells you when a write branch
49
+ left changes; ask the session to merge or discard them.
50
+
36
51
  ## Commands and keys
37
52
 
38
53
  | Command or key | Effect |
39
54
  |---|---|
40
55
  | `/umb-fan [spec]` | start a run yourself; with no argument an editor opens with a template |
41
56
  | `/umb-agents`, `alt+a` | open the agent panel |
42
- | `↓` from the last input line | move the `❯` from `main` into the agent list under the input box |
43
- | `↑` `↓`, then `enter` in that list | pick an agent and open the panel on it; `↑` past the first agent or `esc` goes back |
57
+ | `↓` from the last input line | move the `❯` into the agent tree under the input box |
58
+ | `↑` `↓` in the tree | move between rows; `↑` past `main` or `esc` goes back to the input box |
59
+ | `enter` in the tree | open the row's agents, closing every other row; on `main` it folds the tree back to the top |
60
+ | `x` in the tree | stop the row and every agent under it |
61
+ | `alt+a` in the tree | open the agent panel on that row |
44
62
  | `↑` `↓` in the panel | move between phases, or between the agents of one phase |
45
63
  | `→` `←` in the panel | go into a phase's agents, and back out to the phases |
46
64
  | `x` in the panel | stop the selected phase, or the selected agent |
@@ -67,7 +85,7 @@ wrote stays on disk.
67
85
  | Variable | Default | Effect |
68
86
  |---|---|---|
69
87
  | `FAN_MODEL` | the session's model | model for `fan` branches that do not name one |
70
- | `FAN_TOOLS` | `read,grep,find,ls` | tools a branch may use |
88
+ | `FAN_TOOLS` | `read,grep,find,ls` | tools a read-only branch may use (`[write]` branches get `edit,write,bash` too) |
71
89
  | `FAN_LOAD` | `$LOAD` from `delegate.env` | extra `-e <path>` flags; branches start with `--no-extensions`, so a provider that comes from an extension has to be listed here |
72
90
  | `FAN_TIMEOUT_MS` | `$DELEGATE_TIMEOUT` × 1000, else `300000` | a branch still running after this long is cut off |
73
91