@jx-grxf/patchpilot 0.4.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.
- package/.env.example +17 -1
- package/README.md +113 -23
- package/SECURITY.md +7 -1
- package/dist/cli.js +103 -14
- package/dist/cli.js.map +1 -1
- package/dist/core/agent.d.ts +47 -1
- package/dist/core/agent.js +667 -76
- package/dist/core/agent.js.map +1 -1
- package/dist/core/cleanup.d.ts +3 -0
- package/dist/core/cleanup.js +29 -0
- package/dist/core/cleanup.js.map +1 -0
- package/dist/core/clipboard.d.ts +14 -0
- package/dist/core/clipboard.js +134 -0
- package/dist/core/clipboard.js.map +1 -0
- package/dist/core/codex.d.ts +8 -0
- package/dist/core/codex.js +28 -2
- package/dist/core/codex.js.map +1 -1
- package/dist/core/compaction.d.ts +23 -0
- package/dist/core/compaction.js +145 -0
- package/dist/core/compaction.js.map +1 -0
- package/dist/core/contextFormat.d.ts +21 -0
- package/dist/core/contextFormat.js +87 -0
- package/dist/core/contextFormat.js.map +1 -0
- package/dist/core/contextItem.d.ts +41 -0
- package/dist/core/contextItem.js +93 -0
- package/dist/core/contextItem.js.map +1 -0
- package/dist/core/contextStore.d.ts +48 -0
- package/dist/core/contextStore.js +306 -0
- package/dist/core/contextStore.js.map +1 -0
- package/dist/core/doctor.d.ts +4 -1
- package/dist/core/doctor.js +122 -3
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/gemini.js +10 -4
- package/dist/core/gemini.js.map +1 -1
- package/dist/core/geminiWrapper.d.ts +92 -0
- package/dist/core/geminiWrapper.js +1258 -0
- package/dist/core/geminiWrapper.js.map +1 -0
- package/dist/core/http.js +70 -6
- package/dist/core/http.js.map +1 -1
- package/dist/core/json.d.ts +1 -1
- package/dist/core/json.js +81 -19
- package/dist/core/json.js.map +1 -1
- package/dist/core/memory.d.ts +16 -0
- package/dist/core/memory.js +108 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/modelClient.js +7 -0
- package/dist/core/modelClient.js.map +1 -1
- package/dist/core/nvidia.d.ts +1 -1
- package/dist/core/nvidia.js +13 -4
- package/dist/core/nvidia.js.map +1 -1
- package/dist/core/ollama.js +13 -3
- package/dist/core/ollama.js.map +1 -1
- package/dist/core/openrouter.js +15 -6
- package/dist/core/openrouter.js.map +1 -1
- package/dist/core/projectInit.d.ts +6 -0
- package/dist/core/projectInit.js +44 -0
- package/dist/core/projectInit.js.map +1 -0
- package/dist/core/reasoning.js +6 -0
- package/dist/core/reasoning.js.map +1 -1
- package/dist/core/session.d.ts +1 -0
- package/dist/core/session.js +55 -3
- package/dist/core/session.js.map +1 -1
- package/dist/core/tokenAccounting.d.ts +4 -0
- package/dist/core/tokenAccounting.js +75 -13
- package/dist/core/tokenAccounting.js.map +1 -1
- package/dist/core/types.d.ts +65 -5
- package/dist/core/types.js +30 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/updateCheck.d.ts +19 -0
- package/dist/core/updateCheck.js +103 -0
- package/dist/core/updateCheck.js.map +1 -0
- package/dist/core/workspace.d.ts +37 -0
- package/dist/core/workspace.js +1535 -84
- package/dist/core/workspace.js.map +1 -1
- package/dist/tui/App.d.ts +1 -0
- package/dist/tui/App.js +1841 -140
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/commands.js +141 -9
- package/dist/tui/commands.js.map +1 -1
- package/dist/tui/components/ApprovalPanel.js +16 -1
- package/dist/tui/components/ApprovalPanel.js.map +1 -1
- package/dist/tui/components/CommandSuggestions.js +33 -5
- package/dist/tui/components/CommandSuggestions.js.map +1 -1
- package/dist/tui/components/Composer.d.ts +3 -0
- package/dist/tui/components/Composer.js +57 -5
- package/dist/tui/components/Composer.js.map +1 -1
- package/dist/tui/components/ExperimentalPanel.d.ts +10 -0
- package/dist/tui/components/ExperimentalPanel.js +38 -0
- package/dist/tui/components/ExperimentalPanel.js.map +1 -0
- package/dist/tui/components/Header.js +3 -3
- package/dist/tui/components/Header.js.map +1 -1
- package/dist/tui/components/OnboardingPanel.d.ts +25 -1
- package/dist/tui/components/OnboardingPanel.js +87 -25
- package/dist/tui/components/OnboardingPanel.js.map +1 -1
- package/dist/tui/components/Sidebar.js +17 -13
- package/dist/tui/components/Sidebar.js.map +1 -1
- package/dist/tui/components/StartupBanner.d.ts +4 -0
- package/dist/tui/components/StartupBanner.js +9 -0
- package/dist/tui/components/StartupBanner.js.map +1 -0
- package/dist/tui/components/Transcript.d.ts +7 -0
- package/dist/tui/components/Transcript.js +87 -17
- package/dist/tui/components/Transcript.js.map +1 -1
- package/dist/tui/contextCommands.d.ts +8 -0
- package/dist/tui/contextCommands.js +205 -0
- package/dist/tui/contextCommands.js.map +1 -0
- package/dist/tui/experimental/AnimatedText.d.ts +38 -0
- package/dist/tui/experimental/AnimatedText.js +55 -0
- package/dist/tui/experimental/AnimatedText.js.map +1 -0
- package/dist/tui/experimental/Banner.d.ts +10 -0
- package/dist/tui/experimental/Banner.js +33 -0
- package/dist/tui/experimental/Banner.js.map +1 -0
- package/dist/tui/experimental/CommandPalette.d.ts +11 -0
- package/dist/tui/experimental/CommandPalette.js +25 -0
- package/dist/tui/experimental/CommandPalette.js.map +1 -0
- package/dist/tui/experimental/ExperimentalShell.d.ts +58 -0
- package/dist/tui/experimental/ExperimentalShell.js +366 -0
- package/dist/tui/experimental/ExperimentalShell.js.map +1 -0
- package/dist/tui/experimental/ThemePicker.d.ts +13 -0
- package/dist/tui/experimental/ThemePicker.js +12 -0
- package/dist/tui/experimental/ThemePicker.js.map +1 -0
- package/dist/tui/experimental/attachments.d.ts +35 -0
- package/dist/tui/experimental/attachments.js +244 -0
- package/dist/tui/experimental/attachments.js.map +1 -0
- package/dist/tui/experimental/composer.d.ts +24 -0
- package/dist/tui/experimental/composer.js +84 -0
- package/dist/tui/experimental/composer.js.map +1 -0
- package/dist/tui/experimental/geminiPricing.d.ts +16 -0
- package/dist/tui/experimental/geminiPricing.js +39 -0
- package/dist/tui/experimental/geminiPricing.js.map +1 -0
- package/dist/tui/experimental/layout.d.ts +46 -0
- package/dist/tui/experimental/layout.js +112 -0
- package/dist/tui/experimental/layout.js.map +1 -0
- package/dist/tui/experimental/theme.d.ts +35 -0
- package/dist/tui/experimental/theme.js +86 -0
- package/dist/tui/experimental/theme.js.map +1 -0
- package/dist/tui/experimental/transcriptRows.d.ts +20 -0
- package/dist/tui/experimental/transcriptRows.js +169 -0
- package/dist/tui/experimental/transcriptRows.js.map +1 -0
- package/dist/tui/experimental/ultraModes.d.ts +46 -0
- package/dist/tui/experimental/ultraModes.js +95 -0
- package/dist/tui/experimental/ultraModes.js.map +1 -0
- package/dist/tui/experimental/ultramaxx.d.ts +19 -0
- package/dist/tui/experimental/ultramaxx.js +43 -0
- package/dist/tui/experimental/ultramaxx.js.map +1 -0
- package/dist/tui/format.d.ts +4 -2
- package/dist/tui/format.js +21 -7
- package/dist/tui/format.js.map +1 -1
- package/dist/tui/hosts.js +7 -1
- package/dist/tui/hosts.js.map +1 -1
- package/dist/tui/layout.d.ts +26 -0
- package/dist/tui/layout.js +66 -0
- package/dist/tui/layout.js.map +1 -0
- package/dist/tui/modelSelection.d.ts +1 -1
- package/dist/tui/modelSelection.js +8 -6
- package/dist/tui/modelSelection.js.map +1 -1
- package/dist/tui/modes.d.ts +8 -1
- package/dist/tui/modes.js +20 -2
- package/dist/tui/modes.js.map +1 -1
- package/dist/tui/onboardingPreferences.d.ts +37 -0
- package/dist/tui/onboardingPreferences.js +118 -0
- package/dist/tui/onboardingPreferences.js.map +1 -0
- package/dist/tui/runStatus.d.ts +50 -0
- package/dist/tui/runStatus.js +164 -0
- package/dist/tui/runStatus.js.map +1 -0
- package/dist/tui/types.d.ts +8 -0
- package/dist/tui/types.js.map +1 -1
- package/docs/architecture.md +115 -0
- package/docs/gemini-wrapper.md +110 -0
- package/docs/product-context.md +43 -0
- package/docs/releases/v0.1.1-beta.md +18 -0
- package/docs/releases/v0.2.1.md +1 -1
- package/docs/releases/v0.3.1-beta.md +4 -0
- package/docs/releases/v0.4.0.md +1 -1
- package/docs/releases/v1.0.0.md +28 -0
- package/docs/releases/v1.0.1.md +25 -0
- package/docs/releases/v1.1.0.md +30 -0
- package/docs/releases/v1.2.0.md +28 -0
- package/docs/showcase/patchpilot-banner.png +0 -0
- package/docs/showcase/patchpilot-logo.png +0 -0
- package/package.json +8 -3
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run-status verbs. The spinner glyph animates fast; the verb stays stable and
|
|
3
|
+
* only rotates on a slow cadence, and it advances in a pseudo-random order so
|
|
4
|
+
* it never feels like a fixed list cycling.
|
|
5
|
+
*/
|
|
6
|
+
export const runStatusVerbs = [
|
|
7
|
+
"Accomplishing",
|
|
8
|
+
"Actioning",
|
|
9
|
+
"Architecting",
|
|
10
|
+
"Baking",
|
|
11
|
+
"Bootstrapping",
|
|
12
|
+
"Brewing",
|
|
13
|
+
"Calculating",
|
|
14
|
+
"Cascading",
|
|
15
|
+
"Channeling",
|
|
16
|
+
"Composing",
|
|
17
|
+
"Computing",
|
|
18
|
+
"Concocting",
|
|
19
|
+
"Considering",
|
|
20
|
+
"Contemplating",
|
|
21
|
+
"Cooking",
|
|
22
|
+
"Crafting",
|
|
23
|
+
"Creating",
|
|
24
|
+
"Crunching",
|
|
25
|
+
"Crystallizing",
|
|
26
|
+
"Deciphering",
|
|
27
|
+
"Deliberating",
|
|
28
|
+
"Determining",
|
|
29
|
+
"Distilling",
|
|
30
|
+
"Elucidating",
|
|
31
|
+
"Envisioning",
|
|
32
|
+
"Forging",
|
|
33
|
+
"Generating",
|
|
34
|
+
"Hatching",
|
|
35
|
+
"Ideating",
|
|
36
|
+
"Imagining",
|
|
37
|
+
"Improvising",
|
|
38
|
+
"Incubating",
|
|
39
|
+
"Inferring",
|
|
40
|
+
"Inspecting",
|
|
41
|
+
"Manifesting",
|
|
42
|
+
"Mulling",
|
|
43
|
+
"Musing",
|
|
44
|
+
"Orchestrating",
|
|
45
|
+
"Percolating",
|
|
46
|
+
"Pondering",
|
|
47
|
+
"Processing",
|
|
48
|
+
"Puzzling",
|
|
49
|
+
"Reasoning",
|
|
50
|
+
"Reticulating",
|
|
51
|
+
"Reviewing",
|
|
52
|
+
"Ruminating",
|
|
53
|
+
"Sketching",
|
|
54
|
+
"Spelunking",
|
|
55
|
+
"Synthesizing",
|
|
56
|
+
"Tinkering",
|
|
57
|
+
"Transmuting",
|
|
58
|
+
"Unravelling",
|
|
59
|
+
"Wrangling",
|
|
60
|
+
];
|
|
61
|
+
/** Past-tense verbs for the run-completion summary ("Crunched for 17m 58s"). */
|
|
62
|
+
export const completionVerbs = [
|
|
63
|
+
"Crunched",
|
|
64
|
+
"Cooked",
|
|
65
|
+
"Brewed",
|
|
66
|
+
"Forged",
|
|
67
|
+
"Hammered",
|
|
68
|
+
"Conjured",
|
|
69
|
+
"Distilled",
|
|
70
|
+
"Wrangled",
|
|
71
|
+
"Orchestrated",
|
|
72
|
+
"Synthesized",
|
|
73
|
+
"Composed",
|
|
74
|
+
"Architected",
|
|
75
|
+
"Tinkered",
|
|
76
|
+
"Pondered",
|
|
77
|
+
"Crafted",
|
|
78
|
+
"Spelunked",
|
|
79
|
+
];
|
|
80
|
+
/** Braille spinner glyphs — the classic fast loading animation. */
|
|
81
|
+
export const spinnerGlyphs = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
82
|
+
/** Pulsing accent glyphs used for completion / decorative markers. */
|
|
83
|
+
export const pulseGlyphs = ["✻", "✺", "✷", "✶", "✦", "✶", "✷", "✺"];
|
|
84
|
+
/** Fast spinner glyph cadence in ms. */
|
|
85
|
+
export const spinnerFrameMs = 90;
|
|
86
|
+
/** Wave / highlight animation cadence in ms. */
|
|
87
|
+
export const waveFrameMs = 110;
|
|
88
|
+
/** The verb only changes once every this many ms. */
|
|
89
|
+
export const verbCycleMs = 10_000;
|
|
90
|
+
export function randomRunStatusSeed(random = Math.random) {
|
|
91
|
+
return Math.floor(Math.max(0, Math.min(0.999999999, random())) * 0x7fffffff);
|
|
92
|
+
}
|
|
93
|
+
/** Small deterministic hash so verb order is pseudo-random, not sequential. */
|
|
94
|
+
function hashTick(tick, seed) {
|
|
95
|
+
let value = (Math.trunc(tick) * 2654435761 + Math.trunc(seed) * 40503 + 0x9e3779b9) >>> 0;
|
|
96
|
+
value ^= value >>> 15;
|
|
97
|
+
value = (value * 0x85ebca6b) >>> 0;
|
|
98
|
+
value ^= value >>> 13;
|
|
99
|
+
return value >>> 0;
|
|
100
|
+
}
|
|
101
|
+
/** Pick the fast-animating braille glyph for the given frame counter. */
|
|
102
|
+
export function spinnerGlyph(frame) {
|
|
103
|
+
const safe = Number.isFinite(frame) ? Math.abs(Math.trunc(frame)) : 0;
|
|
104
|
+
return spinnerGlyphs[safe % spinnerGlyphs.length] ?? spinnerGlyphs[0];
|
|
105
|
+
}
|
|
106
|
+
/** Pick a pulsing accent glyph for the given frame counter. */
|
|
107
|
+
export function pulseGlyph(frame) {
|
|
108
|
+
const safe = Number.isFinite(frame) ? Math.abs(Math.trunc(frame)) : 0;
|
|
109
|
+
return pulseGlyphs[safe % pulseGlyphs.length] ?? pulseGlyphs[0];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Pick the run-status verb for the given elapsed time. The verb is stable for
|
|
113
|
+
* `verbCycleMs`, then jumps to a pseudo-random next verb (never a fixed cycle).
|
|
114
|
+
*/
|
|
115
|
+
export function runStatusVerb(elapsedMs, seed = 0) {
|
|
116
|
+
const safeElapsed = Number.isFinite(elapsedMs) && elapsedMs > 0 ? elapsedMs : 0;
|
|
117
|
+
const tick = Math.floor(safeElapsed / verbCycleMs);
|
|
118
|
+
let index = hashTick(tick, seed) % runStatusVerbs.length;
|
|
119
|
+
if (tick > 0) {
|
|
120
|
+
const previousIndex = hashTick(tick - 1, seed) % runStatusVerbs.length;
|
|
121
|
+
if (index === previousIndex) {
|
|
122
|
+
index = (index + 1 + (hashTick(tick + 1, seed) % (runStatusVerbs.length - 1))) % runStatusVerbs.length;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return runStatusVerbs[index] ?? runStatusVerbs[0];
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Split the run status into its parts so the UI can animate the verb on its
|
|
129
|
+
* own and render the (stable) state/detail separately with clear spacing.
|
|
130
|
+
*/
|
|
131
|
+
export function runStatusParts(options) {
|
|
132
|
+
const verb = runStatusVerb(options.elapsedMs, options.seed);
|
|
133
|
+
const state = options.workState.replace(/_/g, " ");
|
|
134
|
+
const trimmedStatus = options.status?.trim() ?? "";
|
|
135
|
+
const detail = trimmedStatus && trimmedStatus !== state ? trimmedStatus : "";
|
|
136
|
+
return { verb, state, detail };
|
|
137
|
+
}
|
|
138
|
+
/** Format elapsed milliseconds as a compact human duration for the status line. */
|
|
139
|
+
export function formatElapsed(elapsedMs) {
|
|
140
|
+
if (!Number.isFinite(elapsedMs) || elapsedMs <= 0) {
|
|
141
|
+
return "starting";
|
|
142
|
+
}
|
|
143
|
+
return formatRunDuration(elapsedMs);
|
|
144
|
+
}
|
|
145
|
+
/** Format a run duration like "4s" or "17m 58s". */
|
|
146
|
+
export function formatRunDuration(elapsedMs) {
|
|
147
|
+
const totalSeconds = Math.max(0, Math.floor((Number.isFinite(elapsedMs) ? elapsedMs : 0) / 1000));
|
|
148
|
+
if (totalSeconds < 60) {
|
|
149
|
+
return `${totalSeconds}s`;
|
|
150
|
+
}
|
|
151
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
152
|
+
const seconds = totalSeconds % 60;
|
|
153
|
+
if (minutes < 60) {
|
|
154
|
+
return `${minutes}m ${String(seconds).padStart(2, "0")}s`;
|
|
155
|
+
}
|
|
156
|
+
const hours = Math.floor(minutes / 60);
|
|
157
|
+
return `${hours}h ${String(minutes % 60).padStart(2, "0")}m`;
|
|
158
|
+
}
|
|
159
|
+
/** Build a run-completion summary like "Crunched for 17m 58s". */
|
|
160
|
+
export function formatCompletionSummary(elapsedMs, seed = 0) {
|
|
161
|
+
const verb = completionVerbs[hashTick(0, seed + 7) % completionVerbs.length] ?? completionVerbs[0];
|
|
162
|
+
return `${verb} for ${formatRunDuration(elapsedMs)}`;
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=runStatus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runStatus.js","sourceRoot":"","sources":["../../src/tui/runStatus.ts"],"names":[],"mappings":"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"}
|
package/dist/tui/types.d.ts
CHANGED
|
@@ -23,4 +23,12 @@ export type AdvisorNote = {
|
|
|
23
23
|
role: SubagentRole;
|
|
24
24
|
message: string;
|
|
25
25
|
};
|
|
26
|
+
export type ToolTelemetry = {
|
|
27
|
+
total: number;
|
|
28
|
+
succeeded: number;
|
|
29
|
+
failed: number;
|
|
30
|
+
approvals: number;
|
|
31
|
+
denied: number;
|
|
32
|
+
byTool: Partial<Record<AgentToolName | "subagent", number>>;
|
|
33
|
+
};
|
|
26
34
|
export declare const maxTranscriptLines = 300;
|
package/dist/tui/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tui/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tui/types.ts"],"names":[],"mappings":"AA0CA,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
PatchPilot is split into a small agent core and an Ink terminal interface.
|
|
4
|
+
|
|
5
|
+
## Components
|
|
6
|
+
|
|
7
|
+
| Component | Responsibility |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `OllamaClient` | Sends chat requests to the selected Ollama HTTP API and reads host model state |
|
|
10
|
+
| `compute` | Classifies the selected Ollama endpoint as local or remote compute |
|
|
11
|
+
| `subagents` | Runs small planner/reviewer advisor calls before the primary agent loop |
|
|
12
|
+
| `AgentRunner` | Maintains the model loop, work-state transitions, session events, and typed tool calls |
|
|
13
|
+
| `WorkspaceTools` | Provides bounded file, search, patch, Git, test, and shell actions |
|
|
14
|
+
| `SessionStore` | Persists append-only JSONL session events and updates the global session index |
|
|
15
|
+
| `App` | Renders the TUI transcript, approval prompts, status, and prompt input |
|
|
16
|
+
| `systemStats` | Samples CPU and memory usage for the live header telemetry |
|
|
17
|
+
|
|
18
|
+
## Compute Model
|
|
19
|
+
|
|
20
|
+
PatchPilot separates the client machine from the compute machine:
|
|
21
|
+
|
|
22
|
+
- The client machine runs the TUI, reads and writes workspace files, runs Git, and executes tests.
|
|
23
|
+
- The compute machine runs Ollama inference.
|
|
24
|
+
- `/connect` changes only the Ollama compute endpoint. It does not move workspace tools to the remote host.
|
|
25
|
+
- Host discovery checks both the local LAN and reachable Tailscale peers, then verifies each candidate against Ollama's `GET /api/version`.
|
|
26
|
+
- A localhost endpoint is classified as local compute. A LAN endpoint such as `http://192.168.1.50:11434` is classified as remote compute.
|
|
27
|
+
|
|
28
|
+
This keeps the Windows-desktop-GPU plus MacBook-editing workflow simple: expose Ollama on the Windows machine, connect from the Mac, and keep all file operations local to the Mac workspace.
|
|
29
|
+
|
|
30
|
+
## Subagents
|
|
31
|
+
|
|
32
|
+
The first subagent layer is advisory and intentionally small:
|
|
33
|
+
|
|
34
|
+
| Subagent | Purpose | Tool Access |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| Planner | Suggests likely files, order of work, and verification steps | None |
|
|
37
|
+
| Reviewer | Calls out risk, missing tests, and platform concerns | None |
|
|
38
|
+
|
|
39
|
+
Both subagents run as separate model calls before the primary agent starts. Their output is injected as advisory context only; the primary agent must still verify with workspace tools before changing code. This follows the useful part of the opencode `primary` vs `subagent` model without granting background agents write or shell permissions.
|
|
40
|
+
|
|
41
|
+
## Native App Direction
|
|
42
|
+
|
|
43
|
+
The target native structure is:
|
|
44
|
+
|
|
45
|
+
| Layer | Direction |
|
|
46
|
+
|---|---|
|
|
47
|
+
| Core CLI | Keep the TypeScript/Node agent as the sidecar because it already owns tools, Ollama, and safety boundaries |
|
|
48
|
+
| Desktop shell | Use Tauri for macOS and Windows instead of maintaining both Electron and Tauri |
|
|
49
|
+
| Connect | Reuse the same Ollama compute endpoint model in CLI and desktop |
|
|
50
|
+
| Security | Bind any local control server to loopback only and keep remote model traffic explicit |
|
|
51
|
+
|
|
52
|
+
## Agent Protocol
|
|
53
|
+
|
|
54
|
+
The first version uses a JSON command envelope instead of provider-specific tool calling. That keeps behavior portable across local models, including models that do not reliably emit native tool calls.
|
|
55
|
+
|
|
56
|
+
Tool request:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"action": "tools",
|
|
61
|
+
"message": "I need to inspect the project files.",
|
|
62
|
+
"tool_calls": [
|
|
63
|
+
{
|
|
64
|
+
"name": "list_files",
|
|
65
|
+
"arguments": {
|
|
66
|
+
"path": "."
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
PatchPilot exposes a `ToolSpec` registry for each tool. Specs describe risk, side effects, permission class, and transcript category. Tool calls execute sequentially so approval-gated reads, writes, and shell actions cannot overwrite each other's pending approval state.
|
|
74
|
+
|
|
75
|
+
Longer runs can also call `update_todo` with a compact task snapshot. The runner stores that state separately from the transcript and the TUI renders it in the lower transcript area, with `in_progress` items animated and `completed` items checked.
|
|
76
|
+
|
|
77
|
+
Final answer:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"action": "final",
|
|
82
|
+
"message": "The repository is a TypeScript TUI agent..."
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Sessions
|
|
87
|
+
|
|
88
|
+
Each TUI launch creates a session id. Events are appended to `.patchpilot/sessions/<session-id>.jsonl` in the workspace:
|
|
89
|
+
|
|
90
|
+
- `session.created`
|
|
91
|
+
- `run.started`
|
|
92
|
+
- `model.request`
|
|
93
|
+
- `tool.requested`
|
|
94
|
+
- `approval.requested`
|
|
95
|
+
- `tool.completed`
|
|
96
|
+
- `run.completed`
|
|
97
|
+
- `run.failed`
|
|
98
|
+
|
|
99
|
+
The workspace `.patchpilot/` folder is ignored by Git. A global index at `~/.patchpilot/session-index.json` keeps recent sessions discoverable for `patchpilot sessions`, `patchpilot resume`, `/sessions`, and `/resume`.
|
|
100
|
+
|
|
101
|
+
## Release Publishing
|
|
102
|
+
|
|
103
|
+
Tagged releases use `.github/workflows/release.yml`. The workflow verifies that `package.json` matches the tag, installs with `npm ci`, runs tests, builds, packs the CLI, publishes `@jx-grxf/patchpilot` to npm, and then creates or updates the GitHub Release with the `.tgz` artifact. Publishing uses the `NPM_TOKEN` repository secret when present and can fall back to npm trusted publishing if the package is configured for GitHub Actions OIDC on npm.
|
|
104
|
+
|
|
105
|
+
## Safety
|
|
106
|
+
|
|
107
|
+
The workspace root is resolved once at startup. Every file path is resolved against that root and rejected if it escapes the workspace. Writes and shell commands are blocked by default. In the TUI, risky tools request approval with allow-once, allow-session, or deny decisions. `--apply` and `--allow-shell` remain explicit compatibility switches for users who want global write or shell permission.
|
|
108
|
+
|
|
109
|
+
## Telemetry
|
|
110
|
+
|
|
111
|
+
PatchPilot reads Ollama's non-streaming chat metadata for prompt tokens, response tokens, total duration, and generation speed. Gemini reads API `usageMetadata`. Codex OAuth runs `codex exec --json` and parses the `turn.completed.usage` event, including `cached_input_tokens`, so the TUI can show real Codex CLI usage instead of only character-based estimates.
|
|
112
|
+
|
|
113
|
+
Model discovery is cached in the current TUI session. Prompt execution reuses the known model list when the selected model is already present, avoiding repeated Gemini model-list calls and keeping Codex/Ollama discovery off the hot path.
|
|
114
|
+
|
|
115
|
+
The TUI also keeps session-level accounting: request count, prompt tokens, cached prompt tokens, output tokens, total tokens, and estimated cost where public API token pricing is known. Local Ollama cost is reported as zero; Codex OAuth cost is shown as an API-price estimate because actual ChatGPT-plan quota handling is external to PatchPilot.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Gemini-Wrapper Setup
|
|
2
|
+
|
|
3
|
+
PatchPilot can use `gemini_webapi` through the `gemini-wrapper` provider. This is an advanced, unofficial Gemini Web bridge. PatchPilot creates a managed Python venv only when you explicitly run `/doctor fix` or `patchpilot doctor --fix`, installs the pinned wrapper there, and starts the bridge command itself. It does not scan browser profiles or read cookies automatically.
|
|
4
|
+
|
|
5
|
+
## 1. Let PatchPilot install the wrapper
|
|
6
|
+
|
|
7
|
+
Do not run `python3 -m pip install -U gemini_webapi` against Homebrew Python. Homebrew blocks that with PEP 668.
|
|
8
|
+
|
|
9
|
+
PatchPilot uses this managed venv instead:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
~/.patchpilot/gemini-wrapper-venv
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
It creates the venv and installs the pinned `gemini_webapi` version when you explicitly approve `patchpilot doctor --fix` or `/doctor fix`. Normal chat startup does not install Python packages.
|
|
16
|
+
|
|
17
|
+
## 2. Get the cookie values manually
|
|
18
|
+
|
|
19
|
+
1. Open `https://gemini.google.com`.
|
|
20
|
+
2. Open DevTools.
|
|
21
|
+
3. Go to Application or Storage.
|
|
22
|
+
4. Open Cookies for `https://gemini.google.com`.
|
|
23
|
+
5. Copy `__Secure-1PSID`.
|
|
24
|
+
6. Copy `__Secure-1PSIDTS` if it exists.
|
|
25
|
+
|
|
26
|
+
Do not paste these values into issues, logs, chats, or commits. `__Secure-1PSID` acts like a Google session token.
|
|
27
|
+
|
|
28
|
+
## 3. Run PatchPilot onboarding
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
patchpilot --provider gemini-wrapper
|
|
32
|
+
patchpilot --provider gemini-wrapper --model flash
|
|
33
|
+
patchpilot --provider gemini-wrapper --model flash-lite
|
|
34
|
+
patchpilot --provider gemini-wrapper --model pro
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Choose `Gemini-Wrapper` in setup. PatchPilot asks for:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
psid > ********
|
|
41
|
+
ts > ********
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`psid` is required. `ts` is optional; press Enter to skip it.
|
|
45
|
+
|
|
46
|
+
PatchPilot writes:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
~/.patchpilot/gemini-cookies.json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
with owner-only file permissions (`0600`) and stores this config:
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
PATCHPILOT_PROVIDER=gemini-wrapper
|
|
56
|
+
PATCHPILOT_MODEL=auto
|
|
57
|
+
PATCHPILOT_GEMINI_WRAPPER_MODE=python
|
|
58
|
+
PATCHPILOT_GEMINI_WRAPPER_COOKIES_JSON=/Users/you/.patchpilot/gemini-cookies.json
|
|
59
|
+
PATCHPILOT_GEMINI_WRAPPER_MIN_INTERVAL_MS=1500
|
|
60
|
+
PATCHPILOT_GEMINI_WRAPPER_TIMEOUT_MS=180000
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If a pasted `__Secure-1PSIDTS` expires, PatchPilot retries the bridge request once without that optional timestamp. Transient WebAPI network timeouts are retried inside the bridge. Bridge calls are also serialized with a small default delay so advisor or agent requests do not hit the wrapper at the same instant. Set `PATCHPILOT_GEMINI_WRAPPER_MIN_INTERVAL_MS=0` only for debugging.
|
|
64
|
+
|
|
65
|
+
The default bridge timeout is 180 seconds. `gemini-3-pro` can take longer through the unofficial WebAPI bridge, so PatchPilot gives Pro models at least 240 seconds. For fast local test loops, use `auto`; PatchPilot omits the model parameter and lets Gemini Web pick its current default.
|
|
66
|
+
|
|
67
|
+
PatchPilot exposes current Gemini Web shortcuts through live bridge discovery:
|
|
68
|
+
|
|
69
|
+
| PatchPilot model | Bridge behavior |
|
|
70
|
+
| --- | --- |
|
|
71
|
+
| `auto` | omit model and let Gemini Web choose |
|
|
72
|
+
| `flash-lite` | resolve the live Flash-Lite model from `client.list_models()` and pass its `model_id` |
|
|
73
|
+
| `flash` | prefer a live 3.5 Flash descriptor when the bridge exposes it; otherwise fall back to the current Flash descriptor or `gemini-3-flash` |
|
|
74
|
+
| `pro` | resolve the live Pro descriptor when available; otherwise fall back to `gemini-3-pro` |
|
|
75
|
+
| `thinking` | legacy compatibility alias for `gemini-3-flash-thinking` when available |
|
|
76
|
+
|
|
77
|
+
Gemini Web now presents Denkaufwand/Thinking-Level controls rather than a recommended standalone `thinking` model. The unofficial `gemini_webapi` bridge does not expose that control as a stable PatchPilot option yet, so `/reasoning` reports the limitation instead of pretending to change Web Denkaufwand.
|
|
78
|
+
|
|
79
|
+
## File Analysis
|
|
80
|
+
|
|
81
|
+
Gemini-Wrapper file analysis uses the same `gemini_webapi` file pipeline documented by the upstream project: PatchPilot passes the approved file path as `files=[...]` to `GeminiClient.generate_content`. This is used by `inspect_document` for screenshots and images when the managed Python bridge is active, and as a fallback for PDFs/DOCX files when local text extraction cannot produce useful text.
|
|
82
|
+
|
|
83
|
+
Supported direct file inputs include PNG, JPEG, WebP, GIF, HEIC/HEIF, PDF, and DOCX. PatchPilot still applies its own safety checks first: external absolute paths require file-analysis approval, sensitive paths are blocked, and browser cookie stores are never auto-scanned.
|
|
84
|
+
|
|
85
|
+
By default, Gemini-Wrapper is tried first for images. PDFs use `pdftotext` first and DOCX is parsed from `word/document.xml` first; provider file analysis is used only when local document extraction fails or returns no useful text. Text/code files are read directly. Images can use local `tesseract` OCR when the user asks for `mode:"local"`/`mode:"ocr"`.
|
|
86
|
+
|
|
87
|
+
The Python wrapper stores refreshed Google cookies in a PatchPilot-owned cache:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
~/.patchpilot/gemini-webapi-cache
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
PatchPilot creates that directory with owner-only permissions (`0700`) and passes it to `gemini_webapi` as `GEMINI_COOKIE_PATH`.
|
|
94
|
+
|
|
95
|
+
## 4. Verify
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
patchpilot doctor --provider gemini-wrapper --check-model auto
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Expected checks:
|
|
102
|
+
|
|
103
|
+
- Node and Git are available.
|
|
104
|
+
- `gemini_webapi` imports through `~/.patchpilot/gemini-wrapper-venv/bin/python`.
|
|
105
|
+
- explicit cookie auth is configured.
|
|
106
|
+
- the bridge lists Gemini models.
|
|
107
|
+
|
|
108
|
+
## Security Boundary
|
|
109
|
+
|
|
110
|
+
PatchPilot never scans Chrome, Safari, Firefox, Arc, Edge, Brave, Keychain, or browser cookie stores. The only supported auth sources are the masked paste onboarding flow, an explicit cookie JSON path, or explicit `GEMINI_SECURE_1PSID` environment variables.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# PatchPilot Product Context
|
|
2
|
+
|
|
3
|
+
PatchPilot is a local-first, permissioned terminal coding agent. It is designed for repository work where the user wants every risky operation to be visible, reviewable, and easy to approve or deny.
|
|
4
|
+
|
|
5
|
+
## Core Workflow
|
|
6
|
+
|
|
7
|
+
1. Inspect the workspace with read-only tools.
|
|
8
|
+
2. Keep a visible todo list for multi-step work.
|
|
9
|
+
3. Propose or apply focused edits in build mode.
|
|
10
|
+
4. Request scoped approvals for writes, package scripts, tests, and shell commands.
|
|
11
|
+
5. Show Git diff, run checks, and leave commits or pull requests under the user's control.
|
|
12
|
+
|
|
13
|
+
## Safety Model
|
|
14
|
+
|
|
15
|
+
- `plan` mode is read-only.
|
|
16
|
+
- `build` mode can request approvals for writes and shell actions.
|
|
17
|
+
- `bypass` mode removes per-tool approval prompts only after an explicit trusted-workspace confirmation.
|
|
18
|
+
- Session approvals are scoped to a concrete target such as a path, script body, patch hash, or normalized shell command.
|
|
19
|
+
- Secrets, browser profiles, cookies, and credential files are denied by default.
|
|
20
|
+
|
|
21
|
+
## TUI Surface
|
|
22
|
+
|
|
23
|
+
- Header: current provider, model, route, mode, and high-level run state.
|
|
24
|
+
- Sidebar: workspace, permissions, machine stats, session telemetry, and advisors.
|
|
25
|
+
- Transcript: compact run log, tool results, todos, and live status.
|
|
26
|
+
- Composer: bounded multiline prompt editor with visible newest input.
|
|
27
|
+
- Command palette: `/models`, `/sessions`, `/connect`, `/doctor`, `/experimental`, and related commands.
|
|
28
|
+
|
|
29
|
+
## Provider Matrix
|
|
30
|
+
|
|
31
|
+
- Ollama: local or remote LAN/Tailscale inference.
|
|
32
|
+
- Gemini: official Google Gemini API key.
|
|
33
|
+
- Gemini-Wrapper: opt-in Gemini Web bridge through pinned `gemini_webapi`; Python bridge supports file analysis, HTTP wrapper mode does not.
|
|
34
|
+
- OpenRouter: broad cloud model routing, including free variants.
|
|
35
|
+
- NVIDIA: OpenAI-compatible NVIDIA NIM endpoints.
|
|
36
|
+
- Codex: ChatGPT login through Codex CLI.
|
|
37
|
+
|
|
38
|
+
## Useful First Questions
|
|
39
|
+
|
|
40
|
+
- "What can PatchPilot do in this repo?"
|
|
41
|
+
- "Summarize this project and list the safest next fixes."
|
|
42
|
+
- "Find the test commands and explain the release process."
|
|
43
|
+
- "Review the current diff for risky changes."
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# PatchPilot v0.1.1-beta
|
|
2
|
+
|
|
3
|
+
## Highlights
|
|
4
|
+
|
|
5
|
+
- Beta packaging pass for the early PatchPilot CLI.
|
|
6
|
+
- Kept the project positioned as an experimental local-first coding-agent TUI.
|
|
7
|
+
|
|
8
|
+
## Fixed
|
|
9
|
+
|
|
10
|
+
- Tightened the first public install surface after the initial v0.1.0 release.
|
|
11
|
+
|
|
12
|
+
## Improved
|
|
13
|
+
|
|
14
|
+
- Clarified the beta release path before the later v0.2 and v0.3 hardening work.
|
|
15
|
+
|
|
16
|
+
## Pull Requests
|
|
17
|
+
|
|
18
|
+
- Early beta release maintenance.
|
package/docs/releases/v0.2.1.md
CHANGED
|
@@ -17,3 +17,7 @@
|
|
|
17
17
|
- Header and sidebar now show `off`, `approval`, or `on` permissions based on the active mode instead of mixing mode and permission state.
|
|
18
18
|
- Slash commands document `/mode bypass` and `/bypass` as explicit advanced controls.
|
|
19
19
|
- Website-facing install flow can point users to the npm package instead of only GitHub assets.
|
|
20
|
+
|
|
21
|
+
## Pull Requests
|
|
22
|
+
|
|
23
|
+
- #17 Prepare v0.3.1 beta mode safety.
|
package/docs/releases/v0.4.0.md
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# PatchPilot v1.0.0
|
|
2
|
+
|
|
3
|
+
## Highlights
|
|
4
|
+
|
|
5
|
+
- Promotes PatchPilot to the first stable CLI release for visible, permissioned coding-agent runs across local, remote, and cloud model routes.
|
|
6
|
+
- Finishes the Gemini-Wrapper provider path with explicit cookie onboarding, manual/auto model modes, pinned managed bridge installation, and clearer failure messages.
|
|
7
|
+
- Adds real session resume context injection, model-driven `/init`, `/cleanup`, `/doctor fix`, and opt-in `/experimental` controls for subagents, file analysis, and memory.
|
|
8
|
+
- Improves the TUI with readable transcript text, scrollable command and session panes, bottom-aligned transcript rendering, approval key isolation, and clearer token/cost/cache labels.
|
|
9
|
+
|
|
10
|
+
## Fixed
|
|
11
|
+
|
|
12
|
+
- Fixed a permission escalation bug where `--apply`, `/write on`, or `/shell on` could collapse into full build+bypass mode. Partial permissions now stay partial; bypass only applies to explicitly enabled permission groups.
|
|
13
|
+
- Fixed shell confinement by blocking absolute shell path arguments outside the workspace and by detecting dangerous `git`/`npm` subcommands even after global options such as `git -C .` or `npm --prefix .`.
|
|
14
|
+
- Fixed stale `/experimental` toggles by making agent runs observe the latest file-analysis and memory settings.
|
|
15
|
+
- Fixed Gemini-Wrapper bridge timeout conversion so Python receives the configured seconds budget instead of a shortened fraction.
|
|
16
|
+
- Fixed Gemini-Wrapper startup so normal chat runs no longer install unpinned Python packages at runtime.
|
|
17
|
+
|
|
18
|
+
## Improved
|
|
19
|
+
|
|
20
|
+
- External file analysis now requires per-path approval and still rejects sensitive paths after resolution.
|
|
21
|
+
- `memory_remember` is treated as a durable write and requires write approval before persisting notes in SQLite.
|
|
22
|
+
- `/init` now asks the selected model to inspect the repository and write project-specific `PATCHPILOT.md` guidance instead of emitting generic boilerplate.
|
|
23
|
+
- Gemini-Wrapper documentation and README copy now label the route as advanced, unofficial, and explicit about session-cookie risk.
|
|
24
|
+
- npm metadata now points to the public PatchPilot project page.
|
|
25
|
+
|
|
26
|
+
## Pull Requests
|
|
27
|
+
|
|
28
|
+
- #20 Harden Gemini-Wrapper, TUI sessions, experimental tools, and v1 release posture.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# PatchPilot v1.0.1
|
|
2
|
+
|
|
3
|
+
## Highlights
|
|
4
|
+
|
|
5
|
+
- Adds real Gemini-Wrapper file analysis for screenshots, images, PDFs, and DOCX files through the managed `gemini_webapi` Python bridge.
|
|
6
|
+
- Adds `create_pdf` and `create_docx` tools so PatchPilot can generate simple text documents from agent output.
|
|
7
|
+
- Adds a live provider-neutral todo panel in the TUI so longer agent runs show pending, active, and completed work.
|
|
8
|
+
|
|
9
|
+
## Fixed
|
|
10
|
+
|
|
11
|
+
- Fixed image inspection only returning metadata. With Gemini-Wrapper enabled, `inspect_document` now sends approved image files to Gemini Web as file inputs and returns visual analysis plus extracted visible text.
|
|
12
|
+
- Fixed escaped multiline file writes. `write_file` and line-range `edit_file` now normalize likely double-escaped code/HTML payloads before writing, preventing `\n` and `\"` from landing as literal one-line source.
|
|
13
|
+
- Fixed scanned/image-based PDF handling by falling back to Gemini-Wrapper file analysis when local `pdftotext` cannot extract text.
|
|
14
|
+
- Fixed false-positive image inspection results. If provider analysis fails and no OCR mode was requested, PatchPilot now reports metadata-only analysis as degraded instead of claiming the image was understood.
|
|
15
|
+
- Fixed approval-gated tools appearing stuck after approval by updating the visible run state immediately and executing tool calls sequentially.
|
|
16
|
+
|
|
17
|
+
## Improved
|
|
18
|
+
|
|
19
|
+
- Local document analysis is faster by default: PDFs use `pdftotext` and DOCX files are parsed directly before PatchPilot spends provider time. Images still use provider vision in `auto`, while `mode:"ocr"` keeps local OCR explicit.
|
|
20
|
+
- Gemini-Wrapper docs now explain the upstream `files=[...]` pipeline and the supported file formats.
|
|
21
|
+
- Providers can update visible run tasks through `update_todo`, with the active item animated in the transcript panel.
|
|
22
|
+
|
|
23
|
+
## Pull Requests
|
|
24
|
+
|
|
25
|
+
- #21 Improve file-edit reliability and Gemini-Wrapper document analysis.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# PatchPilot v1.1.0
|
|
2
|
+
|
|
3
|
+
## Highlights
|
|
4
|
+
|
|
5
|
+
- Adds Gemini-Wrapper document analysis for screenshots, images, PDFs, and DOCX files through the managed `gemini_webapi` bridge.
|
|
6
|
+
- Adds approval-aware file generation tools for simple PDF and DOCX output.
|
|
7
|
+
- Adds visible provider-neutral run todos so longer agent tasks expose pending, active, and completed work in the TUI.
|
|
8
|
+
- Imports Gemini browser-cookie onboarding and model discovery improvements into the stable CLI line.
|
|
9
|
+
|
|
10
|
+
## Fixed
|
|
11
|
+
|
|
12
|
+
- Fixed escaped multiline file writes by normalizing likely double-escaped payloads before writing or line-range editing files.
|
|
13
|
+
- Fixed image inspection that only returned metadata by routing approved image inputs through Gemini-Wrapper file analysis when available.
|
|
14
|
+
- Fixed scanned PDF analysis by falling back to provider file analysis when local `pdftotext` cannot extract text.
|
|
15
|
+
- Fixed approval-gated tools appearing stuck after approval by updating visible run state immediately and executing tool calls sequentially.
|
|
16
|
+
- Fixed Gemini-Wrapper transport resets by retrying recoverable network failures.
|
|
17
|
+
- Fixed local agent artifacts and game experiments leaking toward GitHub by ignoring them and removing generated `PATCHPILOT.md` from the tracked tree.
|
|
18
|
+
|
|
19
|
+
## Improved
|
|
20
|
+
|
|
21
|
+
- Updated runtime and development dependencies, including Ink, Zod, React, tsx, Vitest, Node types, and TypeScript 6.
|
|
22
|
+
- Updated GitHub Actions to `actions/setup-node@v6` and `actions/github-script@v9`.
|
|
23
|
+
- Added release workflow automation that triggers the website refresh after a GitHub release completes.
|
|
24
|
+
- Kept generated local notes and browser-game experiments local-only via `.gitignore`.
|
|
25
|
+
|
|
26
|
+
## Pull Requests
|
|
27
|
+
|
|
28
|
+
- #21 Improve file-edit reliability and Gemini-Wrapper document analysis.
|
|
29
|
+
- #19 Trigger website rebuild after releases.
|
|
30
|
+
- #10, #11, #12, #13, #14, #15, #16 Dependency and workflow updates.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# PatchPilot v1.2.0
|
|
2
|
+
|
|
3
|
+
## Highlights
|
|
4
|
+
|
|
5
|
+
- Makes the fullscreen shell the stable default, with a compact header, command palette, animated run status, artifacts bar, saved-cost counter, cursor-aware composer, and a `/theme` switch back to the legacy layout.
|
|
6
|
+
- Adds context storage and compaction primitives plus `/context` and `/compact` commands so long sessions can preserve useful workspace state without replaying noisy transcripts.
|
|
7
|
+
- Adds composable ultra modes: `ultramaxx`, `ultrafast`, `ultracheap`, `ultrafocus:<path>`, and `ultraloop`, with conflict checks and visible keyword styling.
|
|
8
|
+
- Adds first-run preferences for default mode, reasoning, thinking budget, and subagents, plus a use-at-your-own-risk acceptance step before onboarding continues.
|
|
9
|
+
- Adds Windows hardening for clipboard image paste, path/attachment parsing, Codex CLI launcher resolution, and Gemini-Wrapper bootstrap commands.
|
|
10
|
+
|
|
11
|
+
## Fixed
|
|
12
|
+
|
|
13
|
+
- Hardened shell approvals so pipes remain supported, `&&` and `;` are available only through `/experimental shell-metacharacters`, and redirects, expansion, background jobs, OR chains, multiline commands, and glob expansion require explicit approval even in build+bypass.
|
|
14
|
+
- Fixed `/write on` and `/shell on` so they no longer bypass the trusted-workspace confirmation panel.
|
|
15
|
+
- Fixed fake success for unknown `/experimental` flags by validating supported flags before persisting settings.
|
|
16
|
+
- Fixed external-file approval bypass behavior, shell path guards, attachment context handling, and secret/path checks around workspace tools.
|
|
17
|
+
- Fixed Gemini-Wrapper re-auth flows so expired cookies can trigger an approval-style refresh panel and failed prompts can retry after refresh.
|
|
18
|
+
- Fixed provider retry behavior, todo-only/fake final handling, TUI prompt handling, composer cursor behavior, run-status randomization, and overlay layout clipping.
|
|
19
|
+
|
|
20
|
+
## Improved
|
|
21
|
+
|
|
22
|
+
- Refreshes README guidance for the default shell, ultra modes, context commands, shell-metacharacter controls, onboarding disclaimer, remote host setup, and the current safety model.
|
|
23
|
+
- Refreshes the npm lockfile with `npm update` and keeps the package verification surface aligned with the current dependency graph.
|
|
24
|
+
- Adds broader Vitest coverage for context storage, compaction, shell guards, command help, layout math, clipboard, attachments, provider retry helpers, ultra modes, and Windows-oriented path behavior.
|
|
25
|
+
|
|
26
|
+
## Pull Requests
|
|
27
|
+
|
|
28
|
+
- #23 PatchPilot deep-dive hardening and context system.
|
|
Binary file
|
|
Binary file
|