oh-my-opencode 5.1.6 → 5.1.8
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 +49 -45
- package/dist/cli/run/runnable-agent-resolver.d.ts +3 -0
- package/dist/cli-node/index.js +49 -45
- package/dist/hooks/goal/validation.d.ts +1 -0
- package/dist/hooks/no-hephaestus-non-gpt/hook.d.ts +4 -0
- package/dist/index.js +108 -61
- package/dist/plugin/chat-message/loop-commands.d.ts +1 -0
- package/dist/shared/index.d.ts +0 -1
- package/dist/shared/live-server-route.d.ts +0 -2
- package/dist/shared/tmux/tmux-utils/pane-close.d.ts +0 -3
- package/dist/shared/tmux/tmux-utils/server-health.d.ts +1 -1
- package/dist/skills/browser/runtime/omowright/manifest.json +1 -1
- package/dist/skills/debugging/SKILL.md +1 -1
- package/dist/skills/debugging/references/methodology/06-fix.md +8 -0
- package/dist/tui.js +22 -42
- package/package.json +14 -14
- package/packages/lsp-core/src/post-edit/file-location.ts +7 -2
- package/packages/lsp-core/src/post-edit/not-installed.test.ts +25 -0
- package/packages/lsp-core/src/tool-surface.test.ts +11 -11
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +13 -3
- 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/bootstrap/test/download.test.ts +0 -16
- package/packages/omo-codex/plugin/components/bootstrap/test/environment.test.ts +3 -0
- 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/lsp/test/package-smoke.test.ts +0 -27
- package/packages/omo-codex/plugin/components/rules/README.md +0 -1
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.5.md +1 -1
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.6.md +1 -1
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-6.md +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/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/ultrawork/test/directive-source.test.ts +0 -6
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +0 -15
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-role-matrix.test.ts +16 -0
- 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-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/post-tool-use-recording-spawn-admission.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-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-ulw-execute-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-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 +12 -12
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +1 -1
- package/packages/omo-codex/plugin/skills/debugging/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/06-fix.md +8 -0
- package/packages/omo-codex/plugin/test/AGENTS.md +11 -0
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +0 -50
- package/packages/omo-codex/scripts/install-config-autonomous-features.test.mjs +24 -4
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +15 -5
- package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +1 -1
- package/packages/shared-skills/skills/debugging/SKILL.md +1 -1
- package/packages/shared-skills/skills/debugging/references/methodology/06-fix.md +8 -0
- package/dist/features/team-mode/team-layout-tmux/close-team-member-pane.d.ts +0 -1
- package/dist/features/team-mode/team-tasklist/claim.d.ts +0 -1
- package/dist/features/team-mode/team-tasklist/dependencies.d.ts +0 -1
- package/dist/features/team-mode/team-tasklist/get.d.ts +0 -1
- package/dist/features/team-mode/team-tasklist/store.d.ts +0 -1
- package/dist/features/team-mode/team-tasklist/update.d.ts +0 -1
- package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +0 -29
- package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +0 -13
- package/dist/openclaw/config.d.ts +0 -1
- package/dist/openclaw/dispatcher.d.ts +0 -1
- package/dist/openclaw/gateway-url-validation.d.ts +0 -1
- package/dist/openclaw/reply-listener-injection.d.ts +0 -1
- package/dist/openclaw/reply-listener-start.d.ts +0 -1
- package/dist/openclaw/session-registry.d.ts +0 -1
- package/dist/openclaw/tmux.d.ts +0 -1
package/dist/index.js
CHANGED
|
@@ -7901,7 +7901,7 @@ var init_powershell_zip_entry_listing = __esm(() => {
|
|
|
7901
7901
|
|
|
7902
7902
|
// packages/utils/src/zip-entry-listing/tar-zip-entry-listing.ts
|
|
7903
7903
|
function parseTarListedZipEntry(line) {
|
|
7904
|
-
const match = line.match(/^([^\s])\S*\s+\d+\s+\S+\s+\S+\s+\d+\s+\
|
|
7904
|
+
const match = line.match(/^([^\s])\S*\s+\d+\s+\S+\s+\S+\s+\d+\s+\S+\s+\d+\s+(?:\d{2}:\d{2}|\d{4})\s+(.*)$/);
|
|
7905
7905
|
if (!match) {
|
|
7906
7906
|
return null;
|
|
7907
7907
|
}
|
|
@@ -20373,7 +20373,8 @@ var OmoMemoryRecallSchema = z8.object({
|
|
|
20373
20373
|
event_caps: OmoMemoryRecallEventCapsSchema.default({ tool_args: 400, result_head: 600, assistant: 1500, prompt: 4000 }),
|
|
20374
20374
|
sidecar_max_tokens: z8.number().int().positive().default(48000),
|
|
20375
20375
|
max_concurrent_wakes: z8.number().int().positive().default(2),
|
|
20376
|
-
tool_budget: z8.number().int().positive().default(8)
|
|
20376
|
+
tool_budget: z8.number().int().positive().default(8),
|
|
20377
|
+
query_expansion: z8.boolean().default(false)
|
|
20377
20378
|
}).strict();
|
|
20378
20379
|
var OmoMemoryNudgeSchema = z8.object({
|
|
20379
20380
|
enabled: z8.boolean().default(true),
|
|
@@ -20434,7 +20435,8 @@ var OmoMemoryRecallLayerSchema = z8.object({
|
|
|
20434
20435
|
event_caps: OmoMemoryRecallEventCapsLayerSchema.optional(),
|
|
20435
20436
|
sidecar_max_tokens: z8.number().int().positive().optional(),
|
|
20436
20437
|
max_concurrent_wakes: z8.number().int().positive().optional(),
|
|
20437
|
-
tool_budget: z8.number().int().positive().optional()
|
|
20438
|
+
tool_budget: z8.number().int().positive().optional(),
|
|
20439
|
+
query_expansion: z8.boolean().optional()
|
|
20438
20440
|
}).strict();
|
|
20439
20441
|
var OmoMemoryNudgeLayerSchema = z8.object({
|
|
20440
20442
|
enabled: z8.boolean().optional(),
|
|
@@ -20511,7 +20513,8 @@ var OmoMemorySettingsSchema = z8.object({
|
|
|
20511
20513
|
event_caps: { tool_args: 400, result_head: 600, assistant: 1500, prompt: 4000 },
|
|
20512
20514
|
sidecar_max_tokens: 48000,
|
|
20513
20515
|
max_concurrent_wakes: 2,
|
|
20514
|
-
tool_budget: 8
|
|
20516
|
+
tool_budget: 8,
|
|
20517
|
+
query_expansion: false
|
|
20515
20518
|
}),
|
|
20516
20519
|
compile_warn_tokens: z8.number().int().positive().default(30000),
|
|
20517
20520
|
agents: z8.record(z8.string(), OmoMemoryAgentOverridesSchema).default({})
|
|
@@ -22968,7 +22971,7 @@ var CATEGORY_MODEL_REQUIREMENTS = {
|
|
|
22968
22971
|
{
|
|
22969
22972
|
providers: ["openai", "chatgpt-subscription", "github-copilot", "opencode"],
|
|
22970
22973
|
model: "gpt-6-astra",
|
|
22971
|
-
variant: "
|
|
22974
|
+
variant: "high"
|
|
22972
22975
|
}
|
|
22973
22976
|
]
|
|
22974
22977
|
},
|
|
@@ -27797,7 +27800,7 @@ var OPENAI_CATEGORIES = [
|
|
|
27797
27800
|
},
|
|
27798
27801
|
{
|
|
27799
27802
|
name: "deep-high",
|
|
27800
|
-
config: { model: "openai/gpt-6-astra", variant: "
|
|
27803
|
+
config: { model: "openai/gpt-6-astra", variant: "high" },
|
|
27801
27804
|
description: "Escalation deep lane: a goal whose central decision cannot be settled from evidence alone. Same one-goal, one-deliverable contract as deep-low.",
|
|
27802
27805
|
callerGuidance: DEEP_HIGH_CATEGORY_CALLER_GUIDANCE,
|
|
27803
27806
|
promptAppend: DEEP_HIGH_CATEGORY_PROMPT_APPEND,
|
|
@@ -88276,24 +88279,6 @@ function migrateLegacyWorkspaceDirectory(directory) {
|
|
|
88276
88279
|
function isTaskSystemEnabled(config) {
|
|
88277
88280
|
return config.experimental?.task_system ?? false;
|
|
88278
88281
|
}
|
|
88279
|
-
// packages/omo-opencode/src/shared/excluded-dirs.ts
|
|
88280
|
-
var EXCLUDED_DIR_NAMES = [
|
|
88281
|
-
"node_modules",
|
|
88282
|
-
".git",
|
|
88283
|
-
"dist",
|
|
88284
|
-
"build",
|
|
88285
|
-
".next",
|
|
88286
|
-
".omo",
|
|
88287
|
-
".sisyphus",
|
|
88288
|
-
".turbo",
|
|
88289
|
-
"coverage",
|
|
88290
|
-
"out",
|
|
88291
|
-
".cache",
|
|
88292
|
-
".vscode-test",
|
|
88293
|
-
"target",
|
|
88294
|
-
".local-ignore"
|
|
88295
|
-
];
|
|
88296
|
-
var EXCLUDED_DIRS = Object.freeze(new Set(EXCLUDED_DIR_NAMES));
|
|
88297
88282
|
// packages/omo-opencode/src/shared/replace-tool-args.ts
|
|
88298
88283
|
init_src();
|
|
88299
88284
|
// packages/omo-opencode/src/cli/config-manager/config-context.ts
|
|
@@ -91512,7 +91497,7 @@ var RULE_EXTENSIONS = [".md", ".mdc"];
|
|
|
91512
91497
|
var GITHUB_INSTRUCTIONS_PATTERN = /\.instructions\.md$/;
|
|
91513
91498
|
var AGENTS_FILENAME = "AGENTS.md";
|
|
91514
91499
|
var GLOBAL_DISTANCE = 9999;
|
|
91515
|
-
var
|
|
91500
|
+
var EXCLUDED_DIRS = new Set(["node_modules", ".git", "dist", "build", ".turbo", ".next", "coverage"]);
|
|
91516
91501
|
var SOURCE_PRIORITY = new Map([
|
|
91517
91502
|
[".omo/rules", 0],
|
|
91518
91503
|
[".claude/rules", 1],
|
|
@@ -91650,7 +91635,7 @@ function findRuleFilesRecursive(dir, results, visited = new Set, boundaryRoot) {
|
|
|
91650
91635
|
for (const entry of entries) {
|
|
91651
91636
|
const fullPath = join50(dir, entry.name);
|
|
91652
91637
|
if (entry.isDirectory()) {
|
|
91653
|
-
if (!
|
|
91638
|
+
if (!EXCLUDED_DIRS.has(entry.name))
|
|
91654
91639
|
findRuleFilesRecursive(fullPath, results, visited, effectiveBoundary);
|
|
91655
91640
|
continue;
|
|
91656
91641
|
}
|
|
@@ -91935,11 +91920,6 @@ function resolveStartDir(startPath) {
|
|
|
91935
91920
|
function hasProjectMarker(directory) {
|
|
91936
91921
|
return PROJECT_MARKERS.some((marker) => existsSync41(join52(directory, marker)));
|
|
91937
91922
|
}
|
|
91938
|
-
// packages/agents-md-core/src/constants.ts
|
|
91939
|
-
var TRUNCATION_NOTICE_PREFIX = `
|
|
91940
|
-
|
|
91941
|
-
[Note: Content was truncated to save context window space. For full context, please read the file directly: `;
|
|
91942
|
-
var TRUNCATION_NOTICE_SUFFIX = "]";
|
|
91943
91923
|
// packages/agents-md-core/src/finder.ts
|
|
91944
91924
|
import { realpathSync as realpathSync10 } from "fs";
|
|
91945
91925
|
import { isAbsolute as isAbsolute9, relative as relative11, resolve as resolve13 } from "path";
|
|
@@ -91965,6 +91945,12 @@ function isSameOrChildPath3(childPath, parentPath) {
|
|
|
91965
91945
|
const relativePath = relative11(parentPath, childPath);
|
|
91966
91946
|
return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute9(relativePath);
|
|
91967
91947
|
}
|
|
91948
|
+
// packages/agents-md-core/src/constants.ts
|
|
91949
|
+
var TRUNCATION_NOTICE_PREFIX = `
|
|
91950
|
+
|
|
91951
|
+
[Note: Content was truncated to save context window space. For full context, please read the file directly: `;
|
|
91952
|
+
var TRUNCATION_NOTICE_SUFFIX = "]";
|
|
91953
|
+
|
|
91968
91954
|
// packages/agents-md-core/src/formatter.ts
|
|
91969
91955
|
function formatAgentsMdContextBlock(input) {
|
|
91970
91956
|
const truncationNotice = input.truncated ? `${TRUNCATION_NOTICE_PREFIX}${input.agentsPath}${TRUNCATION_NOTICE_SUFFIX}` : "";
|
|
@@ -98589,7 +98575,7 @@ function getCachedVersion(options = {}) {
|
|
|
98589
98575
|
// package.json
|
|
98590
98576
|
var package_default = {
|
|
98591
98577
|
name: "oh-my-opencode",
|
|
98592
|
-
version: "5.1.
|
|
98578
|
+
version: "5.1.8",
|
|
98593
98579
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
98594
98580
|
main: "./dist/index.js",
|
|
98595
98581
|
types: "dist/index.d.ts",
|
|
@@ -98766,7 +98752,7 @@ var package_default = {
|
|
|
98766
98752
|
},
|
|
98767
98753
|
devDependencies: {
|
|
98768
98754
|
"@clack/prompts": "^1.8.1",
|
|
98769
|
-
"@code-yeongyu/senpi": "2026.
|
|
98755
|
+
"@code-yeongyu/senpi": "2026.10.1-2",
|
|
98770
98756
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
98771
98757
|
"@oh-my-opencode/agents-md-core": "workspace:*",
|
|
98772
98758
|
"@oh-my-opencode/ast-grep-mcp": "workspace:*",
|
|
@@ -98824,18 +98810,18 @@ var package_default = {
|
|
|
98824
98810
|
typescript: "^7.0.2"
|
|
98825
98811
|
},
|
|
98826
98812
|
optionalDependencies: {
|
|
98827
|
-
"oh-my-opencode-darwin-arm64": "5.1.
|
|
98828
|
-
"oh-my-opencode-darwin-x64": "5.1.
|
|
98829
|
-
"oh-my-opencode-darwin-x64-baseline": "5.1.
|
|
98830
|
-
"oh-my-opencode-linux-arm64": "5.1.
|
|
98831
|
-
"oh-my-opencode-linux-arm64-musl": "5.1.
|
|
98832
|
-
"oh-my-opencode-linux-x64": "5.1.
|
|
98833
|
-
"oh-my-opencode-linux-x64-baseline": "5.1.
|
|
98834
|
-
"oh-my-opencode-linux-x64-musl": "5.1.
|
|
98835
|
-
"oh-my-opencode-linux-x64-musl-baseline": "5.1.
|
|
98836
|
-
"oh-my-opencode-windows-arm64": "5.1.
|
|
98837
|
-
"oh-my-opencode-windows-x64": "5.1.
|
|
98838
|
-
"oh-my-opencode-windows-x64-baseline": "5.1.
|
|
98813
|
+
"oh-my-opencode-darwin-arm64": "5.1.8",
|
|
98814
|
+
"oh-my-opencode-darwin-x64": "5.1.8",
|
|
98815
|
+
"oh-my-opencode-darwin-x64-baseline": "5.1.8",
|
|
98816
|
+
"oh-my-opencode-linux-arm64": "5.1.8",
|
|
98817
|
+
"oh-my-opencode-linux-arm64-musl": "5.1.8",
|
|
98818
|
+
"oh-my-opencode-linux-x64": "5.1.8",
|
|
98819
|
+
"oh-my-opencode-linux-x64-baseline": "5.1.8",
|
|
98820
|
+
"oh-my-opencode-linux-x64-musl": "5.1.8",
|
|
98821
|
+
"oh-my-opencode-linux-x64-musl-baseline": "5.1.8",
|
|
98822
|
+
"oh-my-opencode-windows-arm64": "5.1.8",
|
|
98823
|
+
"oh-my-opencode-windows-x64": "5.1.8",
|
|
98824
|
+
"oh-my-opencode-windows-x64-baseline": "5.1.8"
|
|
98839
98825
|
},
|
|
98840
98826
|
overrides: {
|
|
98841
98827
|
hono: "^4.13.8",
|
|
@@ -108009,6 +107995,13 @@ var TOAST_MESSAGE2 = [
|
|
|
108009
107995
|
"For Claude/Kimi/GLM models, always use Sisyphus."
|
|
108010
107996
|
].join(`
|
|
108011
107997
|
`);
|
|
107998
|
+
|
|
107999
|
+
class HephaestusRequiresGptError extends Error {
|
|
108000
|
+
name = "HephaestusRequiresGptError";
|
|
108001
|
+
constructor(modelID) {
|
|
108002
|
+
super(`Hephaestus requires a GPT-family model (got ${modelID}). Use Sisyphus for non-GPT models.`);
|
|
108003
|
+
}
|
|
108004
|
+
}
|
|
108012
108005
|
function showToast2(ctx, sessionID, variant) {
|
|
108013
108006
|
ctx.client.tui.showToast({
|
|
108014
108007
|
body: {
|
|
@@ -108036,11 +108029,13 @@ function createNoHephaestusNonGptHook(ctx, options) {
|
|
|
108036
108029
|
if (allowNonGptModel) {
|
|
108037
108030
|
return;
|
|
108038
108031
|
}
|
|
108039
|
-
|
|
108040
|
-
|
|
108041
|
-
|
|
108042
|
-
|
|
108043
|
-
|
|
108032
|
+
const error = new HephaestusRequiresGptError(modelID);
|
|
108033
|
+
log2("[no-hephaestus-non-gpt] Refusing non-GPT Hephaestus primary", {
|
|
108034
|
+
sessionID: input.sessionID,
|
|
108035
|
+
modelID,
|
|
108036
|
+
error: error.message
|
|
108037
|
+
});
|
|
108038
|
+
throw error;
|
|
108044
108039
|
}
|
|
108045
108040
|
}
|
|
108046
108041
|
};
|
|
@@ -111797,6 +111792,26 @@ function readOpencodeConfigSkills(directory) {
|
|
|
111797
111792
|
// packages/omo-opencode/src/tools/slashcommand/command-discovery.ts
|
|
111798
111793
|
import { existsSync as existsSync76, readdirSync as readdirSync23, readFileSync as readFileSync52, statSync as statSync12 } from "fs";
|
|
111799
111794
|
import { basename as basename15, join as join100 } from "path";
|
|
111795
|
+
|
|
111796
|
+
// packages/omo-opencode/src/shared/excluded-dirs.ts
|
|
111797
|
+
var EXCLUDED_DIR_NAMES = [
|
|
111798
|
+
"node_modules",
|
|
111799
|
+
".git",
|
|
111800
|
+
"dist",
|
|
111801
|
+
"build",
|
|
111802
|
+
".next",
|
|
111803
|
+
".omo",
|
|
111804
|
+
".sisyphus",
|
|
111805
|
+
".turbo",
|
|
111806
|
+
"coverage",
|
|
111807
|
+
"out",
|
|
111808
|
+
".cache",
|
|
111809
|
+
".vscode-test",
|
|
111810
|
+
"target",
|
|
111811
|
+
".local-ignore"
|
|
111812
|
+
];
|
|
111813
|
+
var EXCLUDED_DIRS2 = Object.freeze(new Set(EXCLUDED_DIR_NAMES));
|
|
111814
|
+
// packages/omo-opencode/src/tools/slashcommand/command-discovery.ts
|
|
111800
111815
|
init_logger2();
|
|
111801
111816
|
|
|
111802
111817
|
// packages/omo-opencode/src/features/builtin-commands/templates/goal.ts
|
|
@@ -113320,7 +113335,7 @@ function discoverCommandsFromDir(commandsDir, scope, prefix = "") {
|
|
|
113320
113335
|
const commands = [];
|
|
113321
113336
|
for (const entry of entries) {
|
|
113322
113337
|
if (entry.isDirectory()) {
|
|
113323
|
-
if (
|
|
113338
|
+
if (EXCLUDED_DIRS2.has(entry.name))
|
|
113324
113339
|
continue;
|
|
113325
113340
|
if (entry.name.startsWith("."))
|
|
113326
113341
|
continue;
|
|
@@ -166432,6 +166447,33 @@ function createAgentConfigCacheKey(config) {
|
|
|
166432
166447
|
skills: config.skills
|
|
166433
166448
|
});
|
|
166434
166449
|
}
|
|
166450
|
+
function attachHiddenConfigKeyAliases(config, pluginConfig) {
|
|
166451
|
+
const agents = config.agent;
|
|
166452
|
+
if (typeof agents !== "object" || agents === null) {
|
|
166453
|
+
return;
|
|
166454
|
+
}
|
|
166455
|
+
const agentMap = agents;
|
|
166456
|
+
const overrides = pluginConfig.agents;
|
|
166457
|
+
const configKeys = new Set([
|
|
166458
|
+
...Object.keys(AGENT_DISPLAY_NAMES),
|
|
166459
|
+
...Object.keys(overrides ?? {})
|
|
166460
|
+
]);
|
|
166461
|
+
for (const configKey of configKeys) {
|
|
166462
|
+
const displayName = getAgentListDisplayName(configKey, overrides);
|
|
166463
|
+
if (!displayName || displayName === configKey) {
|
|
166464
|
+
continue;
|
|
166465
|
+
}
|
|
166466
|
+
const displayEntry = agentMap[displayName];
|
|
166467
|
+
if (typeof displayEntry !== "object" || displayEntry === null) {
|
|
166468
|
+
continue;
|
|
166469
|
+
}
|
|
166470
|
+
agentMap[configKey] = {
|
|
166471
|
+
...displayEntry,
|
|
166472
|
+
hidden: true
|
|
166473
|
+
};
|
|
166474
|
+
registerAgentName(configKey);
|
|
166475
|
+
}
|
|
166476
|
+
}
|
|
166435
166477
|
function replayAgentConfigSideEffects(params) {
|
|
166436
166478
|
if (params.configuredDefaultAgent && typeof params.defaultAgent === "string") {
|
|
166437
166479
|
setDefaultAgentForSort(params.defaultAgent);
|
|
@@ -166486,6 +166528,7 @@ function createConfigHandler(deps) {
|
|
|
166486
166528
|
};
|
|
166487
166529
|
}
|
|
166488
166530
|
applyToolConfig({ config, pluginConfig, agentResult });
|
|
166531
|
+
attachHiddenConfigKeyAliases(config, pluginConfig);
|
|
166489
166532
|
await applyMcpConfig({ config, pluginConfig, ctx, pluginComponents });
|
|
166490
166533
|
await applyCommandConfig({ config, pluginConfig, ctx, pluginComponents });
|
|
166491
166534
|
if (runtimeSkillSourceUrl) {
|
|
@@ -173965,11 +174008,20 @@ function handleGoalMessage(args) {
|
|
|
173965
174008
|
if (!hooks.goal || nativeGoalCommand) {
|
|
173966
174009
|
return;
|
|
173967
174010
|
}
|
|
173968
|
-
const promptText = extractPromptText5(output.parts);
|
|
174011
|
+
const promptText = args.originalPromptText ?? extractPromptText5(output.parts);
|
|
173969
174012
|
if (promptText.includes(AUTO_SLASH_COMMAND_TAG_OPEN)) {
|
|
173970
174013
|
return;
|
|
173971
174014
|
}
|
|
173972
|
-
const
|
|
174015
|
+
const goalCommand = promptText.trim().match(/^\/goal(?:\s+([\s\S]*))?$/i);
|
|
174016
|
+
if (!goalCommand) {
|
|
174017
|
+
const objective = promptText.trim();
|
|
174018
|
+
if (isFirstMessage && pluginConfig.default_mode?.goal && objective.length > 0 && objective.length <= MAX_OBJECTIVE_LENGTH) {
|
|
174019
|
+
hooks.goal.setGoal(input.sessionID, objective);
|
|
174020
|
+
log2("[chat-message] Default goal auto-started", { sessionID: input.sessionID, objective });
|
|
174021
|
+
}
|
|
174022
|
+
return;
|
|
174023
|
+
}
|
|
174024
|
+
const parsed = parseGoalCommand(goalCommand[1] ?? "");
|
|
173973
174025
|
switch (parsed.kind) {
|
|
173974
174026
|
case "setObjective":
|
|
173975
174027
|
hooks.goal.setGoal(input.sessionID, parsed.objective);
|
|
@@ -173993,13 +174045,6 @@ function handleGoalMessage(args) {
|
|
|
173993
174045
|
default:
|
|
173994
174046
|
break;
|
|
173995
174047
|
}
|
|
173996
|
-
if (parsed.kind === "show" && isFirstMessage && pluginConfig.default_mode?.goal) {
|
|
173997
|
-
const objective = promptText.trim();
|
|
173998
|
-
if (objective.length > 0) {
|
|
173999
|
-
hooks.goal.setGoal(input.sessionID, objective);
|
|
174000
|
-
log2("[chat-message] Default goal auto-started", { sessionID: input.sessionID, objective });
|
|
174001
|
-
}
|
|
174002
|
-
}
|
|
174003
174048
|
}
|
|
174004
174049
|
|
|
174005
174050
|
// packages/omo-opencode/src/plugin/chat-message/model-cache-warning.ts
|
|
@@ -174224,6 +174269,7 @@ function createChatMessageHandler3(args) {
|
|
|
174224
174269
|
if (input.agent) {
|
|
174225
174270
|
updateSessionAgent(input.sessionID, input.agent);
|
|
174226
174271
|
}
|
|
174272
|
+
const originalPromptText = extractPromptText5(output.parts);
|
|
174227
174273
|
const slashCommand = detectSlashCommand(extractPromptText3(output.parts));
|
|
174228
174274
|
if (slashCommand?.command === "stop-continuation") {
|
|
174229
174275
|
stopContinuation({
|
|
@@ -174254,7 +174300,8 @@ function createChatMessageHandler3(args) {
|
|
|
174254
174300
|
output,
|
|
174255
174301
|
isFirstMessage,
|
|
174256
174302
|
pluginConfig,
|
|
174257
|
-
nativeGoalCommand
|
|
174303
|
+
nativeGoalCommand,
|
|
174304
|
+
originalPromptText
|
|
174258
174305
|
});
|
|
174259
174306
|
await applyUltraworkModelOverrideOnMessage(pluginConfig, input.agent, output, pluginContext.client.tui, input.sessionID, pluginContext.client);
|
|
174260
174307
|
};
|
package/dist/shared/index.d.ts
CHANGED
|
@@ -78,5 +78,4 @@ export * from "./legacy-workspace-migration";
|
|
|
78
78
|
export * from "./task-system-enabled";
|
|
79
79
|
export * from "./parse-tools-config";
|
|
80
80
|
export { parseModelString } from "./model-string-parser";
|
|
81
|
-
export { EXCLUDED_DIRS } from "./excluded-dirs";
|
|
82
81
|
export * from "./replace-tool-args";
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
export declare const LIVE_ROUTE_DISPATCH_LOG = "[live-server-route] dispatch via live listener";
|
|
2
|
-
export declare const LIVE_ROUTE_UNAVAILABLE_LOG = "[live-server-route] route unavailable; using in-process client";
|
|
3
1
|
type RouteResult = {
|
|
4
2
|
client: unknown;
|
|
5
3
|
route: "live" | "in-process";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { createServerHealthState,
|
|
1
|
+
export { createServerHealthState, isServerRunning, markServerRunningInProcess, resetServerCheck, } from "@oh-my-opencode/tmux-core";
|
|
2
2
|
export type { ServerHealthState } from "@oh-my-opencode/tmux-core";
|
|
@@ -73,7 +73,7 @@ Each phase has exactly one reference. Read it as you enter the phase — not in
|
|
|
73
73
|
| 4 | **Oracle Triple** — after 2 consecutive failed rounds, spawn three Oracles with orthogonal framings and synthesize | [references/methodology/04-oracle-triple.md](references/methodology/04-oracle-triple.md) |
|
|
74
74
|
| 5 | **User decision escalation** — only when evidence exhausted and the call has policy implications | [references/methodology/05-escalate.md](references/methodology/05-escalate.md) |
|
|
75
75
|
| 6 | **Root cause confirmation** — confirmed only when toggling the suspected cause toggles the bug | [references/methodology/06-fix.md](references/methodology/06-fix.md) |
|
|
76
|
-
| 7 | **
|
|
76
|
+
| 7 | **Fix locked by a failing proof** — reuse the owner test that already fails or add one regression that fails on the pre-fix code, minimal green, no scope expansion | [references/methodology/06-fix.md](references/methodology/06-fix.md) |
|
|
77
77
|
| 8 | **Manual QA** — actually use the system (tmux for CLI, Playwright for browser, real curl for API, real repro for binary) | [references/methodology/08-qa.md](references/methodology/08-qa.md) |
|
|
78
78
|
| 9 | **Cleanup** — walk the journal, revert every artifact, verify `git diff` shows only fix + test | [references/methodology/09-cleanup.md](references/methodology/09-cleanup.md) |
|
|
79
79
|
| 10 | **Final verification** — four evidence gates before declaring done | [references/methodology/09-cleanup.md](references/methodology/09-cleanup.md) |
|
|
@@ -51,6 +51,14 @@ The "mechanism" field is the acid test. If you can't write the causal chain from
|
|
|
51
51
|
|
|
52
52
|
Red, green, refactor. No shortcuts.
|
|
53
53
|
|
|
54
|
+
### 0. Look for the owner test first
|
|
55
|
+
|
|
56
|
+
Before writing a reproduction test, find the test that already owns this contract at the strongest boundary. Run it on the pre-fix code:
|
|
57
|
+
|
|
58
|
+
- **It already fails for this bug.** It is the red proof. Record its failure and skip step 1.
|
|
59
|
+
- **It passes but covers the path.** Extend it with the failing case (a table row, a fixture case) instead of adding a parallel test.
|
|
60
|
+
- **No owner exists.** Write the new reproduction test in step 1, and apply the repository's test-authoring gate if it has one.
|
|
61
|
+
|
|
54
62
|
### 1. Red — the reproduction as a test
|
|
55
63
|
|
|
56
64
|
Write a test that fails *specifically because of this bug*. Requirements:
|
package/dist/tui.js
CHANGED
|
@@ -3517,7 +3517,7 @@ var init_category_model_requirements = __esm(() => {
|
|
|
3517
3517
|
{
|
|
3518
3518
|
providers: ["openai", "chatgpt-subscription", "github-copilot", "opencode"],
|
|
3519
3519
|
model: "gpt-6-astra",
|
|
3520
|
-
variant: "
|
|
3520
|
+
variant: "high"
|
|
3521
3521
|
}
|
|
3522
3522
|
]
|
|
3523
3523
|
},
|
|
@@ -5319,7 +5319,7 @@ var init_openai_categories = __esm(() => {
|
|
|
5319
5319
|
},
|
|
5320
5320
|
{
|
|
5321
5321
|
name: "deep-high",
|
|
5322
|
-
config: { model: "openai/gpt-6-astra", variant: "
|
|
5322
|
+
config: { model: "openai/gpt-6-astra", variant: "high" },
|
|
5323
5323
|
description: "Escalation deep lane: a goal whose central decision cannot be settled from evidence alone. Same one-goal, one-deliverable contract as deep-low.",
|
|
5324
5324
|
callerGuidance: DEEP_HIGH_CATEGORY_CALLER_GUIDANCE,
|
|
5325
5325
|
promptAppend: DEEP_HIGH_CATEGORY_PROMPT_APPEND,
|
|
@@ -63514,28 +63514,6 @@ var init_legacy_workspace_migration = __esm(() => {
|
|
|
63514
63514
|
// packages/omo-opencode/src/shared/model-string-parser.ts
|
|
63515
63515
|
var init_model_string_parser2 = () => {};
|
|
63516
63516
|
|
|
63517
|
-
// packages/omo-opencode/src/shared/excluded-dirs.ts
|
|
63518
|
-
var EXCLUDED_DIR_NAMES, EXCLUDED_DIRS;
|
|
63519
|
-
var init_excluded_dirs = __esm(() => {
|
|
63520
|
-
EXCLUDED_DIR_NAMES = [
|
|
63521
|
-
"node_modules",
|
|
63522
|
-
".git",
|
|
63523
|
-
"dist",
|
|
63524
|
-
"build",
|
|
63525
|
-
".next",
|
|
63526
|
-
".omo",
|
|
63527
|
-
".sisyphus",
|
|
63528
|
-
".turbo",
|
|
63529
|
-
"coverage",
|
|
63530
|
-
"out",
|
|
63531
|
-
".cache",
|
|
63532
|
-
".vscode-test",
|
|
63533
|
-
"target",
|
|
63534
|
-
".local-ignore"
|
|
63535
|
-
];
|
|
63536
|
-
EXCLUDED_DIRS = Object.freeze(new Set(EXCLUDED_DIR_NAMES));
|
|
63537
|
-
});
|
|
63538
|
-
|
|
63539
63517
|
// packages/omo-opencode/src/shared/replace-tool-args.ts
|
|
63540
63518
|
var init_replace_tool_args = () => {};
|
|
63541
63519
|
|
|
@@ -63546,7 +63524,6 @@ var init_shared = __esm(() => {
|
|
|
63546
63524
|
init_model_resolution_pipeline();
|
|
63547
63525
|
init_session_category_registry();
|
|
63548
63526
|
init_model_string_parser2();
|
|
63549
|
-
init_excluded_dirs();
|
|
63550
63527
|
init_frontmatter2();
|
|
63551
63528
|
init_command_executor2();
|
|
63552
63529
|
init_contains_path2();
|
|
@@ -69930,7 +69907,8 @@ var init_memory = __esm(() => {
|
|
|
69930
69907
|
event_caps: OmoMemoryRecallEventCapsSchema.default({ tool_args: 400, result_head: 600, assistant: 1500, prompt: 4000 }),
|
|
69931
69908
|
sidecar_max_tokens: number2().int().positive().default(48000),
|
|
69932
69909
|
max_concurrent_wakes: number2().int().positive().default(2),
|
|
69933
|
-
tool_budget: number2().int().positive().default(8)
|
|
69910
|
+
tool_budget: number2().int().positive().default(8),
|
|
69911
|
+
query_expansion: boolean2().default(false)
|
|
69934
69912
|
}).strict();
|
|
69935
69913
|
OmoMemoryNudgeSchema = object({
|
|
69936
69914
|
enabled: boolean2().default(true),
|
|
@@ -69991,7 +69969,8 @@ var init_memory = __esm(() => {
|
|
|
69991
69969
|
event_caps: OmoMemoryRecallEventCapsLayerSchema.optional(),
|
|
69992
69970
|
sidecar_max_tokens: number2().int().positive().optional(),
|
|
69993
69971
|
max_concurrent_wakes: number2().int().positive().optional(),
|
|
69994
|
-
tool_budget: number2().int().positive().optional()
|
|
69972
|
+
tool_budget: number2().int().positive().optional(),
|
|
69973
|
+
query_expansion: boolean2().optional()
|
|
69995
69974
|
}).strict();
|
|
69996
69975
|
OmoMemoryNudgeLayerSchema = object({
|
|
69997
69976
|
enabled: boolean2().optional(),
|
|
@@ -70068,7 +70047,8 @@ var init_memory = __esm(() => {
|
|
|
70068
70047
|
event_caps: { tool_args: 400, result_head: 600, assistant: 1500, prompt: 4000 },
|
|
70069
70048
|
sidecar_max_tokens: 48000,
|
|
70070
70049
|
max_concurrent_wakes: 2,
|
|
70071
|
-
tool_budget: 8
|
|
70050
|
+
tool_budget: 8,
|
|
70051
|
+
query_expansion: false
|
|
70072
70052
|
}),
|
|
70073
70053
|
compile_warn_tokens: number2().int().positive().default(30000),
|
|
70074
70054
|
agents: record(string2(), OmoMemoryAgentOverridesSchema).default({})
|
|
@@ -74617,7 +74597,7 @@ init_shared();
|
|
|
74617
74597
|
// package.json
|
|
74618
74598
|
var package_default = {
|
|
74619
74599
|
name: "oh-my-opencode",
|
|
74620
|
-
version: "5.1.
|
|
74600
|
+
version: "5.1.8",
|
|
74621
74601
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
74622
74602
|
main: "./dist/index.js",
|
|
74623
74603
|
types: "dist/index.d.ts",
|
|
@@ -74794,7 +74774,7 @@ var package_default = {
|
|
|
74794
74774
|
},
|
|
74795
74775
|
devDependencies: {
|
|
74796
74776
|
"@clack/prompts": "^1.8.1",
|
|
74797
|
-
"@code-yeongyu/senpi": "2026.
|
|
74777
|
+
"@code-yeongyu/senpi": "2026.10.1-2",
|
|
74798
74778
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
74799
74779
|
"@oh-my-opencode/agents-md-core": "workspace:*",
|
|
74800
74780
|
"@oh-my-opencode/ast-grep-mcp": "workspace:*",
|
|
@@ -74852,18 +74832,18 @@ var package_default = {
|
|
|
74852
74832
|
typescript: "^7.0.2"
|
|
74853
74833
|
},
|
|
74854
74834
|
optionalDependencies: {
|
|
74855
|
-
"oh-my-opencode-darwin-arm64": "5.1.
|
|
74856
|
-
"oh-my-opencode-darwin-x64": "5.1.
|
|
74857
|
-
"oh-my-opencode-darwin-x64-baseline": "5.1.
|
|
74858
|
-
"oh-my-opencode-linux-arm64": "5.1.
|
|
74859
|
-
"oh-my-opencode-linux-arm64-musl": "5.1.
|
|
74860
|
-
"oh-my-opencode-linux-x64": "5.1.
|
|
74861
|
-
"oh-my-opencode-linux-x64-baseline": "5.1.
|
|
74862
|
-
"oh-my-opencode-linux-x64-musl": "5.1.
|
|
74863
|
-
"oh-my-opencode-linux-x64-musl-baseline": "5.1.
|
|
74864
|
-
"oh-my-opencode-windows-arm64": "5.1.
|
|
74865
|
-
"oh-my-opencode-windows-x64": "5.1.
|
|
74866
|
-
"oh-my-opencode-windows-x64-baseline": "5.1.
|
|
74835
|
+
"oh-my-opencode-darwin-arm64": "5.1.8",
|
|
74836
|
+
"oh-my-opencode-darwin-x64": "5.1.8",
|
|
74837
|
+
"oh-my-opencode-darwin-x64-baseline": "5.1.8",
|
|
74838
|
+
"oh-my-opencode-linux-arm64": "5.1.8",
|
|
74839
|
+
"oh-my-opencode-linux-arm64-musl": "5.1.8",
|
|
74840
|
+
"oh-my-opencode-linux-x64": "5.1.8",
|
|
74841
|
+
"oh-my-opencode-linux-x64-baseline": "5.1.8",
|
|
74842
|
+
"oh-my-opencode-linux-x64-musl": "5.1.8",
|
|
74843
|
+
"oh-my-opencode-linux-x64-musl-baseline": "5.1.8",
|
|
74844
|
+
"oh-my-opencode-windows-arm64": "5.1.8",
|
|
74845
|
+
"oh-my-opencode-windows-x64": "5.1.8",
|
|
74846
|
+
"oh-my-opencode-windows-x64-baseline": "5.1.8"
|
|
74867
74847
|
},
|
|
74868
74848
|
overrides: {
|
|
74869
74849
|
hono: "^4.13.8",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oh-my-opencode",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.8",
|
|
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",
|
|
@@ -177,7 +177,7 @@
|
|
|
177
177
|
},
|
|
178
178
|
"devDependencies": {
|
|
179
179
|
"@clack/prompts": "^1.8.1",
|
|
180
|
-
"@code-yeongyu/senpi": "2026.
|
|
180
|
+
"@code-yeongyu/senpi": "2026.10.1-2",
|
|
181
181
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
182
182
|
"@oh-my-opencode/agents-md-core": "workspace:*",
|
|
183
183
|
"@oh-my-opencode/ast-grep-mcp": "workspace:*",
|
|
@@ -235,18 +235,18 @@
|
|
|
235
235
|
"typescript": "^7.0.2"
|
|
236
236
|
},
|
|
237
237
|
"optionalDependencies": {
|
|
238
|
-
"oh-my-opencode-darwin-arm64": "5.1.
|
|
239
|
-
"oh-my-opencode-darwin-x64": "5.1.
|
|
240
|
-
"oh-my-opencode-darwin-x64-baseline": "5.1.
|
|
241
|
-
"oh-my-opencode-linux-arm64": "5.1.
|
|
242
|
-
"oh-my-opencode-linux-arm64-musl": "5.1.
|
|
243
|
-
"oh-my-opencode-linux-x64": "5.1.
|
|
244
|
-
"oh-my-opencode-linux-x64-baseline": "5.1.
|
|
245
|
-
"oh-my-opencode-linux-x64-musl": "5.1.
|
|
246
|
-
"oh-my-opencode-linux-x64-musl-baseline": "5.1.
|
|
247
|
-
"oh-my-opencode-windows-arm64": "5.1.
|
|
248
|
-
"oh-my-opencode-windows-x64": "5.1.
|
|
249
|
-
"oh-my-opencode-windows-x64-baseline": "5.1.
|
|
238
|
+
"oh-my-opencode-darwin-arm64": "5.1.8",
|
|
239
|
+
"oh-my-opencode-darwin-x64": "5.1.8",
|
|
240
|
+
"oh-my-opencode-darwin-x64-baseline": "5.1.8",
|
|
241
|
+
"oh-my-opencode-linux-arm64": "5.1.8",
|
|
242
|
+
"oh-my-opencode-linux-arm64-musl": "5.1.8",
|
|
243
|
+
"oh-my-opencode-linux-x64": "5.1.8",
|
|
244
|
+
"oh-my-opencode-linux-x64-baseline": "5.1.8",
|
|
245
|
+
"oh-my-opencode-linux-x64-musl": "5.1.8",
|
|
246
|
+
"oh-my-opencode-linux-x64-musl-baseline": "5.1.8",
|
|
247
|
+
"oh-my-opencode-windows-arm64": "5.1.8",
|
|
248
|
+
"oh-my-opencode-windows-x64": "5.1.8",
|
|
249
|
+
"oh-my-opencode-windows-x64-baseline": "5.1.8"
|
|
250
250
|
},
|
|
251
251
|
"overrides": {
|
|
252
252
|
"hono": "^4.13.8",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { tmpdir } from "node:os";
|
|
1
|
+
import { homedir, tmpdir } from "node:os";
|
|
2
2
|
import { dirname, resolve } from "node:path";
|
|
3
3
|
|
|
4
4
|
import { nearestMarkedAncestor } from "../lsp/outside-context-workspace.js";
|
|
@@ -11,6 +11,8 @@ export interface PostEditFileLocationOptions {
|
|
|
11
11
|
readonly agentDirs: readonly string[];
|
|
12
12
|
/** Temp roots; defaults to the canonical OS temp dir (plus `/tmp` off Windows). */
|
|
13
13
|
readonly tempDirs?: readonly string[];
|
|
14
|
+
/** Home dirs that never count as a project root themselves; defaults to the OS home dir. */
|
|
15
|
+
readonly homeDirs?: readonly string[];
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
/**
|
|
@@ -19,6 +21,8 @@ export interface PostEditFileLocationOptions {
|
|
|
19
21
|
* A project root is the nearest ancestor carrying one of lsp-core's `WORKSPACE_MARKERS` (the marker set the
|
|
20
22
|
* out-of-cwd workspace resolver uses). Inside a temp dir, only a marked root strictly below the temp root
|
|
21
23
|
* counts, so a stray `package.json` left in the temp root does not turn every scratch file into a project.
|
|
24
|
+
* The home dir is never a project root either: a dotfiles `.git` or stray `~/package.json` there does not make
|
|
25
|
+
* every home-level file a project, while a marked project below home still is one.
|
|
22
26
|
* Paths are canonicalized first because macOS `/tmp` and `/var` are symlinks.
|
|
23
27
|
*/
|
|
24
28
|
export function classifyPostEditFileLocation(
|
|
@@ -38,7 +42,8 @@ export function classifyPostEditFileLocation(
|
|
|
38
42
|
const ownProject = projectRoot !== undefined && projectRoot !== tempRoot && isPathInside(tempRoot, projectRoot);
|
|
39
43
|
return ownProject ? "project" : "temp";
|
|
40
44
|
}
|
|
41
|
-
|
|
45
|
+
if (projectRoot === undefined) return "outside_project";
|
|
46
|
+
return canonicalDirectories(options.homeDirs ?? [homedir()]).includes(projectRoot) ? "outside_project" : "project";
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
function defaultTempDirectories(): readonly string[] {
|
|
@@ -93,6 +93,31 @@ describe("classifyPostEditFileLocation", () => {
|
|
|
93
93
|
}
|
|
94
94
|
});
|
|
95
95
|
|
|
96
|
+
for (const marker of ["package.json", ".git"] as const) {
|
|
97
|
+
it(`#given a ${marker} directly in HOME #when a home-level file is classified #then HOME is not its project`, () => {
|
|
98
|
+
const home = tempRoot("lsp-postedit-home-");
|
|
99
|
+
if (marker === ".git") mkdirSync(join(home, ".git"));
|
|
100
|
+
else touch(join(home, marker), "{}\n");
|
|
101
|
+
const topLevel = touch(join(home, "notes.ts"));
|
|
102
|
+
const nested = touch(join(home, "scratch", "draft.ts"));
|
|
103
|
+
|
|
104
|
+
const options = { cwd: home, agentDirs: [], tempDirs: [], homeDirs: [home] };
|
|
105
|
+
expect(classifyPostEditFileLocation(topLevel, options)).toBe("outside_project");
|
|
106
|
+
expect(classifyPostEditFileLocation(nested, options)).toBe("outside_project");
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
it("#given a marked HOME and a project under it #when a project file is classified #then it is still a project", () => {
|
|
111
|
+
const home = tempRoot("lsp-postedit-homeproject-");
|
|
112
|
+
mkdirSync(join(home, ".git"));
|
|
113
|
+
touch(join(home, "work", "app", "package.json"), "{}\n");
|
|
114
|
+
const file = touch(join(home, "work", "app", "src", "a.ts"));
|
|
115
|
+
|
|
116
|
+
expect(classifyPostEditFileLocation(file, { cwd: home, agentDirs: [], tempDirs: [], homeDirs: [home] })).toBe(
|
|
117
|
+
"project",
|
|
118
|
+
);
|
|
119
|
+
});
|
|
120
|
+
|
|
96
121
|
it("#given a project with its own marker inside a temp dir #when classified #then it is a project", () => {
|
|
97
122
|
const temp = tempRoot("lsp-postedit-tempproject-");
|
|
98
123
|
const project = join(temp, "checkout");
|