oh-my-opencode 5.1.3 → 5.1.4

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.
Files changed (73) hide show
  1. package/dist/cli/index.js +149 -19
  2. package/dist/cli-node/index.js +149 -19
  3. package/dist/index.js +148 -18
  4. package/dist/skills/browser/runtime/omowright/manifest.json +1 -1
  5. package/dist/tui.js +148 -18
  6. package/package.json +14 -14
  7. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +1 -1
  8. package/packages/lsp-core/src/missing-dependency-result.test.ts +32 -2
  9. package/packages/lsp-core/src/missing-dependency-result.ts +3 -0
  10. package/packages/lsp-core/src/post-edit/file-location.ts +50 -0
  11. package/packages/lsp-core/src/post-edit/index.ts +2 -0
  12. package/packages/lsp-core/src/post-edit/not-installed-guidance.ts +36 -0
  13. package/packages/lsp-core/src/post-edit/not-installed.test.ts +199 -0
  14. package/packages/lsp-core/src/post-edit/orchestration.ts +26 -5
  15. package/packages/lsp-daemon/dist/cli.js +2 -1
  16. package/packages/lsp-daemon/dist/client.js +2 -1
  17. package/packages/lsp-daemon/dist/index.js +2 -1
  18. package/packages/lsp-tools-mcp/dist/cli.js +2 -1
  19. package/packages/lsp-tools-mcp/dist/mcp.js +2 -1
  20. package/packages/lsp-tools-mcp/dist/tools.js +2 -1
  21. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  22. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  23. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  24. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  25. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  26. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  27. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  28. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  29. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  30. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  31. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +141 -107
  32. package/packages/omo-codex/plugin/components/lsp/dist/lsp-session-state.js +2 -2
  33. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  34. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  35. package/packages/omo-codex/plugin/components/lsp/src/lsp-session-state.ts +2 -2
  36. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  37. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  38. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  39. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  40. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  41. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  42. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  43. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  44. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  45. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  46. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  47. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  48. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  49. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  50. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  51. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  52. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  53. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  54. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  55. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  56. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  57. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  58. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  59. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  60. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  61. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  62. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  63. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  64. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  65. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  66. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  67. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  68. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  69. package/packages/omo-codex/plugin/package-lock.json +12 -12
  70. package/packages/omo-codex/plugin/package.json +1 -1
  71. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +1 -1
  72. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2 -2
  73. package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +1 -1
@@ -1 +1,3 @@
1
+ export * from "./file-location.js";
2
+ export * from "./not-installed-guidance.js";
1
3
  export * from "./orchestration.js";
