oh-my-opencode 5.0.0-beta.30 → 5.0.0-beta.31
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 +75 -26
- package/dist/cli-node/index.js +75 -26
- package/dist/config/schema/background-task.d.ts +1 -0
- package/dist/config/schema/oh-my-opencode-config.d.ts +1 -0
- package/dist/features/background-agent/constants.d.ts +0 -7
- package/dist/features/background-agent/manager.d.ts +2 -1
- package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
- package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
- package/dist/features/task-toast-manager/manager.d.ts +0 -24
- package/dist/hooks/anthropic-context-window-limit-recovery/message-storage-directory.d.ts +0 -3
- package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +1 -0
- package/dist/hooks/anthropic-context-window-limit-recovery/storage/empty-messages.d.ts +0 -1
- package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
- package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
- package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
- package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
- package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
- package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
- package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
- package/dist/hooks/keyword-detector/hook.d.ts +7 -0
- package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
- package/dist/hooks/model-fallback/hook.d.ts +1 -1
- package/dist/index.js +439 -218
- package/dist/oh-my-opencode.schema.json +5 -0
- package/dist/plugin-dispose.d.ts +3 -0
- package/dist/shared/agent-tool-restrictions.d.ts +0 -1
- package/dist/tools/delegate-task/sync-session-cleanup.d.ts +3 -0
- package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
- package/dist/tools/delegate-task/types.d.ts +1 -0
- package/dist/tui.js +56 -3
- package/package.json +15 -15
- package/packages/git-bash-mcp/dist/cli.js +1 -0
- package/packages/lsp-core/src/lsp/client-wrapper.test.ts +97 -0
- package/packages/lsp-core/src/lsp/client-wrapper.ts +21 -6
- package/packages/lsp-core/src/lsp/constants.ts +5 -0
- package/packages/lsp-core/src/lsp/errors.ts +15 -0
- package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
- package/packages/lsp-core/src/lsp/manager.ts +106 -13
- package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -1
- package/packages/lsp-core/src/mcp.ts +3 -0
- package/packages/lsp-daemon/dist/cli.js +114 -18
- package/packages/lsp-daemon/dist/client.js +114 -18
- package/packages/lsp-daemon/dist/index.js +114 -18
- package/packages/lsp-daemon/dist/proxy.js +3 -0
- package/packages/lsp-tools-mcp/dist/cli.js +114 -18
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +93 -12
- package/packages/lsp-tools-mcp/dist/mcp.js +114 -18
- package/packages/lsp-tools-mcp/dist/tools.js +113 -18
- 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/dist/cli.js +31 -2
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +31 -2
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +12 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable-idle.test.ts +47 -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 +3 -3
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +113 -18
- 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/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-execute-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +100 -54
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +9 -6
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +7 -10
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +3 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +15 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +50 -0
- 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/components/ulw-loop/src/checkpoint.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +16 -5
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +11 -14
- package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +3 -2
- package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +73 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +44 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +25 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +7 -3
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +45 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +20 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -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-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-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-checking-ulw-execute-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/scripts/install-dist/install-local.mjs +2 -2
- package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
- package/dist/hooks/ralph-loop/loop-session-recovery.d.ts +0 -7
- package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
- package/dist/tools/delegate-task/model-string-parser.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
- package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
|
@@ -9233,6 +9233,11 @@
|
|
|
9233
9233
|
"minimum": 1,
|
|
9234
9234
|
"maximum": 9007199254740991
|
|
9235
9235
|
},
|
|
9236
|
+
"maxLiveDescendantsPerRoot": {
|
|
9237
|
+
"type": "integer",
|
|
9238
|
+
"minimum": 0,
|
|
9239
|
+
"maximum": 9007199254740991
|
|
9240
|
+
},
|
|
9236
9241
|
"staleTimeoutMs": {
|
|
9237
9242
|
"type": "number",
|
|
9238
9243
|
"minimum": 60000
|
package/dist/plugin-dispose.d.ts
CHANGED
|
@@ -2,5 +2,4 @@ type AgentToolRestrictionsOptions = {
|
|
|
2
2
|
includeTeamToolDenylist?: boolean;
|
|
3
3
|
};
|
|
4
4
|
export declare function getAgentToolRestrictions(agentName: string, options?: AgentToolRestrictionsOptions): Record<string, boolean>;
|
|
5
|
-
export declare function hasAgentToolRestrictions(agentName: string): boolean;
|
|
6
5
|
export {};
|
|
@@ -8,6 +8,7 @@ export declare function pollSyncSession(ctx: ToolContextWithMetadata, client: Op
|
|
|
8
8
|
} | null | undefined;
|
|
9
9
|
taskId: string | undefined;
|
|
10
10
|
anchorMessageCount?: number;
|
|
11
|
+
anchorMessageID?: string;
|
|
11
12
|
maxAssistantTurns?: number;
|
|
12
13
|
hasActiveChildBackgroundTasks?: (sessionID: string) => boolean;
|
|
13
14
|
hasPendingParentWake?: (sessionID: string) => boolean;
|
|
@@ -46,6 +46,7 @@ export interface OmoAgentClient {
|
|
|
46
46
|
};
|
|
47
47
|
readonly session: {
|
|
48
48
|
readonly abort: (input: SessionPathInput) => Promise<unknown>;
|
|
49
|
+
readonly delete?: (input: SessionPathInput) => Promise<unknown>;
|
|
49
50
|
readonly create: (input: {
|
|
50
51
|
readonly body: Record<string, unknown>;
|
|
51
52
|
readonly query?: {
|
package/dist/tui.js
CHANGED
|
@@ -17156,7 +17156,7 @@ var init_git_master = __esm(() => {
|
|
|
17156
17156
|
});
|
|
17157
17157
|
|
|
17158
17158
|
// packages/omo-config-core/src/schema/memory.ts
|
|
17159
|
-
var OmoMemoryReflectionTriggerSchema, OmoMemoryReflectionSchema, OmoMemorySyncSchema, OmoMemorySearchSchema, OmoMemoryNudgeSchema, OmoMemoryFactsSchema, OmoMemoryDreamSchema, OmoMemoryPeopleSchema, OmoMemorySoulSchema, OmoMemoryWriteNoticeSchema, OmoMemoryReflectionTriggerLayerSchema, OmoMemoryReflectionLayerSchema, OmoMemorySyncLayerSchema, OmoMemorySearchLayerSchema, OmoMemoryNudgeLayerSchema, OmoMemoryFactsLayerSchema, OmoMemoryDreamLayerSchema, OmoMemoryPeopleLayerSchema, OmoMemorySoulLayerSchema, OmoMemoryWriteNoticeLayerSchema, OmoMemoryAgentOverridesSchema, OmoMemorySettingsSchema, OmoMemorySettingsLayerSchema;
|
|
17159
|
+
var OmoMemoryReflectionTriggerSchema, OmoMemoryReflectionSchema, OmoMemorySyncSchema, OmoMemorySearchSchema, OmoMemoryRecallSchema, OmoMemoryNudgeSchema, OmoMemoryFactsSchema, OmoMemoryDreamSchema, OmoMemoryPeopleSchema, OmoMemorySoulSchema, OmoMemoryWriteNoticeSchema, OmoMemoryReflectionTriggerLayerSchema, OmoMemoryReflectionLayerSchema, OmoMemorySyncLayerSchema, OmoMemorySearchLayerSchema, OmoMemoryRecallLayerSchema, OmoMemoryNudgeLayerSchema, OmoMemoryFactsLayerSchema, OmoMemoryDreamLayerSchema, OmoMemoryPeopleLayerSchema, OmoMemorySoulLayerSchema, OmoMemoryWriteNoticeLayerSchema, OmoMemoryAgentOverridesSchema, OmoMemorySettingsSchema, OmoMemorySettingsLayerSchema;
|
|
17160
17160
|
var init_memory = __esm(() => {
|
|
17161
17161
|
init_zod();
|
|
17162
17162
|
OmoMemoryReflectionTriggerSchema = object({
|
|
@@ -17178,6 +17178,14 @@ var init_memory = __esm(() => {
|
|
|
17178
17178
|
OmoMemorySearchSchema = object({
|
|
17179
17179
|
enabled: boolean2().default(true)
|
|
17180
17180
|
}).strict();
|
|
17181
|
+
OmoMemoryRecallSchema = object({
|
|
17182
|
+
enabled: boolean2().default(true),
|
|
17183
|
+
max_items: number2().int().min(1).max(5).default(2),
|
|
17184
|
+
budget_tokens: number2().int().positive().default(600),
|
|
17185
|
+
excerpt_chars: number2().int().positive().default(200),
|
|
17186
|
+
min_score: number2().optional(),
|
|
17187
|
+
exclude: array(string2()).default([])
|
|
17188
|
+
}).strict();
|
|
17181
17189
|
OmoMemoryNudgeSchema = object({
|
|
17182
17190
|
enabled: boolean2().default(true),
|
|
17183
17191
|
every_user_turns: number2().int().min(1).default(10)
|
|
@@ -17224,6 +17232,14 @@ var init_memory = __esm(() => {
|
|
|
17224
17232
|
OmoMemorySearchLayerSchema = object({
|
|
17225
17233
|
enabled: boolean2().optional()
|
|
17226
17234
|
}).strict();
|
|
17235
|
+
OmoMemoryRecallLayerSchema = object({
|
|
17236
|
+
enabled: boolean2().optional(),
|
|
17237
|
+
max_items: number2().int().min(1).max(5).optional(),
|
|
17238
|
+
budget_tokens: number2().int().positive().optional(),
|
|
17239
|
+
excerpt_chars: number2().int().positive().optional(),
|
|
17240
|
+
min_score: number2().optional(),
|
|
17241
|
+
exclude: array(string2()).optional()
|
|
17242
|
+
}).strict();
|
|
17227
17243
|
OmoMemoryNudgeLayerSchema = object({
|
|
17228
17244
|
enabled: boolean2().optional(),
|
|
17229
17245
|
every_user_turns: number2().int().min(1).optional()
|
|
@@ -17263,6 +17279,7 @@ var init_memory = __esm(() => {
|
|
|
17263
17279
|
write_notice: OmoMemoryWriteNoticeLayerSchema.optional(),
|
|
17264
17280
|
sync: OmoMemorySyncLayerSchema.optional(),
|
|
17265
17281
|
search: OmoMemorySearchLayerSchema.optional(),
|
|
17282
|
+
recall: OmoMemoryRecallLayerSchema.optional(),
|
|
17266
17283
|
compile_warn_tokens: number2().int().positive().optional()
|
|
17267
17284
|
}).strict();
|
|
17268
17285
|
OmoMemorySettingsSchema = object({
|
|
@@ -17292,6 +17309,13 @@ var init_memory = __esm(() => {
|
|
|
17292
17309
|
write_notice: OmoMemoryWriteNoticeSchema.default({ enabled: true }),
|
|
17293
17310
|
sync: OmoMemorySyncSchema.default({ enabled: true }),
|
|
17294
17311
|
search: OmoMemorySearchSchema.default({ enabled: true }),
|
|
17312
|
+
recall: OmoMemoryRecallSchema.default({
|
|
17313
|
+
enabled: true,
|
|
17314
|
+
max_items: 2,
|
|
17315
|
+
budget_tokens: 600,
|
|
17316
|
+
excerpt_chars: 200,
|
|
17317
|
+
exclude: []
|
|
17318
|
+
}),
|
|
17295
17319
|
compile_warn_tokens: number2().int().positive().default(30000),
|
|
17296
17320
|
agents: record(string2(), OmoMemoryAgentOverridesSchema).default({})
|
|
17297
17321
|
}).strict();
|
|
@@ -17308,6 +17332,7 @@ var init_memory = __esm(() => {
|
|
|
17308
17332
|
write_notice: OmoMemoryWriteNoticeLayerSchema.optional(),
|
|
17309
17333
|
sync: OmoMemorySyncLayerSchema.optional(),
|
|
17310
17334
|
search: OmoMemorySearchLayerSchema.optional(),
|
|
17335
|
+
recall: OmoMemoryRecallLayerSchema.optional(),
|
|
17311
17336
|
compile_warn_tokens: number2().int().positive().optional(),
|
|
17312
17337
|
agents: record(string2(), OmoMemoryAgentOverridesSchema).optional()
|
|
17313
17338
|
}).strict();
|
|
@@ -17341,11 +17366,11 @@ function resolveOmoTaskSettings(input, resolveParallelism = availableParallelism
|
|
|
17341
17366
|
const record2 = record(string2(), unknown()).parse(input);
|
|
17342
17367
|
return OmoTaskSettingsSchema.parse({
|
|
17343
17368
|
...record2,
|
|
17344
|
-
residency_max_children: record2["residency_max_children"] ?? Math.max(8, resolveParallelism() *
|
|
17369
|
+
residency_max_children: record2["residency_max_children"] ?? Math.min(DEFAULT_RESIDENCY_MAX_CHILDREN, Math.max(8, resolveParallelism() * 2)),
|
|
17345
17370
|
global_concurrency: record2["global_concurrency"] ?? Math.max(8, resolveParallelism() * 2)
|
|
17346
17371
|
});
|
|
17347
17372
|
}
|
|
17348
|
-
var ResidencyMaxChildrenInputSchema, OmoTaskWaitSchema, OmoTaskTeamSettingsSchema, OmoTaskWarningsSchema, OmoTaskDagSettingsSchema, OmoTaskSettingsSchema, OmoTaskDagSettingsLayerSchema, OmoTaskWaitLayerSchema, OmoTaskTeamSettingsLayerSchema, OmoTaskWarningsLayerSchema, OmoTaskSettingsLayerSchema;
|
|
17373
|
+
var DEFAULT_RESIDENCY_MAX_CHILDREN = 16, ResidencyMaxChildrenInputSchema, OmoTaskWaitSchema, OmoTaskTeamSettingsSchema, OmoTaskWarningsSchema, OmoTaskDagSettingsSchema, OmoTaskSettingsSchema, OmoTaskDagSettingsLayerSchema, OmoTaskWaitLayerSchema, OmoTaskTeamSettingsLayerSchema, OmoTaskWarningsLayerSchema, OmoTaskSettingsLayerSchema;
|
|
17349
17374
|
var init_task = __esm(() => {
|
|
17350
17375
|
init_zod();
|
|
17351
17376
|
ResidencyMaxChildrenInputSchema = union([number2().int().nonnegative(), literal("unlimited")]);
|
|
@@ -19367,6 +19392,33 @@ var init_agent_model_requirements = __esm(() => {
|
|
|
19367
19392
|
{ providers: ["opencode-go"], model: "glm-5.2" }
|
|
19368
19393
|
]
|
|
19369
19394
|
},
|
|
19395
|
+
"omo-senpi-code-reviewer": {
|
|
19396
|
+
fallbackChain: [
|
|
19397
|
+
{ providers: ["openai", "openai-codex"], model: "gpt-5.6-terra", variant: "medium" },
|
|
19398
|
+
{ providers: ["github-copilot"], model: "gpt-5.6-terra", variant: "medium" },
|
|
19399
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-6" },
|
|
19400
|
+
{ providers: ["opencode-go"], model: "glm-5.2" },
|
|
19401
|
+
{ providers: ["kimi-for-coding"], model: "kimi-k3" }
|
|
19402
|
+
]
|
|
19403
|
+
},
|
|
19404
|
+
"omo-senpi-qa-executor": {
|
|
19405
|
+
fallbackChain: [
|
|
19406
|
+
{ providers: ["openai", "openai-codex"], model: "gpt-5.6-luna", variant: "high" },
|
|
19407
|
+
{ providers: ["github-copilot"], model: "gpt-5.6-luna", variant: "high" },
|
|
19408
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-4-6" },
|
|
19409
|
+
{ providers: ["opencode-go"], model: "glm-5.2" },
|
|
19410
|
+
{ providers: ["kimi-for-coding"], model: "kimi-k3" }
|
|
19411
|
+
]
|
|
19412
|
+
},
|
|
19413
|
+
"omo-senpi-gate-reviewer": {
|
|
19414
|
+
fallbackChain: [
|
|
19415
|
+
{ providers: ["openai", "openai-codex"], model: "gpt-5.6-sol", variant: "low" },
|
|
19416
|
+
{ providers: ["github-copilot"], model: "gpt-5.6-sol", variant: "low" },
|
|
19417
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-5", variant: "max" },
|
|
19418
|
+
{ providers: ["opencode-go"], model: "glm-5.2" },
|
|
19419
|
+
{ providers: ["kimi-for-coding"], model: "kimi-k3" }
|
|
19420
|
+
]
|
|
19421
|
+
},
|
|
19370
19422
|
atlas: {
|
|
19371
19423
|
fallbackChain: [
|
|
19372
19424
|
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-sonnet-5" },
|
|
@@ -79135,6 +79187,7 @@ var init_background_task = __esm(() => {
|
|
|
79135
79187
|
providerConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(0)).optional(),
|
|
79136
79188
|
modelConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(0)).optional(),
|
|
79137
79189
|
maxDepth: exports_external.number().int().min(1).optional(),
|
|
79190
|
+
maxLiveDescendantsPerRoot: exports_external.number().int().min(0).optional(),
|
|
79138
79191
|
staleTimeoutMs: exports_external.number().min(60000).optional(),
|
|
79139
79192
|
messageStalenessTimeoutMs: exports_external.number().min(60000).optional(),
|
|
79140
79193
|
taskTtlMs: exports_external.number().min(300000).optional(),
|
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.31",
|
|
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.31",
|
|
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.31",
|
|
226
|
+
"oh-my-opencode-darwin-x64": "5.0.0-beta.31",
|
|
227
|
+
"oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.31",
|
|
228
|
+
"oh-my-opencode-linux-arm64": "5.0.0-beta.31",
|
|
229
|
+
"oh-my-opencode-linux-arm64-musl": "5.0.0-beta.31",
|
|
230
|
+
"oh-my-opencode-linux-x64": "5.0.0-beta.31",
|
|
231
|
+
"oh-my-opencode-linux-x64-baseline": "5.0.0-beta.31",
|
|
232
|
+
"oh-my-opencode-linux-x64-musl": "5.0.0-beta.31",
|
|
233
|
+
"oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.31",
|
|
234
|
+
"oh-my-opencode-windows-arm64": "5.0.0-beta.31",
|
|
235
|
+
"oh-my-opencode-windows-x64": "5.0.0-beta.31",
|
|
236
|
+
"oh-my-opencode-windows-x64-baseline": "5.0.0-beta.31"
|
|
237
237
|
},
|
|
238
238
|
"overrides": {
|
|
239
239
|
"@earendil-works/pi-agent-core": "0.84.2",
|
|
@@ -251,6 +251,6 @@
|
|
|
251
251
|
"@code-yeongyu/comment-checker"
|
|
252
252
|
],
|
|
253
253
|
"patchedDependencies": {
|
|
254
|
-
"@code-yeongyu/senpi@2026.8.
|
|
254
|
+
"@code-yeongyu/senpi@2026.8.31": "patches/@code-yeongyu%2Fsenpi@2026.8.31.patch"
|
|
255
255
|
}
|
|
256
256
|
}
|
|
@@ -180,6 +180,7 @@ async function runJsonRpcStdioServer(config) {
|
|
|
180
180
|
const idleTimer = createIdleTimer(idleTimeoutMs, log, () => {
|
|
181
181
|
isClosed = true;
|
|
182
182
|
config.onIdleTimeout?.();
|
|
183
|
+
config.input.destroy();
|
|
183
184
|
});
|
|
184
185
|
const watchdog = createParentWatchdog(config.parentWatchdog, (parentPid, pollIntervalMs) => {
|
|
185
186
|
isClosed = true;
|
|
@@ -4,6 +4,7 @@ import { join } from "node:path";
|
|
|
4
4
|
import { afterEach, describe, expect, it } from "bun:test";
|
|
5
5
|
|
|
6
6
|
import { createStandaloneMcpRequestContext, runWithRequestContext } from "../request-context.js";
|
|
7
|
+
import type { LspClient } from "./client.js";
|
|
7
8
|
import { findWorkspaceRoot, resolveReadablePathInsideContext, withLspClient } from "./client-wrapper.js";
|
|
8
9
|
import { LspInvalidPathError } from "./errors.js";
|
|
9
10
|
import { LspManager } from "./manager.js";
|
|
@@ -22,6 +23,102 @@ function tempRoot(prefix: string): string {
|
|
|
22
23
|
return root;
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
describe("LSP workspace root collapse in monorepos", () => {
|
|
27
|
+
it("#given a git repository containing four package.json packages #when resolving workspace roots for files in each package #then all collapse to the repository root", () => {
|
|
28
|
+
const root = tempRoot("lsp-client-wrapper-monorepo-");
|
|
29
|
+
mkdirSync(join(root, ".git"), { recursive: true });
|
|
30
|
+
const packageDirs = ["alpha", "beta", "gamma", "delta"].map((name) => join(root, "packages", name));
|
|
31
|
+
for (const packageDir of packageDirs) {
|
|
32
|
+
mkdirSync(join(packageDir, "src"), { recursive: true });
|
|
33
|
+
writeFileSync(join(packageDir, "package.json"), "{}\n");
|
|
34
|
+
writeFileSync(join(packageDir, "src", "file.ts"), "export const value = 1;\n");
|
|
35
|
+
}
|
|
36
|
+
const context = createStandaloneMcpRequestContext({ cwd: root });
|
|
37
|
+
|
|
38
|
+
const roots = packageDirs.map((packageDir) =>
|
|
39
|
+
runWithRequestContext(context, () => findWorkspaceRoot(join(packageDir, "src", "file.ts"))),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
expect(new Set(roots).size).toBe(1);
|
|
43
|
+
expect(roots[0]).toBe(realpathSync(root));
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("#given nested package.json markers without any .git #when resolving workspace #then keeps the nearest package root", () => {
|
|
47
|
+
const root = tempRoot("lsp-client-wrapper-nested-");
|
|
48
|
+
const nested = join(root, "parent", "nested");
|
|
49
|
+
mkdirSync(join(nested, "src"), { recursive: true });
|
|
50
|
+
writeFileSync(join(root, "parent", "package.json"), "{}\n");
|
|
51
|
+
writeFileSync(join(nested, "package.json"), "{}\n");
|
|
52
|
+
writeFileSync(join(nested, "src", "file.ts"), "export const value = 1;\n");
|
|
53
|
+
|
|
54
|
+
const workspace = runWithRequestContext(createStandaloneMcpRequestContext({ cwd: root }), () =>
|
|
55
|
+
findWorkspaceRoot(join(nested, "src", "file.ts")),
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
expect(workspace).toBe(realpathSync(nested));
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("#given four monorepo package files under one .git root #when acquiring clients #then one client serves the whole repository", async () => {
|
|
62
|
+
const root = tempRoot("lsp-client-wrapper-oneclient-");
|
|
63
|
+
mkdirSync(join(root, ".git"), { recursive: true });
|
|
64
|
+
const userConfig = join(root, "user-lsp.json");
|
|
65
|
+
writeFileSync(
|
|
66
|
+
userConfig,
|
|
67
|
+
JSON.stringify({ lsp: { monorepoProbe: { command: [process.execPath], extensions: [".monoroot"] } } }),
|
|
68
|
+
);
|
|
69
|
+
const filePaths = ["alpha", "beta", "gamma", "delta"].map((name) => {
|
|
70
|
+
const packageDir = join(root, "packages", name);
|
|
71
|
+
mkdirSync(join(packageDir, "src"), { recursive: true });
|
|
72
|
+
writeFileSync(join(packageDir, "package.json"), "{}\n");
|
|
73
|
+
const filePath = join(packageDir, "src", "probe.monoroot");
|
|
74
|
+
writeFileSync(filePath, "const value = 1;\n");
|
|
75
|
+
return filePath;
|
|
76
|
+
});
|
|
77
|
+
const factoryRoots: string[] = [];
|
|
78
|
+
const manager = new LspManager({
|
|
79
|
+
clientFactory: (workspaceRoot) => {
|
|
80
|
+
factoryRoots.push(workspaceRoot);
|
|
81
|
+
return new StubLspClient() as unknown as LspClient;
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
const context = createStandaloneMcpRequestContext({
|
|
87
|
+
cwd: root,
|
|
88
|
+
env: { LSP_TOOLS_MCP_USER_CONFIG: userConfig },
|
|
89
|
+
});
|
|
90
|
+
await Promise.all(
|
|
91
|
+
filePaths.map((filePath) =>
|
|
92
|
+
runWithRequestContext(context, () =>
|
|
93
|
+
withLspClient(filePath, async () => undefined, "diagnostics", { manager }),
|
|
94
|
+
),
|
|
95
|
+
),
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
expect(factoryRoots).toEqual([realpathSync(root)]);
|
|
99
|
+
expect(manager.clientCount()).toBe(1);
|
|
100
|
+
} finally {
|
|
101
|
+
await manager.stopAll();
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
class StubLspClient {
|
|
107
|
+
async start(): Promise<void> {}
|
|
108
|
+
|
|
109
|
+
async initialize(): Promise<void> {}
|
|
110
|
+
|
|
111
|
+
isAlive(): boolean {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
command(): string[] {
|
|
116
|
+
return [process.execPath];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async stop(): Promise<void> {}
|
|
120
|
+
}
|
|
121
|
+
|
|
25
122
|
describe("LSP client path confinement", () => {
|
|
26
123
|
it("#given a relative file inside context cwd #when resolving workspace #then marker search stays inside cwd", () => {
|
|
27
124
|
const root = tempRoot("lsp-client-wrapper-root-");
|
|
@@ -21,7 +21,7 @@ import { LSP_LOCAL_INSTALL_HINTS } from "./server-definitions.js";
|
|
|
21
21
|
import { loadInstallDecision } from "./server-install-state.js";
|
|
22
22
|
import { findServerForExtension } from "./server-resolution.js";
|
|
23
23
|
import type { ServerLookupResult } from "./types.js";
|
|
24
|
-
import {
|
|
24
|
+
import { GIT_WORKSPACE_MARKER, PROJECT_WORKSPACE_MARKERS } from "./workspace-markers.js";
|
|
25
25
|
|
|
26
26
|
export function isDirectoryPath(filePath: string): boolean {
|
|
27
27
|
try {
|
|
@@ -31,6 +31,15 @@ export function isDirectoryPath(filePath: string): boolean {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Resolves the workspace root for a file inside the request cwd.
|
|
36
|
+
*
|
|
37
|
+
* A `.git`-containing ancestor always wins over nearer package markers, so all packages of a
|
|
38
|
+
* monorepo share one workspace root (one resident client per repository instead of one per
|
|
39
|
+
* package, which multiplies language-server processes by the package count). The nearest
|
|
40
|
+
* package-marked directory is remembered while walking and used only when no `.git` ancestor
|
|
41
|
+
* exists within the request cwd.
|
|
42
|
+
*/
|
|
34
43
|
export function findWorkspaceRoot(filePath: string): string {
|
|
35
44
|
const cwd = contextCwd();
|
|
36
45
|
const abs = resolveReadablePathInsideContext(filePath);
|
|
@@ -43,20 +52,26 @@ export function findWorkspaceRoot(filePath: string): string {
|
|
|
43
52
|
if (!isPathInside(cwd, abs)) return findWorkspaceRootOutsideContext(dir);
|
|
44
53
|
|
|
45
54
|
const fallbackRoot = nearestExistingDirectoryInsideContext(dir, cwd) ?? cwd;
|
|
55
|
+
let nearestPackageRoot: string | undefined;
|
|
46
56
|
while (isPathInside(cwd, dir)) {
|
|
47
57
|
const canonicalDir = existingDirectoryInsideContext(dir, cwd);
|
|
48
58
|
if (canonicalDir !== undefined) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
if (existsSync(join(dir, GIT_WORKSPACE_MARKER))) {
|
|
60
|
+
return canonicalDir;
|
|
61
|
+
}
|
|
62
|
+
if (nearestPackageRoot === undefined && hasProjectWorkspaceMarker(dir)) {
|
|
63
|
+
nearestPackageRoot = canonicalDir;
|
|
53
64
|
}
|
|
54
65
|
}
|
|
55
66
|
if (dir === cwd) break;
|
|
56
67
|
dir = dirname(dir);
|
|
57
68
|
}
|
|
58
69
|
|
|
59
|
-
return fallbackRoot;
|
|
70
|
+
return nearestPackageRoot ?? fallbackRoot;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function hasProjectWorkspaceMarker(directory: string): boolean {
|
|
74
|
+
return PROJECT_WORKSPACE_MARKERS.some((marker) => existsSync(join(directory, marker)));
|
|
60
75
|
}
|
|
61
76
|
|
|
62
77
|
export function resolveReadablePathInsideContext(filePath: string): string {
|
|
@@ -10,3 +10,8 @@ export const MAX_RESIDENT_CLIENTS = 6;
|
|
|
10
10
|
export const REAPER_INTERVAL_MS = 60_000;
|
|
11
11
|
export const STOP_HARD_KILL_TIMEOUT_MS = 5_000;
|
|
12
12
|
export const STOP_SIGKILL_GRACE_MS = 1_000;
|
|
13
|
+
|
|
14
|
+
/** Max consecutive dead client generations respawned for one key before admission is blocked. */
|
|
15
|
+
export const CLIENT_RESPAWN_RETRY_LIMIT = 2;
|
|
16
|
+
/** How long a spent respawn budget blocks admission before a fresh attempt window opens. */
|
|
17
|
+
export const CLIENT_RESPAWN_COOLDOWN_MS = 60_000;
|
|
@@ -69,6 +69,21 @@ export class LspProcessSpawnError extends Error {
|
|
|
69
69
|
override readonly name = "LspProcessSpawnError";
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
export class LspClientRespawnBudgetExceededError extends Error {
|
|
73
|
+
override readonly name = "LspClientRespawnBudgetExceededError";
|
|
74
|
+
|
|
75
|
+
constructor(
|
|
76
|
+
readonly serverId: string,
|
|
77
|
+
readonly root: string,
|
|
78
|
+
readonly retryLimit: number,
|
|
79
|
+
) {
|
|
80
|
+
super(
|
|
81
|
+
`LSP server ${serverId} at ${root} failed to stay alive; respawn budget exhausted ` +
|
|
82
|
+
`(${retryLimit} consecutive dead generations). Retrying after the cooldown may succeed.`,
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
72
87
|
export function isLspDeadConnectionError(err: unknown): err is LspConnectionClosedError | LspProcessExitedError {
|
|
73
88
|
return err instanceof LspConnectionClosedError || err instanceof LspProcessExitedError;
|
|
74
89
|
}
|