@oh-my-pi/pi-coding-agent 14.5.14 → 14.6.1
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 +49 -0
- package/package.json +7 -7
- package/src/autoresearch/command-resume.md +5 -8
- package/src/autoresearch/git.ts +41 -51
- package/src/autoresearch/helpers.ts +43 -359
- package/src/autoresearch/index.ts +281 -273
- package/src/autoresearch/prompt-setup.md +43 -0
- package/src/autoresearch/prompt.md +52 -193
- package/src/autoresearch/resume-message.md +2 -8
- package/src/autoresearch/state.ts +59 -166
- package/src/autoresearch/storage.ts +687 -0
- package/src/autoresearch/tools/init-experiment.ts +201 -290
- package/src/autoresearch/tools/log-experiment.ts +304 -517
- package/src/autoresearch/tools/run-experiment.ts +117 -296
- package/src/autoresearch/tools/update-notes.ts +116 -0
- package/src/autoresearch/types.ts +16 -66
- package/src/cli/list-models.ts +66 -0
- package/src/config/settings-schema.ts +1 -1
- package/src/config/settings.ts +20 -1
- package/src/cursor.ts +1 -1
- package/src/edit/index.ts +9 -31
- package/src/edit/line-hash.ts +70 -43
- package/src/edit/modes/hashline.lark +26 -0
- package/src/edit/modes/hashline.ts +898 -1099
- package/src/edit/modes/patch.ts +0 -7
- package/src/edit/modes/replace.ts +0 -4
- package/src/edit/renderer.ts +22 -20
- package/src/edit/streaming.ts +8 -28
- package/src/eval/eval.lark +24 -30
- package/src/eval/js/context-manager.ts +5 -162
- package/src/eval/js/prelude.txt +0 -12
- package/src/eval/parse.ts +129 -129
- package/src/eval/py/prelude.py +1 -219
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +2 -2
- package/src/internal-urls/docs-index.generated.ts +2 -2
- package/src/main.ts +18 -3
- package/src/modes/components/session-observer-overlay.ts +5 -2
- package/src/modes/components/status-line/segments.ts +1 -1
- package/src/modes/components/status-line.ts +3 -5
- package/src/modes/components/tree-selector.ts +4 -5
- package/src/modes/components/welcome.ts +11 -1
- package/src/modes/controllers/command-controller.ts +2 -6
- package/src/modes/controllers/event-controller.ts +7 -5
- package/src/modes/controllers/extension-ui-controller.ts +3 -15
- package/src/modes/controllers/input-controller.ts +0 -1
- package/src/modes/controllers/selector-controller.ts +1 -1
- package/src/modes/interactive-mode.ts +5 -7
- package/src/prompts/system/system-prompt.md +14 -38
- package/src/prompts/tools/ast-edit.md +8 -8
- package/src/prompts/tools/ast-grep.md +10 -10
- package/src/prompts/tools/eval.md +13 -31
- package/src/prompts/tools/find.md +2 -1
- package/src/prompts/tools/hashline.md +66 -57
- package/src/prompts/tools/search.md +2 -2
- package/src/session/agent-session.ts +1 -1
- package/src/session/session-manager.ts +17 -13
- package/src/tools/ast-edit.ts +141 -44
- package/src/tools/ast-grep.ts +112 -36
- package/src/tools/eval.ts +2 -53
- package/src/tools/find.ts +16 -15
- package/src/tools/gh-renderer.ts +184 -59
- package/src/tools/path-utils.ts +36 -196
- package/src/tools/search.ts +56 -35
- package/src/utils/edit-mode.ts +2 -11
- package/src/utils/file-display-mode.ts +1 -1
- package/src/utils/git.ts +59 -24
- package/src/utils/session-color.ts +0 -12
- package/src/utils/title-generator.ts +22 -38
- package/src/autoresearch/apply-contract-to-state.ts +0 -24
- package/src/autoresearch/contract.ts +0 -288
- package/src/edit/modes/atom.lark +0 -29
- package/src/edit/modes/atom.ts +0 -1773
- package/src/prompts/tools/atom.md +0 -150
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,55 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [14.6.1] - 2026-05-02
|
|
6
|
+
### Changed
|
|
7
|
+
|
|
8
|
+
- Updated GitHub call headers to display operation-specific titles and contextual metadata such as repository, branch, issue/PR IDs, and search query snippets for supported operations
|
|
9
|
+
- Changed non-run-watch result rendering to honor terminal width, truncate long lines, and show a `+N more lines` expansion hint when output exceeds the preview limit
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Fixed GitHub tool output fallbacks that previously always showed a GitHub Run Watch heading so they now show the actual operation and clear `no output`/`request failed` status messaging
|
|
14
|
+
|
|
15
|
+
## [14.6.0] - 2026-05-02
|
|
16
|
+
### Breaking Changes
|
|
17
|
+
|
|
18
|
+
- Reworked autoresearch storage and protocol. State now lives in `~/.omp/autoresearch/<project>.db` (SQLite) and per-run logs in `~/.omp/autoresearch/<project>/runs/<id>/benchmark.log`. The repo-side artifacts `autoresearch.md`, `autoresearch.sh`, `autoresearch.checks.sh`, `autoresearch.program.md`, `autoresearch.ideas.md`, `autoresearch.jsonl`, `.autoresearch/`, and `autoresearch.config.json` are no longer read or written; they are deleted by `/autoresearch clear`. Any existing data is not migrated.
|
|
19
|
+
- Removed the autoresearch edit guard. `write`/`edit`/`ast_edit` are no longer blocked based on scope. Scope/off-limits are now post-hoc accountability fields on `log_experiment`.
|
|
20
|
+
- Replaced rigid `init_experiment` contract validation with a simpler schema: `name`, `goal`, `primary_metric`, `metric_unit`, `direction`, `secondary_metrics`, `scope_paths`, `off_limits`, `constraints`, `max_iterations`, `new_segment`. Removed `from_autoresearch_md`, `abandon_unlogged_runs`, `force`, and `preferred_command` flags — the harness `./autoresearch.sh` is the canonical workload, edit it and bump segment when you need to change it.
|
|
21
|
+
- `run_experiment` no longer accepts a `command` parameter. The tool always runs `bash autoresearch.sh`. To change the workload, edit the harness and call `init_experiment new_segment: true`. Removed `force`, `checks_timeout_seconds`, and the legacy `autoresearch.checks.sh` auto-execution; run validation through the regular `bash` tool.
|
|
22
|
+
- Replaced `log_experiment` ASI requirements and `force`/`skip_restore` flags with `justification` (post-hoc explanation for scope deviations) and `flag_runs` (mark earlier runs suspect to exclude them from baseline math). ASI is now opaque metadata.
|
|
23
|
+
- `/autoresearch clear` now resets the worktree to the session's recorded baseline commit (when on an `autoresearch/*` branch or with `--reset-tree`), closes the active session, and deletes any leftover legacy autoresearch repo artifacts.
|
|
24
|
+
- `/autoresearch` now refuses on a dirty worktree with an explicit error instead of silently continuing on the current branch. Commit or stash before invoking — the session needs a clean baseline on a dedicated `autoresearch/*` branch.
|
|
25
|
+
- Split `/autoresearch` into a two-phase protocol. Phase 1 (no session) prompts the agent to build the benchmark harness as `./autoresearch.sh` (must exit 0 and print `METRIC <name>=<value>`). Calling `init_experiment` ends Phase 1: it requires `./autoresearch.sh` to exist, auto-commits any pending harness changes on an `autoresearch/*` branch, then records that commit as the baseline. Phase 2 is the existing iteration loop.
|
|
26
|
+
- Autoresearch sessions are now scoped to the git branch they were created on. Switching off the `autoresearch/*` branch hides the dashboard widget, detaches the experiment tools, and skips the autoresearch system prompt; switching back resumes seamlessly. `/autoresearch` on a fresh branch starts a fresh session instead of resurrecting a session bound to a different branch.
|
|
27
|
+
- `log_experiment discard` no longer rewinds prior `keep` commits. On an `autoresearch/*` branch it now resets the worktree to `HEAD` (and `git clean`s untracked) instead of `git reset --hard $baseline_commit`. Discard reverts only the current iteration's uncommitted edits; previously kept improvements stay on the branch. `/autoresearch clear` continues to reset to the recorded baseline commit when explicitly requested.
|
|
28
|
+
- Autoresearch SQLite storage is now created lazily on first `init_experiment`. Running `omp` in a project that never invokes `/autoresearch` no longer creates a per-folder DB.
|
|
29
|
+
|
|
30
|
+
- Changed `search`, `find`, `ast_grep`, and `ast_edit` to accept `paths: string[]` instead of comma- or whitespace-delimited path strings.
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- Added `update_notes` tool with `body` (replace) and `append_idea` (append a bullet under an `## Ideas` section). Notes are injected into the system prompt every iteration and replace the file-based `autoresearch.md` / `.program.md` / `.ideas.md` ecosystem.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- Updated `log_experiment` summary output to include the count of scope deviations detected for a run
|
|
39
|
+
- Used the active session context in autoresearch resume instructions instead of referencing deleted repo-side files
|
|
40
|
+
- Removed `PI_STRICT_EDIT_MODE`; model-specific edit mode fallbacks are no longer disableable by environment flag.
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
- Atom edit auto-rebase warning now dedupes by `(originalLid, rebasedLine)` pair. Previously, `@Lid` followed by N `+TEXT` lines emitted N identical "Auto-rebased anchor" warnings (one per cloned cursor anchor); now emits exactly one per distinct rebase.
|
|
45
|
+
- Atom/hashline diff preview no longer renders deleted lines with a 2-space hash placeholder (`-20 |old`) that visually mimicked a Lid. Removed lines now use `--` as the placeholder (`-20--|old`), making them unambiguously non-Lid.
|
|
46
|
+
- Atom/hashline diff preview no longer folds size-mismatched `-`/`+` runs into a confusing mix of `*` (paired modification) lines plus surplus `-`/`+` lines. The `*` collapse now applies only to clean 1:1 line replacements (same number of dels and adds); range replaces with N→M (N≠M) render as plain unified-diff `-` then `+` runs.
|
|
47
|
+
- Atom edits now warn when `@Lid` lands on a brace-opening line and the inserted content is at sibling indent (≤ anchor indent) — a foot-gun where the agent meant `^<nextSibling>` but the inserts ended up as the first body element of the `{...}` block.
|
|
48
|
+
- Atom auto-fix warning for adjacent-duplicate cleanup is now formatted as `AUTO-FIX applied — verify the result. Removed ...` instead of the easier-to-miss `Auto-fixed: removed ...`, and explains that `{}/()/[]` balance was the trigger.
|
|
49
|
+
- Fixed multi-target `search`, `ast-grep`, and `ast-edit` path handling by running each resolved target separately under root-level path resolution
|
|
50
|
+
- Fixed pagination and match/replacement summaries for multi-target AST and text searches so totals and affected file counts include all targets
|
|
51
|
+
- Fixed returned file paths for multi-target `search` and `ast-grep` results by normalizing them to the original search scope
|
|
52
|
+
- Fixed `log_experiment keep` silently dropping the iteration's diff on an autoresearch branch. The previous logic filtered out every path that was already dirty when `run_experiment` ran — but in the iteration cycle the agent's edits always land before `run_experiment`, so the entire iteration was filtered away and nothing was committed. On an autoresearch branch, `keep` now treats every currently-dirty path as the iteration's change and commits it.
|
|
53
|
+
|
|
5
54
|
## [14.5.14] - 2026-05-01
|
|
6
55
|
### Changed
|
|
7
56
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "14.
|
|
4
|
+
"version": "14.6.1",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/can1357/oh-my-pi",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@agentclientprotocol/sdk": "0.20.0",
|
|
48
48
|
"@mozilla/readability": "^0.6.0",
|
|
49
|
-
"@oh-my-pi/omp-stats": "14.
|
|
50
|
-
"@oh-my-pi/pi-agent-core": "14.
|
|
51
|
-
"@oh-my-pi/pi-ai": "14.
|
|
52
|
-
"@oh-my-pi/pi-natives": "14.
|
|
53
|
-
"@oh-my-pi/pi-tui": "14.
|
|
54
|
-
"@oh-my-pi/pi-utils": "14.
|
|
49
|
+
"@oh-my-pi/omp-stats": "14.6.1",
|
|
50
|
+
"@oh-my-pi/pi-agent-core": "14.6.1",
|
|
51
|
+
"@oh-my-pi/pi-ai": "14.6.1",
|
|
52
|
+
"@oh-my-pi/pi-natives": "14.6.1",
|
|
53
|
+
"@oh-my-pi/pi-tui": "14.6.1",
|
|
54
|
+
"@oh-my-pi/pi-utils": "14.6.1",
|
|
55
55
|
"@puppeteer/browsers": "^2.13.0",
|
|
56
56
|
"@sinclair/typebox": "^0.34.49",
|
|
57
57
|
"@xterm/headless": "^6.0.0",
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
Resume autoresearch
|
|
2
|
-
|
|
3
|
-
@{{autoresearch_md_path}}
|
|
1
|
+
Resume autoresearch on the active session.
|
|
4
2
|
|
|
5
3
|
{{branch_status_line}}
|
|
6
4
|
{{#if has_resume_context}}
|
|
@@ -10,8 +8,7 @@ Additional context from the user:
|
|
|
10
8
|
{{resume_context}}
|
|
11
9
|
{{/if}}
|
|
12
10
|
|
|
13
|
-
Use the
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
- keep iterating until interrupted or until the configured iteration cap is reached
|
|
11
|
+
- Use the active session context above as the source of truth for goal, scope, constraints, and run history.
|
|
12
|
+
- Inspect recent git history for context.
|
|
13
|
+
- Continue the most promising unfinished direction.
|
|
14
|
+
- Keep iterating until interrupted or until the configured iteration cap is reached.
|
package/src/autoresearch/git.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "../extensibility/extensions";
|
|
2
2
|
import * as git from "../utils/git";
|
|
3
|
-
import {
|
|
3
|
+
import { normalizePathSpec } from "./helpers";
|
|
4
4
|
|
|
5
5
|
const AUTORESEARCH_BRANCH_PREFIX = "autoresearch/";
|
|
6
6
|
const BRANCH_NAME_MAX_LENGTH = 48;
|
|
@@ -11,9 +11,10 @@ export interface EnsureAutoresearchBranchFailure {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export interface EnsureAutoresearchBranchSuccess {
|
|
14
|
-
branchName: string;
|
|
14
|
+
branchName: string | null;
|
|
15
15
|
created: boolean;
|
|
16
16
|
ok: true;
|
|
17
|
+
warning?: string;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export type EnsureAutoresearchBranchResult = EnsureAutoresearchBranchFailure | EnsureAutoresearchBranchSuccess;
|
|
@@ -23,6 +24,14 @@ export async function getCurrentAutoresearchBranch(_api: ExtensionAPI, workDir:
|
|
|
23
24
|
return currentBranch.startsWith(AUTORESEARCH_BRANCH_PREFIX) ? currentBranch : null;
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Ensure the working tree is on an `autoresearch/*` branch when possible.
|
|
29
|
+
*
|
|
30
|
+
* If the worktree is dirty and we're not already on an autoresearch branch, this returns
|
|
31
|
+
* `{ ok: true, branchName: null, warning }` rather than failing. The caller surfaces the
|
|
32
|
+
* warning and continues on the current branch — `keep` will skip auto-commits and `discard`
|
|
33
|
+
* will revert only run-modified paths instead of resetting to baseline.
|
|
34
|
+
*/
|
|
26
35
|
export async function ensureAutoresearchBranch(
|
|
27
36
|
api: ExtensionAPI,
|
|
28
37
|
workDir: string,
|
|
@@ -31,57 +40,48 @@ export async function ensureAutoresearchBranch(
|
|
|
31
40
|
const repoRoot = await git.repo.root(workDir);
|
|
32
41
|
if (!repoRoot) {
|
|
33
42
|
return {
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
ok: true,
|
|
44
|
+
branchName: null,
|
|
45
|
+
created: false,
|
|
46
|
+
warning:
|
|
47
|
+
"Not in a git repository — autoresearch will run without branch isolation, baseline reset, or auto-commits.",
|
|
36
48
|
};
|
|
37
49
|
}
|
|
38
50
|
|
|
39
51
|
let dirtyPathsOutput: string;
|
|
40
52
|
try {
|
|
41
|
-
dirtyPathsOutput = await git.status(repoRoot, {
|
|
42
|
-
porcelainV1: true,
|
|
43
|
-
untrackedFiles: "all",
|
|
44
|
-
z: true,
|
|
45
|
-
});
|
|
53
|
+
dirtyPathsOutput = await git.status(repoRoot, { porcelainV1: true, untrackedFiles: "all", z: true });
|
|
46
54
|
} catch (err) {
|
|
47
55
|
return {
|
|
48
|
-
error: `Unable to inspect git status before starting autoresearch: ${err instanceof Error ? err.message : String(err)}`,
|
|
49
56
|
ok: false,
|
|
57
|
+
error: `Unable to inspect git status before starting autoresearch: ${err instanceof Error ? err.message : String(err)}`,
|
|
50
58
|
};
|
|
51
59
|
}
|
|
52
60
|
|
|
53
61
|
const workDirPrefix = await readGitWorkDirPrefix(api, workDir);
|
|
54
|
-
const
|
|
62
|
+
const dirtyPaths = collectRelativeDirtyPaths(dirtyPathsOutput, workDirPrefix);
|
|
55
63
|
const currentBranch = await getCurrentAutoresearchBranch(api, workDir);
|
|
56
64
|
if (currentBranch) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
return { ok: true, branchName: currentBranch, created: false };
|
|
66
|
+
}
|
|
67
|
+
if (dirtyPaths.length > 0) {
|
|
68
|
+
const preview = formatDirtyPaths(dirtyPaths);
|
|
60
69
|
return {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
ok: true,
|
|
70
|
+
ok: false,
|
|
71
|
+
error: `Worktree is dirty (${preview}). Commit or stash these changes before starting autoresearch — a fresh autoresearch/* branch needs a clean baseline.`,
|
|
64
72
|
};
|
|
65
73
|
}
|
|
66
|
-
if (unsafeDirtyPaths.length > 0) {
|
|
67
|
-
return buildUnsafeDirtyPathsFailure(unsafeDirtyPaths);
|
|
68
|
-
}
|
|
69
74
|
|
|
70
75
|
const branchName = await allocateBranchName(api, workDir, goal);
|
|
71
76
|
try {
|
|
72
77
|
await git.branch.checkoutNew(workDir, branchName);
|
|
73
78
|
} catch (err) {
|
|
74
79
|
return {
|
|
75
|
-
error: `Failed to create autoresearch branch ${branchName}: ${err instanceof Error ? err.message : String(err)}`,
|
|
76
80
|
ok: false,
|
|
81
|
+
error: `Failed to create autoresearch branch ${branchName}: ${err instanceof Error ? err.message : String(err)}`,
|
|
77
82
|
};
|
|
78
83
|
}
|
|
79
|
-
|
|
80
|
-
return {
|
|
81
|
-
branchName,
|
|
82
|
-
created: true,
|
|
83
|
-
ok: true,
|
|
84
|
-
};
|
|
84
|
+
return { ok: true, branchName, created: true };
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
export function parseWorkDirDirtyPaths(statusOutput: string, workDirPrefix: string): string[] {
|
|
@@ -96,7 +96,7 @@ export function parseWorkDirDirtyPaths(statusOutput: string, workDirPrefix: stri
|
|
|
96
96
|
|
|
97
97
|
export function relativizeGitPathToWorkDir(repoRelativePath: string, workDirPrefix: string): string | null {
|
|
98
98
|
const normalizedPath = normalizeStatusPath(repoRelativePath);
|
|
99
|
-
const normalizedPrefix =
|
|
99
|
+
const normalizedPrefix = normalizePathSpec(workDirPrefix);
|
|
100
100
|
if (normalizedPrefix === "" || normalizedPrefix === ".") {
|
|
101
101
|
return normalizedPath;
|
|
102
102
|
}
|
|
@@ -106,7 +106,7 @@ export function relativizeGitPathToWorkDir(repoRelativePath: string, workDirPref
|
|
|
106
106
|
if (!normalizedPath.startsWith(`${normalizedPrefix}/`)) {
|
|
107
107
|
return null;
|
|
108
108
|
}
|
|
109
|
-
return
|
|
109
|
+
return normalizePathSpec(normalizedPath.slice(normalizedPrefix.length + 1));
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
async function readGitWorkDirPrefix(api: ExtensionAPI, workDir: string): Promise<string> {
|
|
@@ -162,12 +162,12 @@ function parseDirtyPathsLines(statusOutput: string): string[] {
|
|
|
162
162
|
return [...unsafePaths];
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
export function normalizeStatusPath(
|
|
166
|
-
let normalized =
|
|
165
|
+
export function normalizeStatusPath(rawPath: string): string {
|
|
166
|
+
let normalized = rawPath.trim();
|
|
167
167
|
if (normalized.startsWith('"') && normalized.endsWith('"')) {
|
|
168
168
|
normalized = normalized.slice(1, -1);
|
|
169
169
|
}
|
|
170
|
-
return
|
|
170
|
+
return normalizePathSpec(normalized);
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
async function allocateBranchName(api: ExtensionAPI, workDir: string, goal: string | null): Promise<string> {
|
|
@@ -209,32 +209,23 @@ function addDirtyPath(paths: Set<string>, rawPath: string): void {
|
|
|
209
209
|
paths.add(normalizedPath);
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
function buildUnsafeDirtyPathsFailure(unsafeDirtyPaths: string[]): EnsureAutoresearchBranchFailure {
|
|
213
|
-
const preview = unsafeDirtyPaths.slice(0, 5).join(", ");
|
|
214
|
-
const suffix = unsafeDirtyPaths.length > 5 ? ` (+${unsafeDirtyPaths.length - 5} more)` : "";
|
|
215
|
-
return {
|
|
216
|
-
error:
|
|
217
|
-
"Autoresearch needs a clean git worktree before it can create or reuse an isolated branch. " +
|
|
218
|
-
`Commit or stash these paths first: ${preview}${suffix}`,
|
|
219
|
-
ok: false,
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
|
|
223
212
|
function isRenameOrCopy(statusToken: string): boolean {
|
|
224
213
|
const trimmed = statusToken.trim();
|
|
225
214
|
return trimmed.startsWith("R") || trimmed.startsWith("C");
|
|
226
215
|
}
|
|
227
216
|
|
|
228
|
-
function
|
|
229
|
-
const
|
|
217
|
+
function collectRelativeDirtyPaths(statusOutput: string, workDirPrefix: string): string[] {
|
|
218
|
+
const dirtyPaths: string[] = [];
|
|
230
219
|
for (const dirtyPath of parseDirtyPaths(statusOutput)) {
|
|
231
220
|
const relativePath = relativizeGitPathToWorkDir(dirtyPath, workDirPrefix);
|
|
232
|
-
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
unsafeDirtyPaths.push(relativePath ?? normalizeStatusPath(dirtyPath));
|
|
221
|
+
dirtyPaths.push(relativePath ?? normalizeStatusPath(dirtyPath));
|
|
236
222
|
}
|
|
237
|
-
return
|
|
223
|
+
return dirtyPaths;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function formatDirtyPaths(paths: string[]): string {
|
|
227
|
+
const preview = paths.slice(0, 5).join(", ");
|
|
228
|
+
return paths.length > 5 ? `${preview} (+${paths.length - 5} more)` : preview;
|
|
238
229
|
}
|
|
239
230
|
|
|
240
231
|
export interface DirtyPathEntry {
|
|
@@ -318,7 +309,6 @@ export function computeRunModifiedPaths(
|
|
|
318
309
|
const untracked: string[] = [];
|
|
319
310
|
for (const entry of parseWorkDirDirtyPathsWithStatus(currentStatusOutput, workDirPrefix)) {
|
|
320
311
|
if (preRunSet.has(entry.path)) continue;
|
|
321
|
-
if (isAutoresearchLocalStatePath(entry.path)) continue;
|
|
322
312
|
if (entry.untracked) {
|
|
323
313
|
untracked.push(entry.path);
|
|
324
314
|
} else {
|