@@ -0,0 +1,36 @@
1
+ import type { PostEditFileLocation } from "./file-location.js";
2
+
3
+ export interface PostEditNotInstalledOutcome {
4
+ readonly kind: "not_installed";
5
+ readonly serverId: string;
6
+ readonly installDecisionTool: boolean;
7
+ /** A recorded install decision; absent while the user has not decided. */
8
+ readonly decision?: "declined" | "allowed";
9
+ readonly text: string;
10
+ }
11
+
12
+ export interface NotInstalledGuidanceState {
13
+ readonly notInstalledServers: Set<string>;
14
+ }
15
+
16
+ /**
17
+ * Decides whether a missing-server nudge reaches the model.
18
+ *
19
+ * Recorded decisions keep their own text. Undecided nudges are skipped for files outside a project
20
+ * (no marked root, the agent's config dir, or a temp dir) because a repo-local install there would
21
+ * create a manifest in HOME or a temp dir. Without a decision tool nothing can be recorded, so a
22
+ * server is nudged at most once per session state.
23
+ */
24
+ export function notInstalledGuidance(
25
+ filePath: string,
26
+ outcome: PostEditNotInstalledOutcome,
27
+ state: NotInstalledGuidanceState,
28
+ locateFile: ((filePath: string) => PostEditFileLocation) | undefined,
29
+ ): string | undefined {
30
+ if (outcome.decision !== undefined) return outcome.text;
31
+ if (locateFile !== undefined && locateFile(filePath) !== "project") return undefined;
32
+ if (outcome.installDecisionTool) return outcome.text;
33
+ if (state.notInstalledServers.has(outcome.serverId)) return undefined;
34
+ state.notInstalledServers.add(outcome.serverId);
35
+ return outcome.text;
36
+ }
@@ -0,0 +1,199 @@
1
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { afterEach, describe, expect, it } from "bun:test";
5
+
6
+ import {
7
+ classifyPostEditFileLocation,
8
+ collectPostEditDiagnostics,
9
+ createPostEditNotConfiguredCache,
10
+ type PostEditDiagnosticsOutcome,
11
+ type PostEditFileLocation,
12
+ resetPostEditNotConfiguredCache,
13
+ } from "./index.js";
14
+
15
+ const tempDirectories: string[] = [];
16
+
17
+ afterEach(() => {
18
+ for (const directory of tempDirectories.splice(0)) {
19
+ rmSync(directory, { recursive: true, force: true });
20
+ }
21
+ });
22
+
23
+ function tempRoot(prefix: string): string {
24
+ const root = mkdtempSync(join(tmpdir(), prefix));
25
+ tempDirectories.push(root);
26
+ return root;
27
+ }
28
+
29
+ function touch(path: string, text = ""): string {
30
+ mkdirSync(join(path, ".."), { recursive: true });
31
+ writeFileSync(path, text);
32
+ return path;
33
+ }
34
+
35
+ const FULL_NUDGE = [
36
+ "LSP server 'typescript' for .ts is NOT INSTALLED.",
37
+ "To install in THIS repository (preferred — no global install needed):",
38
+ "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
39
+ ].join("\n");
40
+
41
+ function notInstalled(
42
+ serverId: string,
43
+ overrides: Partial<Extract<PostEditDiagnosticsOutcome, { kind: "not_installed" }>> = {},
44
+ ): PostEditDiagnosticsOutcome {
45
+ return {
46
+ kind: "not_installed",
47
+ serverId,
48
+ installDecisionTool: false,
49
+ text: `${FULL_NUDGE} (${serverId})`,
50
+ ...overrides,
51
+ };
52
+ }
53
+
54
+ function at(location: PostEditFileLocation): () => PostEditFileLocation {
55
+ return () => location;
56
+ }
57
+
58
+ describe("classifyPostEditFileLocation", () => {
59
+ it("#given a file with no workspace marker above it #when classified #then it is outside any project", () => {
60
+ const root = tempRoot("lsp-postedit-noproject-");
61
+ const file = touch(join(root, "scratch", "note.mjs"));
62
+
63
+ expect(classifyPostEditFileLocation(file, { cwd: root, agentDirs: [], tempDirs: [] })).toBe("outside_project");
64
+ });
65
+
66
+ it("#given a file under the agent config dir inside a git repository #when classified #then the agent config dir wins", () => {
67
+ const root = tempRoot("lsp-postedit-agentdir-");
68
+ mkdirSync(join(root, ".git"));
69
+ const agentDir = join(root, ".omo", "agent");
70
+ const file = touch(join(agentDir, "models.json"), "{}\n");
71
+
72
+ expect(classifyPostEditFileLocation(file, { cwd: root, agentDirs: [agentDir], tempDirs: [] })).toBe(
73
+ "agent_config",
74
+ );
75
+ });
76
+
77
+ it("#given a temp dir holding a stray package.json #when a scratch file there is classified #then it is a temp file", () => {
78
+ const temp = tempRoot("lsp-postedit-temp-");
79
+ touch(join(temp, "package.json"), "{}\n");
80
+ const file = touch(join(temp, "rules_test.mjs"));
81
+
82
+ expect(classifyPostEditFileLocation(file, { cwd: temp, agentDirs: [], tempDirs: [temp] })).toBe("temp");
83
+ });
84
+
85
+ it("#given the default temp dirs #when an OS temp file is classified #then the canonical temp dir matches", () => {
86
+ const root = tempRoot("lsp-postedit-ostemp-");
87
+ const file = touch(join(root, "scratch.mjs"));
88
+
89
+ expect(classifyPostEditFileLocation(file, { cwd: root, agentDirs: [] })).toBe("temp");
90
+ if (process.platform !== "win32") {
91
+ const slashTmp = join("/tmp", `lsp-postedit-missing-${process.pid}`, "rules_test.mjs");
92
+ expect(classifyPostEditFileLocation(slashTmp, { cwd: root, agentDirs: [] })).toBe("temp");
93
+ }
94
+ });
95
+
96
+ it("#given a project with its own marker inside a temp dir #when classified #then it is a project", () => {
97
+ const temp = tempRoot("lsp-postedit-tempproject-");
98
+ const project = join(temp, "checkout");
99
+ touch(join(project, "package.json"), "{}\n");
100
+ const file = touch(join(project, "src", "a.ts"));
101
+
102
+ expect(classifyPostEditFileLocation(file, { cwd: project, agentDirs: [], tempDirs: [temp] })).toBe("project");
103
+ expect(classifyPostEditFileLocation("src/a.ts", { cwd: project, agentDirs: [], tempDirs: [temp] })).toBe(
104
+ "project",
105
+ );
106
+ });
107
+ });
108
+
109
+ describe("collectPostEditDiagnostics not-installed guidance", () => {
110
+ for (const location of ["outside_project", "agent_config", "temp"] as const) {
111
+ it(`#given a missing server for a ${location} file #when diagnostics run #then the install nudge is skipped`, async () => {
112
+ const result = await collectPostEditDiagnostics({
113
+ filePaths: ["file.ts"],
114
+ runDiagnostics: async () => notInstalled("typescript"),
115
+ locateFile: at(location),
116
+ });
117
+
118
+ expect(result.blocks).toEqual([]);
119
+ expect(result.observations).toEqual([{ filePath: "file.ts", kind: "not_installed" }]);
120
+ });
121
+ }
122
+
123
+ it("#given a missing server for a project file #when diagnostics run #then today's full guidance is kept", async () => {
124
+ const result = await collectPostEditDiagnostics({
125
+ filePaths: ["src/a.ts"],
126
+ runDiagnostics: async () => notInstalled("typescript"),
127
+ locateFile: at("project"),
128
+ });
129
+
130
+ expect(result.blocks).toEqual([{ filePath: "src/a.ts", diagnostics: `${FULL_NUDGE} (typescript)` }]);
131
+ });
132
+
133
+ it("#given no decision tool #when repeated edits hit missing servers #then each server is nudged once per session", async () => {
134
+ const cache = createPostEditNotConfiguredCache();
135
+ const serverFor = (filePath: string): string => (filePath.endsWith(".json") ? "biome" : "typescript");
136
+ const run = (filePaths: readonly string[]) =>
137
+ collectPostEditDiagnostics({
138
+ filePaths,
139
+ cache,
140
+ runDiagnostics: async (filePath) => notInstalled(serverFor(filePath)),
141
+ locateFile: at("project"),
142
+ });
143
+
144
+ const first = await run(["a.ts", "b.ts"]);
145
+ const second = await run(["c.ts", "d.json"]);
146
+ const third = await run(["e.json", "f.ts"]);
147
+
148
+ expect(first.blocks.map((block) => block.filePath)).toEqual(["a.ts"]);
149
+ expect(second.blocks.map((block) => block.filePath)).toEqual(["d.json"]);
150
+ expect(third.blocks).toEqual([]);
151
+
152
+ resetPostEditNotConfiguredCache(cache);
153
+ const afterReset = await run(["g.ts"]);
154
+ expect(afterReset.blocks.map((block) => block.filePath)).toEqual(["g.ts"]);
155
+ });
156
+
157
+ it("#given a decision tool #when repeated edits hit a missing server #then every edit keeps the guidance", async () => {
158
+ const cache = createPostEditNotConfiguredCache();
159
+ const run = (filePath: string) =>
160
+ collectPostEditDiagnostics({
161
+ filePaths: [filePath],
162
+ cache,
163
+ runDiagnostics: async () => notInstalled("typescript", { installDecisionTool: true }),
164
+ locateFile: at("project"),
165
+ });
166
+
167
+ expect((await run("a.ts")).blocks).toHaveLength(1);
168
+ expect((await run("b.ts")).blocks).toHaveLength(1);
169
+ });
170
+
171
+ for (const decision of ["declined", "allowed"] as const) {
172
+ it(`#given a recorded ${decision} decision #when edits repeat anywhere #then that branch's text is unchanged every time`, async () => {
173
+ const cache = createPostEditNotConfiguredCache();
174
+ const text = `LSP server 'typescript' ${decision} branch text`;
175
+ const outcomes: PostEditFileLocation[] = ["project", "outside_project", "project"];
176
+ const blocks: string[] = [];
177
+ for (const location of outcomes) {
178
+ const result = await collectPostEditDiagnostics({
179
+ filePaths: ["a.ts"],
180
+ cache,
181
+ runDiagnostics: async () => notInstalled("typescript", { decision, text }),
182
+ locateFile: at(location),
183
+ });
184
+ blocks.push(...result.blocks.map((block) => block.diagnostics));
185
+ }
186
+
187
+ expect(blocks).toEqual([text, text, text]);
188
+ });
189
+ }
190
+
191
+ it("#given no file locator #when a missing server is reported #then the full guidance is kept", async () => {
192
+ const result = await collectPostEditDiagnostics({
193
+ filePaths: ["a.ts"],
194
+ runDiagnostics: async () => notInstalled("typescript"),
195
+ });
196
+
197
+ expect(result.blocks).toEqual([{ filePath: "a.ts", diagnostics: `${FULL_NUDGE} (typescript)` }]);
198
+ });
199
+ });
@@ -1,5 +1,8 @@
1
1
  import { extname } from "node:path";
