@oh-my-pi/pi-coding-agent 13.18.0 → 14.0.2
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 +316 -1
- package/package.json +86 -24
- package/scripts/format-prompts.ts +2 -2
- package/src/autoresearch/apply-contract-to-state.ts +24 -0
- package/src/autoresearch/contract.ts +0 -44
- package/src/autoresearch/dashboard.ts +1 -2
- package/src/autoresearch/git.ts +116 -30
- package/src/autoresearch/helpers.ts +49 -0
- package/src/autoresearch/index.ts +28 -187
- package/src/autoresearch/prompt.md +26 -9
- package/src/autoresearch/state.ts +0 -6
- package/src/autoresearch/tools/init-experiment.ts +202 -117
- package/src/autoresearch/tools/log-experiment.ts +123 -178
- package/src/autoresearch/tools/run-experiment.ts +48 -10
- package/src/autoresearch/types.ts +2 -2
- package/src/capability/index.ts +4 -2
- package/src/cli/file-processor.ts +3 -3
- package/src/cli/grep-cli.ts +8 -8
- package/src/cli/grievances-cli.ts +78 -0
- package/src/cli/read-cli.ts +67 -0
- package/src/cli/setup-cli.ts +4 -4
- package/src/cli/update-cli.ts +3 -3
- package/src/cli.ts +2 -0
- package/src/commands/grep.ts +6 -1
- package/src/commands/grievances.ts +20 -0
- package/src/commands/read.ts +33 -0
- package/src/commit/agentic/agent.ts +5 -8
- package/src/commit/agentic/index.ts +22 -26
- package/src/commit/agentic/tools/analyze-file.ts +3 -3
- package/src/commit/agentic/tools/git-file-diff.ts +3 -6
- package/src/commit/agentic/tools/git-hunk.ts +3 -3
- package/src/commit/agentic/tools/git-overview.ts +6 -9
- package/src/commit/agentic/tools/index.ts +6 -8
- package/src/commit/agentic/tools/propose-commit.ts +4 -7
- package/src/commit/agentic/tools/recent-commits.ts +3 -3
- package/src/commit/agentic/tools/split-commit.ts +4 -4
- package/src/commit/agentic/validation.ts +1 -1
- package/src/commit/analysis/conventional.ts +4 -4
- package/src/commit/analysis/summary.ts +3 -3
- package/src/commit/changelog/generate.ts +4 -4
- package/src/commit/changelog/index.ts +5 -9
- package/src/commit/map-reduce/map-phase.ts +4 -4
- package/src/commit/map-reduce/reduce-phase.ts +4 -4
- package/src/commit/pipeline.ts +13 -16
- package/src/config/keybindings.ts +7 -6
- package/src/config/prompt-templates.ts +44 -226
- package/src/config/resolve-config-value.ts +4 -2
- package/src/config/settings-schema.ts +98 -2
- package/src/config/settings.ts +25 -26
- package/src/dap/client.ts +674 -0
- package/src/dap/config.ts +150 -0
- package/src/dap/defaults.json +211 -0
- package/src/dap/index.ts +4 -0
- package/src/dap/session.ts +1255 -0
- package/src/dap/types.ts +600 -0
- package/src/debug/log-viewer.ts +3 -2
- package/src/discovery/builtin.ts +1 -2
- package/src/discovery/codex.ts +2 -2
- package/src/discovery/github.ts +2 -1
- package/src/discovery/helpers.ts +2 -2
- package/src/discovery/opencode.ts +2 -2
- package/src/edit/diff.ts +818 -0
- package/src/edit/index.ts +309 -0
- package/src/edit/line-hash.ts +67 -0
- package/src/edit/modes/chunk.ts +454 -0
- package/src/{patch → edit/modes}/hashline.ts +741 -361
- package/src/{patch/applicator.ts → edit/modes/patch.ts} +420 -117
- package/src/{patch/fuzzy.ts → edit/modes/replace.ts} +519 -197
- package/src/{patch → edit}/normalize.ts +97 -76
- package/src/{patch/shared.ts → edit/renderer.ts} +181 -108
- package/src/exec/bash-executor.ts +4 -2
- package/src/exec/idle-timeout-watchdog.ts +126 -0
- package/src/exec/non-interactive-env.ts +5 -0
- package/src/extensibility/custom-commands/bundled/ci-green/index.ts +6 -18
- package/src/extensibility/custom-commands/bundled/review/index.ts +45 -43
- package/src/extensibility/custom-commands/loader.ts +1 -2
- package/src/extensibility/custom-tools/loader.ts +34 -11
- package/src/extensibility/custom-tools/types.ts +1 -1
- package/src/extensibility/extensions/loader.ts +9 -4
- package/src/extensibility/extensions/runner.ts +24 -1
- package/src/extensibility/extensions/types.ts +4 -2
- package/src/extensibility/hooks/loader.ts +5 -6
- package/src/extensibility/hooks/types.ts +2 -2
- package/src/extensibility/plugins/doctor.ts +2 -1
- package/src/extensibility/plugins/marketplace/fetcher.ts +2 -57
- package/src/extensibility/plugins/marketplace/source-resolver.ts +4 -4
- package/src/extensibility/slash-commands.ts +3 -7
- package/src/index.ts +3 -1
- package/src/internal-urls/docs-index.generated.ts +11 -11
- package/src/ipy/executor.ts +58 -17
- package/src/ipy/gateway-coordinator.ts +6 -4
- package/src/ipy/kernel.ts +45 -22
- package/src/ipy/runtime.ts +2 -2
- package/src/lsp/client.ts +7 -4
- package/src/lsp/clients/lsp-linter-client.ts +4 -4
- package/src/lsp/config.ts +2 -2
- package/src/lsp/defaults.json +688 -154
- package/src/lsp/index.ts +234 -45
- package/src/lsp/lspmux.ts +2 -2
- package/src/lsp/startup-events.ts +13 -0
- package/src/lsp/types.ts +12 -1
- package/src/lsp/utils.ts +8 -1
- package/src/main.ts +125 -47
- package/src/memories/index.ts +4 -5
- package/src/modes/acp/acp-agent.ts +563 -163
- package/src/modes/acp/acp-event-mapper.ts +9 -1
- package/src/modes/acp/acp-mode.ts +4 -2
- package/src/modes/components/agent-dashboard.ts +3 -4
- package/src/modes/components/diff.ts +6 -7
- package/src/modes/components/footer.ts +9 -29
- package/src/modes/components/hook-editor.ts +3 -3
- package/src/modes/components/hook-selector.ts +6 -1
- package/src/modes/components/read-tool-group.ts +6 -12
- package/src/modes/components/session-observer-overlay.ts +472 -0
- package/src/modes/components/settings-defs.ts +24 -0
- package/src/modes/components/status-line.ts +15 -61
- package/src/modes/components/tool-execution.ts +1 -1
- package/src/modes/components/welcome.ts +1 -1
- package/src/modes/controllers/btw-controller.ts +2 -2
- package/src/modes/controllers/command-controller.ts +4 -2
- package/src/modes/controllers/event-controller.ts +59 -2
- package/src/modes/controllers/extension-ui-controller.ts +1 -0
- package/src/modes/controllers/input-controller.ts +15 -8
- package/src/modes/controllers/selector-controller.ts +26 -0
- package/src/modes/index.ts +20 -2
- package/src/modes/interactive-mode.ts +278 -69
- package/src/modes/rpc/host-tools.ts +186 -0
- package/src/modes/rpc/rpc-client.ts +178 -13
- package/src/modes/rpc/rpc-mode.ts +73 -3
- package/src/modes/rpc/rpc-types.ts +53 -1
- package/src/modes/session-observer-registry.ts +146 -0
- package/src/modes/shared.ts +0 -42
- package/src/modes/theme/theme.ts +80 -8
- package/src/modes/types.ts +4 -2
- package/src/modes/utils/keybinding-matchers.ts +9 -0
- package/src/prompts/system/custom-system-prompt.md +5 -0
- package/src/prompts/system/system-prompt.md +8 -1
- package/src/prompts/tools/chunk-edit.md +219 -0
- package/src/prompts/tools/debug.md +43 -0
- package/src/prompts/tools/grep.md +3 -0
- package/src/prompts/tools/lsp.md +5 -5
- package/src/prompts/tools/read-chunk.md +17 -0
- package/src/prompts/tools/read.md +19 -5
- package/src/sdk.ts +216 -165
- package/src/secrets/index.ts +1 -1
- package/src/secrets/obfuscator.ts +25 -17
- package/src/session/agent-session.ts +381 -286
- package/src/session/agent-storage.ts +12 -12
- package/src/session/compaction/branch-summarization.ts +3 -3
- package/src/session/compaction/compaction.ts +5 -6
- package/src/session/compaction/utils.ts +3 -3
- package/src/session/history-storage.ts +62 -19
- package/src/session/messages.ts +3 -3
- package/src/session/session-dump-format.ts +203 -0
- package/src/session/session-manager.ts +15 -5
- package/src/session/session-storage.ts +4 -2
- package/src/session/streaming-output.ts +1 -1
- package/src/session/tool-choice-queue.ts +213 -0
- package/src/slash-commands/builtin-registry.ts +56 -8
- package/src/ssh/connection-manager.ts +2 -2
- package/src/ssh/sshfs-mount.ts +5 -5
- package/src/stt/downloader.ts +4 -4
- package/src/stt/recorder.ts +4 -4
- package/src/stt/transcriber.ts +2 -2
- package/src/system-prompt.ts +25 -13
- package/src/task/agents.ts +5 -6
- package/src/task/commands.ts +2 -5
- package/src/task/executor.ts +32 -4
- package/src/task/index.ts +91 -82
- package/src/task/template.ts +2 -2
- package/src/task/types.ts +25 -0
- package/src/task/worktree.ts +131 -149
- package/src/tools/ask.ts +2 -3
- package/src/tools/ast-edit.ts +7 -7
- package/src/tools/ast-grep.ts +7 -7
- package/src/tools/auto-generated-guard.ts +36 -41
- package/src/tools/await-tool.ts +2 -2
- package/src/tools/bash.ts +5 -23
- package/src/tools/browser.ts +4 -5
- package/src/tools/calculator.ts +2 -3
- package/src/tools/cancel-job.ts +2 -2
- package/src/tools/checkpoint.ts +3 -3
- package/src/tools/debug.ts +1007 -0
- package/src/tools/exit-plan-mode.ts +3 -3
- package/src/tools/fetch.ts +67 -3
- package/src/tools/find.ts +4 -5
- package/src/tools/fs-cache-invalidation.ts +5 -0
- package/src/tools/gemini-image.ts +13 -5
- package/src/tools/gh.ts +130 -308
- package/src/tools/grep.ts +57 -9
- package/src/tools/index.ts +44 -22
- package/src/tools/inspect-image.ts +4 -4
- package/src/tools/output-meta.ts +1 -1
- package/src/tools/python.ts +19 -6
- package/src/tools/read.ts +211 -146
- package/src/tools/render-mermaid.ts +2 -3
- package/src/tools/render-utils.ts +20 -6
- package/src/tools/renderers.ts +3 -1
- package/src/tools/report-tool-issue.ts +80 -0
- package/src/tools/resolve.ts +70 -39
- package/src/tools/search-tool-bm25.ts +2 -2
- package/src/tools/ssh.ts +2 -2
- package/src/tools/todo-write.ts +2 -2
- package/src/tools/tool-timeouts.ts +1 -0
- package/src/tools/write.ts +5 -6
- package/src/tui/tree-list.ts +3 -1
- package/src/utils/clipboard.ts +80 -0
- package/src/utils/commit-message-generator.ts +2 -3
- package/src/utils/edit-mode.ts +49 -0
- package/src/utils/external-editor.ts +11 -5
- package/src/utils/file-display-mode.ts +6 -5
- package/src/utils/file-mentions.ts +8 -7
- package/src/utils/git.ts +1400 -0
- package/src/utils/image-loading.ts +98 -0
- package/src/utils/title-generator.ts +2 -3
- package/src/utils/tools-manager.ts +6 -6
- package/src/web/scrapers/choosealicense.ts +1 -1
- package/src/web/search/index.ts +3 -3
- package/src/web/search/render.ts +6 -4
- package/src/autoresearch/command-initialize.md +0 -34
- package/src/commit/git/errors.ts +0 -9
- package/src/commit/git/index.ts +0 -210
- package/src/commit/git/operations.ts +0 -54
- package/src/patch/diff.ts +0 -433
- package/src/patch/index.ts +0 -888
- package/src/patch/parser.ts +0 -532
- package/src/patch/types.ts +0 -292
- package/src/prompts/agents/oracle.md +0 -77
- package/src/tools/gh-cli.ts +0 -125
- package/src/tools/pending-action.ts +0 -49
- package/src/utils/child-process.ts +0 -88
- package/src/utils/frontmatter.ts +0 -117
- package/src/utils/image-input.ts +0 -274
- package/src/utils/mime.ts +0 -53
- package/src/utils/prompt-format.ts +0 -170
package/src/cli/grep-cli.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Handles `omp grep` subcommand for testing grep tool on Windows.
|
|
5
5
|
*/
|
|
6
6
|
import * as path from "node:path";
|
|
7
|
-
import { grep } from "@oh-my-pi/pi-natives";
|
|
7
|
+
import { GrepOutputMode, grep } from "@oh-my-pi/pi-natives";
|
|
8
8
|
import { APP_NAME } from "@oh-my-pi/pi-utils";
|
|
9
9
|
import chalk from "chalk";
|
|
10
10
|
|
|
@@ -14,7 +14,7 @@ export interface GrepCommandArgs {
|
|
|
14
14
|
glob?: string;
|
|
15
15
|
limit: number;
|
|
16
16
|
context: number;
|
|
17
|
-
mode:
|
|
17
|
+
mode: GrepOutputMode;
|
|
18
18
|
gitignore: boolean;
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -32,7 +32,7 @@ export function parseGrepArgs(args: string[]): GrepCommandArgs | undefined {
|
|
|
32
32
|
path: ".",
|
|
33
33
|
limit: 20,
|
|
34
34
|
context: 2,
|
|
35
|
-
mode:
|
|
35
|
+
mode: GrepOutputMode.Content,
|
|
36
36
|
gitignore: true,
|
|
37
37
|
};
|
|
38
38
|
|
|
@@ -47,9 +47,9 @@ export function parseGrepArgs(args: string[]): GrepCommandArgs | undefined {
|
|
|
47
47
|
} else if (arg === "--context" || arg === "-C") {
|
|
48
48
|
result.context = parseInt(args[++i], 10);
|
|
49
49
|
} else if (arg === "--files" || arg === "-f") {
|
|
50
|
-
result.mode =
|
|
50
|
+
result.mode = GrepOutputMode.FilesWithMatches;
|
|
51
51
|
} else if (arg === "--count" || arg === "-c") {
|
|
52
|
-
result.mode =
|
|
52
|
+
result.mode = GrepOutputMode.Count;
|
|
53
53
|
} else if (arg === "--no-gitignore") {
|
|
54
54
|
result.gitignore = false;
|
|
55
55
|
} else if (!arg.startsWith("-")) {
|
|
@@ -89,7 +89,7 @@ export async function runGrepCommand(cmd: GrepCommandArgs): Promise<void> {
|
|
|
89
89
|
glob: cmd.glob,
|
|
90
90
|
mode: cmd.mode,
|
|
91
91
|
maxCount: cmd.limit,
|
|
92
|
-
context: cmd.mode ===
|
|
92
|
+
context: cmd.mode === GrepOutputMode.Content ? cmd.context : undefined,
|
|
93
93
|
hidden: true,
|
|
94
94
|
gitignore: cmd.gitignore,
|
|
95
95
|
});
|
|
@@ -105,7 +105,7 @@ export async function runGrepCommand(cmd: GrepCommandArgs): Promise<void> {
|
|
|
105
105
|
for (const match of result.matches) {
|
|
106
106
|
const displayPath = match.path.replace(/\\/g, "/");
|
|
107
107
|
|
|
108
|
-
if (cmd.mode ===
|
|
108
|
+
if (cmd.mode === GrepOutputMode.Content) {
|
|
109
109
|
if (match.contextBefore) {
|
|
110
110
|
for (const ctx of match.contextBefore) {
|
|
111
111
|
console.log(chalk.dim(`${displayPath}-${ctx.lineNumber}- ${ctx.line}`));
|
|
@@ -118,7 +118,7 @@ export async function runGrepCommand(cmd: GrepCommandArgs): Promise<void> {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
console.log("");
|
|
121
|
-
} else if (cmd.mode ===
|
|
121
|
+
} else if (cmd.mode === GrepOutputMode.Count) {
|
|
122
122
|
console.log(`${chalk.cyan(displayPath)}: ${match.matchCount ?? 0} matches`);
|
|
123
123
|
} else {
|
|
124
124
|
console.log(chalk.cyan(displayPath));
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI handler for `omp grievances` — view reported tool issues from auto-QA.
|
|
3
|
+
*/
|
|
4
|
+
import { Database } from "bun:sqlite";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import { getAutoQaDbPath } from "../tools/report-tool-issue";
|
|
7
|
+
|
|
8
|
+
interface GrievanceRow {
|
|
9
|
+
id: number;
|
|
10
|
+
model: string;
|
|
11
|
+
version: string;
|
|
12
|
+
tool: string;
|
|
13
|
+
report: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ListGrievancesOptions {
|
|
17
|
+
limit: number;
|
|
18
|
+
tool?: string;
|
|
19
|
+
json: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function openDb(): Database | null {
|
|
23
|
+
try {
|
|
24
|
+
const db = new Database(getAutoQaDbPath(), { readonly: true });
|
|
25
|
+
return db;
|
|
26
|
+
} catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function listGrievances(options: ListGrievancesOptions): Promise<void> {
|
|
32
|
+
const db = openDb();
|
|
33
|
+
if (!db) {
|
|
34
|
+
if (options.json) {
|
|
35
|
+
console.log("[]");
|
|
36
|
+
} else {
|
|
37
|
+
console.log(
|
|
38
|
+
chalk.dim("No grievances database found. Enable auto-QA with PI_AUTO_QA=1 or the dev.autoqa setting."),
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
let rows: GrievanceRow[];
|
|
46
|
+
if (options.tool) {
|
|
47
|
+
rows = db
|
|
48
|
+
.prepare("SELECT id, model, version, tool, report FROM grievances WHERE tool = ? ORDER BY id DESC LIMIT ?")
|
|
49
|
+
.all(options.tool, options.limit) as GrievanceRow[];
|
|
50
|
+
} else {
|
|
51
|
+
rows = db
|
|
52
|
+
.prepare("SELECT id, model, version, tool, report FROM grievances ORDER BY id DESC LIMIT ?")
|
|
53
|
+
.all(options.limit) as GrievanceRow[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (options.json) {
|
|
57
|
+
console.log(JSON.stringify(rows, null, 2));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (rows.length === 0) {
|
|
62
|
+
console.log(chalk.dim("No grievances recorded yet."));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (const row of rows) {
|
|
67
|
+
console.log(
|
|
68
|
+
`${chalk.dim(`#${row.id}`)} ${chalk.cyan(row.tool)} ${chalk.dim(`(${row.model} v${row.version})`)}`,
|
|
69
|
+
);
|
|
70
|
+
console.log(` ${row.report}`);
|
|
71
|
+
console.log();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
console.log(chalk.dim(`Showing ${rows.length} most recent${options.tool ? ` for ${options.tool}` : ""}`));
|
|
75
|
+
} finally {
|
|
76
|
+
db.close();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read CLI command handler.
|
|
3
|
+
*
|
|
4
|
+
* Handles `omp read` subcommand — emits chunk-mode read output for files,
|
|
5
|
+
* and delegates URL reads through the read tool pipeline.
|
|
6
|
+
*/
|
|
7
|
+
import * as path from "node:path";
|
|
8
|
+
import chalk from "chalk";
|
|
9
|
+
import { Settings } from "../config/settings";
|
|
10
|
+
import { formatChunkedRead, resolveAnchorStyle } from "../edit/modes/chunk";
|
|
11
|
+
import { getLanguageFromPath } from "../modes/theme/theme";
|
|
12
|
+
import type { ToolSession } from "../tools";
|
|
13
|
+
import { parseReadUrlTarget } from "../tools/fetch";
|
|
14
|
+
import { ReadTool } from "../tools/read";
|
|
15
|
+
|
|
16
|
+
export interface ReadCommandArgs {
|
|
17
|
+
path: string;
|
|
18
|
+
sel?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function createCliReadSession(cwd: string, settings: Settings): ToolSession {
|
|
22
|
+
return {
|
|
23
|
+
cwd,
|
|
24
|
+
hasUI: false,
|
|
25
|
+
hasEditTool: true,
|
|
26
|
+
getSessionFile: () => null,
|
|
27
|
+
getSessionSpawns: () => null,
|
|
28
|
+
settings,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function runReadCommand(cmd: ReadCommandArgs): Promise<void> {
|
|
33
|
+
const cwd = process.cwd();
|
|
34
|
+
const parsedUrlTarget = parseReadUrlTarget(cmd.path, cmd.sel);
|
|
35
|
+
if (parsedUrlTarget) {
|
|
36
|
+
const settings = await Settings.init({ cwd });
|
|
37
|
+
const tool = new ReadTool(createCliReadSession(cwd, settings));
|
|
38
|
+
const result = await tool.execute("cli-read", { path: cmd.path, sel: cmd.sel });
|
|
39
|
+
const text = result.content.find((content): content is { type: "text"; text: string } => content.type === "text");
|
|
40
|
+
console.log(text?.text ?? "");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const filePath = path.resolve(cmd.path);
|
|
45
|
+
const file = Bun.file(filePath);
|
|
46
|
+
if (!(await file.exists())) {
|
|
47
|
+
console.error(chalk.red(`Error: File not found: ${cmd.path}`));
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const readPath = cmd.sel ? `${filePath}:${cmd.sel}` : filePath;
|
|
52
|
+
const language = getLanguageFromPath(filePath);
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const result = await formatChunkedRead({
|
|
56
|
+
filePath,
|
|
57
|
+
readPath,
|
|
58
|
+
cwd,
|
|
59
|
+
language,
|
|
60
|
+
anchorStyle: resolveAnchorStyle(),
|
|
61
|
+
});
|
|
62
|
+
console.log(result.text);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
console.error(chalk.red(`Error: ${err instanceof Error ? err.message : String(err)}`));
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
}
|
package/src/cli/setup-cli.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Handles `omp setup <component>` to install dependencies for optional features.
|
|
5
5
|
*/
|
|
6
6
|
import * as path from "node:path";
|
|
7
|
-
import { APP_NAME, getPythonEnvDir } from "@oh-my-pi/pi-utils";
|
|
7
|
+
import { $which, APP_NAME, getPythonEnvDir } from "@oh-my-pi/pi-utils";
|
|
8
8
|
import { $ } from "bun";
|
|
9
9
|
import chalk from "chalk";
|
|
10
10
|
import { theme } from "../modes/theme/theme";
|
|
@@ -90,12 +90,12 @@ async function checkPythonSetup(): Promise<PythonCheckResult> {
|
|
|
90
90
|
managedEnvPath: MANAGED_PYTHON_ENV,
|
|
91
91
|
};
|
|
92
92
|
|
|
93
|
-
const systemPythonPath =
|
|
93
|
+
const systemPythonPath = $which("python") ?? $which("python3");
|
|
94
94
|
const managedPath = managedPythonPath();
|
|
95
95
|
const hasManagedEnv = await Bun.file(managedPath).exists();
|
|
96
96
|
|
|
97
|
-
result.uvPath =
|
|
98
|
-
result.pipPath =
|
|
97
|
+
result.uvPath = $which("uv") ?? undefined;
|
|
98
|
+
result.pipPath = $which("pip3") ?? $which("pip") ?? undefined;
|
|
99
99
|
|
|
100
100
|
const candidates = [systemPythonPath, hasManagedEnv ? managedPath : undefined].filter(
|
|
101
101
|
(candidate): candidate is string => !!candidate,
|
package/src/cli/update-cli.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import * as fs from "node:fs";
|
|
8
8
|
import * as path from "node:path";
|
|
9
9
|
import { pipeline } from "node:stream/promises";
|
|
10
|
-
import { APP_NAME, isEnoent, VERSION } from "@oh-my-pi/pi-utils";
|
|
10
|
+
import { $which, APP_NAME, isEnoent, VERSION } from "@oh-my-pi/pi-utils";
|
|
11
11
|
import { $ } from "bun";
|
|
12
12
|
import chalk from "chalk";
|
|
13
13
|
import { theme } from "../modes/theme/theme";
|
|
@@ -36,7 +36,7 @@ export function parseUpdateArgs(args: string[]): { force: boolean; check: boolea
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
async function getBunGlobalBinDir(): Promise<string | undefined> {
|
|
39
|
-
if (
|
|
39
|
+
if (!$which("bun")) return undefined;
|
|
40
40
|
try {
|
|
41
41
|
const result = await $`bun pm bin -g`.quiet().nothrow();
|
|
42
42
|
if (result.exitCode !== 0) return undefined;
|
|
@@ -167,7 +167,7 @@ function getBinaryName(): string {
|
|
|
167
167
|
* Resolve the path that `omp` maps to in the user's PATH.
|
|
168
168
|
*/
|
|
169
169
|
function resolveOmpPath(): string | undefined {
|
|
170
|
-
return
|
|
170
|
+
return $which(APP_NAME) ?? undefined;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
/**
|
package/src/cli.ts
CHANGED
|
@@ -48,6 +48,8 @@ const commands: CommandEntry[] = [
|
|
|
48
48
|
{ name: "commit", load: () => import("./commands/commit").then(m => m.default) },
|
|
49
49
|
{ name: "config", load: () => import("./commands/config").then(m => m.default) },
|
|
50
50
|
{ name: "grep", load: () => import("./commands/grep").then(m => m.default) },
|
|
51
|
+
{ name: "grievances", load: () => import("./commands/grievances").then(m => m.default) },
|
|
52
|
+
{ name: "read", load: () => import("./commands/read").then(m => m.default) },
|
|
51
53
|
{ name: "jupyter", load: () => import("./commands/jupyter").then(m => m.default) },
|
|
52
54
|
{ name: "plugin", load: () => import("./commands/plugin").then(m => m.default) },
|
|
53
55
|
{ name: "setup", load: () => import("./commands/setup").then(m => m.default) },
|
package/src/commands/grep.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Test grep tool.
|
|
3
3
|
*/
|
|
4
|
+
import { GrepOutputMode } from "@oh-my-pi/pi-natives";
|
|
4
5
|
import { Args, Command, Flags } from "@oh-my-pi/pi-utils/cli";
|
|
5
6
|
import { type GrepCommandArgs, runGrepCommand } from "../cli/grep-cli";
|
|
6
7
|
import { initTheme } from "../modes/theme/theme";
|
|
@@ -25,7 +26,11 @@ export default class Grep extends Command {
|
|
|
25
26
|
async run(): Promise<void> {
|
|
26
27
|
const { args, flags } = await this.parse(Grep);
|
|
27
28
|
|
|
28
|
-
const mode: GrepCommandArgs["mode"] = flags.count
|
|
29
|
+
const mode: GrepCommandArgs["mode"] = flags.count
|
|
30
|
+
? GrepOutputMode.Count
|
|
31
|
+
: flags.files
|
|
32
|
+
? GrepOutputMode.FilesWithMatches
|
|
33
|
+
: GrepOutputMode.Content;
|
|
29
34
|
|
|
30
35
|
const cmd: GrepCommandArgs = {
|
|
31
36
|
pattern: args.pattern ?? "",
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* View recently reported tool issues from automated QA.
|
|
3
|
+
*/
|
|
4
|
+
import { Command, Flags } from "@oh-my-pi/pi-utils/cli";
|
|
5
|
+
import { listGrievances } from "../cli/grievances-cli";
|
|
6
|
+
|
|
7
|
+
export default class Grievances extends Command {
|
|
8
|
+
static description = "View reported tool issues (auto-QA grievances)";
|
|
9
|
+
|
|
10
|
+
static flags = {
|
|
11
|
+
limit: Flags.integer({ char: "n", description: "Number of recent issues to show", default: 20 }),
|
|
12
|
+
tool: Flags.string({ char: "t", description: "Filter by tool name" }),
|
|
13
|
+
json: Flags.boolean({ char: "j", description: "Output as JSON", default: false }),
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
async run(): Promise<void> {
|
|
17
|
+
const { flags } = await this.parse(Grievances);
|
|
18
|
+
await listGrievances({ limit: flags.limit, tool: flags.tool, json: flags.json });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chunk-mode read tool.
|
|
3
|
+
*/
|
|
4
|
+
import { Args, Command, Flags } from "@oh-my-pi/pi-utils/cli";
|
|
5
|
+
import { type ReadCommandArgs, runReadCommand } from "../cli/read-cli";
|
|
6
|
+
import { initTheme } from "../modes/theme/theme";
|
|
7
|
+
|
|
8
|
+
export default class Read extends Command {
|
|
9
|
+
static description = "Read a file as a chunk tree";
|
|
10
|
+
|
|
11
|
+
static args = {
|
|
12
|
+
path: Args.string({ description: "File path to read", required: true }),
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
static flags = {
|
|
16
|
+
sel: Flags.string({
|
|
17
|
+
char: "s",
|
|
18
|
+
description: "Chunk selector or line range (e.g. class_Foo.fn_bar, L10-L20)",
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
async run(): Promise<void> {
|
|
23
|
+
const { args, flags } = await this.parse(Read);
|
|
24
|
+
|
|
25
|
+
const cmd: ReadCommandArgs = {
|
|
26
|
+
path: args.path ?? "",
|
|
27
|
+
sel: flags.sel,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
await initTheme();
|
|
31
|
+
await runReadCommand(cmd);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { INTENT_FIELD, type ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { Api, Model } from "@oh-my-pi/pi-ai";
|
|
3
3
|
import { Markdown } from "@oh-my-pi/pi-tui";
|
|
4
|
+
import { prompt } from "@oh-my-pi/pi-utils";
|
|
4
5
|
import chalk from "chalk";
|
|
5
|
-
import type { ControlledGit } from "../../commit/git";
|
|
6
6
|
import typesDescriptionPrompt from "../../commit/prompts/types-description.md" with { type: "text" };
|
|
7
7
|
import type { ModelRegistry } from "../../config/model-registry";
|
|
8
|
-
import { renderPromptTemplate } from "../../config/prompt-templates";
|
|
9
8
|
import type { Settings } from "../../config/settings";
|
|
10
9
|
import { getMarkdownTheme } from "../../modes/theme/theme";
|
|
11
10
|
import { createAgentSession } from "../../sdk";
|
|
@@ -18,7 +17,6 @@ import { createCommitTools } from "./tools";
|
|
|
18
17
|
|
|
19
18
|
export interface CommitAgentInput {
|
|
20
19
|
cwd: string;
|
|
21
|
-
git: ControlledGit;
|
|
22
20
|
model: Model<Api>;
|
|
23
21
|
thinkingLevel?: ThinkingLevel;
|
|
24
22
|
settings: Settings;
|
|
@@ -38,15 +36,14 @@ export interface ExistingChangelogEntries {
|
|
|
38
36
|
}
|
|
39
37
|
|
|
40
38
|
export async function runCommitAgentSession(input: CommitAgentInput): Promise<CommitAgentState> {
|
|
41
|
-
const typesDescription =
|
|
42
|
-
const systemPrompt =
|
|
39
|
+
const typesDescription = prompt.render(typesDescriptionPrompt);
|
|
40
|
+
const systemPrompt = prompt.render(agentSystemPrompt, {
|
|
43
41
|
types_description: typesDescription,
|
|
44
42
|
});
|
|
45
43
|
const state: CommitAgentState = { diffText: input.diffText };
|
|
46
44
|
const spawns = "quick_task";
|
|
47
45
|
const tools = createCommitTools({
|
|
48
46
|
cwd: input.cwd,
|
|
49
|
-
git: input.git,
|
|
50
47
|
authStorage: input.authStorage,
|
|
51
48
|
modelRegistry: input.modelRegistry,
|
|
52
49
|
settings: input.settings,
|
|
@@ -152,7 +149,7 @@ export async function runCommitAgentSession(input: CommitAgentInput): Promise<Co
|
|
|
152
149
|
});
|
|
153
150
|
|
|
154
151
|
try {
|
|
155
|
-
const
|
|
152
|
+
const agentUserMessage = prompt.render(agentUserPrompt, {
|
|
156
153
|
user_context: input.userContext,
|
|
157
154
|
changelog_targets: input.changelogTargets.length > 0 ? input.changelogTargets.join("\n") : undefined,
|
|
158
155
|
existing_changelog_entries: input.existingChangelogEntries,
|
|
@@ -161,7 +158,7 @@ export async function runCommitAgentSession(input: CommitAgentInput): Promise<Co
|
|
|
161
158
|
let retryCount = 0;
|
|
162
159
|
const needsChangelog = input.requireChangelog && input.changelogTargets.length > 0;
|
|
163
160
|
|
|
164
|
-
await session.prompt(
|
|
161
|
+
await session.prompt(agentUserMessage, {
|
|
165
162
|
attribution: "agent",
|
|
166
163
|
expandPromptTemplates: false,
|
|
167
164
|
});
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import { createInterface } from "node:readline/promises";
|
|
3
|
-
import { $env, getProjectDir, isEnoent } from "@oh-my-pi/pi-utils";
|
|
3
|
+
import { $env, getProjectDir, isEnoent, prompt } from "@oh-my-pi/pi-utils";
|
|
4
4
|
import { applyChangelogProposals } from "../../commit/changelog";
|
|
5
5
|
import { detectChangelogBoundaries } from "../../commit/changelog/detect";
|
|
6
6
|
import { parseUnreleasedSection } from "../../commit/changelog/parse";
|
|
7
|
-
import { ControlledGit } from "../../commit/git";
|
|
8
7
|
import { formatCommitMessage } from "../../commit/message";
|
|
9
8
|
import { resolvePrimaryModel, resolveSmolModel } from "../../commit/model-selection";
|
|
10
9
|
import type { CommitCommandArgs, ConventionalAnalysis } from "../../commit/types";
|
|
11
10
|
import { ModelRegistry } from "../../config/model-registry";
|
|
12
|
-
import { renderPromptTemplate } from "../../config/prompt-templates";
|
|
13
11
|
import { Settings } from "../../config/settings";
|
|
14
12
|
import { discoverAuthStorage, discoverContextFiles } from "../../sdk";
|
|
13
|
+
import * as git from "../../utils/git";
|
|
15
14
|
import { type ExistingChangelogEntries, runCommitAgentSession } from "./agent";
|
|
16
15
|
import { generateFallbackProposal } from "./fallback";
|
|
17
16
|
import splitConfirmPrompt from "./prompts/split-confirm.md" with { type: "text" };
|
|
@@ -20,25 +19,24 @@ import { computeDependencyOrder } from "./topo-sort";
|
|
|
20
19
|
import { detectTrivialChange } from "./trivial";
|
|
21
20
|
|
|
22
21
|
interface CommitExecutionContext {
|
|
23
|
-
|
|
22
|
+
cwd: string;
|
|
24
23
|
dryRun: boolean;
|
|
25
24
|
push: boolean;
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
29
28
|
const cwd = getProjectDir();
|
|
30
|
-
const git = new ControlledGit(cwd);
|
|
31
29
|
const [settings, authStorage] = await Promise.all([Settings.init({ cwd }), discoverAuthStorage()]);
|
|
32
30
|
|
|
33
31
|
process.stdout.write("● Resolving model...\n");
|
|
34
32
|
const modelRegistry = new ModelRegistry(authStorage);
|
|
35
33
|
await modelRegistry.refresh();
|
|
36
34
|
const stagedFilesPromise = (async () => {
|
|
37
|
-
let stagedFiles = await git.
|
|
35
|
+
let stagedFiles = await git.diff.changedFiles(cwd, { cached: true });
|
|
38
36
|
if (stagedFiles.length === 0) {
|
|
39
37
|
process.stdout.write("No staged changes detected, staging all changes...\n");
|
|
40
|
-
await git.
|
|
41
|
-
stagedFiles = await git.
|
|
38
|
+
await git.stage.files(cwd);
|
|
39
|
+
stagedFiles = await git.diff.changedFiles(cwd, { cached: true });
|
|
42
40
|
}
|
|
43
41
|
return stagedFiles;
|
|
44
42
|
})();
|
|
@@ -66,8 +64,8 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
66
64
|
const [changelogBoundaries, contextFiles, numstat, diff] = await Promise.all([
|
|
67
65
|
args.noChangelog ? [] : detectChangelogBoundaries(cwd, stagedFiles),
|
|
68
66
|
discoverContextFiles(cwd),
|
|
69
|
-
git.
|
|
70
|
-
git.
|
|
67
|
+
git.diff.numstat(cwd, { cached: true }),
|
|
68
|
+
git.diff(cwd, { cached: true }),
|
|
71
69
|
]);
|
|
72
70
|
const changelogTargets = changelogBoundaries.map(boundary => boundary.changelogPath);
|
|
73
71
|
if (!args.noChangelog) {
|
|
@@ -93,7 +91,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
93
91
|
if (forceFallback) {
|
|
94
92
|
process.stdout.write("● Forcing fallback commit generation...\n");
|
|
95
93
|
const fallbackProposal = generateFallbackProposal(numstat);
|
|
96
|
-
await runSingleCommit(fallbackProposal, {
|
|
94
|
+
await runSingleCommit(fallbackProposal, { cwd, dryRun: args.dryRun, push: args.push });
|
|
97
95
|
return;
|
|
98
96
|
}
|
|
99
97
|
|
|
@@ -110,7 +108,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
110
108
|
summary: trivialChange.summary,
|
|
111
109
|
warnings: [],
|
|
112
110
|
};
|
|
113
|
-
await runSingleCommit(trivialProposal, {
|
|
111
|
+
await runSingleCommit(trivialProposal, { cwd, dryRun: args.dryRun, push: args.push });
|
|
114
112
|
return;
|
|
115
113
|
}
|
|
116
114
|
|
|
@@ -129,7 +127,6 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
129
127
|
try {
|
|
130
128
|
commitState = await runCommitAgentSession({
|
|
131
129
|
cwd,
|
|
132
|
-
git,
|
|
133
130
|
model: agentModel,
|
|
134
131
|
thinkingLevel: agentThinkingLevel,
|
|
135
132
|
settings,
|
|
@@ -169,7 +166,6 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
169
166
|
}
|
|
170
167
|
process.stdout.write("● Applying changelog entries...\n");
|
|
171
168
|
const updated = await applyChangelogProposals({
|
|
172
|
-
git,
|
|
173
169
|
cwd,
|
|
174
170
|
proposals: commitState.changelogProposal.entries,
|
|
175
171
|
dryRun: args.dryRun,
|
|
@@ -188,13 +184,13 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
188
184
|
}
|
|
189
185
|
|
|
190
186
|
if (commitState.proposal) {
|
|
191
|
-
await runSingleCommit(commitState.proposal, {
|
|
187
|
+
await runSingleCommit(commitState.proposal, { cwd, dryRun: args.dryRun, push: args.push });
|
|
192
188
|
return;
|
|
193
189
|
}
|
|
194
190
|
|
|
195
191
|
if (commitState.splitProposal) {
|
|
196
192
|
await runSplitCommit(commitState.splitProposal, {
|
|
197
|
-
|
|
193
|
+
cwd,
|
|
198
194
|
dryRun: args.dryRun,
|
|
199
195
|
push: args.push,
|
|
200
196
|
additionalFiles: updatedChangelogFiles,
|
|
@@ -215,10 +211,10 @@ async function runSingleCommit(proposal: CommitProposal, ctx: CommitExecutionCon
|
|
|
215
211
|
process.stdout.write(`${commitMessage}\n`);
|
|
216
212
|
return;
|
|
217
213
|
}
|
|
218
|
-
await
|
|
214
|
+
await git.commit(ctx.cwd, commitMessage);
|
|
219
215
|
process.stdout.write("Commit created.\n");
|
|
220
216
|
if (ctx.push) {
|
|
221
|
-
await
|
|
217
|
+
await git.push(ctx.cwd);
|
|
222
218
|
process.stdout.write("Pushed to remote.\n");
|
|
223
219
|
}
|
|
224
220
|
}
|
|
@@ -233,7 +229,7 @@ async function runSplitCommit(
|
|
|
233
229
|
if (ctx.additionalFiles && ctx.additionalFiles.length > 0) {
|
|
234
230
|
appendFilesToLastCommit(plan, ctx.additionalFiles);
|
|
235
231
|
}
|
|
236
|
-
const stagedFiles = await
|
|
232
|
+
const stagedFiles = await git.diff.changedFiles(ctx.cwd, { cached: true });
|
|
237
233
|
const plannedFiles = new Set(plan.commits.flatMap(commit => commit.changes.map(change => change.path)));
|
|
238
234
|
const missingFiles = stagedFiles.filter(file => !plannedFiles.has(file));
|
|
239
235
|
if (missingFiles.length > 0) {
|
|
@@ -270,10 +266,10 @@ async function runSplitCommit(
|
|
|
270
266
|
throw new Error(order.error);
|
|
271
267
|
}
|
|
272
268
|
|
|
273
|
-
await
|
|
269
|
+
await git.stage.reset(ctx.cwd);
|
|
274
270
|
for (const commitIndex of order) {
|
|
275
271
|
const commit = plan.commits[commitIndex];
|
|
276
|
-
await
|
|
272
|
+
await git.stage.hunks(ctx.cwd, commit.changes);
|
|
277
273
|
const analysis: ConventionalAnalysis = {
|
|
278
274
|
type: commit.type,
|
|
279
275
|
scope: commit.scope,
|
|
@@ -281,12 +277,12 @@ async function runSplitCommit(
|
|
|
281
277
|
issueRefs: commit.issueRefs,
|
|
282
278
|
};
|
|
283
279
|
const message = formatCommitMessage(analysis, commit.summary);
|
|
284
|
-
await
|
|
285
|
-
await
|
|
280
|
+
await git.commit(ctx.cwd, message);
|
|
281
|
+
await git.stage.reset(ctx.cwd);
|
|
286
282
|
}
|
|
287
283
|
process.stdout.write("Split commits created.\n");
|
|
288
284
|
if (ctx.push) {
|
|
289
|
-
await
|
|
285
|
+
await git.push(ctx.cwd);
|
|
290
286
|
process.stdout.write("Pushed to remote.\n");
|
|
291
287
|
}
|
|
292
288
|
}
|
|
@@ -308,8 +304,8 @@ async function confirmSplitCommitPlan(plan: SplitCommitPlan): Promise<boolean> {
|
|
|
308
304
|
}
|
|
309
305
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
310
306
|
try {
|
|
311
|
-
const
|
|
312
|
-
const answer = await rl.question(
|
|
307
|
+
const splitConfirmQuestion = prompt.render(splitConfirmPrompt, { count: plan.commits.length });
|
|
308
|
+
const answer = await rl.question(splitConfirmQuestion);
|
|
313
309
|
return ["y", "yes"].includes(answer.trim().toLowerCase());
|
|
314
310
|
} finally {
|
|
315
311
|
rl.close();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { prompt } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import { Type } from "@sinclair/typebox";
|
|
2
3
|
import analyzeFilePrompt from "../../../commit/agentic/prompts/analyze-file.md" with { type: "text" };
|
|
3
4
|
import type { CommitAgentState } from "../../../commit/agentic/state";
|
|
4
5
|
import type { NumstatEntry } from "../../../commit/types";
|
|
5
6
|
import type { ModelRegistry } from "../../../config/model-registry";
|
|
6
|
-
import { renderPromptTemplate } from "../../../config/prompt-templates";
|
|
7
7
|
import type { Settings } from "../../../config/settings";
|
|
8
8
|
import type { CustomTool, CustomToolContext } from "../../../extensibility/custom-tools/types";
|
|
9
9
|
import type { AuthStorage } from "../../../session/auth-storage";
|
|
@@ -66,7 +66,7 @@ export function createAnalyzeFileTool(options: {
|
|
|
66
66
|
const numstat = options.state.overview?.numstat ?? [];
|
|
67
67
|
const tasks = params.files.map((file, index) => {
|
|
68
68
|
const relatedFiles = formatRelatedFiles(params.files, file, numstat);
|
|
69
|
-
const
|
|
69
|
+
const assignment = prompt.render(analyzeFilePrompt, {
|
|
70
70
|
file,
|
|
71
71
|
goal: params.goal,
|
|
72
72
|
related_files: relatedFiles,
|
|
@@ -74,7 +74,7 @@ export function createAnalyzeFileTool(options: {
|
|
|
74
74
|
return {
|
|
75
75
|
id: `AnalyzeFile${index + 1}`,
|
|
76
76
|
description: `Analyze ${file}`,
|
|
77
|
-
assignment
|
|
77
|
+
assignment,
|
|
78
78
|
};
|
|
79
79
|
});
|
|
80
80
|
const taskParams: TaskParams = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Type } from "@sinclair/typebox";
|
|
2
2
|
import type { CommitAgentState } from "../../../commit/agentic/state";
|
|
3
|
-
import type { ControlledGit } from "../../../commit/git";
|
|
4
3
|
import type { CustomTool } from "../../../extensibility/custom-tools/types";
|
|
4
|
+
import * as git from "../../../utils/git";
|
|
5
5
|
|
|
6
6
|
const TARGET_TOKENS = 30000;
|
|
7
7
|
const CHARS_PER_TOKEN = 4;
|
|
@@ -136,10 +136,7 @@ const gitFileDiffSchema = Type.Object({
|
|
|
136
136
|
staged: Type.Optional(Type.Boolean({ description: "Use staged changes (default: true)" })),
|
|
137
137
|
});
|
|
138
138
|
|
|
139
|
-
export function createGitFileDiffTool(
|
|
140
|
-
git: ControlledGit,
|
|
141
|
-
state: CommitAgentState,
|
|
142
|
-
): CustomTool<typeof gitFileDiffSchema> {
|
|
139
|
+
export function createGitFileDiffTool(cwd: string, state: CommitAgentState): CustomTool<typeof gitFileDiffSchema> {
|
|
143
140
|
return {
|
|
144
141
|
name: "git_file_diff",
|
|
145
142
|
label: "Git File Diff",
|
|
@@ -167,7 +164,7 @@ export function createGitFileDiffTool(
|
|
|
167
164
|
|
|
168
165
|
if (uncachedFiles.length > 0) {
|
|
169
166
|
for (const file of uncachedFiles) {
|
|
170
|
-
const diff = await git.
|
|
167
|
+
const diff = await git.diff(cwd, { cached: staged, files: [file] });
|
|
171
168
|
if (diff) {
|
|
172
169
|
diffs.set(file, diff);
|
|
173
170
|
state.diffCache.set(cacheKey(file), diff);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Type } from "@sinclair/typebox";
|
|
2
|
-
import type { ControlledGit } from "../../../commit/git";
|
|
3
2
|
import type { DiffHunk, FileHunks } from "../../../commit/types";
|
|
4
3
|
import type { CustomTool } from "../../../extensibility/custom-tools/types";
|
|
4
|
+
import * as git from "../../../utils/git";
|
|
5
5
|
|
|
6
6
|
const gitHunkSchema = Type.Object({
|
|
7
7
|
file: Type.String({ description: "File path" }),
|
|
@@ -15,7 +15,7 @@ function selectHunks(fileHunks: FileHunks, requested?: number[]): DiffHunk[] {
|
|
|
15
15
|
return fileHunks.hunks.filter(hunk => wanted.has(hunk.index + 1));
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export function createGitHunkTool(
|
|
18
|
+
export function createGitHunkTool(cwd: string): CustomTool<typeof gitHunkSchema> {
|
|
19
19
|
return {
|
|
20
20
|
name: "git_hunk",
|
|
21
21
|
label: "Git Hunk",
|
|
@@ -23,7 +23,7 @@ export function createGitHunkTool(git: ControlledGit): CustomTool<typeof gitHunk
|
|
|
23
23
|
parameters: gitHunkSchema,
|
|
24
24
|
async execute(_toolCallId, params) {
|
|
25
25
|
const staged = params.staged ?? true;
|
|
26
|
-
const hunks = await git.
|
|
26
|
+
const hunks = await git.diff.hunks(cwd, [params.file], { cached: staged });
|
|
27
27
|
const fileHunks = hunks.find(entry => entry.filename === params.file) ?? {
|
|
28
28
|
filename: params.file,
|
|
29
29
|
isBinary: false,
|