oh-my-opencode 5.0.0-beta.17 → 5.0.0-beta.18
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/dist/cli/index.js +367 -16
- package/dist/cli/runtime-commands.d.ts +1 -1
- package/dist/cli/worktree-sweep/classify.d.ts +16 -0
- package/dist/cli/worktree-sweep/format.d.ts +8 -0
- package/dist/cli/worktree-sweep/git.d.ts +19 -0
- package/dist/cli/worktree-sweep/index.d.ts +7 -0
- package/dist/cli/worktree-sweep/options.d.ts +2 -0
- package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
- package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
- package/dist/cli/worktree-sweep/types.d.ts +65 -0
- package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
- package/dist/cli-node/index.js +367 -16
- package/dist/index.js +14 -14
- package/dist/skills/review-work/SKILL.md +3 -3
- package/package.json +14 -14
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +13 -13
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +3 -3
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +2 -2
- package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
package/dist/cli-node/index.js
CHANGED
|
@@ -55,7 +55,7 @@ var package_default;
|
|
|
55
55
|
var init_package = __esm(() => {
|
|
56
56
|
package_default = {
|
|
57
57
|
name: "oh-my-opencode",
|
|
58
|
-
version: "5.0.0-beta.
|
|
58
|
+
version: "5.0.0-beta.18",
|
|
59
59
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
60
60
|
main: "./dist/index.js",
|
|
61
61
|
types: "dist/index.d.ts",
|
|
@@ -236,7 +236,7 @@ var init_package = __esm(() => {
|
|
|
236
236
|
zod: "^4.4.3"
|
|
237
237
|
},
|
|
238
238
|
devDependencies: {
|
|
239
|
-
"@code-yeongyu/senpi": "2026.8.
|
|
239
|
+
"@code-yeongyu/senpi": "2026.8.23",
|
|
240
240
|
"@oh-my-opencode/agents-md-core": "workspace:*",
|
|
241
241
|
"@oh-my-opencode/ast-grep-mcp": "workspace:*",
|
|
242
242
|
"@oh-my-opencode/boulder-state": "workspace:*",
|
|
@@ -277,18 +277,18 @@ var init_package = __esm(() => {
|
|
|
277
277
|
typescript: "^7.0.2"
|
|
278
278
|
},
|
|
279
279
|
optionalDependencies: {
|
|
280
|
-
"oh-my-opencode-darwin-arm64": "5.0.0-beta.
|
|
281
|
-
"oh-my-opencode-darwin-x64": "5.0.0-beta.
|
|
282
|
-
"oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.
|
|
283
|
-
"oh-my-opencode-linux-arm64": "5.0.0-beta.
|
|
284
|
-
"oh-my-opencode-linux-arm64-musl": "5.0.0-beta.
|
|
285
|
-
"oh-my-opencode-linux-x64": "5.0.0-beta.
|
|
286
|
-
"oh-my-opencode-linux-x64-baseline": "5.0.0-beta.
|
|
287
|
-
"oh-my-opencode-linux-x64-musl": "5.0.0-beta.
|
|
288
|
-
"oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.
|
|
289
|
-
"oh-my-opencode-windows-arm64": "5.0.0-beta.
|
|
290
|
-
"oh-my-opencode-windows-x64": "5.0.0-beta.
|
|
291
|
-
"oh-my-opencode-windows-x64-baseline": "5.0.0-beta.
|
|
280
|
+
"oh-my-opencode-darwin-arm64": "5.0.0-beta.18",
|
|
281
|
+
"oh-my-opencode-darwin-x64": "5.0.0-beta.18",
|
|
282
|
+
"oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.18",
|
|
283
|
+
"oh-my-opencode-linux-arm64": "5.0.0-beta.18",
|
|
284
|
+
"oh-my-opencode-linux-arm64-musl": "5.0.0-beta.18",
|
|
285
|
+
"oh-my-opencode-linux-x64": "5.0.0-beta.18",
|
|
286
|
+
"oh-my-opencode-linux-x64-baseline": "5.0.0-beta.18",
|
|
287
|
+
"oh-my-opencode-linux-x64-musl": "5.0.0-beta.18",
|
|
288
|
+
"oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.18",
|
|
289
|
+
"oh-my-opencode-windows-arm64": "5.0.0-beta.18",
|
|
290
|
+
"oh-my-opencode-windows-x64": "5.0.0-beta.18",
|
|
291
|
+
"oh-my-opencode-windows-x64-baseline": "5.0.0-beta.18"
|
|
292
292
|
},
|
|
293
293
|
overrides: {
|
|
294
294
|
"@earendil-works/pi-agent-core": "0.84.2",
|
|
@@ -94386,7 +94386,7 @@ var package_default2;
|
|
|
94386
94386
|
var init_package2 = __esm(() => {
|
|
94387
94387
|
package_default2 = {
|
|
94388
94388
|
name: "@oh-my-opencode/omo-codex",
|
|
94389
|
-
version: "5.0.0-beta.
|
|
94389
|
+
version: "5.0.0-beta.18",
|
|
94390
94390
|
type: "module",
|
|
94391
94391
|
private: true,
|
|
94392
94392
|
description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
|
|
@@ -103358,7 +103358,7 @@ function localLauncherCmdPath(homeDir = homedir10()) {
|
|
|
103358
103358
|
}
|
|
103359
103359
|
function renderLocalLauncher(options) {
|
|
103360
103360
|
const brand = {
|
|
103361
|
-
name: "
|
|
103361
|
+
name: "OmO",
|
|
103362
103362
|
displayVersion: options.version ?? "local",
|
|
103363
103363
|
configDir: ".omo",
|
|
103364
103364
|
flatLayout: false,
|
|
@@ -113978,6 +113978,333 @@ async function refreshModelCapabilities(options, deps = {}) {
|
|
|
113978
113978
|
}
|
|
113979
113979
|
}
|
|
113980
113980
|
|
|
113981
|
+
// packages/omo-opencode/src/cli/worktree-sweep/classify.ts
|
|
113982
|
+
import path15 from "node:path";
|
|
113983
|
+
var DEFAULT_EXCLUDE_PREFIXES = [
|
|
113984
|
+
"~/.codex/worktrees",
|
|
113985
|
+
"~/.codex-gui-cli-remote/worktrees"
|
|
113986
|
+
];
|
|
113987
|
+
function expandHome(value, home) {
|
|
113988
|
+
if (value === "~")
|
|
113989
|
+
return home;
|
|
113990
|
+
if (value.startsWith("~/"))
|
|
113991
|
+
return path15.join(home, value.slice(2));
|
|
113992
|
+
return value;
|
|
113993
|
+
}
|
|
113994
|
+
function isExcludedPath(worktreePath, prefixes, home) {
|
|
113995
|
+
const target = path15.resolve(expandHome(worktreePath, home));
|
|
113996
|
+
return prefixes.some((prefix) => {
|
|
113997
|
+
const resolved = path15.resolve(expandHome(prefix, home));
|
|
113998
|
+
return target === resolved || target.startsWith(`${resolved}${path15.sep}`);
|
|
113999
|
+
});
|
|
114000
|
+
}
|
|
114001
|
+
function worktreeRef(record3) {
|
|
114002
|
+
return record3.branch ?? record3.head ?? "";
|
|
114003
|
+
}
|
|
114004
|
+
function classifyWorktree(input) {
|
|
114005
|
+
const { record: record3 } = input;
|
|
114006
|
+
const ref = worktreeRef(record3);
|
|
114007
|
+
if (record3.locked)
|
|
114008
|
+
return { path: record3.path, ref, decision: "KEEP", reason: "locked" };
|
|
114009
|
+
if (!input.pathExists)
|
|
114010
|
+
return { path: record3.path, ref, decision: "PRUNE" };
|
|
114011
|
+
if (input.external)
|
|
114012
|
+
return { path: record3.path, ref, decision: "KEEP", reason: "external" };
|
|
114013
|
+
if (!input.merged && !input.agedOut) {
|
|
114014
|
+
return { path: record3.path, ref, decision: "KEEP", reason: "unmerged" };
|
|
114015
|
+
}
|
|
114016
|
+
if (input.dirty)
|
|
114017
|
+
return { path: record3.path, ref, decision: "KEEP", reason: "dirty" };
|
|
114018
|
+
return { path: record3.path, ref, decision: "SWEEP" };
|
|
114019
|
+
}
|
|
114020
|
+
// packages/omo-opencode/src/cli/worktree-sweep/format.ts
|
|
114021
|
+
function formatClassification(classification) {
|
|
114022
|
+
const head = classification.decision === "KEEP" && classification.reason !== undefined ? `KEEP(${classification.reason})` : classification.decision;
|
|
114023
|
+
return classification.ref.length > 0 ? `${head} ${classification.path} ${classification.ref}` : `${head} ${classification.path}`;
|
|
114024
|
+
}
|
|
114025
|
+
function formatSummary(result) {
|
|
114026
|
+
const mode = result.apply ? "apply" : "dry-run";
|
|
114027
|
+
const removed2 = result.repos.reduce((total, repo) => total + repo.removed.length, 0);
|
|
114028
|
+
const failed = result.repos.reduce((total, repo) => total + repo.failed.length, 0);
|
|
114029
|
+
return `SUMMARY mode=${mode} repos=${result.repos.length} sweep=${result.sweepCount} keep=${result.keepCount} prune=${result.pruneCount} removed=${removed2} failed=${failed}`;
|
|
114030
|
+
}
|
|
114031
|
+
function formatResult(result) {
|
|
114032
|
+
const lines = [];
|
|
114033
|
+
for (const repo of result.repos) {
|
|
114034
|
+
lines.push(`REPO ${repo.repo} default=${repo.defaultBranch}`);
|
|
114035
|
+
for (const classification of repo.classifications) {
|
|
114036
|
+
lines.push(formatClassification(classification));
|
|
114037
|
+
}
|
|
114038
|
+
for (const failure of repo.failed) {
|
|
114039
|
+
lines.push(`FAILED ${failure.path} ${failure.error}`);
|
|
114040
|
+
}
|
|
114041
|
+
}
|
|
114042
|
+
lines.push(formatSummary(result));
|
|
114043
|
+
return lines;
|
|
114044
|
+
}
|
|
114045
|
+
// packages/omo-opencode/src/cli/worktree-sweep/options.ts
|
|
114046
|
+
function parseOlderThanDays(value) {
|
|
114047
|
+
const parsed = Number(value);
|
|
114048
|
+
if (!Number.isFinite(parsed) || parsed < 0 || !Number.isInteger(parsed)) {
|
|
114049
|
+
throw new Error(`--older-than must be a non-negative integer number of days, got: ${value}`);
|
|
114050
|
+
}
|
|
114051
|
+
return parsed;
|
|
114052
|
+
}
|
|
114053
|
+
// packages/omo-opencode/src/cli/worktree-sweep/parse-worktree-list.ts
|
|
114054
|
+
import { normalize } from "node:path";
|
|
114055
|
+
function emptyRecord() {
|
|
114056
|
+
return { detached: false, locked: false, prunable: false };
|
|
114057
|
+
}
|
|
114058
|
+
function finalize2(record3) {
|
|
114059
|
+
if (record3.path === undefined || record3.path.length === 0)
|
|
114060
|
+
return;
|
|
114061
|
+
return {
|
|
114062
|
+
path: normalize(record3.path),
|
|
114063
|
+
...record3.head === undefined ? {} : { head: record3.head },
|
|
114064
|
+
...record3.branch === undefined ? {} : { branch: record3.branch },
|
|
114065
|
+
detached: record3.detached,
|
|
114066
|
+
locked: record3.locked,
|
|
114067
|
+
...record3.lockReason === undefined ? {} : { lockReason: record3.lockReason },
|
|
114068
|
+
prunable: record3.prunable
|
|
114069
|
+
};
|
|
114070
|
+
}
|
|
114071
|
+
function applyLine(record3, line) {
|
|
114072
|
+
if (line.startsWith("worktree ")) {
|
|
114073
|
+
record3.path = line.slice("worktree ".length);
|
|
114074
|
+
return;
|
|
114075
|
+
}
|
|
114076
|
+
if (line.startsWith("HEAD ")) {
|
|
114077
|
+
record3.head = line.slice("HEAD ".length);
|
|
114078
|
+
return;
|
|
114079
|
+
}
|
|
114080
|
+
if (line.startsWith("branch ")) {
|
|
114081
|
+
record3.branch = line.slice("branch ".length).replace(/^refs\/heads\//, "");
|
|
114082
|
+
return;
|
|
114083
|
+
}
|
|
114084
|
+
if (line === "detached") {
|
|
114085
|
+
record3.detached = true;
|
|
114086
|
+
return;
|
|
114087
|
+
}
|
|
114088
|
+
if (line === "locked" || line.startsWith("locked ")) {
|
|
114089
|
+
record3.locked = true;
|
|
114090
|
+
const reason = line.slice("locked".length).trim();
|
|
114091
|
+
if (reason.length > 0)
|
|
114092
|
+
record3.lockReason = reason;
|
|
114093
|
+
return;
|
|
114094
|
+
}
|
|
114095
|
+
if (line === "prunable" || line.startsWith("prunable ")) {
|
|
114096
|
+
record3.prunable = true;
|
|
114097
|
+
}
|
|
114098
|
+
}
|
|
114099
|
+
function parseWorktreeList(porcelain) {
|
|
114100
|
+
const records = [];
|
|
114101
|
+
let current = emptyRecord();
|
|
114102
|
+
for (const rawLine of porcelain.split(`
|
|
114103
|
+
`)) {
|
|
114104
|
+
const line = rawLine.replace(/\r$/, "");
|
|
114105
|
+
if (line.length === 0) {
|
|
114106
|
+
const finalized = finalize2(current);
|
|
114107
|
+
if (finalized)
|
|
114108
|
+
records.push(finalized);
|
|
114109
|
+
current = emptyRecord();
|
|
114110
|
+
continue;
|
|
114111
|
+
}
|
|
114112
|
+
applyLine(current, line);
|
|
114113
|
+
}
|
|
114114
|
+
const trailing = finalize2(current);
|
|
114115
|
+
if (trailing)
|
|
114116
|
+
records.push(trailing);
|
|
114117
|
+
return records;
|
|
114118
|
+
}
|
|
114119
|
+
function linkedWorktrees(records) {
|
|
114120
|
+
return records.slice(1);
|
|
114121
|
+
}
|
|
114122
|
+
// packages/omo-opencode/src/cli/worktree-sweep/sweep.ts
|
|
114123
|
+
import { existsSync as existsSync66 } from "node:fs";
|
|
114124
|
+
import { stat as stat8 } from "node:fs/promises";
|
|
114125
|
+
import os7 from "node:os";
|
|
114126
|
+
import { normalize as normalize2 } from "node:path";
|
|
114127
|
+
|
|
114128
|
+
// packages/omo-opencode/src/cli/worktree-sweep/git.ts
|
|
114129
|
+
init_runtime();
|
|
114130
|
+
async function runGit(cwd, args) {
|
|
114131
|
+
const child = spawn({ cmd: ["git", "-C", cwd, ...args], stdout: "pipe", stderr: "pipe" });
|
|
114132
|
+
const [code, stdout2, stderr] = await Promise.all([
|
|
114133
|
+
child.exited,
|
|
114134
|
+
new Response(child.stdout).text(),
|
|
114135
|
+
new Response(child.stderr).text()
|
|
114136
|
+
]);
|
|
114137
|
+
return { code, stdout: stdout2, stderr };
|
|
114138
|
+
}
|
|
114139
|
+
async function listWorktreesPorcelain(repo) {
|
|
114140
|
+
const result = await runGit(repo, ["worktree", "list", "--porcelain"]);
|
|
114141
|
+
if (result.code !== 0) {
|
|
114142
|
+
throw new Error(result.stderr.trim() || `git worktree list failed in ${repo}`);
|
|
114143
|
+
}
|
|
114144
|
+
return result.stdout;
|
|
114145
|
+
}
|
|
114146
|
+
async function detectDefaultBranch(repo) {
|
|
114147
|
+
const symbolic = await runGit(repo, [
|
|
114148
|
+
"symbolic-ref",
|
|
114149
|
+
"--quiet",
|
|
114150
|
+
"--short",
|
|
114151
|
+
"refs/remotes/origin/HEAD"
|
|
114152
|
+
]);
|
|
114153
|
+
if (symbolic.code === 0) {
|
|
114154
|
+
const value = symbolic.stdout.trim();
|
|
114155
|
+
if (value.length > 0)
|
|
114156
|
+
return value.replace(/^[^/]*\//, "");
|
|
114157
|
+
}
|
|
114158
|
+
const local = await runGit(repo, [
|
|
114159
|
+
"branch",
|
|
114160
|
+
"--list",
|
|
114161
|
+
"main",
|
|
114162
|
+
"master",
|
|
114163
|
+
"--format=%(refname:short)"
|
|
114164
|
+
]);
|
|
114165
|
+
if (local.code === 0) {
|
|
114166
|
+
for (const candidate2 of ["main", "master"]) {
|
|
114167
|
+
if (local.stdout.split(`
|
|
114168
|
+
`).map((line) => line.trim()).includes(candidate2)) {
|
|
114169
|
+
return candidate2;
|
|
114170
|
+
}
|
|
114171
|
+
}
|
|
114172
|
+
}
|
|
114173
|
+
return;
|
|
114174
|
+
}
|
|
114175
|
+
async function isMerged(repo, ref, defaultBranch) {
|
|
114176
|
+
if (ref.length === 0)
|
|
114177
|
+
return false;
|
|
114178
|
+
const result = await runGit(repo, ["merge-base", "--is-ancestor", ref, defaultBranch]);
|
|
114179
|
+
return result.code === 0;
|
|
114180
|
+
}
|
|
114181
|
+
async function isDirty(worktreePath) {
|
|
114182
|
+
const result = await runGit(worktreePath, ["status", "--porcelain"]);
|
|
114183
|
+
if (result.code !== 0)
|
|
114184
|
+
return true;
|
|
114185
|
+
return result.stdout.trim().length > 0;
|
|
114186
|
+
}
|
|
114187
|
+
async function removeWorktree(repo, worktreePath) {
|
|
114188
|
+
return runGit(repo, ["worktree", "remove", worktreePath]);
|
|
114189
|
+
}
|
|
114190
|
+
async function pruneWorktrees(repo) {
|
|
114191
|
+
return runGit(repo, ["worktree", "prune"]);
|
|
114192
|
+
}
|
|
114193
|
+
async function resolveRepoRoot(cwd) {
|
|
114194
|
+
const result = await runGit(cwd, ["rev-parse", "--show-toplevel"]);
|
|
114195
|
+
if (result.code !== 0)
|
|
114196
|
+
return;
|
|
114197
|
+
const value = result.stdout.trim();
|
|
114198
|
+
return value.length > 0 ? value : undefined;
|
|
114199
|
+
}
|
|
114200
|
+
|
|
114201
|
+
// packages/omo-opencode/src/cli/worktree-sweep/sweep.ts
|
|
114202
|
+
var DAY_MS = 24 * 60 * 60 * 1000;
|
|
114203
|
+
async function isOlderThan(worktreePath, days, now) {
|
|
114204
|
+
if (days <= 0)
|
|
114205
|
+
return false;
|
|
114206
|
+
try {
|
|
114207
|
+
const stats = await stat8(worktreePath);
|
|
114208
|
+
return now - stats.mtimeMs > days * DAY_MS;
|
|
114209
|
+
} catch {
|
|
114210
|
+
return false;
|
|
114211
|
+
}
|
|
114212
|
+
}
|
|
114213
|
+
async function classifyRecord(repo, record3, defaultBranch, options) {
|
|
114214
|
+
const pathExists3 = existsSync66(record3.path);
|
|
114215
|
+
const external2 = isExcludedPath(record3.path, options.excludePrefixes, options.home);
|
|
114216
|
+
if (record3.locked || !pathExists3 || external2) {
|
|
114217
|
+
return classifyWorktree({
|
|
114218
|
+
record: record3,
|
|
114219
|
+
pathExists: pathExists3,
|
|
114220
|
+
merged: false,
|
|
114221
|
+
agedOut: false,
|
|
114222
|
+
dirty: false,
|
|
114223
|
+
external: external2
|
|
114224
|
+
});
|
|
114225
|
+
}
|
|
114226
|
+
const merged = await isMerged(repo, worktreeRef(record3), defaultBranch);
|
|
114227
|
+
const agedOut = merged ? false : await isOlderThan(record3.path, options.olderThanDays, options.now);
|
|
114228
|
+
const dirty = merged || agedOut ? await isDirty(record3.path) : false;
|
|
114229
|
+
return classifyWorktree({ record: record3, pathExists: pathExists3, merged, agedOut, dirty, external: external2 });
|
|
114230
|
+
}
|
|
114231
|
+
async function sweepRepo(repo, options) {
|
|
114232
|
+
const root = normalize2(await resolveRepoRoot(repo) ?? repo);
|
|
114233
|
+
const defaultBranch = await detectDefaultBranch(root);
|
|
114234
|
+
if (defaultBranch === undefined) {
|
|
114235
|
+
throw new Error(`Could not determine the default branch for ${root}`);
|
|
114236
|
+
}
|
|
114237
|
+
const records = linkedWorktrees(parseWorktreeList(await listWorktreesPorcelain(root)));
|
|
114238
|
+
const classifications = [];
|
|
114239
|
+
for (const record3 of records) {
|
|
114240
|
+
classifications.push(await classifyRecord(root, record3, defaultBranch, options));
|
|
114241
|
+
}
|
|
114242
|
+
const removed2 = [];
|
|
114243
|
+
const failed = [];
|
|
114244
|
+
if (options.apply) {
|
|
114245
|
+
for (const classification of classifications) {
|
|
114246
|
+
if (classification.decision !== "SWEEP")
|
|
114247
|
+
continue;
|
|
114248
|
+
const result = await removeWorktree(root, classification.path);
|
|
114249
|
+
if (result.code === 0)
|
|
114250
|
+
removed2.push(classification.path);
|
|
114251
|
+
else {
|
|
114252
|
+
failed.push({
|
|
114253
|
+
path: classification.path,
|
|
114254
|
+
error: result.stderr.trim() || `git worktree remove exited with ${result.code}`
|
|
114255
|
+
});
|
|
114256
|
+
}
|
|
114257
|
+
}
|
|
114258
|
+
await pruneWorktrees(root);
|
|
114259
|
+
}
|
|
114260
|
+
return { repo: root, defaultBranch, classifications, removed: removed2, failed };
|
|
114261
|
+
}
|
|
114262
|
+
async function sweepWorktrees(options = {}) {
|
|
114263
|
+
const apply = options.apply === true;
|
|
114264
|
+
const olderThanDays = options.olderThanDays ?? 0;
|
|
114265
|
+
const excludePrefixes = options.excludePrefixes ?? DEFAULT_EXCLUDE_PREFIXES;
|
|
114266
|
+
const home = os7.homedir();
|
|
114267
|
+
const now = Date.now();
|
|
114268
|
+
const repos = options.repos && options.repos.length > 0 ? options.repos : [options.cwd ?? process.cwd()];
|
|
114269
|
+
const reports = [];
|
|
114270
|
+
for (const repo of repos) {
|
|
114271
|
+
reports.push(await sweepRepo(repo, { apply, olderThanDays, excludePrefixes, home, now }));
|
|
114272
|
+
}
|
|
114273
|
+
const all = reports.flatMap((report) => report.classifications);
|
|
114274
|
+
return {
|
|
114275
|
+
apply,
|
|
114276
|
+
olderThanDays,
|
|
114277
|
+
repos: reports,
|
|
114278
|
+
sweepCount: all.filter((item) => item.decision === "SWEEP").length,
|
|
114279
|
+
keepCount: all.filter((item) => item.decision === "KEEP").length,
|
|
114280
|
+
pruneCount: all.filter((item) => item.decision === "PRUNE").length
|
|
114281
|
+
};
|
|
114282
|
+
}
|
|
114283
|
+
// packages/omo-opencode/src/cli/worktree-sweep/worktree-sweep.ts
|
|
114284
|
+
async function worktreeSweep(options = {}) {
|
|
114285
|
+
let result;
|
|
114286
|
+
try {
|
|
114287
|
+
result = await sweepWorktrees(options);
|
|
114288
|
+
} catch (error51) {
|
|
114289
|
+
process.stderr.write(`[omo] worktree-sweep failed: ${error51 instanceof Error ? error51.message : String(error51)}
|
|
114290
|
+
`);
|
|
114291
|
+
return 1;
|
|
114292
|
+
}
|
|
114293
|
+
if (options.json === true) {
|
|
114294
|
+
process.stdout.write(JSON.stringify(result, null, 2));
|
|
114295
|
+
process.stdout.write(`
|
|
114296
|
+
`);
|
|
114297
|
+
} else {
|
|
114298
|
+
process.stdout.write(formatResult(result).join(`
|
|
114299
|
+
`));
|
|
114300
|
+
process.stdout.write(`
|
|
114301
|
+
`);
|
|
114302
|
+
}
|
|
114303
|
+
const failedTotal = result.repos.reduce((total, repo) => total + repo.failed.length, 0);
|
|
114304
|
+
if (failedTotal > 0)
|
|
114305
|
+
return 1;
|
|
114306
|
+
return 0;
|
|
114307
|
+
}
|
|
113981
114308
|
// packages/omo-opencode/src/cli/runtime-commands.ts
|
|
113982
114309
|
init_shared();
|
|
113983
114310
|
init_package();
|
|
@@ -114002,6 +114329,30 @@ function configureRuntimeCommands(program2) {
|
|
|
114002
114329
|
});
|
|
114003
114330
|
process.exit(exitCode);
|
|
114004
114331
|
});
|
|
114332
|
+
program2.command("worktree-sweep").description("Report (and optionally remove) stale linked git worktrees").option("--apply", "Actually remove SWEEP worktrees and prune stale metadata (default is dry-run)").option("--older-than <days>", "Sweep unmerged worktrees older than N days (0 = merged-only)", (value) => {
|
|
114333
|
+
try {
|
|
114334
|
+
return parseOlderThanDays(value);
|
|
114335
|
+
} catch (error51) {
|
|
114336
|
+
throw new InvalidArgumentError(error51 instanceof Error ? error51.message : String(error51));
|
|
114337
|
+
}
|
|
114338
|
+
}).option("--repo <path>", "Repository to sweep (repeatable)", (value, previous = []) => [...previous, value]).option("--json", "Output structured JSON result").addHelpText("after", `
|
|
114339
|
+
Examples:
|
|
114340
|
+
$ omo-agent-toolkit worktree-sweep
|
|
114341
|
+
$ omo-agent-toolkit worktree-sweep --older-than=14
|
|
114342
|
+
$ omo-agent-toolkit worktree-sweep --repo /path/to/repo --repo /path/to/other --apply
|
|
114343
|
+
|
|
114344
|
+
Lines: SWEEP <path> <ref> | KEEP(<reason>) <path> <ref> | PRUNE <path> <ref>
|
|
114345
|
+
KEEP reasons: locked, external, unmerged, dirty. Dry-run is the default; --apply
|
|
114346
|
+
removes with 'git worktree remove' (never --force) and then prunes.
|
|
114347
|
+
`).action(async (options) => {
|
|
114348
|
+
const exitCode = await worktreeSweep({
|
|
114349
|
+
apply: options.apply === true,
|
|
114350
|
+
olderThanDays: options.olderThan ?? 0,
|
|
114351
|
+
repos: options.repo,
|
|
114352
|
+
json: options.json ?? false
|
|
114353
|
+
});
|
|
114354
|
+
process.exit(exitCode);
|
|
114355
|
+
});
|
|
114005
114356
|
program2.command("ulw-loop [args...]").allowUnknownOption().passThroughOptions().description("Run the Codex LazyCodex ulw-loop CLI").action(async (args = []) => {
|
|
114006
114357
|
const exitCode = await codexUlwLoop(args);
|
|
114007
114358
|
process.exit(exitCode);
|
package/dist/index.js
CHANGED
|
@@ -98672,7 +98672,7 @@ function getCachedVersion(options = {}) {
|
|
|
98672
98672
|
// package.json
|
|
98673
98673
|
var package_default = {
|
|
98674
98674
|
name: "oh-my-opencode",
|
|
98675
|
-
version: "5.0.0-beta.
|
|
98675
|
+
version: "5.0.0-beta.18",
|
|
98676
98676
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
98677
98677
|
main: "./dist/index.js",
|
|
98678
98678
|
types: "dist/index.d.ts",
|
|
@@ -98853,7 +98853,7 @@ var package_default = {
|
|
|
98853
98853
|
zod: "^4.4.3"
|
|
98854
98854
|
},
|
|
98855
98855
|
devDependencies: {
|
|
98856
|
-
"@code-yeongyu/senpi": "2026.8.
|
|
98856
|
+
"@code-yeongyu/senpi": "2026.8.23",
|
|
98857
98857
|
"@oh-my-opencode/agents-md-core": "workspace:*",
|
|
98858
98858
|
"@oh-my-opencode/ast-grep-mcp": "workspace:*",
|
|
98859
98859
|
"@oh-my-opencode/boulder-state": "workspace:*",
|
|
@@ -98894,18 +98894,18 @@ var package_default = {
|
|
|
98894
98894
|
typescript: "^7.0.2"
|
|
98895
98895
|
},
|
|
98896
98896
|
optionalDependencies: {
|
|
98897
|
-
"oh-my-opencode-darwin-arm64": "5.0.0-beta.
|
|
98898
|
-
"oh-my-opencode-darwin-x64": "5.0.0-beta.
|
|
98899
|
-
"oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.
|
|
98900
|
-
"oh-my-opencode-linux-arm64": "5.0.0-beta.
|
|
98901
|
-
"oh-my-opencode-linux-arm64-musl": "5.0.0-beta.
|
|
98902
|
-
"oh-my-opencode-linux-x64": "5.0.0-beta.
|
|
98903
|
-
"oh-my-opencode-linux-x64-baseline": "5.0.0-beta.
|
|
98904
|
-
"oh-my-opencode-linux-x64-musl": "5.0.0-beta.
|
|
98905
|
-
"oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.
|
|
98906
|
-
"oh-my-opencode-windows-arm64": "5.0.0-beta.
|
|
98907
|
-
"oh-my-opencode-windows-x64": "5.0.0-beta.
|
|
98908
|
-
"oh-my-opencode-windows-x64-baseline": "5.0.0-beta.
|
|
98897
|
+
"oh-my-opencode-darwin-arm64": "5.0.0-beta.18",
|
|
98898
|
+
"oh-my-opencode-darwin-x64": "5.0.0-beta.18",
|
|
98899
|
+
"oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.18",
|
|
98900
|
+
"oh-my-opencode-linux-arm64": "5.0.0-beta.18",
|
|
98901
|
+
"oh-my-opencode-linux-arm64-musl": "5.0.0-beta.18",
|
|
98902
|
+
"oh-my-opencode-linux-x64": "5.0.0-beta.18",
|
|
98903
|
+
"oh-my-opencode-linux-x64-baseline": "5.0.0-beta.18",
|
|
98904
|
+
"oh-my-opencode-linux-x64-musl": "5.0.0-beta.18",
|
|
98905
|
+
"oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.18",
|
|
98906
|
+
"oh-my-opencode-windows-arm64": "5.0.0-beta.18",
|
|
98907
|
+
"oh-my-opencode-windows-x64": "5.0.0-beta.18",
|
|
98908
|
+
"oh-my-opencode-windows-x64-baseline": "5.0.0-beta.18"
|
|
98909
98909
|
},
|
|
98910
98910
|
overrides: {
|
|
98911
98911
|
"@earendil-works/pi-agent-core": "0.84.2",
|
|
@@ -90,7 +90,7 @@ Before launching agents, collect these inputs. Extract from conversation history
|
|
|
90
90
|
</required_inputs>
|
|
91
91
|
|
|
92
92
|
|
|
93
|
-
Review PRs and branches from a dedicated review worktree only: create or attach one with `git worktree add <path> <branch>` before collecting changed files, diff, file contents, or running checks
|
|
93
|
+
Review PRs and branches from a dedicated review worktree only: create or attach one with `git worktree add <path> <branch>` before collecting changed files, diff, file contents, or running checks, then immediately lock it with `git worktree lock <path> --reason "review:<pr-or-branch>"`. The main worktree is read-only context; never checkout, test, or edit the review branch there.
|
|
94
94
|
|
|
95
95
|
**Auto-collection sequence:**
|
|
96
96
|
|
|
@@ -530,8 +530,6 @@ OUTPUT FORMAT:
|
|
|
530
530
|
""")
|
|
531
531
|
```
|
|
532
532
|
|
|
533
|
-
---
|
|
534
|
-
|
|
535
533
|
## Phase 2: Wait & Collect
|
|
536
534
|
|
|
537
535
|
After launching all 5 agents in one turn, wait for completions in bounded
|
|
@@ -561,6 +559,8 @@ review result with the incomplete lane named. Do not spin in repeated
|
|
|
561
559
|
wait/followup cycles. Do not use `multi_agent_v1.send_input` as an interrupt; queued
|
|
562
560
|
followups are not cancellation.
|
|
563
561
|
|
|
562
|
+
After ALL 5 lanes reach a terminal state and before delivering the verdict, tear down the review worktree: run `git worktree unlock <path>` followed by `git worktree remove <path>`. The lanes above run inside that worktree, so removing it earlier destroys their working directory; a crashed review leaves the locked tree as a recoverable marker for manual cleanup.
|
|
563
|
+
|
|
564
564
|
---
|
|
565
565
|
|
|
566
566
|
## Phase 3: Deliver Verdict
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oh-my-opencode",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.18",
|
|
4
4
|
"description": "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
"zod": "^4.4.3"
|
|
182
182
|
},
|
|
183
183
|
"devDependencies": {
|
|
184
|
-
"@code-yeongyu/senpi": "2026.8.
|
|
184
|
+
"@code-yeongyu/senpi": "2026.8.23",
|
|
185
185
|
"@oh-my-opencode/agents-md-core": "workspace:*",
|
|
186
186
|
"@oh-my-opencode/ast-grep-mcp": "workspace:*",
|
|
187
187
|
"@oh-my-opencode/boulder-state": "workspace:*",
|
|
@@ -222,18 +222,18 @@
|
|
|
222
222
|
"typescript": "^7.0.2"
|
|
223
223
|
},
|
|
224
224
|
"optionalDependencies": {
|
|
225
|
-
"oh-my-opencode-darwin-arm64": "5.0.0-beta.
|
|
226
|
-
"oh-my-opencode-darwin-x64": "5.0.0-beta.
|
|
227
|
-
"oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.
|
|
228
|
-
"oh-my-opencode-linux-arm64": "5.0.0-beta.
|
|
229
|
-
"oh-my-opencode-linux-arm64-musl": "5.0.0-beta.
|
|
230
|
-
"oh-my-opencode-linux-x64": "5.0.0-beta.
|
|
231
|
-
"oh-my-opencode-linux-x64-baseline": "5.0.0-beta.
|
|
232
|
-
"oh-my-opencode-linux-x64-musl": "5.0.0-beta.
|
|
233
|
-
"oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.
|
|
234
|
-
"oh-my-opencode-windows-arm64": "5.0.0-beta.
|
|
235
|
-
"oh-my-opencode-windows-x64": "5.0.0-beta.
|
|
236
|
-
"oh-my-opencode-windows-x64-baseline": "5.0.0-beta.
|
|
225
|
+
"oh-my-opencode-darwin-arm64": "5.0.0-beta.18",
|
|
226
|
+
"oh-my-opencode-darwin-x64": "5.0.0-beta.18",
|
|
227
|
+
"oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.18",
|
|
228
|
+
"oh-my-opencode-linux-arm64": "5.0.0-beta.18",
|
|
229
|
+
"oh-my-opencode-linux-arm64-musl": "5.0.0-beta.18",
|
|
230
|
+
"oh-my-opencode-linux-x64": "5.0.0-beta.18",
|
|
231
|
+
"oh-my-opencode-linux-x64-baseline": "5.0.0-beta.18",
|
|
232
|
+
"oh-my-opencode-linux-x64-musl": "5.0.0-beta.18",
|
|
233
|
+
"oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.18",
|
|
234
|
+
"oh-my-opencode-windows-arm64": "5.0.0-beta.18",
|
|
235
|
+
"oh-my-opencode-windows-x64": "5.0.0-beta.18",
|
|
236
|
+
"oh-my-opencode-windows-x64-baseline": "5.0.0-beta.18"
|
|
237
237
|
},
|
|
238
238
|
"overrides": {
|
|
239
239
|
"@earendil-works/pi-agent-core": "0.84.2",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/bootstrap/dist/cli.js\" hook session-start",
|
|
9
9
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\bootstrap.ps1\"",
|
|
10
10
|
"timeout": 30,
|
|
11
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
11
|
+
"statusMessage": "(OmO 5.0.0-beta.18) Checking Bootstrap Provisioning"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sisyphuslabs/codex-bootstrap",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.18",
|
|
4
4
|
"description": "Codex SessionStart bootstrap component that provisions LazyCodex runtime dependencies from a detached worker.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": true,
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook pre-tool-use",
|
|
10
10
|
"timeout": 5,
|
|
11
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
11
|
+
"statusMessage": "(OmO 5.0.0-beta.18) Recommending Git Bash MCP"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"type": "command",
|
|
21
21
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
|
|
22
22
|
"timeout": 5,
|
|
23
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
23
|
+
"statusMessage": "(OmO 5.0.0-beta.18) Resetting Git Bash MCP Reminder"
|
|
24
24
|
}
|
|
25
25
|
]
|
|
26
26
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/components/lazycodex-executor-verify/dist/cli.js\" hook subagent-stop",
|
|
10
10
|
"timeout": 10,
|
|
11
|
-
"statusMessage": "(OmO 5.0.0-beta.
|
|
11
|
+
"statusMessage": "(OmO 5.0.0-beta.18) Verifying LazyCodex Executor Evidence"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/codex-lazycodex-executor-verify",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.18",
|
|
4
4
|
"description": "Codex SubagentStop evidence verifier for LazyCodex executor completions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "npm@11.12.1",
|