shariq-pi-extensions 0.1.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 (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +94 -0
  3. package/THIRD_PARTY_NOTICES.md +11 -0
  4. package/docs/ARCHITECTURE.md +54 -0
  5. package/docs/DEVELOPMENT.md +88 -0
  6. package/docs/EXTENSIONS.md +89 -0
  7. package/extensions/antigravity-provider/LICENSE +21 -0
  8. package/extensions/antigravity-provider/README.md +23 -0
  9. package/extensions/antigravity-provider/antigravity/cloud-code-assist.ts +519 -0
  10. package/extensions/antigravity-provider/antigravity/index.ts +67 -0
  11. package/extensions/antigravity-provider/antigravity/models.ts +184 -0
  12. package/extensions/antigravity-provider/antigravity/oauth.ts +499 -0
  13. package/extensions/antigravity-provider/index.ts +3 -0
  14. package/extensions/ask-user/README.md +21 -0
  15. package/extensions/ask-user/index.ts +417 -0
  16. package/extensions/background-terminals/README.md +43 -0
  17. package/extensions/background-terminals/index.ts +400 -0
  18. package/extensions/background-terminals/src/manager.ts +480 -0
  19. package/extensions/background-terminals/src/output-buffer.ts +110 -0
  20. package/extensions/background-terminals/src/presentation.ts +74 -0
  21. package/extensions/background-terminals/src/types.ts +47 -0
  22. package/extensions/background-terminals/src/ui.ts +478 -0
  23. package/extensions/context-usage/LICENSE +21 -0
  24. package/extensions/context-usage/README.md +20 -0
  25. package/extensions/context-usage/index.ts +2006 -0
  26. package/extensions/context-usage/lib/ansi.ts +60 -0
  27. package/extensions/context-usage/lib/boundary.ts +27 -0
  28. package/extensions/context-usage/lib/chat.ts +190 -0
  29. package/extensions/context-usage/lib/config.ts +30 -0
  30. package/extensions/context-usage/lib/fmt.ts +59 -0
  31. package/extensions/context-usage/lib/style.ts +260 -0
  32. package/extensions/copy-all/README.md +15 -0
  33. package/extensions/copy-all/index.ts +72 -0
  34. package/extensions/factory-provider/API_KEYS.md +17 -0
  35. package/extensions/factory-provider/AUTH.md +15 -0
  36. package/extensions/factory-provider/README.md +90 -0
  37. package/extensions/factory-provider/REFRESH_MODELS.md +185 -0
  38. package/extensions/factory-provider/UPDATING.md +97 -0
  39. package/extensions/factory-provider/factory/api-keys.ts +407 -0
  40. package/extensions/factory-provider/factory/auth.ts +132 -0
  41. package/extensions/factory-provider/factory/constants.ts +15 -0
  42. package/extensions/factory-provider/factory/dashboard.ts +363 -0
  43. package/extensions/factory-provider/factory/droid.ts +84 -0
  44. package/extensions/factory-provider/factory/limits.ts +342 -0
  45. package/extensions/factory-provider/factory/models.ts +283 -0
  46. package/extensions/factory-provider/factory/responses.ts +331 -0
  47. package/extensions/factory-provider/factory/warm-theme.ts +53 -0
  48. package/extensions/factory-provider/factory/websocket.ts +130 -0
  49. package/extensions/factory-provider/index.ts +204 -0
  50. package/extensions/factory-provider/scripts/audit-reasoning-efforts.py +84 -0
  51. package/extensions/firecrawl-web/README.md +31 -0
  52. package/extensions/firecrawl-web/auth.ts +92 -0
  53. package/extensions/firecrawl-web/client.ts +238 -0
  54. package/extensions/firecrawl-web/index.ts +96 -0
  55. package/extensions/firecrawl-web/output.ts +125 -0
  56. package/extensions/git-info/README.md +25 -0
  57. package/extensions/git-info/index.ts +162 -0
  58. package/extensions/git-info/src/git.ts +206 -0
  59. package/extensions/git-info/src/ui.ts +291 -0
  60. package/extensions/goal/README.md +44 -0
  61. package/extensions/goal/constants.ts +4 -0
  62. package/extensions/goal/extension.ts +1064 -0
  63. package/extensions/goal/index.ts +2 -0
  64. package/extensions/goal/types.ts +56 -0
  65. package/extensions/goal/ui.ts +334 -0
  66. package/extensions/orchestration/README.md +58 -0
  67. package/extensions/orchestration/dashboard.ts +192 -0
  68. package/extensions/orchestration/engine.ts +706 -0
  69. package/extensions/orchestration/index.ts +243 -0
  70. package/extensions/orchestration/prompts.ts +124 -0
  71. package/extensions/orchestration/protocol.ts +116 -0
  72. package/extensions/orchestration/settings-ui.ts +41 -0
  73. package/extensions/orchestration/settings.ts +59 -0
  74. package/extensions/orchestration/storage.ts +49 -0
  75. package/extensions/orchestration/types.ts +105 -0
  76. package/extensions/performance-status/README.md +5 -0
  77. package/extensions/performance-status/index.ts +171 -0
  78. package/extensions/pi-memory/README.md +53 -0
  79. package/extensions/pi-memory/index.ts +326 -0
  80. package/extensions/pi-memory/src/config.ts +75 -0
  81. package/extensions/pi-memory/src/database.ts +617 -0
  82. package/extensions/pi-memory/src/extraction.ts +178 -0
  83. package/extensions/pi-memory/src/project.ts +80 -0
  84. package/extensions/pi-memory/src/projection.ts +59 -0
  85. package/extensions/pi-memory/src/redaction.ts +60 -0
  86. package/extensions/pi-memory/src/retrieval.ts +30 -0
  87. package/extensions/pi-memory/src/service.ts +194 -0
  88. package/extensions/pi-memory/src/session.ts +146 -0
  89. package/extensions/pi-memory/src/types.ts +82 -0
  90. package/extensions/shared/README.md +18 -0
  91. package/extensions/shared/activity-status.ts +31 -0
  92. package/extensions/shared/child-session.ts +150 -0
  93. package/extensions/shared/context-utilization.ts +47 -0
  94. package/extensions/shared/dashboard-state.ts +99 -0
  95. package/extensions/shared/tool-call-timeout.ts +104 -0
  96. package/extensions/shared/tui-dashboard.ts +139 -0
  97. package/extensions/shell-shortcuts/README.md +17 -0
  98. package/extensions/shell-shortcuts/features/exit-alias.ts +10 -0
  99. package/extensions/shell-shortcuts/index.ts +6 -0
  100. package/extensions/subagents/README.md +89 -0
  101. package/extensions/subagents/index.ts +1386 -0
  102. package/extensions/subagents/src/backend.ts +69 -0
  103. package/extensions/subagents/src/backends/pi.ts +781 -0
  104. package/extensions/subagents/src/catalog.ts +85 -0
  105. package/extensions/subagents/src/config.ts +241 -0
  106. package/extensions/subagents/src/context.ts +57 -0
  107. package/extensions/subagents/src/coordinator.ts +64 -0
  108. package/extensions/subagents/src/domain.ts +294 -0
  109. package/extensions/subagents/src/format.ts +74 -0
  110. package/extensions/subagents/src/manager.ts +813 -0
  111. package/extensions/subagents/src/prompt.ts +94 -0
  112. package/extensions/subagents/src/result-delivery.ts +20 -0
  113. package/extensions/subagents/src/runtime.ts +48 -0
  114. package/extensions/subagents/src/ui/takeover.ts +695 -0
  115. package/extensions/subagents/src/ui/transcript.ts +182 -0
  116. package/extensions/subagents/src/worktree.ts +175 -0
  117. package/extensions/web-fetch/README.md +13 -0
  118. package/extensions/web-fetch/index.ts +441 -0
  119. package/package.json +117 -0
  120. package/skills/background-terminals/SKILL.md +42 -0
  121. package/skills/orchestration/SKILL.md +33 -0
  122. package/skills/subagents/SKILL.md +89 -0
  123. package/themes/ember-warm-dark.json +85 -0
@@ -0,0 +1,139 @@
1
+ import type { Theme } from "@earendil-works/pi-coding-agent";
2
+ import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
3
+
4
+ export type SemanticState =
5
+ | "active"
6
+ | "success"
7
+ | "warning"
8
+ | "error"
9
+ | "muted";
10
+
11
+ const STATE_COLORS = {
12
+ active: "accent",
13
+ success: "success",
14
+ warning: "warning",
15
+ error: "error",
16
+ muted: "muted",
17
+ } as const;
18
+
19
+ export function stateDot(theme: Theme, state: SemanticState): string {
20
+ return theme.fg(STATE_COLORS[state], "●");
21
+ }
22
+
23
+ export function stateLabel(
24
+ theme: Theme,
25
+ state: SemanticState,
26
+ label: string,
27
+ ): string {
28
+ return `${stateDot(theme, state)} ${theme.fg(STATE_COLORS[state], label)}`;
29
+ }
30
+
31
+ export function sanitizeTerminalText(text: string): string {
32
+ return text
33
+ .replace(/(?:\u001b\]|\u009d)(?:[^\u0007\u001b\u009c]|\u001b(?!\\))*(?:\u0007|\u001b\\|\u009c)/g, "")
34
+ .replace(/(?:\u001b\[|\u009b)[0-?]*[ -/]*[@-~]/g, "")
35
+ .replace(/\u001b(?:[()][0-2A-Z]|[ -/]*[@-~])/g, "")
36
+ .replaceAll("\t", " ")
37
+ .replace(/[\u0000-\u0008\u000b-\u001f\u007f-\u009f]/g, "");
38
+ }
39
+
40
+ export function oneLine(text: string): string {
41
+ return sanitizeTerminalText(text).replace(/\s+/g, " ").trim();
42
+ }
43
+
44
+ export function padLine(text: string, width: number): string {
45
+ const safeWidth = Math.max(0, width);
46
+ const truncated = truncateToWidth(text, safeWidth, "");
47
+ return truncated + " ".repeat(Math.max(0, safeWidth - visibleWidth(truncated)));
48
+ }
49
+
50
+ export function joinSides(left: string, right: string, width: number): string {
51
+ const safeWidth = Math.max(0, width);
52
+ const rightWidth = visibleWidth(right);
53
+ if (rightWidth >= safeWidth) return truncateToWidth(right, safeWidth);
54
+ const leftWidth = Math.max(0, safeWidth - rightWidth - 1);
55
+ const fittedLeft = truncateToWidth(left, leftWidth, "…");
56
+ return truncateToWidth(
57
+ fittedLeft + " ".repeat(Math.max(1, safeWidth - visibleWidth(fittedLeft) - rightWidth)) + right,
58
+ safeWidth,
59
+ );
60
+ }
61
+
62
+ export function rule(theme: Theme, width: number, accent = false): string {
63
+ return theme.fg(accent ? "borderAccent" : "border", "─".repeat(Math.max(0, width)));
64
+ }
65
+
66
+ export function framedRow(
67
+ theme: Theme,
68
+ content: string,
69
+ width: number,
70
+ selected = false,
71
+ ): string {
72
+ const innerWidth = Math.max(0, width - 2);
73
+ const body = padLine(content, innerWidth);
74
+ const row = `${theme.fg(selected ? "borderAccent" : "border", "│")}${body}${theme.fg(selected ? "borderAccent" : "border", "│")}`;
75
+ return selected ? theme.bg("selectedBg", row) : row;
76
+ }
77
+
78
+ export function frameTop(theme: Theme, width: number, title = ""): string {
79
+ const inner = Math.max(0, width - 2);
80
+ const label = title ? ` ${oneLine(title)} ` : "";
81
+ const fitted = truncateToWidth(label, Math.max(0, inner - 1), "…");
82
+ return (
83
+ theme.fg("border", "╭") +
84
+ (fitted ? theme.fg("muted", fitted) : "") +
85
+ theme.fg("border", "─".repeat(Math.max(0, inner - visibleWidth(fitted)))) +
86
+ theme.fg("border", "╮")
87
+ );
88
+ }
89
+
90
+ export function frameBottom(theme: Theme, width: number): string {
91
+ return (
92
+ theme.fg("border", "╰") +
93
+ theme.fg("border", "─".repeat(Math.max(0, width - 2))) +
94
+ theme.fg("border", "╯")
95
+ );
96
+ }
97
+
98
+ export function meter(
99
+ theme: Theme,
100
+ value: number,
101
+ total: number,
102
+ width: number,
103
+ state: SemanticState = "active",
104
+ ): string {
105
+ const safeWidth = Math.max(3, width);
106
+ const ratio = total > 0 ? Math.min(1, Math.max(0, value / total)) : 0;
107
+ const percent = Math.round(ratio * 100);
108
+ const percentText = `${percent}%`;
109
+ const barWidth = Math.max(1, safeWidth - percentText.length - 1);
110
+ const filled = Math.min(barWidth, Math.round(barWidth * ratio));
111
+ const bar =
112
+ theme.fg(STATE_COLORS[state], "━".repeat(filled)) +
113
+ theme.fg("borderMuted", "─".repeat(Math.max(0, barWidth - filled)));
114
+ return `${bar} ${theme.fg("muted", percentText)}`;
115
+ }
116
+
117
+ export function formatDurationMs(milliseconds: number): string {
118
+ const seconds = Math.max(0, Math.floor(milliseconds / 1000));
119
+ const hours = Math.floor(seconds / 3600);
120
+ const minutes = Math.floor((seconds % 3600) / 60);
121
+ const remainder = seconds % 60;
122
+ if (hours > 0) return `${hours}h ${minutes.toString().padStart(2, "0")}m`;
123
+ if (minutes > 0) return `${minutes}m ${remainder.toString().padStart(2, "0")}s`;
124
+ return `${remainder}s`;
125
+ }
126
+
127
+ export function viewportSlice<T>(
128
+ items: ReadonlyArray<T>,
129
+ selectedIndex: number,
130
+ height: number,
131
+ ): { start: number; items: ReadonlyArray<T> } {
132
+ const safeHeight = Math.max(0, height);
133
+ if (items.length <= safeHeight) return { start: 0, items };
134
+ const start = Math.min(
135
+ Math.max(0, selectedIndex - Math.floor(safeHeight / 2)),
136
+ Math.max(0, items.length - safeHeight),
137
+ );
138
+ return { start, items: items.slice(start, start + safeHeight) };
139
+ }
@@ -0,0 +1,17 @@
1
+ # Pi shell shortcuts
2
+
3
+ Small always-on quality-of-life features for local Pi.
4
+
5
+ ## Features
6
+
7
+ - `features/exit-alias.ts` — adds `/exit` as an alias for `/quit`.
8
+
9
+ ## Removed
10
+
11
+ - `features/native-max-thinking.ts` was removed because Pi 0.80.7 supports `--thinking max` natively.
12
+
13
+ ## When to add here
14
+
15
+ Add tiny, low-risk workflow conveniences here when they do not deserve a standalone extension.
16
+
17
+ Keep larger or security-sensitive systems separate, such as provider auth, web search, subagents, MCP, and persistent goals.
@@ -0,0 +1,10 @@
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+
3
+ export default function exitAliasExtension(pi: ExtensionAPI) {
4
+ pi.registerCommand("exit", {
5
+ description: "Alias for /quit",
6
+ handler: async (_args, ctx) => {
7
+ ctx.shutdown();
8
+ },
9
+ });
10
+ }
@@ -0,0 +1,6 @@
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+ import exitAliasExtension from "./features/exit-alias.ts";
3
+
4
+ export default function qolExtension(pi: ExtensionAPI) {
5
+ exitAliasExtension(pi);
6
+ }
@@ -0,0 +1,89 @@
1
+ # Pi subagents
2
+
3
+ A Pi-only subagent system with an Effect-managed lifecycle, persistent child sessions, configurable profiles, context forks, resumability, worktree isolation, and a live takeover dashboard.
4
+
5
+ ## Topology
6
+
7
+ The system is deliberately flat. Only the main Pi thread can spawn subagents. Children may list and message existing peers through the main-thread manager, but they do not receive spawn, agent-management, or workflow tools. This permits collaboration without recursive fan-out or runaway agent trees.
8
+
9
+ ## Parent tools
10
+
11
+ - `spawn_agent` — start a background child with an optional profile, persona, capability mode, context fork, model override, or isolated worktree
12
+ - `wait_agent` — collect results already available and report running children as pending without blocking
13
+ - `close_agent` — interrupt children while retaining their transcripts
14
+ - `check_agent` — inspect live activity without waiting
15
+ - `list_agent_profiles` — discover active profiles, personas, defaults, and concurrency
16
+ - `list_agents` — list live and globally archived/resumable children
17
+ - `send_message` — steer a running child or start its next turn
18
+ - `apply_agent_changes` — inspect, patch, cherry-pick, merge, or discard an isolated child worktree
19
+ - `reply_question` — answer a child’s blocking `ask_parent` request
20
+ - `task` — atomically reserve capacity for up to the configured limit (maximum 50), start the fan-out in the background, and return child ids immediately
21
+
22
+ Child sessions receive `message_parent`, `ask_parent`, `list_peers`, and `message_peer`. Peer messages are routed through the main-thread manager and can steer a running child or continue a settled one; they cannot create agents. Background completions wake the parent automatically, so the main turn can continue independent work or end and remain available to the user.
23
+
24
+ ## Profiles and capabilities
25
+
26
+ Built-in profiles:
27
+
28
+ - `general-purpose` — unrestricted coding worker
29
+ - `explore` — investigation with read and command execution, but no file edits
30
+ - `plan` — investigation followed by a concrete implementation plan, with no file edits
31
+
32
+ Capability modes:
33
+
34
+ - `read-only` — allowlisted read/search and parent-communication tools only
35
+ - `read-write` — the read-only allowlist plus direct file write/edit tools, without shell execution
36
+ - `execute` — the read-only allowlist plus shell and background-terminal execution, without direct file edit tools
37
+ - `all` — full child tool access
38
+
39
+ Restrictive modes fail closed: newly registered extension tools remain unavailable until they are explicitly classified. This prevents another extension from silently bypassing the selected capability.
40
+
41
+ Optional user profiles and personas can be defined in `~/.pi/agent/subagents.json`. Trusted projects may override them in `.pi/subagents.json`:
42
+
43
+ ```json
44
+ {
45
+ "maxConcurrent": 6,
46
+ "profiles": {
47
+ "reviewer": {
48
+ "description": "Review changes without editing",
49
+ "instructions": "Find correctness and regression risks. Cite files and lines.",
50
+ "capability": "execute"
51
+ }
52
+ },
53
+ "personas": {
54
+ "concise": {
55
+ "instructions": "Return only findings, evidence, and the recommended action."
56
+ }
57
+ }
58
+ }
59
+ ```
60
+
61
+ Project configuration is ignored when the project is not trusted. Concurrency is bounded to 1–50; this private package defaults to 50. `/subagents profiles` provides discovery, while `/subagents config` opens a validated editor for global or trusted-project configuration.
62
+
63
+ ## Context and continuation
64
+
65
+ New children start with independent context by default. `fork_turns` may be `all` or a positive number of recent user turns. Forking keeps user messages and final assistant text while removing thinking, tool calls, and tool results so the child never inherits an unresolved tool protocol.
66
+
67
+ Every child uses a persistent Pi session file. `resume_from` continues a completed child with its full transcript, tool state, and logical agent id, including after a parent `/reload` or resume. Non-secret metadata is stored both in the parent session and in `~/.pi/agent/subagents/catalog.json`, so children created by an ephemeral or different parent process remain discoverable. Existing legacy ids remain valid catalog keys.
68
+
69
+ ## Worktree isolation
70
+
71
+ Children share the requested workspace by default. Use `isolation: "worktree"` only when the user requests it, a configured profile requires it, or concurrent write tasks are likely to overlap or interfere. Read-only work and edits to clearly separate areas should stay in the shared workspace.
72
+
73
+ `isolation: "worktree"` requires a clean source checkout, then creates a dedicated branch and persistent git worktree from `HEAD` under `~/.pi/agent/subagent-worktrees/`. A dirty source is rejected rather than silently giving the child stale code; commit or stash first, or use the shared workspace. `apply_agent_changes` supports `inspect`, checked patch application, commit-preserving cherry-pick, merge, and permanent discard. Cherry-pick and merge first run in a temporary worktree; conflicts leave the source checkout unchanged. Discard requires confirmation in interactive mode. A failed spawn removes the worktree it created; completed worktrees remain available for inspection or continuation.
74
+
75
+ ## UI
76
+
77
+ `/subagents` or `/subagents agents` opens the live operations dashboard and takeover UI. `/btw <question>` starts a read-only, context-aware side investigation owned by the user; it opens directly in takeover view and records its answer without waking the parent model. Wide terminals use a split-pane agent list and selected-agent inspector with running/completed/failed counts, model/profile/access metadata, a context meter, current tool activity, queue state, elapsed time, turns, cwd, and latest output. The takeover view adds a live transcript, context meter, active-tool state, scrolling, child interruption, and follow-up input. `/subagents peers` shows the persistent peer-message audit trail. `/subagents profiles` browses profiles and personas, and `/subagents config` edits validated configuration.
78
+
79
+ ## Architecture
80
+
81
+ - `src/manager.ts` — Effect service, bounded lifecycle, normalized snapshots, cancellation, and retention
82
+ - `src/backends/pi.ts` — in-process Pi sessions, trust-gated resources, capability filtering, context seeding, resume, and parent bridge
83
+ - `src/config.ts` — built-in and user/project profiles, personas, validation, and limits
84
+ - `src/catalog.ts` — global non-secret resumable-agent catalog
85
+ - `src/context.ts` — safe context-fork selection and profile prompt assembly
86
+ - `src/worktree.ts` — isolated worktree creation, inspection, conflict preflight, integration, and cleanup
87
+ - `src/runtime.ts` — managed runtime and Pi backend registry
88
+ - `src/ui/` — dashboard, transcript, and takeover components
89
+ - `src/result-delivery.ts` — deferred automatic result delivery