2
2
 
3
+ import type { PostEditFileLocation } from "./file-location.js";
4
+ import { notInstalledGuidance, type PostEditNotInstalledOutcome } from "./not-installed-guidance.js";
5
+
3
6
  const DEFAULT_MAX_CONCURRENCY = 4;
4
7
  const CLEAN_DIAGNOSTICS_TEXT = "No diagnostics found";
5
8
 
@@ -8,7 +11,8 @@ export type PostEditDiagnosticsOutcome =
8
11
  | {
9
12
  readonly kind: "not_configured";
10
13
  readonly extension: string;
11
- };
14
+ }
15
+ | PostEditNotInstalledOutcome;
12
16
 
13
17
  export type DiagnosticsRunner = (filePath: string) => Promise<PostEditDiagnosticsOutcome>;
14
18
 
@@ -19,7 +23,7 @@ export interface PostEditDiagnosticsBlock {
19
23
 
20
24
  export interface PostEditDiagnosticsObservation {
21
25
  readonly filePath: string;
22
- readonly kind: "block" | "clean" | "not_configured";
26
+ readonly kind: "block" | "clean" | "not_configured" | "not_installed";
23
27
  }
24
28
 
25
29
  export interface PostEditDiagnosticsResult {
@@ -29,6 +33,7 @@ export interface PostEditDiagnosticsResult {
29
33
 
30
34
  export interface PostEditNotConfiguredCache {
31
35
  readonly notConfiguredExtensions: Set<string>;
36
+ readonly notInstalledServers: Set<string>;
32
37
  }
33
38
 
34
39
  export interface CollectPostEditDiagnosticsInput {
@@ -36,6 +41,7 @@ export interface CollectPostEditDiagnosticsInput {
36
41
  readonly runDiagnostics: DiagnosticsRunner;
37
42
  readonly cache?: PostEditNotConfiguredCache;
38
43
  readonly maxConcurrency?: number;
44
+ readonly locateFile?: (filePath: string) => PostEditFileLocation;
39
45
  }
40
46
 
41
47
  interface IndexedFilePath {
@@ -50,11 +56,12 @@ interface IndexedDiagnostics {
50
56
  }
51
57
 
52
58
  export function createPostEditNotConfiguredCache(): PostEditNotConfiguredCache {
53
- return { notConfiguredExtensions: new Set() };
59
+ return { notConfiguredExtensions: new Set(), notInstalledServers: new Set() };
54
60
  }
55
61
 
56
62
  export function resetPostEditNotConfiguredCache(cache: PostEditNotConfiguredCache): void {
57
63
  cache.notConfiguredExtensions.clear();
64
+ cache.notInstalledServers.clear();
58
65
  }
59
66
 
60
67
  export async function collectPostEditDiagnostics(
@@ -67,8 +74,15 @@ export async function collectPostEditDiagnostics(
67
74
  const observations: PostEditDiagnosticsObservation[] = [];
68
75
 
69
76
  for (const result of results) {
70
- const classification = classifyDiagnostics(result.outcome);
77
+ const outcome = result.outcome;
78
+ const classification =
79
+ typeof outcome !== "string" && outcome.kind === "not_installed"
80
+ ? classifyNotInstalled(notInstalledGuidance(result.filePath, outcome, cache, input.locateFile))
81
+ : classifyDiagnostics(outcome);
71
82
  switch (classification.kind) {
83
+ case "not_installed":
84
+ observations.push({ filePath: result.filePath, kind: "not_installed" });
85
+ break;
72
86
  case "clean":
73
87
  observations.push({ filePath: result.filePath, kind: "clean" });
74
88
  break;
@@ -146,9 +160,16 @@ async function collectFileDiagnostics(
146
160
 
147
161
  function normalizeDiagnosticsOutcome(outcome: PostEditDiagnosticsOutcome): PostEditDiagnosticsOutcome {
148
162
  if (typeof outcome === "string") return normalizeDiagnosticsText(outcome);
163
+ if (outcome.kind === "not_installed") return { ...outcome, text: normalizeDiagnosticsText(outcome.text) };
149
164
  return outcome;
150
165
  }
151
166
 
167
+ function classifyNotInstalled(
168
+ guidance: string | undefined,
169
+ ): { readonly kind: "not_installed" } | { readonly kind: "block"; readonly diagnostics: string } {
170
+ return guidance === undefined ? { kind: "not_installed" } : { kind: "block", diagnostics: guidance };
171
+ }
172
+
152
173
  function normalizeDiagnosticsText(text: string): string {
153
174
  return text.trim();
154
175
  }
@@ -159,7 +180,7 @@ function formatDiagnosticsError(error: Error): string {
159
180
  }
160
181
 
161
182
  function classifyDiagnostics(
162
- outcome: PostEditDiagnosticsOutcome,
183
+ outcome: Exclude<PostEditDiagnosticsOutcome, PostEditNotInstalledOutcome>,
163
184
  ):
164
185
  | { readonly kind: "clean" }
165
186
  | { readonly kind: "not_configured"; readonly extension: string }
@@ -5350,7 +5350,8 @@ function missingDependencyAvailability(error) {
5350
5350
  extensions: [...error.lookup.server.extensions],
5351
5351
  installHint: error.lookup.installHint,
5352
5352
  installDecisionTool: context.capabilities.installDecisionTool,
5353
- installDecisionsPath: context.installDecisionsPath
5353
+ installDecisionsPath: context.installDecisionsPath,
5354
+ decision: loadInstallDecision(error.lookup.server.id)?.decision ?? null
5354
5355
  };
5355
5356
  default: {
5356
5357
  const exhaustive = error.lookup;
@@ -5586,7 +5586,8 @@ function missingDependencyAvailability(error) {
5586
5586
  extensions: [...error.lookup.server.extensions],
5587
5587
  installHint: error.lookup.installHint,
5588
5588
  installDecisionTool: context.capabilities.installDecisionTool,
5589
- installDecisionsPath: context.installDecisionsPath
5589
+ installDecisionsPath: context.installDecisionsPath,
5590
+ decision: loadInstallDecision(error.lookup.server.id)?.decision ?? null
5590
5591
  };
5591
5592
  default: {
5592
5593
  const exhaustive = error.lookup;
@@ -5581,7 +5581,8 @@ function missingDependencyAvailability(error) {
5581
5581
  extensions: [...error.lookup.server.extensions],
5582
5582
  installHint: error.lookup.installHint,
5583
5583
  installDecisionTool: context.capabilities.installDecisionTool,
5584
- installDecisionsPath: context.installDecisionsPath
5584
+ installDecisionsPath: context.installDecisionsPath,
5585
+ decision: loadInstallDecision(error.lookup.server.id)?.decision ?? null
5585
5586
  };
5586
5587
  default: {
5587
5588
  const exhaustive = error.lookup;
@@ -4919,7 +4919,8 @@ function missingDependencyAvailability(error) {
4919
4919
  extensions: [...error.lookup.server.extensions],
4920
4920
  installHint: error.lookup.installHint,
4921
4921
  installDecisionTool: context.capabilities.installDecisionTool,
4922
- installDecisionsPath: context.installDecisionsPath
4922
+ installDecisionsPath: context.installDecisionsPath,
4923
+ decision: loadInstallDecision(error.lookup.server.id)?.decision ?? null
4923
4924
  };
4924
4925
  default: {
4925
4926
  const exhaustive = error.lookup;
@@ -4915,7 +4915,8 @@ function missingDependencyAvailability(error) {
4915
4915
  extensions: [...error.lookup.server.extensions],
4916
4916
  installHint: error.lookup.installHint,
4917
4917
  installDecisionTool: context.capabilities.installDecisionTool,
4918
- installDecisionsPath: context.installDecisionsPath
4918
+ installDecisionsPath: context.installDecisionsPath,
4919
+ decision: loadInstallDecision(error.lookup.server.id)?.decision ?? null
4919
4920
  };
4920
4921
  default: {
4921
4922
  const exhaustive = error.lookup;
@@ -4603,7 +4603,8 @@ function missingDependencyAvailability(error) {
4603
4603
  extensions: [...error.lookup.server.extensions],
4604
4604
  installHint: error.lookup.installHint,
4605
4605
  installDecisionTool: context.capabilities.installDecisionTool,
4606
- installDecisionsPath: context.installDecisionsPath
4606
+ installDecisionsPath: context.installDecisionsPath,
4607
+ decision: loadInstallDecision(error.lookup.server.id)?.decision ?? null
4607
4608
  };
4608
4609
  default: {
4609
4610
  const exhaustive = error.lookup;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omo",
3
- "version": "5.1.3",
3
+ "version": "5.1.4",
4
4
  "description": "One Codex plugin namespace for Yeongyu's local Codex components.",
5
5
  "author": {
6
6
  "name": "Yeongyu Kim",
@@ -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.1.3) Checking Bootstrap Provisioning"
11
+ "statusMessage": "(OmO 5.1.4) Checking Bootstrap Provisioning"
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sisyphuslabs/codex-bootstrap",
3
- "version": "5.1.3",
3
+ "version": "5.1.4",
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 post-tool-use",
10
10
  "timeout": 30,
11
- "statusMessage": "(OmO 5.1.3) Checking Comments"
11
+ "statusMessage": "(OmO 5.1.4) Checking Comments"
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-comment-checker",
3
- "version": "5.1.3",
3
+ "version": "5.1.4",
4
4
  "description": "Codex plugin that runs comment-checker after edit-like PostToolUse hooks.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -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.1.3) Recommending Git Bash MCP"
11
+ "statusMessage": "(OmO 5.1.4) 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.1.3) Resetting Git Bash MCP Reminder"
23
+ "statusMessage": "(OmO 5.1.4) Resetting Git Bash MCP Reminder"
24
24
  }
25
25
  ]
26
26
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sisyphuslabs/codex-git-bash-hook",
3
- "version": "5.1.3",
3
+ "version": "5.1.4",
4
4
  "description": "Codex hook component that reminds Windows sessions to prefer the OMO git_bash MCP.",
5
5
  "type": "module",
6
6
  "private": true,
@@ -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.1.3) Verifying LazyCodex Executor Evidence"
11
+ "statusMessage": "(OmO 5.1.4) 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.1.3",
3
+ "version": "5.1.4",
4
4
  "description": "Codex SubagentStop evidence verifier for LazyCodex executor completions.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "5.1.3",
4
- "inputDigest": "sha256:affd143b968dfe926241288a42ac81d6f67cd8a853569bd8d7bac0c9ee6ed75c",
3
+ "version": "5.1.4",
4
+ "inputDigest": "sha256:4b9c0202761e8abe92155e627fa7548e4252aadd31dd92f1412d6bf1e357ed23",
5
5
  "outputs": [
6
6
  {
7
7
  "path": "cli.d.ts",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  {
11
11
  "path": "cli.js",
12
- "sha256": "a0155ce31758825f26a35acbc894361e22a6531bab3fc47bc1f5c2ed054580ef"
12
+ "sha256": "d793d83fb82b1fafe52e619f545c5195398498d1f95f15d84904fe3d0a20befe"
13
13
  },
14
14
  {
15
15
  "path": "codex-hook-cli.d.ts",
@@ -41,7 +41,7 @@
41
41
  },
42
42
  {
43
43
  "path": "lsp-session-state.js",
44
- "sha256": "d9c1f4bbace5a8a1fad3d0c3d225e4019700946b2391d1d5ae4d2362ca2e495f"
44
+ "sha256": "8c0e4fff28cb9deaca9c1b12ed2b0663a93fdf8532a8028f90a241b0607b8368"
45
45
  },
46
46
  {
47
47
  "path": "mutated-file-paths.d.ts",