@jx-grxf/patchpilot 1.0.0 → 1.2.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 (154) hide show
  1. package/README.md +51 -16
  2. package/dist/cli.js +46 -3
  3. package/dist/cli.js.map +1 -1
  4. package/dist/core/agent.d.ts +44 -1
  5. package/dist/core/agent.js +617 -70
  6. package/dist/core/agent.js.map +1 -1
  7. package/dist/core/clipboard.d.ts +14 -0
  8. package/dist/core/clipboard.js +134 -0
  9. package/dist/core/clipboard.js.map +1 -0
  10. package/dist/core/codex.d.ts +8 -0
  11. package/dist/core/codex.js +28 -2
  12. package/dist/core/codex.js.map +1 -1
  13. package/dist/core/compaction.d.ts +23 -0
  14. package/dist/core/compaction.js +145 -0
  15. package/dist/core/compaction.js.map +1 -0
  16. package/dist/core/contextFormat.d.ts +21 -0
  17. package/dist/core/contextFormat.js +87 -0
  18. package/dist/core/contextFormat.js.map +1 -0
  19. package/dist/core/contextItem.d.ts +41 -0
  20. package/dist/core/contextItem.js +93 -0
  21. package/dist/core/contextItem.js.map +1 -0
  22. package/dist/core/contextStore.d.ts +48 -0
  23. package/dist/core/contextStore.js +306 -0
  24. package/dist/core/contextStore.js.map +1 -0
  25. package/dist/core/doctor.js +9 -8
  26. package/dist/core/doctor.js.map +1 -1
  27. package/dist/core/gemini.js +10 -4
  28. package/dist/core/gemini.js.map +1 -1
  29. package/dist/core/geminiWrapper.d.ts +43 -2
  30. package/dist/core/geminiWrapper.js +582 -42
  31. package/dist/core/geminiWrapper.js.map +1 -1
  32. package/dist/core/http.js +70 -6
  33. package/dist/core/http.js.map +1 -1
  34. package/dist/core/json.d.ts +1 -1
  35. package/dist/core/json.js +18 -20
  36. package/dist/core/json.js.map +1 -1
  37. package/dist/core/nvidia.d.ts +1 -1
  38. package/dist/core/nvidia.js +13 -4
  39. package/dist/core/nvidia.js.map +1 -1
  40. package/dist/core/ollama.js +13 -3
  41. package/dist/core/ollama.js.map +1 -1
  42. package/dist/core/openrouter.js +15 -6
  43. package/dist/core/openrouter.js.map +1 -1
  44. package/dist/core/reasoning.js +3 -0
  45. package/dist/core/reasoning.js.map +1 -1
  46. package/dist/core/session.js +9 -3
  47. package/dist/core/session.js.map +1 -1
  48. package/dist/core/tokenAccounting.d.ts +4 -0
  49. package/dist/core/tokenAccounting.js +75 -13
  50. package/dist/core/tokenAccounting.js.map +1 -1
  51. package/dist/core/types.d.ts +58 -3
  52. package/dist/core/types.js +30 -1
  53. package/dist/core/types.js.map +1 -1
  54. package/dist/core/updateCheck.d.ts +19 -0
  55. package/dist/core/updateCheck.js +103 -0
  56. package/dist/core/updateCheck.js.map +1 -0
  57. package/dist/core/workspace.d.ts +29 -0
  58. package/dist/core/workspace.js +1271 -92
  59. package/dist/core/workspace.js.map +1 -1
  60. package/dist/tui/App.d.ts +1 -0
  61. package/dist/tui/App.js +1346 -112
  62. package/dist/tui/App.js.map +1 -1
  63. package/dist/tui/commands.js +109 -6
  64. package/dist/tui/commands.js.map +1 -1
  65. package/dist/tui/components/ApprovalPanel.js +16 -1
  66. package/dist/tui/components/ApprovalPanel.js.map +1 -1
  67. package/dist/tui/components/CommandSuggestions.js +26 -3
  68. package/dist/tui/components/CommandSuggestions.js.map +1 -1
  69. package/dist/tui/components/Composer.d.ts +3 -0
  70. package/dist/tui/components/Composer.js +57 -5
  71. package/dist/tui/components/Composer.js.map +1 -1
  72. package/dist/tui/components/ExperimentalPanel.d.ts +1 -1
  73. package/dist/tui/components/ExperimentalPanel.js +5 -0
  74. package/dist/tui/components/ExperimentalPanel.js.map +1 -1
  75. package/dist/tui/components/OnboardingPanel.d.ts +12 -0
  76. package/dist/tui/components/OnboardingPanel.js +69 -21
  77. package/dist/tui/components/OnboardingPanel.js.map +1 -1
  78. package/dist/tui/components/StartupBanner.d.ts +4 -0
  79. package/dist/tui/components/StartupBanner.js +9 -0
  80. package/dist/tui/components/StartupBanner.js.map +1 -0
  81. package/dist/tui/components/Transcript.d.ts +7 -0
  82. package/dist/tui/components/Transcript.js +86 -16
  83. package/dist/tui/components/Transcript.js.map +1 -1
  84. package/dist/tui/contextCommands.d.ts +8 -0
  85. package/dist/tui/contextCommands.js +205 -0
  86. package/dist/tui/contextCommands.js.map +1 -0
  87. package/dist/tui/experimental/AnimatedText.d.ts +38 -0
  88. package/dist/tui/experimental/AnimatedText.js +55 -0
  89. package/dist/tui/experimental/AnimatedText.js.map +1 -0
  90. package/dist/tui/experimental/Banner.d.ts +10 -0
  91. package/dist/tui/experimental/Banner.js +33 -0
  92. package/dist/tui/experimental/Banner.js.map +1 -0
  93. package/dist/tui/experimental/CommandPalette.d.ts +11 -0
  94. package/dist/tui/experimental/CommandPalette.js +25 -0
  95. package/dist/tui/experimental/CommandPalette.js.map +1 -0
  96. package/dist/tui/experimental/ExperimentalShell.d.ts +58 -0
  97. package/dist/tui/experimental/ExperimentalShell.js +366 -0
  98. package/dist/tui/experimental/ExperimentalShell.js.map +1 -0
  99. package/dist/tui/experimental/ThemePicker.d.ts +13 -0
  100. package/dist/tui/experimental/ThemePicker.js +12 -0
  101. package/dist/tui/experimental/ThemePicker.js.map +1 -0
  102. package/dist/tui/experimental/attachments.d.ts +35 -0
  103. package/dist/tui/experimental/attachments.js +244 -0
  104. package/dist/tui/experimental/attachments.js.map +1 -0
  105. package/dist/tui/experimental/composer.d.ts +24 -0
  106. package/dist/tui/experimental/composer.js +84 -0
  107. package/dist/tui/experimental/composer.js.map +1 -0
  108. package/dist/tui/experimental/geminiPricing.d.ts +16 -0
  109. package/dist/tui/experimental/geminiPricing.js +39 -0
  110. package/dist/tui/experimental/geminiPricing.js.map +1 -0
  111. package/dist/tui/experimental/layout.d.ts +46 -0
  112. package/dist/tui/experimental/layout.js +112 -0
  113. package/dist/tui/experimental/layout.js.map +1 -0
  114. package/dist/tui/experimental/theme.d.ts +35 -0
  115. package/dist/tui/experimental/theme.js +86 -0
  116. package/dist/tui/experimental/theme.js.map +1 -0
  117. package/dist/tui/experimental/transcriptRows.d.ts +20 -0
  118. package/dist/tui/experimental/transcriptRows.js +169 -0
  119. package/dist/tui/experimental/transcriptRows.js.map +1 -0
  120. package/dist/tui/experimental/ultraModes.d.ts +46 -0
  121. package/dist/tui/experimental/ultraModes.js +95 -0
  122. package/dist/tui/experimental/ultraModes.js.map +1 -0
  123. package/dist/tui/experimental/ultramaxx.d.ts +19 -0
  124. package/dist/tui/experimental/ultramaxx.js +43 -0
  125. package/dist/tui/experimental/ultramaxx.js.map +1 -0
  126. package/dist/tui/format.d.ts +4 -2
  127. package/dist/tui/format.js +14 -0
  128. package/dist/tui/format.js.map +1 -1
  129. package/dist/tui/hosts.js +7 -1
  130. package/dist/tui/hosts.js.map +1 -1
  131. package/dist/tui/layout.d.ts +26 -0
  132. package/dist/tui/layout.js +66 -0
  133. package/dist/tui/layout.js.map +1 -0
  134. package/dist/tui/modelSelection.d.ts +1 -1
  135. package/dist/tui/modelSelection.js +8 -6
  136. package/dist/tui/modelSelection.js.map +1 -1
  137. package/dist/tui/modes.d.ts +7 -0
  138. package/dist/tui/modes.js +12 -0
  139. package/dist/tui/modes.js.map +1 -1
  140. package/dist/tui/onboardingPreferences.d.ts +37 -0
  141. package/dist/tui/onboardingPreferences.js +118 -0
  142. package/dist/tui/onboardingPreferences.js.map +1 -0
  143. package/dist/tui/runStatus.d.ts +50 -0
  144. package/dist/tui/runStatus.js +164 -0
  145. package/dist/tui/runStatus.js.map +1 -0
  146. package/dist/tui/types.d.ts +8 -0
  147. package/dist/tui/types.js.map +1 -1
  148. package/docs/architecture.md +115 -0
  149. package/docs/gemini-wrapper.md +23 -0
  150. package/docs/product-context.md +43 -0
  151. package/docs/releases/v1.0.1.md +25 -0
  152. package/docs/releases/v1.1.0.md +30 -0
  153. package/docs/releases/v1.2.0.md +28 -0
  154. package/package.json +4 -2
