@chankov/agent-skills 0.2.0 → 0.3.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 (178) hide show
  1. package/.claude/commands/{doctor.md → doctor-agent-skills.md} +1 -1
  2. package/.pi/extensions/agent-skills-update-check/README.md +4 -4
  3. package/.pi/prompts/{doctor.md → doctor-agent-skills.md} +1 -1
  4. package/.versions/0.2.0/.claude/commands/{doctor.md → doctor-agent-skills.md} +1 -1
  5. package/.versions/0.2.0/.pi/extensions/agent-skills-update-check/README.md +4 -4
  6. package/.versions/0.2.0/.pi/prompts/{doctor.md → doctor-agent-skills.md} +1 -1
  7. package/.versions/0.2.0/skills/guided-workspace-setup/SKILL.md +40 -2
  8. package/.versions/0.3.0/.claude/commands/build.md +18 -0
  9. package/.versions/0.3.0/.claude/commands/code-simplify.md +22 -0
  10. package/.versions/0.3.0/.claude/commands/design-agent.md +14 -0
  11. package/.versions/0.3.0/.claude/commands/doctor-agent-skills.md +13 -0
  12. package/.versions/0.3.0/.claude/commands/plan.md +16 -0
  13. package/.versions/0.3.0/.claude/commands/prime.md +22 -0
  14. package/.versions/0.3.0/.claude/commands/review.md +16 -0
  15. package/.versions/0.3.0/.claude/commands/setup-agent-skills.md +19 -0
  16. package/.versions/0.3.0/.claude/commands/ship.md +17 -0
  17. package/.versions/0.3.0/.claude/commands/spec.md +15 -0
  18. package/.versions/0.3.0/.claude/commands/test.md +19 -0
  19. package/.versions/0.3.0/.opencode/commands/as-build.md +17 -0
  20. package/.versions/0.3.0/.opencode/commands/as-code-simplify.md +16 -0
  21. package/.versions/0.3.0/.opencode/commands/as-design-agent.md +15 -0
  22. package/.versions/0.3.0/.opencode/commands/as-doctor-agent-skills.md +11 -0
  23. package/.versions/0.3.0/.opencode/commands/as-plan.md +16 -0
  24. package/.versions/0.3.0/.opencode/commands/as-prime.md +22 -0
  25. package/.versions/0.3.0/.opencode/commands/as-review.md +15 -0
  26. package/.versions/0.3.0/.opencode/commands/as-setup-agent-skills.md +11 -0
  27. package/.versions/0.3.0/.opencode/commands/as-ship.md +16 -0
  28. package/.versions/0.3.0/.opencode/commands/as-spec.md +16 -0
  29. package/.versions/0.3.0/.opencode/commands/as-test.md +21 -0
  30. package/.versions/0.3.0/.pi/agents/agent-chain.yaml +49 -0
  31. package/.versions/0.3.0/.pi/agents/bowser.md +19 -0
  32. package/.versions/0.3.0/.pi/agents/pi-pi/agent-expert.md +98 -0
  33. package/.versions/0.3.0/.pi/agents/pi-pi/cli-expert.md +41 -0
  34. package/.versions/0.3.0/.pi/agents/pi-pi/config-expert.md +63 -0
  35. package/.versions/0.3.0/.pi/agents/pi-pi/ext-expert.md +43 -0
  36. package/.versions/0.3.0/.pi/agents/pi-pi/keybinding-expert.md +134 -0
  37. package/.versions/0.3.0/.pi/agents/pi-pi/pi-orchestrator.md +57 -0
  38. package/.versions/0.3.0/.pi/agents/pi-pi/prompt-expert.md +70 -0
  39. package/.versions/0.3.0/.pi/agents/pi-pi/skill-expert.md +42 -0
  40. package/.versions/0.3.0/.pi/agents/pi-pi/theme-expert.md +40 -0
  41. package/.versions/0.3.0/.pi/agents/pi-pi/tui-expert.md +85 -0
  42. package/.versions/0.3.0/.pi/agents/teams.yaml +31 -0
  43. package/.versions/0.3.0/.pi/damage-control-rules.yaml +278 -0
  44. package/.versions/0.3.0/.pi/extensions/agent-skills-update-check/README.md +58 -0
  45. package/.versions/0.3.0/.pi/extensions/agent-skills-update-check/index.ts +161 -0
  46. package/.versions/0.3.0/.pi/extensions/agent-skills-update-check/package.json +6 -0
  47. package/.versions/0.3.0/.pi/extensions/chrome-devtools-mcp/README.md +39 -0
  48. package/.versions/0.3.0/.pi/extensions/chrome-devtools-mcp/index.ts +61 -0
  49. package/.versions/0.3.0/.pi/extensions/chrome-devtools-mcp/package.json +6 -0
  50. package/.versions/0.3.0/.pi/extensions/compact-and-continue/README.md +42 -0
  51. package/.versions/0.3.0/.pi/extensions/compact-and-continue/index.ts +120 -0
  52. package/.versions/0.3.0/.pi/extensions/compact-and-continue/package.json +6 -0
  53. package/.versions/0.3.0/.pi/extensions/mcp-bridge/README.md +46 -0
  54. package/.versions/0.3.0/.pi/extensions/mcp-bridge/index.ts +206 -0
  55. package/.versions/0.3.0/.pi/extensions/mcp-bridge/package.json +6 -0
  56. package/.versions/0.3.0/.pi/extensions/package-lock.json +1143 -0
  57. package/.versions/0.3.0/.pi/extensions/package.json +9 -0
  58. package/.versions/0.3.0/.pi/harnesses/agent-chain/README.md +37 -0
  59. package/.versions/0.3.0/.pi/harnesses/agent-chain/index.ts +795 -0
  60. package/.versions/0.3.0/.pi/harnesses/agent-chain/package.json +6 -0
  61. package/.versions/0.3.0/.pi/harnesses/agent-team/README.md +38 -0
  62. package/.versions/0.3.0/.pi/harnesses/agent-team/index.ts +732 -0
  63. package/.versions/0.3.0/.pi/harnesses/agent-team/package.json +6 -0
  64. package/.versions/0.3.0/.pi/harnesses/coms/README.md +36 -0
  65. package/.versions/0.3.0/.pi/harnesses/coms/index.ts +1595 -0
  66. package/.versions/0.3.0/.pi/harnesses/coms/package.json +6 -0
  67. package/.versions/0.3.0/.pi/harnesses/coms-net/README.md +46 -0
  68. package/.versions/0.3.0/.pi/harnesses/coms-net/index.ts +1637 -0
  69. package/.versions/0.3.0/.pi/harnesses/coms-net/package.json +6 -0
  70. package/.versions/0.3.0/.pi/harnesses/damage-control/README.md +38 -0
  71. package/.versions/0.3.0/.pi/harnesses/damage-control/index.ts +207 -0
  72. package/.versions/0.3.0/.pi/harnesses/damage-control/package.json +6 -0
  73. package/.versions/0.3.0/.pi/harnesses/damage-control-continue/README.md +37 -0
  74. package/.versions/0.3.0/.pi/harnesses/damage-control-continue/index.ts +234 -0
  75. package/.versions/0.3.0/.pi/harnesses/damage-control-continue/package.json +6 -0
  76. package/.versions/0.3.0/.pi/harnesses/minimal/README.md +27 -0
  77. package/.versions/0.3.0/.pi/harnesses/minimal/index.ts +32 -0
  78. package/.versions/0.3.0/.pi/harnesses/minimal/package.json +6 -0
  79. package/.versions/0.3.0/.pi/harnesses/package-lock.json +35 -0
  80. package/.versions/0.3.0/.pi/harnesses/package.json +9 -0
  81. package/.versions/0.3.0/.pi/harnesses/pi-pi/README.md +39 -0
  82. package/.versions/0.3.0/.pi/harnesses/pi-pi/index.ts +631 -0
  83. package/.versions/0.3.0/.pi/harnesses/pi-pi/package.json +6 -0
  84. package/.versions/0.3.0/.pi/harnesses/purpose-gate/README.md +27 -0
  85. package/.versions/0.3.0/.pi/harnesses/purpose-gate/index.ts +82 -0
  86. package/.versions/0.3.0/.pi/harnesses/purpose-gate/package.json +6 -0
  87. package/.versions/0.3.0/.pi/harnesses/session-replay/README.md +28 -0
  88. package/.versions/0.3.0/.pi/harnesses/session-replay/index.ts +214 -0
  89. package/.versions/0.3.0/.pi/harnesses/session-replay/package.json +6 -0
  90. package/.versions/0.3.0/.pi/harnesses/subagent-widget/README.md +36 -0
  91. package/.versions/0.3.0/.pi/harnesses/subagent-widget/index.ts +479 -0
  92. package/.versions/0.3.0/.pi/harnesses/subagent-widget/package.json +6 -0
  93. package/.versions/0.3.0/.pi/harnesses/system-select/README.md +39 -0
  94. package/.versions/0.3.0/.pi/harnesses/system-select/index.ts +165 -0
  95. package/.versions/0.3.0/.pi/harnesses/system-select/package.json +6 -0
  96. package/.versions/0.3.0/.pi/harnesses/tilldone/README.md +35 -0
  97. package/.versions/0.3.0/.pi/harnesses/tilldone/index.ts +724 -0
  98. package/.versions/0.3.0/.pi/harnesses/tilldone/package.json +6 -0
  99. package/.versions/0.3.0/.pi/harnesses/tool-counter/README.md +31 -0
  100. package/.versions/0.3.0/.pi/harnesses/tool-counter/index.ts +100 -0
  101. package/.versions/0.3.0/.pi/harnesses/tool-counter/package.json +6 -0
  102. package/.versions/0.3.0/.pi/harnesses/tool-counter-widget/README.md +27 -0
  103. package/.versions/0.3.0/.pi/harnesses/tool-counter-widget/index.ts +66 -0
  104. package/.versions/0.3.0/.pi/harnesses/tool-counter-widget/package.json +6 -0
  105. package/.versions/0.3.0/.pi/prompts/build.md +24 -0
  106. package/.versions/0.3.0/.pi/prompts/code-simplify.md +22 -0
  107. package/.versions/0.3.0/.pi/prompts/doctor-agent-skills.md +13 -0
  108. package/.versions/0.3.0/.pi/prompts/plan.md +16 -0
  109. package/.versions/0.3.0/.pi/prompts/review.md +16 -0
  110. package/.versions/0.3.0/.pi/prompts/setup-agent-skills.md +19 -0
  111. package/.versions/0.3.0/.pi/prompts/ship.md +17 -0
  112. package/.versions/0.3.0/.pi/prompts/spec.md +15 -0
  113. package/.versions/0.3.0/.pi/prompts/test.md +19 -0
  114. package/.versions/0.3.0/.pi/skills/bowser/SKILL.md +114 -0
  115. package/.versions/0.3.0/.version +1 -0
  116. package/.versions/0.3.0/agents/builder.md +6 -0
  117. package/.versions/0.3.0/agents/code-reviewer.md +93 -0
  118. package/.versions/0.3.0/agents/documenter.md +6 -0
  119. package/.versions/0.3.0/agents/plan-reviewer.md +22 -0
  120. package/.versions/0.3.0/agents/planner.md +6 -0
  121. package/.versions/0.3.0/agents/scout.md +6 -0
  122. package/.versions/0.3.0/agents/security-auditor.md +97 -0
  123. package/.versions/0.3.0/agents/test-engineer.md +89 -0
  124. package/.versions/0.3.0/hooks/SIMPLIFY-IGNORE.md +90 -0
  125. package/.versions/0.3.0/hooks/hooks.json +14 -0
  126. package/.versions/0.3.0/hooks/session-start.sh +74 -0
  127. package/.versions/0.3.0/hooks/simplify-ignore-test.sh +247 -0
  128. package/.versions/0.3.0/hooks/simplify-ignore.sh +302 -0
  129. package/.versions/0.3.0/references/accessibility-checklist.md +159 -0
  130. package/.versions/0.3.0/references/performance-checklist.md +121 -0
  131. package/.versions/0.3.0/references/prompting-patterns.md +380 -0
  132. package/.versions/0.3.0/references/security-checklist.md +134 -0
  133. package/.versions/0.3.0/references/testing-patterns.md +236 -0
  134. package/.versions/0.3.0/skills/api-and-interface-design/SKILL.md +294 -0
  135. package/.versions/0.3.0/skills/browser-testing-with-devtools/SKILL.md +335 -0
  136. package/.versions/0.3.0/skills/ci-cd-and-automation/SKILL.md +390 -0
  137. package/.versions/0.3.0/skills/code-review-and-quality/SKILL.md +347 -0
  138. package/.versions/0.3.0/skills/code-simplification/SKILL.md +331 -0
  139. package/.versions/0.3.0/skills/context-engineering/SKILL.md +291 -0
  140. package/.versions/0.3.0/skills/debugging-and-error-recovery/SKILL.md +300 -0
  141. package/.versions/0.3.0/skills/deprecation-and-migration/SKILL.md +206 -0
  142. package/.versions/0.3.0/skills/designing-agents/SKILL.md +394 -0
  143. package/.versions/0.3.0/skills/designing-agents/pi-harness-authoring.md +213 -0
  144. package/.versions/0.3.0/skills/documentation-and-adrs/SKILL.md +278 -0
  145. package/.versions/0.3.0/skills/frontend-ui-engineering/SKILL.md +322 -0
  146. package/.versions/0.3.0/skills/git-workflow-and-versioning/SKILL.md +316 -0
  147. package/.versions/0.3.0/skills/guided-workspace-setup/SKILL.md +331 -0
  148. package/.versions/0.3.0/skills/idea-refine/SKILL.md +178 -0
  149. package/.versions/0.3.0/skills/idea-refine/examples.md +238 -0
  150. package/.versions/0.3.0/skills/idea-refine/frameworks.md +99 -0
  151. package/.versions/0.3.0/skills/idea-refine/refinement-criteria.md +113 -0
  152. package/.versions/0.3.0/skills/idea-refine/scripts/idea-refine.sh +15 -0
  153. package/.versions/0.3.0/skills/incremental-implementation/SKILL.md +279 -0
  154. package/.versions/0.3.0/skills/performance-optimization/SKILL.md +350 -0
  155. package/.versions/0.3.0/skills/planning-and-task-breakdown/SKILL.md +237 -0
  156. package/.versions/0.3.0/skills/security-and-hardening/SKILL.md +349 -0
  157. package/.versions/0.3.0/skills/shipping-and-launch/SKILL.md +309 -0
  158. package/.versions/0.3.0/skills/source-driven-development/SKILL.md +194 -0
  159. package/.versions/0.3.0/skills/spec-driven-development/SKILL.md +237 -0
  160. package/.versions/0.3.0/skills/test-driven-development/SKILL.md +379 -0
  161. package/.versions/0.3.0/skills/using-agent-skills/SKILL.md +176 -0
  162. package/CHANGELOG.md +72 -0
  163. package/README.md +5 -5
  164. package/bin/cli.js +100 -24
  165. package/bin/lib/bootstrap.js +254 -0
  166. package/bin/lib/doctor.js +1 -1
  167. package/docs/getting-started.md +2 -2
  168. package/docs/npm-install.md +34 -11
  169. package/package.json +1 -1
  170. package/skills/guided-workspace-setup/SKILL.md +40 -2
  171. /package/.claude/commands/{setup.md → setup-agent-skills.md} +0 -0
  172. /package/.opencode/commands/{as-doctor.md → as-doctor-agent-skills.md} +0 -0
  173. /package/.opencode/commands/{as-setup.md → as-setup-agent-skills.md} +0 -0
  174. /package/.pi/prompts/{setup.md → setup-agent-skills.md} +0 -0
  175. /package/.versions/0.2.0/.claude/commands/{setup.md → setup-agent-skills.md} +0 -0
  176. /package/.versions/0.2.0/.opencode/commands/{as-doctor.md → as-doctor-agent-skills.md} +0 -0
  177. /package/.versions/0.2.0/.opencode/commands/{as-setup.md → as-setup-agent-skills.md} +0 -0
  178. /package/.versions/0.2.0/.pi/prompts/{setup.md → setup-agent-skills.md} +0 -0
