@oh-my-pi/pi-coding-agent 12.18.1 → 12.19.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/CHANGELOG.md +47 -0
- package/package.json +7 -7
- package/src/async/index.ts +1 -0
- package/src/async/job-manager.ts +341 -0
- package/src/cli/file-processor.ts +3 -3
- package/src/cli/list-models.ts +3 -17
- package/src/cli/stats-cli.ts +3 -22
- package/src/cli/web-search-cli.ts +8 -16
- package/src/commit/agentic/agent.ts +6 -9
- package/src/commit/agentic/index.ts +44 -50
- package/src/commit/agentic/state.ts +0 -9
- package/src/commit/agentic/tools/propose-commit.ts +1 -30
- package/src/commit/agentic/tools/schemas.ts +31 -0
- package/src/commit/agentic/tools/split-commit.ts +1 -30
- package/src/commit/agentic/validation.ts +1 -18
- package/src/commit/analysis/conventional.ts +3 -50
- package/src/commit/analysis/summary.ts +2 -13
- package/src/commit/changelog/detect.ts +4 -1
- package/src/commit/changelog/generate.ts +2 -25
- package/src/commit/changelog/index.ts +1 -2
- package/src/commit/cli.ts +4 -12
- package/src/commit/map-reduce/reduce-phase.ts +2 -43
- package/src/commit/pipeline.ts +7 -15
- package/src/commit/utils.ts +44 -0
- package/src/config/prompt-templates.ts +1 -81
- package/src/config/settings-schema.ts +20 -1
- package/src/config.ts +2 -3
- package/src/debug/index.ts +1 -6
- package/src/debug/system-info.ts +2 -6
- package/src/discovery/builtin.ts +5 -9
- package/src/discovery/helpers.ts +0 -26
- package/src/discovery/ssh.ts +1 -8
- package/src/exa/company.ts +8 -39
- package/src/exa/factory.ts +64 -0
- package/src/exa/index.ts +0 -16
- package/src/exa/linkedin.ts +8 -39
- package/src/exa/mcp-client.ts +0 -64
- package/src/exa/researcher.ts +17 -59
- package/src/exa/search.ts +30 -154
- package/src/extensibility/custom-tools/loader.ts +3 -41
- package/src/extensibility/extensions/loader.ts +2 -9
- package/src/extensibility/hooks/loader.ts +3 -20
- package/src/extensibility/hooks/runner.ts +3 -19
- package/src/extensibility/plugins/installer.ts +2 -1
- package/src/extensibility/plugins/loader.ts +29 -117
- package/src/extensibility/skills.ts +2 -89
- package/src/extensibility/slash-commands.ts +1 -63
- package/src/extensibility/utils.ts +38 -0
- package/src/index.ts +9 -25
- package/src/internal-urls/index.ts +1 -0
- package/src/internal-urls/jobs-protocol.ts +118 -0
- package/src/ipy/kernel.ts +2 -0
- package/src/lsp/config.ts +1 -5
- package/src/lsp/lspmux.ts +0 -17
- package/src/lsp/utils.ts +2 -24
- package/src/main.ts +16 -24
- package/src/mcp/client.ts +1 -46
- package/src/mcp/render.ts +8 -1
- package/src/mcp/tool-cache.ts +1 -5
- package/src/mcp/transports/http.ts +2 -7
- package/src/mcp/transports/stdio.ts +2 -7
- package/src/modes/components/bash-execution.ts +2 -16
- package/src/modes/components/extensions/inspector-panel.ts +8 -18
- package/src/modes/components/footer.ts +10 -50
- package/src/modes/components/model-selector.ts +2 -21
- package/src/modes/components/python-execution.ts +2 -16
- package/src/modes/components/settings-selector.ts +1 -10
- package/src/modes/components/status-line/segments.ts +8 -25
- package/src/modes/components/status-line.ts +14 -31
- package/src/modes/components/tool-execution.ts +8 -2
- package/src/modes/controllers/command-controller.ts +71 -30
- package/src/modes/controllers/event-controller.ts +34 -4
- package/src/modes/controllers/mcp-command-controller.ts +3 -34
- package/src/modes/controllers/selector-controller.ts +2 -2
- package/src/modes/controllers/ssh-command-controller.ts +3 -34
- package/src/modes/interactive-mode.ts +6 -2
- package/src/modes/rpc/rpc-client.ts +1 -5
- package/src/modes/shared.ts +73 -0
- package/src/modes/types.ts +1 -0
- package/src/modes/utils/ui-helpers.ts +26 -2
- package/src/patch/index.ts +4 -4
- package/src/patch/normalize.ts +22 -65
- package/src/patch/shared.ts +16 -16
- package/src/prompts/system/custom-system-prompt.md +0 -10
- package/src/prompts/system/system-prompt.md +69 -89
- package/src/prompts/tools/async-result.md +5 -0
- package/src/prompts/tools/bash.md +5 -0
- package/src/prompts/tools/cancel-job.md +7 -0
- package/src/prompts/tools/poll-jobs.md +7 -0
- package/src/prompts/tools/task.md +4 -0
- package/src/sdk.ts +70 -6
- package/src/session/agent-session.ts +40 -6
- package/src/session/agent-storage.ts +69 -278
- package/src/session/auth-storage.ts +14 -1430
- package/src/session/session-manager.ts +69 -5
- package/src/session/session-storage.ts +1 -5
- package/src/session/streaming-output.ts +637 -76
- package/src/slash-commands/builtin-registry.ts +8 -0
- package/src/ssh/connection-manager.ts +4 -12
- package/src/ssh/sshfs-mount.ts +3 -7
- package/src/ssh/utils.ts +8 -0
- package/src/system-prompt.ts +24 -90
- package/src/task/executor.ts +11 -1
- package/src/task/index.ts +258 -13
- package/src/task/parallel.ts +32 -0
- package/src/task/render.ts +15 -7
- package/src/task/types.ts +5 -0
- package/src/tools/ask.ts +4 -7
- package/src/tools/bash-interactive.ts +4 -5
- package/src/tools/bash.ts +125 -41
- package/src/tools/cancel-job.ts +93 -0
- package/src/tools/fetch.ts +7 -27
- package/src/tools/find.ts +3 -3
- package/src/tools/gemini-image.ts +15 -14
- package/src/tools/grep.ts +3 -3
- package/src/tools/index.ts +13 -29
- package/src/tools/json-tree.ts +12 -1
- package/src/tools/jtd-to-json-schema.ts +10 -74
- package/src/tools/jtd-to-typescript.ts +10 -72
- package/src/tools/jtd-utils.ts +102 -0
- package/src/tools/notebook.ts +4 -9
- package/src/tools/output-meta.ts +52 -26
- package/src/tools/path-utils.ts +13 -7
- package/src/tools/poll-jobs.ts +178 -0
- package/src/tools/python.ts +32 -35
- package/src/tools/read.ts +61 -82
- package/src/tools/render-utils.ts +8 -159
- package/src/tools/ssh.ts +7 -20
- package/src/tools/submit-result.ts +1 -1
- package/src/tools/tool-errors.ts +0 -30
- package/src/tools/tool-result.ts +1 -2
- package/src/tools/write.ts +8 -10
- package/src/tui/code-cell.ts +8 -3
- package/src/tui/status-line.ts +4 -4
- package/src/tui/types.ts +0 -1
- package/src/tui/utils.ts +1 -14
- package/src/utils/command-args.ts +76 -0
- package/src/utils/file-mentions.ts +15 -19
- package/src/utils/frontmatter.ts +5 -10
- package/src/utils/shell-snapshot.ts +0 -11
- package/src/utils/title-generator.ts +0 -12
- package/src/web/scrapers/artifacthub.ts +7 -16
- package/src/web/scrapers/arxiv.ts +3 -8
- package/src/web/scrapers/aur.ts +8 -22
- package/src/web/scrapers/biorxiv.ts +5 -14
- package/src/web/scrapers/bluesky.ts +13 -36
- package/src/web/scrapers/brew.ts +5 -10
- package/src/web/scrapers/cheatsh.ts +2 -12
- package/src/web/scrapers/chocolatey.ts +63 -26
- package/src/web/scrapers/choosealicense.ts +3 -18
- package/src/web/scrapers/cisa-kev.ts +4 -18
- package/src/web/scrapers/clojars.ts +6 -33
- package/src/web/scrapers/coingecko.ts +25 -33
- package/src/web/scrapers/crates-io.ts +7 -26
- package/src/web/scrapers/crossref.ts +4 -18
- package/src/web/scrapers/devto.ts +11 -41
- package/src/web/scrapers/discogs.ts +7 -10
- package/src/web/scrapers/discourse.ts +6 -31
- package/src/web/scrapers/dockerhub.ts +12 -35
- package/src/web/scrapers/fdroid.ts +8 -33
- package/src/web/scrapers/firefox-addons.ts +10 -34
- package/src/web/scrapers/flathub.ts +7 -24
- package/src/web/scrapers/github-gist.ts +2 -12
- package/src/web/scrapers/github.ts +9 -47
- package/src/web/scrapers/gitlab.ts +130 -185
- package/src/web/scrapers/go-pkg.ts +12 -22
- package/src/web/scrapers/hackage.ts +88 -43
- package/src/web/scrapers/hackernews.ts +25 -45
- package/src/web/scrapers/hex.ts +19 -36
- package/src/web/scrapers/huggingface.ts +26 -91
- package/src/web/scrapers/iacr.ts +3 -8
- package/src/web/scrapers/jetbrains-marketplace.ts +9 -20
- package/src/web/scrapers/lemmy.ts +5 -23
- package/src/web/scrapers/lobsters.ts +16 -28
- package/src/web/scrapers/mastodon.ts +24 -43
- package/src/web/scrapers/maven.ts +6 -21
- package/src/web/scrapers/mdn.ts +7 -11
- package/src/web/scrapers/metacpan.ts +9 -41
- package/src/web/scrapers/musicbrainz.ts +4 -28
- package/src/web/scrapers/npm.ts +8 -25
- package/src/web/scrapers/nuget.ts +14 -37
- package/src/web/scrapers/nvd.ts +6 -28
- package/src/web/scrapers/ollama.ts +7 -34
- package/src/web/scrapers/open-vsx.ts +5 -19
- package/src/web/scrapers/opencorporates.ts +30 -14
- package/src/web/scrapers/openlibrary.ts +49 -33
- package/src/web/scrapers/orcid.ts +4 -18
- package/src/web/scrapers/osv.ts +7 -24
- package/src/web/scrapers/packagist.ts +9 -24
- package/src/web/scrapers/pub-dev.ts +7 -50
- package/src/web/scrapers/pubmed.ts +54 -21
- package/src/web/scrapers/pypi.ts +8 -26
- package/src/web/scrapers/rawg.ts +11 -19
- package/src/web/scrapers/readthedocs.ts +4 -9
- package/src/web/scrapers/reddit.ts +5 -15
- package/src/web/scrapers/repology.ts +8 -20
- package/src/web/scrapers/rfc.ts +5 -14
- package/src/web/scrapers/rubygems.ts +6 -21
- package/src/web/scrapers/searchcode.ts +8 -36
- package/src/web/scrapers/sec-edgar.ts +4 -18
- package/src/web/scrapers/semantic-scholar.ts +15 -35
- package/src/web/scrapers/snapcraft.ts +5 -19
- package/src/web/scrapers/sourcegraph.ts +5 -43
- package/src/web/scrapers/spdx.ts +4 -18
- package/src/web/scrapers/spotify.ts +4 -23
- package/src/web/scrapers/stackoverflow.ts +8 -13
- package/src/web/scrapers/terraform.ts +9 -37
- package/src/web/scrapers/tldr.ts +3 -7
- package/src/web/scrapers/twitter.ts +3 -7
- package/src/web/scrapers/types.ts +105 -27
- package/src/web/scrapers/utils.ts +97 -103
- package/src/web/scrapers/vimeo.ts +7 -27
- package/src/web/scrapers/vscode-marketplace.ts +8 -17
- package/src/web/scrapers/w3c.ts +6 -14
- package/src/web/scrapers/wikidata.ts +5 -19
- package/src/web/scrapers/wikipedia.ts +2 -12
- package/src/web/scrapers/youtube.ts +5 -34
- package/src/web/search/index.ts +0 -9
- package/src/web/search/providers/anthropic.ts +3 -2
- package/src/web/search/providers/brave.ts +3 -18
- package/src/web/search/providers/exa.ts +1 -12
- package/src/web/search/providers/kimi.ts +5 -44
- package/src/web/search/providers/perplexity.ts +1 -12
- package/src/web/search/providers/synthetic.ts +3 -26
- package/src/web/search/providers/utils.ts +36 -0
- package/src/web/search/providers/zai.ts +9 -50
- package/src/web/search/types.ts +0 -28
- package/src/web/search/utils.ts +17 -0
- package/src/tools/output-utils.ts +0 -63
- package/src/tools/truncate.ts +0 -385
- package/src/web/search/auth.ts +0 -178
package/src/patch/normalize.ts
CHANGED
|
@@ -206,72 +206,29 @@ export function convertLeadingTabsToSpaces(text: string, spacesPerTab: number):
|
|
|
206
206
|
// Unicode Normalization
|
|
207
207
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
208
208
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
code === 0x2013 || // EN DASH
|
|
226
|
-
code === 0x2014 || // EM DASH
|
|
227
|
-
code === 0x2015 || // HORIZONTAL BAR
|
|
228
|
-
code === 0x2212 // MINUS SIGN
|
|
229
|
-
) {
|
|
230
|
-
return "-";
|
|
231
|
-
}
|
|
209
|
+
const UNICODE_REPLACEMENTS: [RegExp, string][] = [
|
|
210
|
+
// Various dash/hyphen code-points → ASCII '-'
|
|
211
|
+
[/[\u2010-\u2015\u2212]/g, "-"],
|
|
212
|
+
// Fancy single quotes → '
|
|
213
|
+
[/[\u2018-\u201B]/g, "'"],
|
|
214
|
+
// Fancy double quotes → "
|
|
215
|
+
[/[\u201C-\u201F]/g, '"'],
|
|
216
|
+
// Non-breaking space and other odd spaces → normal space
|
|
217
|
+
[/[\u00A0\u2002-\u200A\u202F\u205F\u3000]/g, " "],
|
|
218
|
+
// Not-equal sign → !=
|
|
219
|
+
[/\u2260/g, "!="],
|
|
220
|
+
// Vulgar fraction ½ → 1/2
|
|
221
|
+
[/\u00BD/g, "1/2"],
|
|
222
|
+
// Zero-width characters → remove
|
|
223
|
+
[/[\u200B-\u200D\uFEFF]/g, ""],
|
|
224
|
+
];
|
|
232
225
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
) {
|
|
240
|
-
return "'";
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Fancy double quotes → "
|
|
244
|
-
if (
|
|
245
|
-
code === 0x201c || // LEFT DOUBLE QUOTATION MARK
|
|
246
|
-
code === 0x201d || // RIGHT DOUBLE QUOTATION MARK
|
|
247
|
-
code === 0x201e || // DOUBLE LOW-9 QUOTATION MARK
|
|
248
|
-
code === 0x201f // DOUBLE HIGH-REVERSED-9 QUOTATION MARK
|
|
249
|
-
) {
|
|
250
|
-
return '"';
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// Non-breaking space and other odd spaces → normal space
|
|
254
|
-
if (
|
|
255
|
-
code === 0x00a0 || // NO-BREAK SPACE
|
|
256
|
-
code === 0x2002 || // EN SPACE
|
|
257
|
-
code === 0x2003 || // EM SPACE
|
|
258
|
-
code === 0x2004 || // THREE-PER-EM SPACE
|
|
259
|
-
code === 0x2005 || // FOUR-PER-EM SPACE
|
|
260
|
-
code === 0x2006 || // SIX-PER-EM SPACE
|
|
261
|
-
code === 0x2007 || // FIGURE SPACE
|
|
262
|
-
code === 0x2008 || // PUNCTUATION SPACE
|
|
263
|
-
code === 0x2009 || // THIN SPACE
|
|
264
|
-
code === 0x200a || // HAIR SPACE
|
|
265
|
-
code === 0x202f || // NARROW NO-BREAK SPACE
|
|
266
|
-
code === 0x205f || // MEDIUM MATHEMATICAL SPACE
|
|
267
|
-
code === 0x3000 // IDEOGRAPHIC SPACE
|
|
268
|
-
) {
|
|
269
|
-
return " ";
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
return c;
|
|
273
|
-
})
|
|
274
|
-
.join("");
|
|
226
|
+
export function normalizeUnicode(s: string): string {
|
|
227
|
+
let result = s.trim();
|
|
228
|
+
for (const [pattern, replacement] of UNICODE_REPLACEMENTS) {
|
|
229
|
+
result = result.replace(pattern, replacement);
|
|
230
|
+
}
|
|
231
|
+
return result.normalize("NFC");
|
|
275
232
|
}
|
|
276
233
|
|
|
277
234
|
/**
|
package/src/patch/shared.ts
CHANGED
|
@@ -10,13 +10,15 @@ import { renderDiff as renderDiffColored } from "../modes/components/diff";
|
|
|
10
10
|
import { getLanguageFromPath, type Theme } from "../modes/theme/theme";
|
|
11
11
|
import type { OutputMeta } from "../tools/output-meta";
|
|
12
12
|
import {
|
|
13
|
+
formatDiagnostics,
|
|
14
|
+
formatDiffStats,
|
|
13
15
|
formatExpandHint,
|
|
14
16
|
formatStatusIcon,
|
|
17
|
+
formatTitle,
|
|
15
18
|
getDiffStats,
|
|
16
19
|
PREVIEW_LIMITS,
|
|
17
20
|
replaceTabs,
|
|
18
21
|
shortenPath,
|
|
19
|
-
ToolUIKit,
|
|
20
22
|
truncateDiffByHunk,
|
|
21
23
|
} from "../tools/render-utils";
|
|
22
24
|
import { Ellipsis, Hasher, type RenderCache, renderStatusLine, truncateToWidth } from "../tui";
|
|
@@ -120,7 +122,7 @@ function formatStreamingDiff(diff: string, rawPath: string, uiTheme: Theme, labe
|
|
|
120
122
|
return text;
|
|
121
123
|
}
|
|
122
124
|
|
|
123
|
-
function formatStreamingHashlineEdits(edits: unknown[], uiTheme: Theme
|
|
125
|
+
function formatStreamingHashlineEdits(edits: unknown[], uiTheme: Theme): string {
|
|
124
126
|
const MAX_EDITS = 4;
|
|
125
127
|
const MAX_DST_LINES = 8;
|
|
126
128
|
let text = "\n\n";
|
|
@@ -132,17 +134,17 @@ function formatStreamingHashlineEdits(edits: unknown[], uiTheme: Theme, ui: Tool
|
|
|
132
134
|
shownEdits++;
|
|
133
135
|
if (shownEdits > MAX_EDITS) break;
|
|
134
136
|
const formatted = formatHashlineEdit(edit);
|
|
135
|
-
text += uiTheme.fg("toolOutput",
|
|
137
|
+
text += uiTheme.fg("toolOutput", truncateToWidth(replaceTabs(formatted.srcLabel), 120));
|
|
136
138
|
text += "\n";
|
|
137
139
|
if (formatted.dst === "") {
|
|
138
|
-
text += uiTheme.fg("dim",
|
|
140
|
+
text += uiTheme.fg("dim", truncateToWidth(" (delete)", 120));
|
|
139
141
|
text += "\n";
|
|
140
142
|
continue;
|
|
141
143
|
}
|
|
142
144
|
for (const dstLine of formatted.dst.split("\n")) {
|
|
143
145
|
shownDstLines++;
|
|
144
146
|
if (shownDstLines > MAX_DST_LINES) break;
|
|
145
|
-
text += uiTheme.fg("toolOutput",
|
|
147
|
+
text += uiTheme.fg("toolOutput", truncateToWidth(replaceTabs(`+ ${dstLine}`), 120));
|
|
146
148
|
text += "\n";
|
|
147
149
|
}
|
|
148
150
|
if (shownDstLines > MAX_DST_LINES) break;
|
|
@@ -221,15 +223,15 @@ function renderDiffSection(
|
|
|
221
223
|
rawPath: string,
|
|
222
224
|
expanded: boolean,
|
|
223
225
|
uiTheme: Theme,
|
|
224
|
-
ui: ToolUIKit,
|
|
225
226
|
renderDiffFn: (t: string, o?: { filePath?: string }) => string,
|
|
226
227
|
): string {
|
|
227
228
|
let text = "";
|
|
228
229
|
const diffStats = getDiffStats(diff);
|
|
229
|
-
text += `\n${uiTheme.fg("dim", uiTheme.format.bracketLeft)}${
|
|
230
|
+
text += `\n${uiTheme.fg("dim", uiTheme.format.bracketLeft)}${formatDiffStats(
|
|
230
231
|
diffStats.added,
|
|
231
232
|
diffStats.removed,
|
|
232
233
|
diffStats.hunks,
|
|
234
|
+
uiTheme,
|
|
233
235
|
)}${uiTheme.fg("dim", uiTheme.format.bracketRight)}`;
|
|
234
236
|
|
|
235
237
|
const {
|
|
@@ -254,7 +256,6 @@ export const editToolRenderer = {
|
|
|
254
256
|
mergeCallAndResult: true,
|
|
255
257
|
|
|
256
258
|
renderCall(args: EditRenderArgs, options: RenderResultOptions, uiTheme: Theme): Component {
|
|
257
|
-
const ui = new ToolUIKit(uiTheme);
|
|
258
259
|
const rawPath = args.file_path || args.path || "";
|
|
259
260
|
const filePath = shortenPath(rawPath);
|
|
260
261
|
const editLanguage = getLanguageFromPath(rawPath) ?? "text";
|
|
@@ -270,7 +271,7 @@ export const editToolRenderer = {
|
|
|
270
271
|
const opTitle = args.op === "create" ? "Create" : args.op === "delete" ? "Delete" : "Edit";
|
|
271
272
|
const spinner =
|
|
272
273
|
options?.spinnerFrame !== undefined ? formatStatusIcon("running", uiTheme, options.spinnerFrame) : "";
|
|
273
|
-
let text = `${
|
|
274
|
+
let text = `${formatTitle(opTitle, uiTheme)} ${spinner ? `${spinner} ` : ""}${editIcon} ${pathDisplay}`;
|
|
274
275
|
|
|
275
276
|
// Show streaming preview of diff/content
|
|
276
277
|
if (args.previewDiff) {
|
|
@@ -278,13 +279,13 @@ export const editToolRenderer = {
|
|
|
278
279
|
} else if (args.diff && args.op) {
|
|
279
280
|
text += formatStreamingDiff(args.diff, rawPath, uiTheme);
|
|
280
281
|
} else if (args.edits && args.edits.length > 0) {
|
|
281
|
-
text += formatStreamingHashlineEdits(args.edits, uiTheme
|
|
282
|
+
text += formatStreamingHashlineEdits(args.edits, uiTheme);
|
|
282
283
|
} else if (args.diff) {
|
|
283
284
|
const previewLines = args.diff.split("\n");
|
|
284
285
|
const maxLines = 6;
|
|
285
286
|
text += "\n\n";
|
|
286
287
|
for (const line of previewLines.slice(0, maxLines)) {
|
|
287
|
-
text += `${uiTheme.fg("toolOutput",
|
|
288
|
+
text += `${uiTheme.fg("toolOutput", truncateToWidth(replaceTabs(line), 80))}\n`;
|
|
288
289
|
}
|
|
289
290
|
if (previewLines.length > maxLines) {
|
|
290
291
|
text += uiTheme.fg("dim", `… ${previewLines.length - maxLines} more lines`);
|
|
@@ -294,7 +295,7 @@ export const editToolRenderer = {
|
|
|
294
295
|
const maxLines = 6;
|
|
295
296
|
text += "\n\n";
|
|
296
297
|
for (const line of previewLines.slice(0, maxLines)) {
|
|
297
|
-
text += `${uiTheme.fg("toolOutput",
|
|
298
|
+
text += `${uiTheme.fg("toolOutput", truncateToWidth(replaceTabs(line), 80))}\n`;
|
|
298
299
|
}
|
|
299
300
|
if (previewLines.length > maxLines) {
|
|
300
301
|
text += uiTheme.fg("dim", `… ${previewLines.length - maxLines} more lines`);
|
|
@@ -310,7 +311,6 @@ export const editToolRenderer = {
|
|
|
310
311
|
uiTheme: Theme,
|
|
311
312
|
args?: EditRenderArgs,
|
|
312
313
|
): Component {
|
|
313
|
-
const ui = new ToolUIKit(uiTheme);
|
|
314
314
|
const rawPath = args?.file_path || args?.path || "";
|
|
315
315
|
const filePath = shortenPath(rawPath);
|
|
316
316
|
const editLanguage = getLanguageFromPath(rawPath) ?? "text";
|
|
@@ -370,18 +370,18 @@ export const editToolRenderer = {
|
|
|
370
370
|
text += `\n\n${uiTheme.fg("error", replaceTabs(errorText))}`;
|
|
371
371
|
}
|
|
372
372
|
} else if (result.details?.diff) {
|
|
373
|
-
text += renderDiffSection(result.details.diff, rawPath, expanded, uiTheme,
|
|
373
|
+
text += renderDiffSection(result.details.diff, rawPath, expanded, uiTheme, renderDiffFn);
|
|
374
374
|
} else if (editDiffPreview) {
|
|
375
375
|
if ("error" in editDiffPreview) {
|
|
376
376
|
text += `\n\n${uiTheme.fg("error", replaceTabs(editDiffPreview.error))}`;
|
|
377
377
|
} else if (editDiffPreview.diff) {
|
|
378
|
-
text += renderDiffSection(editDiffPreview.diff, rawPath, expanded, uiTheme,
|
|
378
|
+
text += renderDiffSection(editDiffPreview.diff, rawPath, expanded, uiTheme, renderDiffFn);
|
|
379
379
|
}
|
|
380
380
|
}
|
|
381
381
|
|
|
382
382
|
// Show LSP diagnostics if available
|
|
383
383
|
if (result.details?.diagnostics) {
|
|
384
|
-
text +=
|
|
384
|
+
text += formatDiagnostics(result.details.diagnostics, expanded, uiTheme, (fp: string) =>
|
|
385
385
|
uiTheme.getLangIcon(getLanguageFromPath(fp)),
|
|
386
386
|
);
|
|
387
387
|
}
|
|
@@ -16,16 +16,6 @@
|
|
|
16
16
|
</file>
|
|
17
17
|
{{/list}}
|
|
18
18
|
</instructions>
|
|
19
|
-
{{/if}}
|
|
20
|
-
{{#if git.isRepo}}
|
|
21
|
-
## Version Control
|
|
22
|
-
Snapshot; does not update during conversation.
|
|
23
|
-
Current branch: {{git.currentBranch}}
|
|
24
|
-
Main branch: {{git.mainBranch}}
|
|
25
|
-
{{git.status}}
|
|
26
|
-
### History
|
|
27
|
-
{{git.commits}}
|
|
28
|
-
{{/if}}
|
|
29
19
|
</project>
|
|
30
20
|
{{/ifAny}}
|
|
31
21
|
{{#if skills.length}}
|
|
@@ -10,22 +10,28 @@ Say truth; omit filler. No apologies. No comfort where clarity belongs.
|
|
|
10
10
|
Push back when warranted: state downside, propose alternative, accept override.
|
|
11
11
|
</identity>
|
|
12
12
|
|
|
13
|
+
<output_style>
|
|
14
|
+
- No summary closings ("In summary…"). No filler. No emojis. No ceremony.
|
|
15
|
+
- Suppress: "genuinely", "honestly", "straightforward".
|
|
16
|
+
- User execution-mode instructions (do-it-yourself vs delegate) override tool-use defaults.
|
|
17
|
+
- Requirements conflict or are unclear → ask only after exhaustive exploration.
|
|
18
|
+
</output_style>
|
|
19
|
+
|
|
13
20
|
<discipline>
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
Before writing code, think through:
|
|
21
|
-
- What are my assumptions about input? About environment?
|
|
22
|
-
- What breaks this?
|
|
23
|
-
- What would a malicious caller do?
|
|
21
|
+
**Guard against the completion reflex** — the urge to ship something that compiles before you've understood the problem:
|
|
22
|
+
- Resist pattern-matching to a similar problem before reading this one
|
|
23
|
+
- Compiling ≠ correct; "it works" ≠ "works in all cases"
|
|
24
|
+
**Before acting on any change**, think through:
|
|
25
|
+
- What are my assumptions about input, environment, callers?
|
|
26
|
+
- What breaks this? What would a malicious caller do?
|
|
24
27
|
- Would a tired maintainer misunderstand this?
|
|
25
|
-
- Can this be simpler?
|
|
26
|
-
-
|
|
28
|
+
- Can this be simpler? Are these abstractions earning their keep?
|
|
29
|
+
- What else does this touch? Did I find all consumers?
|
|
27
30
|
|
|
28
31
|
The question is not "does this work?" but "under what conditions? What happens outside them?"
|
|
32
|
+
**No breadcrumbs.** When you delete or move code, remove it cleanly — no `// moved to X` comments, no `// relocated` markers, no re-exports from the old location. The old location dies silent.
|
|
33
|
+
**Fix from first principles.** Don't apply bandaids. Find the root cause and fix it there. A symptom suppressed is a bug deferred.
|
|
34
|
+
**Debug before rerouting.** When a tool call fails or returns unexpected output, read the full error and diagnose — don't abandon the approach and try an alternative.
|
|
29
35
|
</discipline>
|
|
30
36
|
|
|
31
37
|
{{#if systemPromptCustomization}}
|
|
@@ -94,46 +100,53 @@ Don't open a file hoping. Hope is not a strategy.
|
|
|
94
100
|
|
|
95
101
|
<procedure>
|
|
96
102
|
## Task Execution
|
|
97
|
-
|
|
103
|
+
|
|
104
|
+
### Scope
|
|
98
105
|
{{#if skills.length}}- If a skill matches the domain, read it before starting.{{/if}}
|
|
99
106
|
{{#if rules.length}}- If an applicable rule exists, read it before starting.{{/if}}
|
|
100
|
-
{{#has tools "task"}}-
|
|
101
|
-
- If
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
-
|
|
107
|
+
{{#has tools "task"}}- Determine if the task is parallelizable via Task tool; make a conflict-free delegation plan.{{/has}}
|
|
108
|
+
- If multi-file or imprecisely scoped, write out a step-by-step plan (3–7 steps) before touching any file.
|
|
109
|
+
- For new work: (1) think about architecture, (2) search official docs/papers on best practices, (3) review existing codebase, (4) compare research with codebase, (5) implement the best fit or surface tradeoffs.
|
|
110
|
+
|
|
111
|
+
### Before You Edit
|
|
112
|
+
- Read the relevant section of any file before editing. Never edit from a grep snippet alone — context above and below the match changes what the correct edit is.
|
|
113
|
+
- Grep for existing examples before implementing any pattern, utility, or abstraction. If the codebase already solves it, use that. Inventing a parallel convention is always wrong.
|
|
114
|
+
{{#has tools "lsp"}}- Before modifying any function, type, or exported symbol: run `lsp references` to find every consumer. Changes propagate — a missed callsite is a bug you shipped.{{/has}}
|
|
115
|
+
### While Working
|
|
116
|
+
- Write idiomatic, simple, maintainable code. Complexity must earn its place.
|
|
117
|
+
- Fix in the place the bug lives. Don't bandaid the problem within the caller.
|
|
118
|
+
- Clean up unused code ruthlessly: dead parameters, unused helpers, orphaned types. Delete them; update callers. Resulting code should be pristine.
|
|
119
|
+
{{#has tools "web_search"}}- If stuck or uncertain, gather more information. Don't pivot approach unless asked.{{/has}}
|
|
120
|
+
### If Blocked
|
|
121
|
+
- Exhaust tools/context/files first — explore.
|
|
106
122
|
- Only then ask — minimum viable question.
|
|
107
|
-
**If requested change includes refactor**:
|
|
108
|
-
- Cleanup dead code and unused elements, do not yield until your solution is pristine.
|
|
109
123
|
|
|
110
124
|
{{#has tools "todo_write"}}
|
|
111
125
|
### Task Tracking
|
|
112
126
|
- Never create a todo list and then stop.
|
|
113
|
-
-
|
|
127
|
+
- Update todos as you progress — don't batch.
|
|
114
128
|
- Skip entirely for single-step or trivial requests.
|
|
115
129
|
{{/has}}
|
|
116
130
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
-
|
|
121
|
-
- Investigating 2+ independent subsystems
|
|
122
|
-
- Work that decomposes into pieces not needing each other's results
|
|
123
|
-
|
|
124
|
-
Task tool is for **parallel execution**, not deferred execution. If you can do it now, do it now. Sequential is fine when steps depend on each other — don't parallelize for its own sake.
|
|
125
|
-
{{/has}}
|
|
131
|
+
### Testing
|
|
132
|
+
- Test everything. Tests must be rigorous enough that a future contributor cannot break the behavior without a failure.
|
|
133
|
+
- Prefer unit tests or e2e tests. Avoid mocks — they invent behaviors that never happen in production and hide real bugs.
|
|
134
|
+
- Run only the tests you added or modified unless asked otherwise.
|
|
126
135
|
|
|
127
136
|
### Verification
|
|
128
|
-
- Prefer external proof: tests, linters, type checks, repro steps.
|
|
129
|
-
-
|
|
130
|
-
- Non-trivial logic: define test first when feasible.
|
|
137
|
+
- Prefer external proof: tests, linters, type checks, repro steps. Do not yield without proof that the change is correct.
|
|
138
|
+
- Non-trivial logic: define the test first when feasible.
|
|
131
139
|
- Algorithmic work: naive correct version before optimizing.
|
|
132
|
-
- **Formatting is a batch operation.** Make all semantic changes first, then run the project's formatter once.
|
|
140
|
+
- **Formatting is a batch operation.** Make all semantic changes first, then run the project's formatter once.
|
|
141
|
+
|
|
142
|
+
### Handoff
|
|
143
|
+
Before finishing:
|
|
144
|
+
- List all commands run and confirm they passed.
|
|
145
|
+
- Summarize changes with file and line references.
|
|
146
|
+
- Call out TODOs, follow-up work, or uncertainties — no surprises.
|
|
133
147
|
|
|
134
|
-
### Concurrency
|
|
135
|
-
You are not alone in the codebase. Others may edit concurrently.
|
|
136
|
-
If contents differ or edits fail: re-read, adapt.
|
|
148
|
+
### Concurrency
|
|
149
|
+
You are not alone in the codebase. Others may edit concurrently. If contents differ or edits fail: re-read, adapt.
|
|
137
150
|
{{#has tools "ask"}}
|
|
138
151
|
Ask before `git checkout/restore/reset`, bulk overwrites, or deleting code you didn't write.
|
|
139
152
|
{{else}}
|
|
@@ -146,6 +159,7 @@ Never run destructive git commands, bulk overwrites, or delete code you didn't w
|
|
|
146
159
|
{{#list agentsMdSearch.files join="\n"}}- {{this}}{{/list}}
|
|
147
160
|
{{/if}}
|
|
148
161
|
- Resolve blockers before yielding.
|
|
162
|
+
- When adding dependencies: search for the best-maintained, widely-used option. Use the most recent stable major version. Avoid unmaintained or niche packages.
|
|
149
163
|
</procedure>
|
|
150
164
|
|
|
151
165
|
<project>
|
|
@@ -157,19 +171,6 @@ Never run destructive git commands, bulk overwrites, or delete code you didn't w
|
|
|
157
171
|
</file>
|
|
158
172
|
{{/list}}
|
|
159
173
|
{{/if}}
|
|
160
|
-
|
|
161
|
-
{{#if git.isRepo}}
|
|
162
|
-
## Version Control
|
|
163
|
-
Snapshot; no updates during conversation.
|
|
164
|
-
|
|
165
|
-
Current branch: {{git.currentBranch}}
|
|
166
|
-
Main branch: {{git.mainBranch}}
|
|
167
|
-
|
|
168
|
-
{{git.status}}
|
|
169
|
-
|
|
170
|
-
### History
|
|
171
|
-
{{git.commits}}
|
|
172
|
-
{{/if}}
|
|
173
174
|
</project>
|
|
174
175
|
|
|
175
176
|
<harness>
|
|
@@ -185,7 +186,7 @@ Oh My Pi ships internal documentation accessible via `docs://` URLs (resolved by
|
|
|
185
186
|
|
|
186
187
|
{{#if skills.length}}
|
|
187
188
|
<skills>
|
|
188
|
-
|
|
189
|
+
Match skill descriptions to the task domain. If a skill is relevant, read `skill://<name>` before starting.
|
|
189
190
|
Relative paths in skill files resolve against the skill directory.
|
|
190
191
|
|
|
191
192
|
{{#list skills join="\n"}}
|
|
@@ -232,26 +233,32 @@ Notice the sequential habit:
|
|
|
232
233
|
- Comfort in doing one thing at a time
|
|
233
234
|
- Illusion that order = correctness
|
|
234
235
|
- Assumption that B depends on A
|
|
235
|
-
|
|
236
|
+
|
|
237
|
+
<critical>
|
|
238
|
+
**ALWAYS** use the Task tool to launch subagents when work forks into independent streams:
|
|
236
239
|
- Editing 4+ files with no dependencies between edits
|
|
237
|
-
- Investigating
|
|
238
|
-
- Work decomposes into pieces
|
|
240
|
+
- Investigating multiple subsystems
|
|
241
|
+
- Work that decomposes into independent pieces
|
|
242
|
+
</critical>
|
|
239
243
|
|
|
240
244
|
Sequential work requires justification. If you cannot articulate why B depends on A → parallelize.
|
|
241
245
|
</parallel_reflex>
|
|
242
246
|
{{/has}}
|
|
243
247
|
|
|
244
|
-
<
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
248
|
+
<stakes>
|
|
249
|
+
Incomplete work means they start over — your effort wasted, their time lost.
|
|
250
|
+
|
|
251
|
+
Tests you didn't write: bugs shipped. Assumptions you didn't validate: incidents to debug. Edge cases you ignored: pages at 3am.
|
|
252
|
+
|
|
253
|
+
User works in a high-reliability domain — defense, finance, healthcare, infrastructure — where bugs have material impact on human lives.
|
|
254
|
+
|
|
255
|
+
You have unlimited stamina; the user does not. Persist on hard problems. Don't burn their energy on problems you failed to think through. Write what you can defend.
|
|
256
|
+
</stakes>
|
|
250
257
|
|
|
251
258
|
<contract>
|
|
252
259
|
These are inviolable. Violation is system failure.
|
|
253
260
|
1. Never claim unverified correctness.
|
|
254
|
-
2. Never yield unless your deliverable is complete
|
|
261
|
+
2. Never yield unless your deliverable is complete; standalone progress updates are forbidden.
|
|
255
262
|
3. Never suppress tests to make code pass. Never fabricate outputs not observed.
|
|
256
263
|
4. Never avoid breaking changes that correctness requires.
|
|
257
264
|
5. Never solve the wished-for problem instead of the actual problem.
|
|
@@ -259,33 +266,6 @@ These are inviolable. Violation is system failure.
|
|
|
259
266
|
7. Full cutover. Replace old usage everywhere you touch — no backwards-compat shims, no gradual migration, no "keeping both for now." The old way is dead; treat lingering instances as bugs.
|
|
260
267
|
</contract>
|
|
261
268
|
|
|
262
|
-
<diligence>
|
|
263
|
-
**GET THE TASK DONE.**
|
|
264
|
-
Complete the full request before yielding. Use tools for verifiable facts. Results conflict → investigate. Incomplete → iterate.
|
|
265
|
-
If you find yourself stopping without producing a change, you have failed.
|
|
266
|
-
|
|
267
|
-
You have unlimited stamina; the user does not. Persist on hard problems. Don't burn their energy on problems you failed to think through.
|
|
268
|
-
|
|
269
|
-
This matters. Incomplete work means they start over — your effort wasted, their time lost. The person waiting deserves your best work.
|
|
270
|
-
|
|
271
|
-
Tests you didn't write: bugs shipped.
|
|
272
|
-
Assumptions you didn't validate: incidents to debug.
|
|
273
|
-
Edge cases you ignored: pages at 3am.
|
|
274
|
-
|
|
275
|
-
Question not "Does this work?" but "Under what conditions? What happens outside them?"
|
|
276
|
-
|
|
277
|
-
Write what you can defend.
|
|
278
|
-
</diligence>
|
|
279
|
-
|
|
280
|
-
<stakes>
|
|
281
|
-
This is not practice. Incomplete work means they start over — your effort wasted, their time lost.
|
|
282
|
-
|
|
283
|
-
You are capable of extraordinary work.
|
|
284
|
-
The person waiting deserves to receive it.
|
|
285
|
-
|
|
286
|
-
User works in a high-reliability industry—defense, finance, healthcare, infrastructure—where bugs have material impact on people's lives, even death.
|
|
287
|
-
</stakes>
|
|
288
|
-
|
|
289
269
|
<critical>
|
|
290
270
|
- Every turn must advance the deliverable. A non-final turn without at least one side-effect is invalid.
|
|
291
271
|
- Default to action. Never ask for confirmation to continue work. If you hit an error, fix it. If you know the next step, take it. The user will intervene if needed.
|
|
@@ -9,6 +9,11 @@ Executes bash command in shell session for terminal operations like git, bun, ca
|
|
|
9
9
|
- `python skill://my-skill/scripts/init.py` runs the script from the skill directory
|
|
10
10
|
- `skill://<name>/<relative-path>` resolves within the skill's base directory
|
|
11
11
|
- `agent://`, `artifact://`, `plan://`, `memory://`, `rule://`, and `docs://` URIs are also auto-resolved to filesystem paths before execution
|
|
12
|
+
{{#if asyncEnabled}}
|
|
13
|
+
- Use `async: true` for long-running commands when you don't need immediate output; the call returns a background job ID and the result is delivered automatically as a follow-up.
|
|
14
|
+
- Use `read jobs://` to inspect all background jobs and `read jobs://<job_id>` for detailed status/output when needed.
|
|
15
|
+
- When you need to wait for async results before continuing, call `poll_jobs` — it blocks until jobs complete. Do NOT poll `read jobs://` in a loop or yield and hope for delivery.
|
|
16
|
+
{{/if}}
|
|
12
17
|
</instruction>
|
|
13
18
|
|
|
14
19
|
<output>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Poll Jobs
|
|
2
|
+
|
|
3
|
+
Block until one or more background jobs complete, fail, or are cancelled.
|
|
4
|
+
|
|
5
|
+
Use this instead of polling `read jobs://` in a loop when you need to wait for background task or bash results before continuing.
|
|
6
|
+
|
|
7
|
+
Returns the status and results of all watched jobs once at least one finishes.
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# Task
|
|
2
2
|
|
|
3
3
|
Launch subagents to execute parallel, well-scoped tasks.
|
|
4
|
+
{{#if asyncEnabled}}
|
|
5
|
+
Use `read jobs://` to inspect background task state and `read jobs://<job_id>` for detailed status/output when needed.
|
|
6
|
+
When you need to wait for async results before continuing, call `poll_jobs` — it blocks until jobs complete. Do NOT poll `read jobs://` in a loop or yield and hope for delivery.
|
|
7
|
+
{{/if}}
|
|
4
8
|
|
|
5
9
|
## What subagents inherit automatically
|
|
6
10
|
Subagents receive the **full system prompt**, including AGENTS.md, context files, and skills. Do NOT repeat project rules, coding conventions, or style guidelines in `context` — they already have them.
|