@@ -0,0 +1,205 @@
1
+ import { planCompaction } from "../core/compaction.js";
2
+ import { formatContextDashboard } from "../core/contextFormat.js";
3
+ import { ContextStore } from "../core/contextStore.js";
4
+ export async function runContextSlashCommand(options) {
5
+ const store = new ContextStore({
6
+ workspace: options.workspace,
7
+ sessionId: options.sessionId
8
+ });
9
+ if (options.command === "context") {
10
+ return await runContextCommand(store, options.workspace, options.sessionId, options.args);
11
+ }
12
+ return await runCompactCommand(store, options.args);
13
+ }
14
+ async function runContextCommand(store, workspace, sessionId, args) {
15
+ const action = normalizeContextAction(args[0]);
16
+ const snapshot = await store.snapshot();
17
+ const activeItems = snapshot.items.filter((item) => !item.dropped);
18
+ switch (action) {
19
+ case "show":
20
+ return {
21
+ kind: "status",
22
+ tone: activeItems.length > 0 ? "accent" : "muted",
23
+ label: "context",
24
+ text: activeItems.length > 0 ? `Context has ${activeItems.length} active item${activeItems.length === 1 ? "" : "s"}.` : "No active saved context for this session.",
25
+ detail: formatContextDashboard(snapshot)
26
+ };
27
+ case "files": {
28
+ const items = activeItems.filter((item) => item.path || item.kind === "attachment" || item.kind === "artifact" || item.kind === "pinned_file");
29
+ return {
30
+ kind: "status",
31
+ tone: items.length > 0 ? "accent" : "muted",
32
+ label: "context",
33
+ text: items.length > 0 ? `Found ${items.length} path-backed context item${items.length === 1 ? "" : "s"}.` : "No path-backed context items.",
34
+ detail: formatItemList(items)
35
+ };
36
+ }
37
+ case "pins": {
38
+ const items = activeItems.filter((item) => item.pinned);
39
+ return {
40
+ kind: "status",
41
+ tone: items.length > 0 ? "accent" : "muted",
42
+ label: "context",
43
+ text: items.length > 0 ? `Found ${items.length} pinned context item${items.length === 1 ? "" : "s"}.` : "No pinned context items.",
44
+ detail: formatItemList(items)
45
+ };
46
+ }
47
+ case "clear": {
48
+ const clearableCount = activeItems.filter((item) => !item.pinned).length;
49
+ await store.clear({
50
+ includePinned: false
51
+ });
52
+ return {
53
+ kind: "status",
54
+ tone: clearableCount > 0 ? "success" : "muted",
55
+ label: "context",
56
+ text: clearableCount > 0 ? `Cleared ${clearableCount} unpinned context item${clearableCount === 1 ? "" : "s"}.` : "No unpinned context items to clear.",
57
+ detail: "Pinned context remains active."
58
+ };
59
+ }
60
+ case "export": {
61
+ const exportSnapshot = await store.snapshot();
62
+ const snapshotPath = ContextStore.workspaceSnapshotPath(workspace, sessionId);
63
+ return {
64
+ kind: "status",
65
+ tone: "accent",
66
+ label: "context",
67
+ text: `Context snapshot exported to ${snapshotPath}.`,
68
+ detail: JSON.stringify(exportSnapshot, null, 2)
69
+ };
70
+ }
71
+ }
72
+ }
73
+ async function runCompactCommand(store, args) {
74
+ const action = normalizeCompactAction(args[0]);
75
+ switch (action) {
76
+ case "auto": {
77
+ const enabled = normalizeAutoCompactionValue(args[0]?.toLowerCase() === "on" || args[0]?.toLowerCase() === "off" ? args[0] : args[1]);
78
+ await store.setAutoCompaction(enabled);
79
+ return {
80
+ kind: "status",
81
+ tone: "success",
82
+ label: "compact",
83
+ text: `Automatic context compaction ${enabled ? "enabled" : "disabled"}.`
84
+ };
85
+ }
86
+ case "reset":
87
+ await store.resetSummaries();
88
+ await store.setAutoCompaction(false);
89
+ return {
90
+ kind: "status",
91
+ tone: "success",
92
+ label: "compact",
93
+ text: "Context compaction summaries reset and auto-compaction disabled."
94
+ };
95
+ case "now":
96
+ return await compactNow(store);
97
+ }
98
+ }
99
+ async function compactNow(store) {
100
+ const snapshot = await store.snapshot();
101
+ const activeItems = snapshot.items.filter((item) => !item.dropped);
102
+ const plan = planCompaction(activeItems, {
103
+ targetTokens: 0,
104
+ minItemsToCompact: 1
105
+ });
106
+ const summarizedItems = plan.summarize.map((entry) => entry.item);
107
+ const droppedItems = plan.drop.map((entry) => entry.item);
108
+ const itemIds = [...new Set([...summarizedItems, ...droppedItems].map((item) => item.id))];
109
+ if (itemIds.length === 0) {
110
+ return {
111
+ kind: "status",
112
+ tone: "muted",
113
+ label: "compact",
114
+ text: "No eligible unpinned context items to compact.",
115
+ detail: formatCompactionPlan(plan.keep.map((entry) => entry.item), "Kept")
116
+ };
117
+ }
118
+ if (summarizedItems.length > 0) {
119
+ await store.recordSummary({
120
+ label: "manual context compaction",
121
+ text: summarizedItems.map((item) => `${item.kind}: ${item.label}${item.text ? ` - ${clip(item.text, 180)}` : ""}`).join("\n"),
122
+ tokenEstimate: summarizedItems.reduce((total, item) => total + Math.min(item.tokenEstimate, 80), 0),
123
+ priority: 60
124
+ });
125
+ }
126
+ for (const itemId of itemIds) {
127
+ await store.drop(itemId);
128
+ }
129
+ return {
130
+ kind: "status",
131
+ tone: "success",
132
+ label: "compact",
133
+ text: `Compacted ${itemIds.length} context item${itemIds.length === 1 ? "" : "s"}.`,
134
+ detail: [
135
+ `Summarized: ${summarizedItems.length}`,
136
+ `Dropped: ${droppedItems.length}`,
137
+ `Kept: ${plan.keep.length}`,
138
+ plan.blockedSecrets.length > 0 ? `Secret-like items dropped without summary: ${plan.blockedSecrets.length}` : ""
139
+ ]
140
+ .filter(Boolean)
141
+ .join("\n")
142
+ };
143
+ }
144
+ function normalizeContextAction(value) {
145
+ switch (value?.toLowerCase()) {
146
+ case undefined:
147
+ case "":
148
+ case "show":
149
+ case "list":
150
+ return "show";
151
+ case "files":
152
+ case "file":
153
+ return "files";
154
+ case "pins":
155
+ case "pin":
156
+ case "pinned":
157
+ return "pins";
158
+ case "clear":
159
+ return "clear";
160
+ case "export":
161
+ return "export";
162
+ default:
163
+ return "show";
164
+ }
165
+ }
166
+ function normalizeCompactAction(value) {
167
+ switch (value?.toLowerCase()) {
168
+ case "auto":
169
+ case "on":
170
+ case "off":
171
+ return "auto";
172
+ case "reset":
173
+ return "reset";
174
+ case undefined:
175
+ case "":
176
+ case "now":
177
+ default:
178
+ return "now";
179
+ }
180
+ }
181
+ function normalizeAutoCompactionValue(value) {
182
+ if (value?.toLowerCase() === "off" || value?.toLowerCase() === "false" || value === "0") {
183
+ return false;
184
+ }
185
+ return true;
186
+ }
187
+ function formatItemList(items) {
188
+ if (items.length === 0) {
189
+ return "none";
190
+ }
191
+ return items
192
+ .slice(0, 12)
193
+ .map((item, index) => `${index + 1}. ${item.kind}${item.pinned ? " pinned" : ""}: ${clip(item.label, 96)}${item.path ? ` (${item.path})` : ""}`)
194
+ .join("\n");
195
+ }
196
+ function formatCompactionPlan(items, title) {
197
+ if (items.length === 0) {
198
+ return `${title}: none`;
199
+ }
200
+ return `${title}:\n${formatItemList(items)}`;
201
+ }
202
+ function clip(value, maxLength) {
203
+ return value.length <= maxLength ? value : `${value.slice(0, maxLength)}...`;
204
+ }
205
+ //# sourceMappingURL=contextCommands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contextCommands.js","sourceRoot":"","sources":["../../src/tui/contextCommands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import React from "react";
2
+ import type { UltraMode } from "./ultraModes.js";
3
+ /** Rainbow palette for the ultramaxx power mode. */
4
+ export declare const rainbowPalette: string[];
5
+ /**
6
+ * Per-ultra-mode colour gradients. Each mode flows its own palette so the
7
+ * keyword reads at a glance: maxx = hot rainbow, cheap = frugal green,
8
+ * focus = laser cyan, loop = cycling violet.
9
+ */
10
+ export declare const ultraGradients: Record<UltraMode, string[]>;
11
+ /** Flowing-gradient text for any palette — generalises RainbowText. */
12
+ export declare function GradientText(props: {
13
+ text: string;
14
+ palette: string[];
15
+ frame: number;
16
+ bold?: boolean;
17
+ }): React.ReactElement;
18
+ /**
19
+ * Text with a highlight "wave" travelling through it: the verb stays in its
20
+ * base color while a bright crest sweeps across the characters.
21
+ */
22
+ export declare function WaveText(props: {
23
+ text: string;
24
+ frame: number;
25
+ bold?: boolean;
26
+ base?: string;
27
+ crest?: string;
28
+ glow?: string;
29
+ }): React.ReactElement;
30
+ /**
31
+ * Rainbow text with the colors flowing through it — used to render the
32
+ * `ultramaxx` keyword and the spinner verb while ultramaxx mode is active.
33
+ */
34
+ export declare function RainbowText(props: {
35
+ text: string;
36
+ frame: number;
37
+ bold?: boolean;
38
+ }): React.ReactElement;
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Text } from "ink";
3
+ /** Orange base + white crest, used for normal run-status verbs. */
4
+ const WAVE_BASE = "#f6a13d";
5
+ const WAVE_CREST = "#ffffff";
6
+ const WAVE_GLOW = "#ffd9a0";
7
+ /** Rainbow palette for the ultramaxx power mode. */
8
+ export const rainbowPalette = ["#ff5f7e", "#ff9d3c", "#ffe14a", "#5fe08a", "#4fc6ff", "#9d8bff", "#ff7ad9"];
9
+ /**
10
+ * Per-ultra-mode colour gradients. Each mode flows its own palette so the
11
+ * keyword reads at a glance: maxx = hot rainbow, cheap = frugal green,
12
+ * focus = laser cyan, loop = cycling violet.
13
+ */
14
+ export const ultraGradients = {
15
+ maxx: rainbowPalette,
16
+ cheap: ["#3fae6a", "#5fe08a", "#9fe8b8", "#5fe08a", "#3fae6a"],
17
+ fast: ["#ff8a3d", "#ffd54a", "#fff1a8", "#ffd54a", "#ff8a3d"],
18
+ focus: ["#2f8fd0", "#4fc6ff", "#bdeaff", "#4fc6ff", "#2f8fd0"],
19
+ loop: ["#7a5fff", "#9d8bff", "#c77dff", "#9d8bff", "#7a5fff"],
20
+ };
21
+ /** Flowing-gradient text for any palette — generalises RainbowText. */
22
+ export function GradientText(props) {
23
+ const chars = [...props.text];
24
+ const palette = props.palette.length > 0 ? props.palette : rainbowPalette;
25
+ return (_jsx(Text, { bold: props.bold, children: chars.map((char, index) => (_jsx(Text, { color: palette[(index + props.frame) % palette.length], children: char }, `grad-${index}`))) }));
26
+ }
27
+ /**
28
+ * Text with a highlight "wave" travelling through it: the verb stays in its
29
+ * base color while a bright crest sweeps across the characters.
30
+ */
31
+ export function WaveText(props) {
32
+ const chars = [...props.text];
33
+ const base = props.base ?? WAVE_BASE;
34
+ const crest = props.crest ?? WAVE_CREST;
35
+ const glow = props.glow ?? WAVE_GLOW;
36
+ const span = chars.length + 6;
37
+ const head = ((props.frame % span) + span) % span;
38
+ return (_jsx(Text, { bold: props.bold, children: chars.map((char, index) => {
39
+ const distance = head - index;
40
+ const color = distance === 0 ? crest : distance === 1 || distance === -1 ? glow : base;
41
+ return (_jsx(Text, { color: color, children: char }, `wave-${index}`));
42
+ }) }));
43
+ }
44
+ /**
45
+ * Rainbow text with the colors flowing through it — used to render the
46
+ * `ultramaxx` keyword and the spinner verb while ultramaxx mode is active.
47
+ */
48
+ export function RainbowText(props) {
49
+ const chars = [...props.text];
50
+ return (_jsx(Text, { bold: props.bold, children: chars.map((char, index) => {
51
+ const color = rainbowPalette[(index + props.frame) % rainbowPalette.length];
52
+ return (_jsx(Text, { color: color, children: char }, `rainbow-${index}`));
53
+ }) }));
54
+ }
55
+ //# sourceMappingURL=AnimatedText.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnimatedText.js","sourceRoot":"","sources":["../../../src/tui/experimental/AnimatedText.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ /**
3
+ * Claude-Code-style welcome banner for the experimental shell. Renders the
4
+ * full PATCHPILOT wordmark when there is room, and degrades responsively to a
5
+ * compact heading on narrow terminals instead of forcing a clipped block.
6
+ */
7
+ export declare function ExperimentalBanner(props: {
8
+ width: number;
9
+ height: number;
10
+ }): React.ReactElement;
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ const wordmark = [
4
+ "██████╗ █████╗ ████████╗ ██████╗██╗ ██╗██████╗ ██╗██╗ ██████╗ ████████╗",
5
+ "██╔══██╗██╔══██╗╚══██╔══╝██╔════╝██║ ██║██╔══██╗██║██║ ██╔═══██╗╚══██╔══╝",
6
+ "██████╔╝███████║ ██║ ██║ ███████║██████╔╝██║██║ ██║ ██║ ██║",
7
+ "██╔═══╝ ██╔══██║ ██║ ██║ ██╔══██║██╔═══╝ ██║██║ ██║ ██║ ██║",
8
+ "██║ ██║ ██║ ██║ ╚██████╗██║ ██║██║ ██║███████╗╚██████╔╝ ██║",
9
+ "╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝",
10
+ ];
11
+ const wordmarkWidth = Math.max(...wordmark.map((line) => line.length));
12
+ // Small robot + wrench, kept compact so it clips gracefully on narrow terminals.
13
+ const robot = [
14
+ " ╭───────╮",
15
+ " │ ◠ ◠ │ ⚡",
16
+ " │ ▿ │ ╱",
17
+ " ╰──┬─┬──╯╱",
18
+ " ┌──┴─┴──┐",
19
+ ];
20
+ /**
21
+ * Claude-Code-style welcome banner for the experimental shell. Renders the
22
+ * full PATCHPILOT wordmark when there is room, and degrades responsively to a
23
+ * compact heading on narrow terminals instead of forcing a clipped block.
24
+ */
25
+ export function ExperimentalBanner(props) {
26
+ const showWordmark = props.width >= wordmarkWidth + 2 && props.height >= 12;
27
+ const showRobot = props.width >= wordmarkWidth + 16 && props.height >= 14;
28
+ if (!showWordmark) {
29
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsxs(Text, { color: "cyan", bold: true, children: ["\u25B8 PatchPilot ", _jsx(Text, { color: "gray", children: "\u2014 experimental shell" })] }), _jsx(Text, { color: "gray", children: "Local-first coding agent. Visible tools, explicit permissions." }), _jsx(Text, { color: "gray", children: "Type a task, or press / for the command palette." })] }));
30
+ }
31
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { flexDirection: "column", children: wordmark.map((line, index) => (_jsx(Text, { color: "cyan", bold: true, children: line }, `wm-${index}`))) }), showRobot ? (_jsx(Box, { flexDirection: "column", marginLeft: 2, children: robot.map((line, index) => (_jsx(Text, { color: index === 1 ? "cyan" : "gray", children: line }, `bot-${index}`))) })) : null] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "white", bold: true, children: "Welcome to the experimental shell." }), _jsx(Text, { color: "gray", children: "Local-first coding agent \u2014 every read, write, command, and model route stays visible." }), _jsxs(Text, { color: "gray", children: [_jsx(Text, { color: "cyan", children: "/" }), " command palette ", _jsx(Text, { color: "gray", children: "\u00B7" }), " ", _jsx(Text, { color: "cyan", children: "tab" }), " plan / build / bypass ", _jsx(Text, { color: "gray", children: "\u00B7" }), " ", _jsx(Text, { color: "cyan", children: "/help" }), " for everything"] })] })] }));
32
+ }
33
+ //# sourceMappingURL=Banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Banner.js","sourceRoot":"","sources":["../../../src/tui/experimental/Banner.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,MAAM,QAAQ,GAAG;IACf,gFAAgF;IAChF,gFAAgF;IAChF,6EAA6E;IAC7E,6EAA6E;IAC7E,6EAA6E;IAC7E,6EAA6E;CAC9E,CAAC;AAEF,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAEvE,iFAAiF;AACjF,MAAM,KAAK,GAAG;IACZ,aAAa;IACb,gBAAgB;IAChB,eAAe;IACf,cAAc;IACd,aAAa;CACd,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAwC;IACzE,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,IAAI,aAAa,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;IAC5E,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,IAAI,aAAa,GAAG,EAAE,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;IAE1E,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,aACrC,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,yCACR,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,0CAA4B,IACtD,EACP,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,+EAAsE,EACxF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,iEAAwD,IACtE,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,aACrC,MAAC,GAAG,IAAC,aAAa,EAAC,KAAK,aACtB,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,YACxB,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAC7B,KAAC,IAAI,IAAqB,KAAK,EAAC,MAAM,EAAC,IAAI,kBACxC,IAAI,IADI,MAAM,KAAK,EAAE,CAEjB,CACR,CAAC,GACE,EACL,SAAS,CAAC,CAAC,CAAC,CACX,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,UAAU,EAAE,CAAC,YACtC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAC1B,KAAC,IAAI,IAAsB,KAAK,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,YAC5D,IAAI,IADI,OAAO,KAAK,EAAE,CAElB,CACR,CAAC,GACE,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,EACN,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,aACvC,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,EAAC,IAAI,yDAEjB,EACP,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,2GAEX,EACP,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,aAChB,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,kBAAS,uBAAiB,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,uBAAS,EAAC,GAAG,EAC3E,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,oBAAW,6BAAuB,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,uBAAS,EAAC,GAAG,EACnF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,sBAAa,uBAC1B,IACH,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import type { CommandSuggestionItem } from "../components/CommandSuggestions.js";
3
+ /**
4
+ * Command palette picker for the experimental shell: a real categorized list
5
+ * with a live preview pane for the highlighted entry.
6
+ */
7
+ export declare function CommandPalette(props: {
8
+ items: CommandSuggestionItem[];
9
+ selectedIndex: number;
10
+ width: number;
11
+ }): React.ReactElement | null;
@@ -0,0 +1,25 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { symbols } from "./theme.js";
4
+ const MAX_VISIBLE = 8;
5
+ /**
6
+ * Command palette picker for the experimental shell: a real categorized list
7
+ * with a live preview pane for the highlighted entry.
8
+ */
9
+ export function CommandPalette(props) {
10
+ if (props.items.length === 0) {
11
+ return null;
12
+ }
13
+ const selectedIndex = Math.max(0, Math.min(props.selectedIndex, props.items.length - 1));
14
+ const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE / 2), Math.max(0, props.items.length - MAX_VISIBLE)));
15
+ const visibleItems = props.items.slice(startIndex, startIndex + MAX_VISIBLE);
16
+ const selectedItem = props.items[selectedIndex];
17
+ const wide = props.width >= 96;
18
+ const labelWidth = wide ? 22 : 18;
19
+ return (_jsxs(Box, { borderStyle: "round", borderColor: "cyan", flexDirection: "column", paddingX: 1, children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsxs(Text, { color: "cyan", bold: true, children: [symbols.arrow, " Command palette"] }), _jsxs(Text, { color: "gray", children: [selectedIndex + 1, "/", props.items.length, " \u00B7 \u2191\u2193 move \u00B7 \u23CE apply \u00B7 esc clear"] })] }), _jsxs(Box, { flexDirection: wide ? "row" : "column", marginTop: 1, children: [_jsx(Box, { flexDirection: "column", width: wide ? Math.floor(props.width * 0.52) : undefined, children: visibleItems.map((item, index) => {
20
+ const absoluteIndex = startIndex + index;
21
+ const isSelected = absoluteIndex === selectedIndex;
22
+ return (_jsxs(Box, { children: [_jsx(Box, { width: 2, children: _jsx(Text, { color: isSelected ? "cyan" : "gray", children: isSelected ? symbols.todoActive : " " }) }), _jsx(Box, { width: 11, children: _jsx(Text, { color: "gray", dimColor: !isSelected, children: item.category.slice(0, 10) }) }), _jsx(Box, { width: labelWidth, children: _jsx(Text, { color: isSelected ? "white" : "cyan", bold: isSelected, wrap: "truncate", children: item.label }) }), !wide ? (_jsx(Text, { color: isSelected ? "white" : "gray", dimColor: !isSelected, wrap: "truncate", children: item.detail })) : null] }, item.key));
23
+ }) }), selectedItem ? (_jsxs(Box, { flexDirection: "column", flexGrow: 1, marginLeft: wide ? 2 : 0, marginTop: wide ? 0 : 1, borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsx(Text, { color: "cyan", bold: true, wrap: "truncate", children: selectedItem.label }), _jsx(Text, { color: "white", wrap: "wrap", children: selectedItem.detail }), _jsx(Text, { color: "gray", wrap: "truncate", children: selectedItem.hint ? `${symbols.bullet} ${selectedItem.hint}` : `${symbols.bullet} ${selectedItem.category}` })] })) : null] })] }));
24
+ }
25
+ //# sourceMappingURL=CommandPalette.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommandPalette.js","sourceRoot":"","sources":["../../../src/tui/experimental/CommandPalette.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import React from "react";
2
+ import type { AgentTodoItem, AgentWorkState, ApprovalRequest, ModelProvider, ModelTelemetry, SessionTelemetry } from "../../core/types.js";
3
+ import type { CommandSuggestionItem } from "../components/CommandSuggestions.js";
4
+ import type { OllamaHostDetails } from "../hosts.js";
5
+ import type { AgentMode, LogLine } from "../types.js";
6
+ import { type Artifact } from "./attachments.js";
7
+ export type ExperimentalShellProps = {
8
+ provider: ModelProvider;
9
+ model: string;
10
+ workspace: string;
11
+ sessionId: string;
12
+ agentMode: AgentMode;
13
+ allowWrite: boolean;
14
+ allowShell: boolean;
15
+ subagents: boolean;
16
+ workState: AgentWorkState;
17
+ status: string;
18
+ isRunning: boolean;
19
+ ultramaxxRun: boolean;
20
+ telemetry: ModelTelemetry | null;
21
+ sessionTelemetry: SessionTelemetry;
22
+ draftTokens: number;
23
+ lines: LogLine[];
24
+ todos: AgentTodoItem[];
25
+ todoFrame: number;
26
+ pendingApproval: ApprovalRequest | null;
27
+ bypassConfirmation: boolean;
28
+ updatePrompt: {
29
+ currentVersion: string;
30
+ latestVersion: string;
31
+ source: "npm" | "github";
32
+ command: string;
33
+ } | null;
34
+ updateBusy: boolean;
35
+ reauthActive: boolean;
36
+ reauthBusy: boolean;
37
+ transcriptScrollOffset: number;
38
+ input: string;
39
+ paletteItems: CommandSuggestionItem[];
40
+ paletteIndex: number;
41
+ rows: number;
42
+ columns: number;
43
+ activeHost: OllamaHostDetails | null;
44
+ artifacts: Artifact[];
45
+ onChange: (value: string) => void;
46
+ onSubmit: (value: string) => void;
47
+ onAttach: (path: string) => string;
48
+ };
49
+ /**
50
+ * Fullscreen experimental shell — a Claude-Code / Codex-CLI flavoured layout:
51
+ * compact header, scrolling transcript, a first-class todo dock, prominent
52
+ * approvals, a categorized command palette, and a bottom-pinned composer.
53
+ *
54
+ * Purely presentational. Keyboard routing (palette navigation, approval keys,
55
+ * scrolling, mode toggle) stays in App's central useInput; only the composer
56
+ * owns its own typing input.
57
+ */
58
+ export declare function ExperimentalShell(props: ExperimentalShellProps): React.ReactElement;