@@ -0,0 +1,27 @@
1
+ # purpose-gate
2
+
3
+ Forces the engineer to declare intent before working.
4
+
5
+ > Ported from [`pi-vs-claude-code`](https://github.com/disler/pi-vs-claude-code) by [disler](https://github.com/disler) (MIT). See the [extension catalog](../../../docs/pi-extensions.md).
6
+
7
+ ## What it does
8
+
9
+ On session start it immediately asks "What is the purpose of this agent?" via a text
10
+ input dialog and **blocks all prompts until answered**. A persistent widget then shows
11
+ the declared purpose for the rest of the session, keeping the work anchored to one
12
+ stated goal.
13
+
14
+ ## Commands & tools
15
+
16
+ None — a session-start dialog plus a persistent widget.
17
+
18
+ ## Usage
19
+
20
+ ```bash
21
+ pi -e .pi/harnesses/purpose-gate/index.ts
22
+ ```
23
+
24
+ ## Upstream changes
25
+
26
+ - Theme integration removed — the `themeMap.ts` import and the `applyExtensionDefaults()`
27
+ call were stripped (this repo does not ship pi themes).
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Purpose Gate — Forces the engineer to declare intent before working
3
+ *
4
+ * On session start, immediately asks "What is the purpose of this agent?"
5
+ * via a text input dialog. A persistent widget shows the purpose for the
6
+ * rest of the session, keeping focus. Blocks all prompts until answered.
7
+ *
8
+ * Usage: pi -e extensions/purpose-gate.ts
9
+ */
10
+
11
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
12
+ import { Text, truncateToWidth } from "@mariozechner/pi-tui";
13
+
14
+ // synthwave: bgWarm #4a1e6a → rgb(74,30,106)
15
+ function bg(s: string): string {
16
+ return `\x1b[48;2;74;30;106m${s}\x1b[49m`;
17
+ }
18
+
19
+ // synthwave: pink #ff7edb
20
+ function pink(s: string): string {
21
+ return `\x1b[38;2;255;126;219m${s}\x1b[39m`;
22
+ }
23
+
24
+ // synthwave: cyan #36f9f6
25
+ function cyan(s: string): string {
26
+ return `\x1b[38;2;54;249;246m${s}\x1b[39m`;
27
+ }
28
+
29
+ function bold(s: string): string {
30
+ return `\x1b[1m${s}\x1b[22m`;
31
+ }
32
+
33
+ export default function (pi: ExtensionAPI) {
34
+ let purpose: string | undefined;
35
+
36
+ async function askForPurpose(ctx: any) {
37
+ while (!purpose) {
38
+ const answer = await ctx.ui.input(
39
+ "What is the purpose of this agent?",
40
+ "e.g. Refactor the auth module to use JWT"
41
+ );
42
+
43
+ if (answer && answer.trim()) {
44
+ purpose = answer.trim();
45
+ } else {
46
+ ctx.ui.notify("Purpose is required.", "warning");
47
+ }
48
+ }
49
+
50
+ ctx.ui.setWidget("purpose", () => {
51
+ return {
52
+ render(width: number): string[] {
53
+ const pad = bg(" ".repeat(width));
54
+ const label = pink(bold(" PURPOSE: "));
55
+ const msg = cyan(bold(purpose!));
56
+ const content = bg(truncateToWidth(label + msg + " ".repeat(width), width, ""));
57
+ return [pad, content, pad];
58
+ },
59
+ invalidate() {},
60
+ };
61
+ });
62
+ }
63
+
64
+ pi.on("session_start", async (_event, ctx) => {
65
+ void askForPurpose(ctx);
66
+ });
67
+
68
+ pi.on("before_agent_start", async (event) => {
69
+ if (!purpose) return;
70
+ return {
71
+ systemPrompt: event.systemPrompt + `\n\n<purpose>\nYour singular purpose this session: ${purpose}\nStay focused on this goal. If a request drifts from this purpose, gently remind the user.\n</purpose>`,
72
+ };
73
+ });
74
+
75
+ pi.on("input", async (_event, ctx) => {
76
+ if (!purpose) {
77
+ ctx.ui.notify("Set a purpose first.", "warning");
78
+ return { action: "handled" as const };
79
+ }
80
+ return { action: "continue" as const };
81
+ });
82
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "agent-skills-pi-purpose-gate",
3
+ "private": true,
4
+ "type": "module",
5
+ "main": "index.ts"
6
+ }
@@ -0,0 +1,28 @@
1
+ # session-replay
2
+
3
+ Scrollable timeline overlay of session history.
4
+
5
+ > Ported from [`pi-vs-claude-code`](https://github.com/disler/pi-vs-claude-code) by [disler](https://github.com/disler) (MIT). See the [extension catalog](../../../docs/pi-extensions.md).
6
+
7
+ ## What it does
8
+
9
+ Adds a `/replay` overlay that renders the current session as a scrollable timeline of
10
+ user, assistant, and tool entries — each with timestamps and elapsed-time deltas. Useful
11
+ for reviewing what happened in a long session without scrolling the live transcript.
12
+
13
+ ## Commands & tools
14
+
15
+ - `/replay` — open the timeline overlay
16
+ - Inside the overlay: `↑`/`↓` to move, `Enter` to expand an entry, `Esc` to close
17
+
18
+ ## Usage
19
+
20
+ ```bash
21
+ pi -e .pi/harnesses/session-replay/index.ts
22
+ ```
23
+
24
+ ## Upstream changes
25
+
26
+ - Theme integration removed — the `themeMap.ts` import and the `applyExtensionDefaults()`
27
+ call were stripped (this repo does not ship pi themes). The overlay renders against
28
+ pi's active theme.
@@ -0,0 +1,214 @@
1
+ import { ExtensionAPI } from "@mariozechner/pi-coding-agent";
2
+ import {
3
+ Box, Text, Markdown, Container, Spacer,
4
+ matchesKey, Key, truncateToWidth, getMarkdownTheme
5
+ } from "@mariozechner/pi-tui";
6
+ import { DynamicBorder, getMarkdownTheme as getPiMdTheme } from "@mariozechner/pi-coding-agent";
7
+
8
+ // Minimal shim for timestamp handling if not directly in Message objects
9
+ function formatTime(date: Date): string {
10
+ return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });
11
+ }
12
+
13
+ function getElapsedTime(start: Date, end: Date): string {
14
+ const diffMs = end.getTime() - start.getTime();
15
+ const diffSec = Math.floor(diffMs / 1000);
16
+ if (diffSec < 60) return `${diffSec}s`;
17
+ const diffMin = Math.floor(diffSec / 60);
18
+ return `${diffMin}m ${diffSec % 60}s`;
19
+ }
20
+
21
+ interface HistoryItem {
22
+ type: 'user' | 'assistant' | 'tool';
23
+ title: string;
24
+ content: string;
25
+ timestamp: Date;
26
+ elapsed?: string;
27
+ }
28
+
29
+ class SessionReplayUI {
30
+ private selectedIndex = 0;
31
+ private expandedIndex: number | null = null;
32
+ private scrollOffset = 0;
33
+
34
+ constructor(
35
+ private items: HistoryItem[],
36
+ private onDone: () => void
37
+ ) {
38
+ // Start selected at the bottom (most recent)
39
+ this.selectedIndex = Math.max(0, items.length - 1);
40
+ this.ensureVisible(20); // rough height estimate
41
+ }
42
+
43
+ handleInput(data: string, tui: any): void {
44
+ if (matchesKey(data, Key.up)) {
45
+ this.selectedIndex = Math.max(0, this.selectedIndex - 1);
46
+ } else if (matchesKey(data, Key.down)) {
47
+ this.selectedIndex = Math.min(this.items.length - 1, this.selectedIndex + 1);
48
+ } else if (matchesKey(data, Key.enter)) {
49
+ this.expandedIndex = this.expandedIndex === this.selectedIndex ? null : this.selectedIndex;
50
+ } else if (matchesKey(data, Key.escape)) {
51
+ this.onDone();
52
+ return;
53
+ }
54
+ tui.requestRender();
55
+ }
56
+
57
+ private ensureVisible(height: number) {
58
+ // Simple scroll window logic
59
+ const pageSize = Math.floor(height / 3); // Approx items per page
60
+ if (this.selectedIndex < this.scrollOffset) {
61
+ this.scrollOffset = this.selectedIndex;
62
+ } else if (this.selectedIndex >= this.scrollOffset + pageSize) {
63
+ this.scrollOffset = this.selectedIndex - pageSize + 1;
64
+ }
65
+ }
66
+
67
+ render(width: number, height: number, theme: any): string[] {
68
+ this.ensureVisible(height);
69
+
70
+ const container = new Container();
71
+ const mdTheme = getPiMdTheme();
72
+
73
+ // Header
74
+ container.addChild(new DynamicBorder((s: string) => theme.fg("accent", s)));
75
+ container.addChild(new Text(`${theme.fg("accent", theme.bold(" SESSION REPLAY"))} ${theme.fg("dim", "|")} ${theme.fg("success", this.items.length.toString())} entries`, 1, 0));
76
+ container.addChild(new Spacer(1));
77
+
78
+ // Calculate visible range
79
+ const visibleItems = this.items.slice(this.scrollOffset);
80
+
81
+ visibleItems.forEach((item, idx) => {
82
+ const absoluteIndex = idx + this.scrollOffset;
83
+ const isSelected = absoluteIndex === this.selectedIndex;
84
+ const isExpanded = absoluteIndex === this.expandedIndex;
85
+
86
+ const cardBox = new Box(1, 0, (s) => isSelected ? theme.bg("selectedBg", s) : s);
87
+
88
+ // Icon and Title
89
+ let icon = "○";
90
+ let color = "dim";
91
+ if (item.type === 'user') { icon = "👤"; color = "success"; }
92
+ else if (item.type === 'assistant') { icon = "🤖"; color = "accent"; }
93
+ else if (item.type === 'tool') { icon = "🛠️"; color = "warning"; }
94
+
95
+ const timeStr = theme.fg("success", `[${formatTime(item.timestamp)}]`);
96
+ const elapsedStr = item.elapsed ? theme.fg("dim", ` (+${item.elapsed})`) : "";
97
+
98
+ const titleLine = `${theme.fg(color, icon)} ${theme.bold(item.title)} ${timeStr}${elapsedStr}`;
99
+ cardBox.addChild(new Text(titleLine, 0, 0));
100
+
101
+ if (isExpanded) {
102
+ cardBox.addChild(new Spacer(1));
103
+ cardBox.addChild(new Markdown(item.content, 2, 0, mdTheme));
104
+ } else {
105
+ // Truncated preview
106
+ const preview = item.content.replace(/\n/g, ' ').substring(0, width - 10);
107
+ cardBox.addChild(new Text(theme.fg("dim", " " + preview + "..."), 0, 0));
108
+ }
109
+
110
+ container.addChild(cardBox);
111
+ // Don't add too many spacers if we have many items
112
+ if (visibleItems.length < 15) container.addChild(new Spacer(1));
113
+ });
114
+
115
+ // Footer
116
+ container.addChild(new Spacer(1));
117
+ container.addChild(new Text(theme.fg("dim", " ↑/↓ Navigate • Enter Expand • Esc Close"), 1, 0));
118
+ container.addChild(new DynamicBorder((s: string) => theme.fg("accent", s)));
119
+
120
+ return container.render(width);
121
+ }
122
+ }
123
+
124
+ function extractContent(entry: any): string {
125
+ const msg = entry.message;
126
+ if (!msg) return "";
127
+ const content = msg.content;
128
+ if (!content) return "";
129
+ if (typeof content === "string") return content;
130
+ if (Array.isArray(content)) {
131
+ return content
132
+ .map((c: any) => {
133
+ if (c.type === "text") return c.text || "";
134
+ if (c.type === "toolCall") return `Tool: ${c.name}(${JSON.stringify(c.arguments).slice(0, 200)})`;
135
+ return "";
136
+ })
137
+ .filter(Boolean)
138
+ .join("\n");
139
+ }
140
+ return JSON.stringify(content).slice(0, 500);
141
+ }
142
+
143
+ export default function(pi: ExtensionAPI) {
144
+ pi.registerCommand("replay", {
145
+ description: "Show a scrollable timeline of the current session",
146
+ handler: async (args, ctx) => {
147
+ const branch = ctx.sessionManager.getBranch();
148
+ const items: HistoryItem[] = [];
149
+
150
+ let prevTime: Date | null = null;
151
+
152
+ for (const entry of branch) {
153
+ if (entry.type !== "message") continue;
154
+ const msg = entry.message;
155
+ if (!msg) continue;
156
+
157
+ const ts = msg.timestamp ? new Date(msg.timestamp) : new Date();
158
+ const elapsed = prevTime ? getElapsedTime(prevTime, ts) : undefined;
159
+ prevTime = ts;
160
+
161
+ const role = msg.role;
162
+ const text = extractContent(entry);
163
+ if (!text) continue;
164
+
165
+ if (role === "user") {
166
+ items.push({
167
+ type: "user",
168
+ title: "User Prompt",
169
+ content: text,
170
+ timestamp: ts,
171
+ elapsed,
172
+ });
173
+ } else if (role === "assistant") {
174
+ items.push({
175
+ type: "assistant",
176
+ title: "Assistant",
177
+ content: text,
178
+ timestamp: ts,
179
+ elapsed,
180
+ });
181
+ } else if (role === "toolResult") {
182
+ const toolName = (msg as any).toolName || "tool";
183
+ items.push({
184
+ type: "tool",
185
+ title: `Tool: ${toolName}`,
186
+ content: text,
187
+ timestamp: ts,
188
+ elapsed,
189
+ });
190
+ }
191
+ }
192
+
193
+ if (items.length === 0) {
194
+ ctx.ui.notify("No session history found.", "warning");
195
+ return;
196
+ }
197
+
198
+ await ctx.ui.custom((tui, theme, kb, done) => {
199
+ const component = new SessionReplayUI(items, () => done(undefined));
200
+ return {
201
+ render: (w) => component.render(w, 30, theme),
202
+ handleInput: (data) => component.handleInput(data, tui),
203
+ invalidate: () => {},
204
+ };
205
+ }, {
206
+ overlay: true,
207
+ overlayOptions: { width: "80%", anchor: "center" },
208
+ });
209
+ },
210
+ });
211
+
212
+ pi.on("session_start", async (_event, ctx) => {
213
+ });
214
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "agent-skills-pi-session-replay",
3
+ "private": true,
4
+ "type": "module",
5
+ "main": "index.ts"
6
+ }
@@ -0,0 +1,36 @@
1
+ # subagent-widget
2
+
3
+ Background subagents with stacking live widgets.
4
+
5
+ > Ported from [`pi-vs-claude-code`](https://github.com/disler/pi-vs-claude-code) by [disler](https://github.com/disler) (MIT). See the [extension catalog](../../../docs/pi-extensions.md).
6
+
7
+ ## What it does
8
+
9
+ `/sub <task>` spawns a background pi subagent with its own persistent session and a live
10
+ widget that streams its progress. Multiple subagents stack as separate widgets, and each
11
+ can be resumed with a follow-up via `/subcont`.
12
+
13
+ ## Commands & tools
14
+
15
+ - `/sub <task>` — spawn a new background subagent
16
+ - `/subcont <n> <task>` — continue subagent #n's conversation with a new prompt
17
+ - `/subrm <n>` — remove subagent #n's widget
18
+ - `/subclear` — clear all subagent widgets
19
+
20
+ ## Usage
21
+
22
+ ```bash
23
+ pi -e .pi/harnesses/subagent-widget/index.ts
24
+ ```
25
+
26
+ Then, for example:
27
+
28
+ ```
29
+ /sub list files and summarize
30
+ /subcont 1 now write tests for it
31
+ ```
32
+
33
+ ## Upstream changes
34
+
35
+ - Theme integration removed — the `themeMap.ts` import and the `applyExtensionDefaults()`
36
+ call were stripped (this repo does not ship pi themes).