oh-my-opencode 4.11.1 → 4.12.0
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/.agents/skills/codex-qa/scripts/lib/app-server-client.mjs +132 -82
- package/.agents/skills/codex-qa/scripts/lib/app-server-client.test.js +48 -0
- package/.agents/skills/opencode-qa/scripts/serve-wake-split-probe.sh +361 -84
- package/.agents/skills/work-with-pr/SKILL.md +19 -5
- package/.opencode/skills/work-with-pr/SKILL.md +19 -5
- package/dist/agents/types.d.ts +7 -6
- package/dist/cli/index.js +438 -306
- package/dist/cli-node/index.js +438 -306
- package/dist/features/background-agent/parent-wake-flush-runner.d.ts +1 -0
- package/dist/features/background-agent/parent-wake-history-state.d.ts +1 -0
- package/dist/features/background-agent/parent-wake-session-history.d.ts +1 -47
- package/dist/features/background-agent/parent-wake-session-message.d.ts +47 -0
- package/dist/index.js +245 -69
- package/dist/plugin/tool-execute-before.d.ts +2 -0
- package/dist/plugin-handlers/plugin-components-loader.d.ts +1 -0
- package/dist/skills/ulw-plan/SKILL.md +2 -1
- package/dist/skills/ulw-plan/references/full-workflow.md +1 -1
- package/dist/skills/ulw-plan/references/intent-clear.md +2 -2
- package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -2
- package/dist/tools/delegate-task/sync-session-turns.d.ts +3 -0
- package/dist/tui.js +16 -7
- package/package.json +13 -13
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +22 -2
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +25 -9
- 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 +10 -3
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +9 -2
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +7 -2
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +2 -1
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +9 -9
- package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +94 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +33 -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/comment-checker/test/package-smoke.test.ts +2 -71
- 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/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +26 -104
- 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/rules/test/package-smoke.test.ts +12 -92
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +157 -234
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +227 -15
- package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +62 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +34 -3
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +139 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs +111 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-state.mjs +250 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +220 -0
- 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/test-support/package-smoke-fixture.ts +158 -0
- 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/skills/ulw-plan/SKILL.md +2 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +76 -49
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +17 -0
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +17 -0
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +17 -0
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +17 -0
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +17 -0
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +16 -0
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +16 -0
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +16 -0
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +16 -0
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +16 -0
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +17 -0
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +16 -0
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +16 -0
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +16 -0
- package/packages/omo-codex/plugin/package-lock.json +12 -22
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +14 -11
- package/packages/omo-codex/plugin/scripts/sync-hook-status-messages.mjs +15 -4
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +37 -0
- package/packages/omo-codex/plugin/skills/ast-grep/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/comment-checker/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/debugging/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/frontend/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/git-master/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/init-deep/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-doctor/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lsp/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/programming/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/refactor/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/remove-ai-slops/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/review-work/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/rules/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/teammode/SKILL.md +139 -0
- package/packages/omo-codex/plugin/skills/teammode/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-guide.mjs +111 -0
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-state.mjs +250 -0
- package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +220 -0
- package/packages/omo-codex/plugin/skills/ultraresearch/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +2 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -2
- package/packages/omo-codex/plugin/skills/visual-qa/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +34 -33
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +5 -2
- package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +13 -0
- package/packages/omo-codex/plugin/test/bootstrap-binlinks.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/bootstrap-hooks.test.mjs +14 -6
- package/packages/omo-codex/plugin/test/bootstrap-ps-guard.test.mjs +7 -3
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +3 -3
- package/packages/omo-codex/plugin/test/display-metadata.test.mjs +83 -0
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +30 -19
- package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +3 -3
- package/packages/omo-codex/plugin/test/sync-hook-status-messages.test.mjs +6 -6
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +2 -0
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +9 -4
- package/packages/omo-codex/plugin/test/teammode-safety-fixture.mjs +88 -0
- package/packages/omo-codex/plugin/test/teammode-safety.test.mjs +240 -0
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +385 -206
- package/packages/omo-codex/scripts/install-hook-targets.test.mjs +93 -0
- package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +2 -2
- package/packages/omo-codex/scripts/install-local-bun-global-update.test.mjs +63 -0
- package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +109 -1
- package/packages/omo-codex/scripts/install-local.mjs +1 -0
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +2 -1
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -2
- package/packages/omo-codex/plugin/hooks/hooks.json +0 -214
|
@@ -96,20 +96,20 @@ var init_atomic_write = __esm(() => {
|
|
|
96
96
|
|
|
97
97
|
// packages/telemetry-core/src/activity-state.ts
|
|
98
98
|
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync } from "node:fs";
|
|
99
|
-
import { basename as basename5, join as
|
|
99
|
+
import { basename as basename5, join as join27 } from "node:path";
|
|
100
100
|
function resolveTelemetryStateDir(product, options = {}) {
|
|
101
101
|
const dataDir = resolveXdgDataDir(product.cacheDirName, {
|
|
102
102
|
env: options.env,
|
|
103
103
|
osProvider: options.osProvider
|
|
104
104
|
});
|
|
105
|
-
const xdgStateDir = options.env?.XDG_DATA_HOME === undefined ? undefined :
|
|
105
|
+
const xdgStateDir = options.env?.XDG_DATA_HOME === undefined ? undefined : join27(options.env.XDG_DATA_HOME, product.cacheDirName);
|
|
106
106
|
if (dataDir === xdgStateDir || xdgStateDir === undefined && basename5(dataDir) === product.cacheDirName) {
|
|
107
107
|
return dataDir;
|
|
108
108
|
}
|
|
109
|
-
return
|
|
109
|
+
return join27(dataDir, product.cacheDirName);
|
|
110
110
|
}
|
|
111
111
|
function getTelemetryActivityStateFilePath(stateDir) {
|
|
112
|
-
return
|
|
112
|
+
return join27(stateDir, POSTHOG_ACTIVITY_STATE_FILE);
|
|
113
113
|
}
|
|
114
114
|
function getDailyActiveCaptureState(input) {
|
|
115
115
|
const state = readPostHogActivityState(input.stateDir, input.diagnostics);
|
|
@@ -180,9 +180,9 @@ var DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com", DEFAULT_POSTHOG_API_KEY =
|
|
|
180
180
|
|
|
181
181
|
// packages/telemetry-core/src/diagnostics.ts
|
|
182
182
|
import { appendFileSync, existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
183
|
-
import { join as
|
|
183
|
+
import { join as join28 } from "node:path";
|
|
184
184
|
function getTelemetryDiagnosticsFilePath(diagnosticsDir) {
|
|
185
|
-
return
|
|
185
|
+
return join28(diagnosticsDir, DIAGNOSTICS_FILE_NAME);
|
|
186
186
|
}
|
|
187
187
|
function writeTelemetryDiagnostic(input, options) {
|
|
188
188
|
const now = options.now ?? new Date;
|
|
@@ -348,7 +348,7 @@ function getTelemetryDistinctId(machineIdPrefix, osProvider = getDefaultTelemetr
|
|
|
348
348
|
var init_machine_id = () => {};
|
|
349
349
|
|
|
350
350
|
// node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
351
|
-
import { dirname as dirname7, posix, sep as
|
|
351
|
+
import { dirname as dirname7, posix, sep as sep7 } from "node:path";
|
|
352
352
|
function createModulerModifier() {
|
|
353
353
|
const getModuleFromFileName = createGetModuleFromFilename();
|
|
354
354
|
return async (frames) => {
|
|
@@ -357,7 +357,7 @@ function createModulerModifier() {
|
|
|
357
357
|
return frames;
|
|
358
358
|
};
|
|
359
359
|
}
|
|
360
|
-
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname7(process.argv[1]) : process.cwd(), isWindows =
|
|
360
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname7(process.argv[1]) : process.cwd(), isWindows = sep7 === "\\") {
|
|
361
361
|
const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
|
|
362
362
|
return (filename) => {
|
|
363
363
|
if (!filename)
|
|
@@ -3378,9 +3378,9 @@ var init_context_lines_node = __esm(() => {
|
|
|
3378
3378
|
});
|
|
3379
3379
|
|
|
3380
3380
|
// node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/relative-path.node.mjs
|
|
3381
|
-
import { isAbsolute as isAbsolute5, relative as relative4, sep as
|
|
3381
|
+
import { isAbsolute as isAbsolute5, relative as relative4, sep as sep8 } from "node:path";
|
|
3382
3382
|
function createRelativePathModifier(basePath = process.cwd()) {
|
|
3383
|
-
const isWindows =
|
|
3383
|
+
const isWindows = sep8 === "\\";
|
|
3384
3384
|
const toUnix = (p) => isWindows ? p.replace(/\\/g, "/") : p;
|
|
3385
3385
|
const normalizedBase = toUnix(basePath);
|
|
3386
3386
|
return async (frames) => {
|
|
@@ -5907,7 +5907,7 @@ var package_default;
|
|
|
5907
5907
|
var init_package = __esm(() => {
|
|
5908
5908
|
package_default = {
|
|
5909
5909
|
name: "@oh-my-opencode/omo-codex",
|
|
5910
|
-
version: "4.
|
|
5910
|
+
version: "4.12.0",
|
|
5911
5911
|
type: "module",
|
|
5912
5912
|
private: true,
|
|
5913
5913
|
description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
|
|
@@ -6127,7 +6127,7 @@ var init_telemetry = __esm(() => {
|
|
|
6127
6127
|
|
|
6128
6128
|
// packages/omo-codex/src/install/install-local-cli.ts
|
|
6129
6129
|
import { readFile as readFile19 } from "node:fs/promises";
|
|
6130
|
-
import { dirname as dirname9, join as
|
|
6130
|
+
import { dirname as dirname9, join as join33, resolve as resolve11 } from "node:path";
|
|
6131
6131
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
6132
6132
|
|
|
6133
6133
|
// packages/utils/src/runtime/spawn.ts
|
|
@@ -6395,7 +6395,7 @@ var defaultRunCommand = async (command, args, options) => {
|
|
|
6395
6395
|
};
|
|
6396
6396
|
|
|
6397
6397
|
// packages/omo-codex/src/install/install-codex.ts
|
|
6398
|
-
import { join as
|
|
6398
|
+
import { join as join29, resolve as resolve10 } from "node:path";
|
|
6399
6399
|
import { existsSync as existsSync6 } from "node:fs";
|
|
6400
6400
|
import { homedir as homedir2 } from "node:os";
|
|
6401
6401
|
|
|
@@ -6759,8 +6759,8 @@ async function existingNonSymlink(path) {
|
|
|
6759
6759
|
}
|
|
6760
6760
|
}
|
|
6761
6761
|
// packages/omo-codex/src/install/codex-cache-install.ts
|
|
6762
|
-
import { cp as cp2, mkdir as mkdir3, readFile as
|
|
6763
|
-
import { basename as basename2, dirname as dirname3, join as
|
|
6762
|
+
import { cp as cp2, mkdir as mkdir3, readFile as readFile7, rename, rm as rm3 } from "node:fs/promises";
|
|
6763
|
+
import { basename as basename2, dirname as dirname3, join as join9, sep as sep5 } from "node:path";
|
|
6764
6764
|
|
|
6765
6765
|
// packages/omo-codex/src/install/codex-cache-bundled-mcps.ts
|
|
6766
6766
|
import { cp, mkdir as mkdir2, readFile as readFile3, stat as stat2 } from "node:fs/promises";
|
|
@@ -7055,13 +7055,83 @@ async function rewriteCachedManifestRoot(pluginRoot, fromRoot, toRoot) {
|
|
|
7055
7055
|
`);
|
|
7056
7056
|
}
|
|
7057
7057
|
|
|
7058
|
+
// packages/omo-codex/src/install/codex-hook-targets.ts
|
|
7059
|
+
import { readFile as readFile6 } from "node:fs/promises";
|
|
7060
|
+
import { join as join8, sep as sep4 } from "node:path";
|
|
7061
|
+
var PLUGIN_ROOT_TARGET_PATTERN = /\$\{PLUGIN_ROOT\}[\\/]+([^"']+)/g;
|
|
7062
|
+
async function findMissingHookCommandTargets(pluginRoot) {
|
|
7063
|
+
const commands = [];
|
|
7064
|
+
for (const manifestPath of await hookManifestPaths(pluginRoot)) {
|
|
7065
|
+
if (!await fileExistsStrict(manifestPath))
|
|
7066
|
+
continue;
|
|
7067
|
+
const parsed = JSON.parse(await readFile6(manifestPath, "utf8"));
|
|
7068
|
+
collectCommands(parsed, commands);
|
|
7069
|
+
}
|
|
7070
|
+
const missing = [];
|
|
7071
|
+
const seen = new Set;
|
|
7072
|
+
for (const command of commands) {
|
|
7073
|
+
for (const match of command.matchAll(PLUGIN_ROOT_TARGET_PATTERN)) {
|
|
7074
|
+
const targetSuffix = match[1];
|
|
7075
|
+
if (targetSuffix === undefined)
|
|
7076
|
+
continue;
|
|
7077
|
+
const target = join8(pluginRoot, ...targetSuffix.split(/[\\/]+/));
|
|
7078
|
+
if (seen.has(target))
|
|
7079
|
+
continue;
|
|
7080
|
+
seen.add(target);
|
|
7081
|
+
if (!await fileExistsStrict(target))
|
|
7082
|
+
missing.push(target);
|
|
7083
|
+
}
|
|
7084
|
+
}
|
|
7085
|
+
return missing;
|
|
7086
|
+
}
|
|
7087
|
+
async function hookManifestPaths(pluginRoot) {
|
|
7088
|
+
const pluginManifestPath = join8(pluginRoot, ".codex-plugin", "plugin.json");
|
|
7089
|
+
if (!await fileExistsStrict(pluginManifestPath))
|
|
7090
|
+
return [join8(pluginRoot, "hooks", "hooks.json")];
|
|
7091
|
+
const parsed = JSON.parse(await readFile6(pluginManifestPath, "utf8"));
|
|
7092
|
+
if (!isPlainRecord(parsed))
|
|
7093
|
+
return [];
|
|
7094
|
+
if (typeof parsed.hooks === "string" && parsed.hooks.trim() !== "") {
|
|
7095
|
+
return [join8(pluginRoot, stripDotSlash(parsed.hooks))];
|
|
7096
|
+
}
|
|
7097
|
+
if (Array.isArray(parsed.hooks)) {
|
|
7098
|
+
return parsed.hooks.filter((hookPath) => typeof hookPath === "string" && hookPath.trim() !== "").map((hookPath) => join8(pluginRoot, stripDotSlash(hookPath)));
|
|
7099
|
+
}
|
|
7100
|
+
return [];
|
|
7101
|
+
}
|
|
7102
|
+
function stripDotSlash(path) {
|
|
7103
|
+
return path.startsWith("./") ? path.slice(2) : path;
|
|
7104
|
+
}
|
|
7105
|
+
async function assertHookCommandTargets(pluginRoot) {
|
|
7106
|
+
const missing = await findMissingHookCommandTargets(pluginRoot);
|
|
7107
|
+
if (missing.length === 0)
|
|
7108
|
+
return;
|
|
7109
|
+
const relativeMissing = missing.map((path) => path.split(`${pluginRoot}${sep4}`).join("").split(sep4).join("/"));
|
|
7110
|
+
throw new Error(`Plugin payload is missing ${missing.length} hook command target(s) referenced by hooks.json: ${relativeMissing.join(", ")}. ` + "The previous plugin cache was left untouched; this payload was not activated.");
|
|
7111
|
+
}
|
|
7112
|
+
function collectCommands(value, commands) {
|
|
7113
|
+
if (Array.isArray(value)) {
|
|
7114
|
+
for (const entry of value)
|
|
7115
|
+
collectCommands(entry, commands);
|
|
7116
|
+
return;
|
|
7117
|
+
}
|
|
7118
|
+
if (!isPlainRecord(value))
|
|
7119
|
+
return;
|
|
7120
|
+
if (value["type"] === "command" && typeof value["command"] === "string")
|
|
7121
|
+
commands.push(value["command"]);
|
|
7122
|
+
if (value["type"] === "command" && typeof value["commandWindows"] === "string")
|
|
7123
|
+
commands.push(value["commandWindows"]);
|
|
7124
|
+
for (const entry of Object.values(value))
|
|
7125
|
+
collectCommands(entry, commands);
|
|
7126
|
+
}
|
|
7127
|
+
|
|
7058
7128
|
// packages/omo-codex/src/install/codex-cache-install.ts
|
|
7059
7129
|
async function installCachedPlugin(input) {
|
|
7060
7130
|
if (input.buildSource !== false) {
|
|
7061
7131
|
await maybeRunNpmInstall(input.sourcePath, input.runCommand);
|
|
7062
7132
|
await maybeRunNpmBuild(input.sourcePath, input.runCommand);
|
|
7063
7133
|
}
|
|
7064
|
-
const targetPath =
|
|
7134
|
+
const targetPath = join9(input.codexHome, "plugins", "cache", input.marketplaceName, input.name, input.version);
|
|
7065
7135
|
const tempPath = createTempSiblingPath(targetPath);
|
|
7066
7136
|
await rm3(tempPath, { recursive: true, force: true });
|
|
7067
7137
|
try {
|
|
@@ -7071,6 +7141,7 @@ async function installCachedPlugin(input) {
|
|
|
7071
7141
|
await maybeRunNpmInstall(tempPath, input.runCommand, ["ci", "--omit=dev"]);
|
|
7072
7142
|
await rewriteCachedMcpManifest(tempPath, input.sourcePath);
|
|
7073
7143
|
await rewriteCachedManifestRoot(tempPath, tempPath, targetPath);
|
|
7144
|
+
await assertHookCommandTargets(tempPath);
|
|
7074
7145
|
await promoteDirectory(tempPath, targetPath, input.renameDirectory ?? rename);
|
|
7075
7146
|
} catch (error) {
|
|
7076
7147
|
await rm3(tempPath, { recursive: true, force: true });
|
|
@@ -7079,14 +7150,14 @@ async function installCachedPlugin(input) {
|
|
|
7079
7150
|
return { name: input.name, version: input.version, path: targetPath };
|
|
7080
7151
|
}
|
|
7081
7152
|
async function maybeRunNpmInstall(cwd, runCommand, args = ["install"]) {
|
|
7082
|
-
if (!await fileExistsStrict(
|
|
7153
|
+
if (!await fileExistsStrict(join9(cwd, "package.json")))
|
|
7083
7154
|
return;
|
|
7084
7155
|
await runCommand("npm", args, { cwd });
|
|
7085
7156
|
}
|
|
7086
7157
|
async function maybeRunNpmBuild(cwd, runCommand) {
|
|
7087
|
-
if (!await fileExistsStrict(
|
|
7158
|
+
if (!await fileExistsStrict(join9(cwd, "package.json")))
|
|
7088
7159
|
return;
|
|
7089
|
-
const packageJson = JSON.parse(await
|
|
7160
|
+
const packageJson = JSON.parse(await readFile7(join9(cwd, "package.json"), "utf8"));
|
|
7090
7161
|
if (!isPlainRecord(packageJson))
|
|
7091
7162
|
return;
|
|
7092
7163
|
const scripts = packageJson.scripts;
|
|
@@ -7095,10 +7166,10 @@ async function maybeRunNpmBuild(cwd, runCommand) {
|
|
|
7095
7166
|
await runCommand("npm", ["run", "build"], { cwd });
|
|
7096
7167
|
}
|
|
7097
7168
|
function createTempSiblingPath(targetPath) {
|
|
7098
|
-
return
|
|
7169
|
+
return join9(dirname3(targetPath), `.tmp-${basename2(targetPath)}-${process.pid}-${Date.now()}`);
|
|
7099
7170
|
}
|
|
7100
7171
|
function createBackupSiblingPath(targetPath) {
|
|
7101
|
-
return
|
|
7172
|
+
return join9(dirname3(targetPath), `.backup-${basename2(targetPath)}-${process.pid}-${Date.now()}`);
|
|
7102
7173
|
}
|
|
7103
7174
|
async function copyDirectory(sourcePath, targetPath) {
|
|
7104
7175
|
await mkdir3(dirname3(targetPath), { recursive: true });
|
|
@@ -7129,17 +7200,17 @@ async function restoreBackupDirectory(backupPath, targetPath, renameDirectory) {
|
|
|
7129
7200
|
await renameDirectory(backupPath, targetPath);
|
|
7130
7201
|
}
|
|
7131
7202
|
function shouldCopyPluginPath(path, root) {
|
|
7132
|
-
const relative4 = path === root ? "" : path.slice(root.length +
|
|
7203
|
+
const relative4 = path === root ? "" : path.slice(root.length + sep5.length);
|
|
7133
7204
|
if (relative4 === "")
|
|
7134
7205
|
return true;
|
|
7135
|
-
const parts = relative4.split(
|
|
7206
|
+
const parts = relative4.split(sep5);
|
|
7136
7207
|
return !parts.some((part) => part === ".git" || part === "node_modules");
|
|
7137
7208
|
}
|
|
7138
7209
|
// packages/omo-codex/src/install/codex-cache-prune.ts
|
|
7139
7210
|
import { lstat as lstat4, readdir as readdir3, rm as rm4, stat as stat3 } from "node:fs/promises";
|
|
7140
|
-
import { join as
|
|
7211
|
+
import { join as join10 } from "node:path";
|
|
7141
7212
|
async function pruneMarketplaceCache(input) {
|
|
7142
|
-
const cacheRoot =
|
|
7213
|
+
const cacheRoot = join10(input.codexHome, "plugins", "cache", input.marketplaceName);
|
|
7143
7214
|
if (!await fileExistsStrict(cacheRoot))
|
|
7144
7215
|
return;
|
|
7145
7216
|
const keep = new Set(input.keepPluginNames);
|
|
@@ -7147,15 +7218,15 @@ async function pruneMarketplaceCache(input) {
|
|
|
7147
7218
|
for (const entry of entries) {
|
|
7148
7219
|
if (!entry.isDirectory() || keep.has(entry.name))
|
|
7149
7220
|
continue;
|
|
7150
|
-
await rm4(
|
|
7221
|
+
await rm4(join10(cacheRoot, entry.name), { recursive: true, force: true });
|
|
7151
7222
|
}
|
|
7152
7223
|
}
|
|
7153
7224
|
async function pruneMarketplacePluginCaches(input) {
|
|
7154
|
-
const cacheRoot =
|
|
7225
|
+
const cacheRoot = join10(input.codexHome, "plugins", "cache", input.marketplaceName);
|
|
7155
7226
|
if (!await fileExistsStrict(cacheRoot))
|
|
7156
7227
|
return;
|
|
7157
7228
|
for (const pluginName of input.pluginNames) {
|
|
7158
|
-
await rm4(
|
|
7229
|
+
await rm4(join10(cacheRoot, pluginName), { recursive: true, force: true });
|
|
7159
7230
|
}
|
|
7160
7231
|
const remainingEntries = await readCacheEntryNames(cacheRoot);
|
|
7161
7232
|
if (remainingEntries.length === 0) {
|
|
@@ -7202,11 +7273,11 @@ async function isBrokenCacheSymlink(path) {
|
|
|
7202
7273
|
}
|
|
7203
7274
|
// packages/omo-codex/src/install/codex-cached-marketplace-manifest.ts
|
|
7204
7275
|
import { mkdir as mkdir4, writeFile as writeFile4 } from "node:fs/promises";
|
|
7205
|
-
import { join as
|
|
7276
|
+
import { join as join11 } from "node:path";
|
|
7206
7277
|
async function writeCachedMarketplaceManifest(input) {
|
|
7207
|
-
const marketplaceDir =
|
|
7278
|
+
const marketplaceDir = join11(input.marketplaceRoot, ".agents", "plugins");
|
|
7208
7279
|
await mkdir4(marketplaceDir, { recursive: true });
|
|
7209
|
-
await writeFile4(
|
|
7280
|
+
await writeFile4(join11(marketplaceDir, "marketplace.json"), `${JSON.stringify({
|
|
7210
7281
|
name: input.marketplaceName,
|
|
7211
7282
|
plugins: input.plugins.map((plugin) => ({
|
|
7212
7283
|
name: plugin.name,
|
|
@@ -7218,8 +7289,8 @@ async function writeCachedMarketplaceManifest(input) {
|
|
|
7218
7289
|
|
|
7219
7290
|
// packages/omo-codex/src/install/codex-package-layout.ts
|
|
7220
7291
|
import { existsSync as existsSync2 } from "node:fs";
|
|
7221
|
-
import { readFile as
|
|
7222
|
-
import { join as
|
|
7292
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
7293
|
+
import { join as join12 } from "node:path";
|
|
7223
7294
|
var PACKAGED_CODEX_INSTALLER_NAMES = new Set([
|
|
7224
7295
|
"@code-yeongyu/lazycodex",
|
|
7225
7296
|
"@code-yeongyu/lazycodex-ai",
|
|
@@ -7229,19 +7300,19 @@ var PACKAGED_CODEX_INSTALLER_NAMES = new Set([
|
|
|
7229
7300
|
"oh-my-openagent"
|
|
7230
7301
|
]);
|
|
7231
7302
|
async function shouldBuildSourcePackages(repoRoot) {
|
|
7232
|
-
if (existsSync2(
|
|
7303
|
+
if (existsSync2(join12(repoRoot, "packages", "omo-opencode", "src", "index.ts")))
|
|
7233
7304
|
return true;
|
|
7234
|
-
const packageJsonPath =
|
|
7305
|
+
const packageJsonPath = join12(repoRoot, "package.json");
|
|
7235
7306
|
if (!existsSync2(packageJsonPath))
|
|
7236
7307
|
return true;
|
|
7237
|
-
const packageJson = JSON.parse(await
|
|
7308
|
+
const packageJson = JSON.parse(await readFile8(packageJsonPath, "utf8"));
|
|
7238
7309
|
if (!isPlainRecord(packageJson) || typeof packageJson.name !== "string")
|
|
7239
7310
|
return true;
|
|
7240
7311
|
return !PACKAGED_CODEX_INSTALLER_NAMES.has(packageJson.name);
|
|
7241
7312
|
}
|
|
7242
7313
|
|
|
7243
7314
|
// packages/omo-codex/src/install/codex-config-toml.ts
|
|
7244
|
-
import { mkdir as mkdir5, readFile as
|
|
7315
|
+
import { mkdir as mkdir5, readFile as readFile10 } from "node:fs/promises";
|
|
7245
7316
|
import { dirname as dirname5 } from "node:path";
|
|
7246
7317
|
|
|
7247
7318
|
// packages/omo-codex/src/install/toml-section-editor.ts
|
|
@@ -7429,12 +7500,12 @@ function tomlKeySegment(value) {
|
|
|
7429
7500
|
|
|
7430
7501
|
// packages/omo-codex/src/install/codex-config-atomic-write.ts
|
|
7431
7502
|
import { lstat as lstat5, readlink as readlink3, realpath, rename as rename2, unlink, writeFile as writeFile5 } from "node:fs/promises";
|
|
7432
|
-
import { basename as basename3, dirname as dirname4, isAbsolute as isAbsolute4, join as
|
|
7503
|
+
import { basename as basename3, dirname as dirname4, isAbsolute as isAbsolute4, join as join13, resolve as resolve5 } from "node:path";
|
|
7433
7504
|
var RENAME_RETRY_DELAYS_MS = [10, 25, 50];
|
|
7434
7505
|
var RETRIABLE_RENAME_CODES = new Set(["EPERM", "EBUSY"]);
|
|
7435
7506
|
async function writeFileAtomic(targetPath, data) {
|
|
7436
7507
|
const writeTarget = await resolveSymlinkTarget(targetPath);
|
|
7437
|
-
const temporaryPath =
|
|
7508
|
+
const temporaryPath = join13(dirname4(writeTarget), `.tmp-${basename3(writeTarget)}-${process.pid}-${Date.now()}`);
|
|
7438
7509
|
await writeFile5(temporaryPath, data);
|
|
7439
7510
|
try {
|
|
7440
7511
|
await renameWithRetry(temporaryPath, writeTarget);
|
|
@@ -7704,8 +7775,8 @@ function isRootSetting(line, key) {
|
|
|
7704
7775
|
}
|
|
7705
7776
|
|
|
7706
7777
|
// packages/omo-codex/src/install/codex-model-catalog.ts
|
|
7707
|
-
import { readFile as
|
|
7708
|
-
import { join as
|
|
7778
|
+
import { readFile as readFile9 } from "node:fs/promises";
|
|
7779
|
+
import { join as join14 } from "node:path";
|
|
7709
7780
|
var FALLBACK_CODEX_MODEL_CATALOG = {
|
|
7710
7781
|
current: {
|
|
7711
7782
|
model: "gpt-5.5",
|
|
@@ -7724,9 +7795,9 @@ var FALLBACK_CODEX_MODEL_CATALOG = {
|
|
|
7724
7795
|
]
|
|
7725
7796
|
};
|
|
7726
7797
|
async function readCodexModelCatalog(codexPackageRoot) {
|
|
7727
|
-
const catalogPath =
|
|
7798
|
+
const catalogPath = join14(codexPackageRoot, "plugin", "model-catalog.json");
|
|
7728
7799
|
try {
|
|
7729
|
-
const parsed = JSON.parse(await
|
|
7800
|
+
const parsed = JSON.parse(await readFile9(catalogPath, "utf8"));
|
|
7730
7801
|
return parseCodexModelCatalog(parsed) ?? FALLBACK_CODEX_MODEL_CATALOG;
|
|
7731
7802
|
} catch (error) {
|
|
7732
7803
|
if (error instanceof Error)
|
|
@@ -7807,7 +7878,7 @@ async function updateCodexConfig(input) {
|
|
|
7807
7878
|
await mkdir5(dirname5(input.configPath), { recursive: true });
|
|
7808
7879
|
let config = "";
|
|
7809
7880
|
if (await exists(input.configPath))
|
|
7810
|
-
config = await
|
|
7881
|
+
config = await readFile10(input.configPath, "utf8");
|
|
7811
7882
|
const pluginSet = new Set(input.pluginNames);
|
|
7812
7883
|
for (const legacyMarketplaceName of legacyMarketplaceNames(input.marketplaceName)) {
|
|
7813
7884
|
config = removeMarketplaceBlock(config, legacyMarketplaceName);
|
|
@@ -7843,7 +7914,7 @@ async function updateCodexConfig(input) {
|
|
|
7843
7914
|
}
|
|
7844
7915
|
async function exists(path) {
|
|
7845
7916
|
try {
|
|
7846
|
-
await
|
|
7917
|
+
await readFile10(path, "utf8");
|
|
7847
7918
|
return true;
|
|
7848
7919
|
} catch (error) {
|
|
7849
7920
|
if (error instanceof Error)
|
|
@@ -7854,8 +7925,8 @@ async function exists(path) {
|
|
|
7854
7925
|
|
|
7855
7926
|
// packages/omo-codex/src/install/codex-hook-trust.ts
|
|
7856
7927
|
import { createHash } from "node:crypto";
|
|
7857
|
-
import { readFile as
|
|
7858
|
-
import { join as
|
|
7928
|
+
import { readFile as readFile11 } from "node:fs/promises";
|
|
7929
|
+
import { join as join15 } from "node:path";
|
|
7859
7930
|
var EVENT_LABELS = new Map([
|
|
7860
7931
|
["PreToolUse", "pre_tool_use"],
|
|
7861
7932
|
["PermissionRequest", "permission_request"],
|
|
@@ -7869,21 +7940,37 @@ var EVENT_LABELS = new Map([
|
|
|
7869
7940
|
["Stop", "stop"]
|
|
7870
7941
|
]);
|
|
7871
7942
|
async function trustedHookStatesForPlugin(input) {
|
|
7872
|
-
const manifestPath =
|
|
7943
|
+
const manifestPath = join15(input.pluginRoot, ".codex-plugin", "plugin.json");
|
|
7873
7944
|
if (!await exists2(manifestPath))
|
|
7874
7945
|
return [];
|
|
7875
|
-
const manifest = JSON.parse(await
|
|
7876
|
-
if (!isPlainRecord(manifest)
|
|
7946
|
+
const manifest = JSON.parse(await readFile11(manifestPath, "utf8"));
|
|
7947
|
+
if (!isPlainRecord(manifest))
|
|
7877
7948
|
return [];
|
|
7878
|
-
const
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7949
|
+
const states = [];
|
|
7950
|
+
for (const hookPath of hookManifestPaths2(manifest.hooks)) {
|
|
7951
|
+
const hooksPath = join15(input.pluginRoot, hookPath);
|
|
7952
|
+
if (!await exists2(hooksPath))
|
|
7953
|
+
continue;
|
|
7954
|
+
const parsed = JSON.parse(await readFile11(hooksPath, "utf8"));
|
|
7955
|
+
if (!isPlainRecord(parsed) || !isPlainRecord(parsed.hooks))
|
|
7956
|
+
continue;
|
|
7957
|
+
states.push(...trustedHookStatesForHooksFile({
|
|
7958
|
+
keySource: `${input.pluginName}@${input.marketplaceName}:${hookPath}`,
|
|
7959
|
+
hooks: parsed.hooks
|
|
7960
|
+
}));
|
|
7961
|
+
}
|
|
7962
|
+
return states;
|
|
7963
|
+
}
|
|
7964
|
+
function hookManifestPaths2(value) {
|
|
7965
|
+
if (typeof value === "string" && value.trim() !== "")
|
|
7966
|
+
return [stripDotSlash2(value)];
|
|
7967
|
+
if (!Array.isArray(value))
|
|
7883
7968
|
return [];
|
|
7884
|
-
|
|
7969
|
+
return value.filter((item) => typeof item === "string" && item.trim() !== "").map(stripDotSlash2);
|
|
7970
|
+
}
|
|
7971
|
+
function trustedHookStatesForHooksFile(input) {
|
|
7885
7972
|
const states = [];
|
|
7886
|
-
for (const [eventName, groups] of Object.entries(
|
|
7973
|
+
for (const [eventName, groups] of Object.entries(input.hooks)) {
|
|
7887
7974
|
if (!Array.isArray(groups))
|
|
7888
7975
|
continue;
|
|
7889
7976
|
const eventLabel = EVENT_LABELS.get(eventName);
|
|
@@ -7899,7 +7986,7 @@ async function trustedHookStatesForPlugin(input) {
|
|
|
7899
7986
|
continue;
|
|
7900
7987
|
if (typeof handler.command !== "string" || handler.command.trim() === "")
|
|
7901
7988
|
continue;
|
|
7902
|
-
const key = `${keySource}:${eventLabel}:${groupIndex}:${handlerIndex}`;
|
|
7989
|
+
const key = `${input.keySource}:${eventLabel}:${groupIndex}:${handlerIndex}`;
|
|
7903
7990
|
states.push({ key, trustedHash: commandHookHash(eventLabel, group.matcher, handler) });
|
|
7904
7991
|
}
|
|
7905
7992
|
}
|
|
@@ -7933,12 +8020,12 @@ function canonicalJson(value) {
|
|
|
7933
8020
|
}
|
|
7934
8021
|
return result;
|
|
7935
8022
|
}
|
|
7936
|
-
function
|
|
8023
|
+
function stripDotSlash2(value) {
|
|
7937
8024
|
return value.startsWith("./") ? value.slice(2) : value;
|
|
7938
8025
|
}
|
|
7939
8026
|
async function exists2(path) {
|
|
7940
8027
|
try {
|
|
7941
|
-
await
|
|
8028
|
+
await readFile11(path, "utf8");
|
|
7942
8029
|
return true;
|
|
7943
8030
|
} catch (error) {
|
|
7944
8031
|
if (error instanceof Error)
|
|
@@ -7989,12 +8076,12 @@ function toCodexResolution(resolution) {
|
|
|
7989
8076
|
}
|
|
7990
8077
|
|
|
7991
8078
|
// packages/omo-codex/src/install/link-cached-plugin-agents.ts
|
|
7992
|
-
import { copyFile, lstat as lstat7, mkdir as mkdir6, readFile as
|
|
7993
|
-
import { basename as basename4, join as
|
|
8079
|
+
import { copyFile, lstat as lstat7, mkdir as mkdir6, readFile as readFile13, readdir as readdir4, rm as rm6, writeFile as writeFile6 } from "node:fs/promises";
|
|
8080
|
+
import { basename as basename4, join as join17 } from "node:path";
|
|
7994
8081
|
|
|
7995
8082
|
// packages/omo-codex/src/install/retired-managed-agent-purge.ts
|
|
7996
|
-
import { lstat as lstat6, readFile as
|
|
7997
|
-
import { join as
|
|
8083
|
+
import { lstat as lstat6, readFile as readFile12, rm as rm5 } from "node:fs/promises";
|
|
8084
|
+
import { join as join16 } from "node:path";
|
|
7998
8085
|
var RETIRED_MANAGED_AGENT_FILES = [
|
|
7999
8086
|
{
|
|
8000
8087
|
fileName: "codex-ultrawork-reviewer.toml",
|
|
@@ -8006,11 +8093,11 @@ var RETIRED_MANAGED_AGENT_FILES = [
|
|
|
8006
8093
|
}
|
|
8007
8094
|
];
|
|
8008
8095
|
async function purgeRetiredManagedAgentFiles(input) {
|
|
8009
|
-
const agentsDir =
|
|
8096
|
+
const agentsDir = join16(input.codexHome, "agents");
|
|
8010
8097
|
if (!await exists3(agentsDir))
|
|
8011
8098
|
return;
|
|
8012
8099
|
for (const retiredAgent of RETIRED_MANAGED_AGENT_FILES) {
|
|
8013
|
-
const agentPath =
|
|
8100
|
+
const agentPath = join16(agentsDir, retiredAgent.fileName);
|
|
8014
8101
|
if (!await exists3(agentPath))
|
|
8015
8102
|
continue;
|
|
8016
8103
|
const agentStat = await lstat6(agentPath);
|
|
@@ -8027,7 +8114,7 @@ function hasRequiredMarkers(content, markers) {
|
|
|
8027
8114
|
}
|
|
8028
8115
|
async function readTextIfExists(path) {
|
|
8029
8116
|
try {
|
|
8030
|
-
return await
|
|
8117
|
+
return await readFile12(path, "utf8");
|
|
8031
8118
|
} catch (error) {
|
|
8032
8119
|
if (nodeErrorCode(error) === "ENOENT")
|
|
8033
8120
|
return null;
|
|
@@ -8053,7 +8140,7 @@ function nodeErrorCode(error) {
|
|
|
8053
8140
|
// packages/omo-codex/src/install/link-cached-plugin-agents.ts
|
|
8054
8141
|
var MANIFEST_FILE = ".installed-agents.json";
|
|
8055
8142
|
async function capturePreservedAgentReasoning(input) {
|
|
8056
|
-
const agentsDir =
|
|
8143
|
+
const agentsDir = join17(input.codexHome, "agents");
|
|
8057
8144
|
if (!await exists4(agentsDir))
|
|
8058
8145
|
return new Map;
|
|
8059
8146
|
const preserved = new Map;
|
|
@@ -8061,7 +8148,7 @@ async function capturePreservedAgentReasoning(input) {
|
|
|
8061
8148
|
for (const entry of agentEntries) {
|
|
8062
8149
|
if (!entry.name.endsWith(".toml"))
|
|
8063
8150
|
continue;
|
|
8064
|
-
const content = await readTextIfExists2(
|
|
8151
|
+
const content = await readTextIfExists2(join17(agentsDir, entry.name));
|
|
8065
8152
|
if (content === null)
|
|
8066
8153
|
continue;
|
|
8067
8154
|
const effort = extractReasoningEffort(content);
|
|
@@ -8071,7 +8158,7 @@ async function capturePreservedAgentReasoning(input) {
|
|
|
8071
8158
|
return preserved;
|
|
8072
8159
|
}
|
|
8073
8160
|
async function capturePreservedAgentServiceTier(input) {
|
|
8074
|
-
const agentsDir =
|
|
8161
|
+
const agentsDir = join17(input.codexHome, "agents");
|
|
8075
8162
|
if (!await exists4(agentsDir))
|
|
8076
8163
|
return new Map;
|
|
8077
8164
|
const preserved = new Map;
|
|
@@ -8079,7 +8166,7 @@ async function capturePreservedAgentServiceTier(input) {
|
|
|
8079
8166
|
for (const entry of agentEntries) {
|
|
8080
8167
|
if (!entry.name.endsWith(".toml"))
|
|
8081
8168
|
continue;
|
|
8082
|
-
const content = await readTextIfExists2(
|
|
8169
|
+
const content = await readTextIfExists2(join17(agentsDir, entry.name));
|
|
8083
8170
|
if (content === null)
|
|
8084
8171
|
continue;
|
|
8085
8172
|
preserved.set(agentNameFromToml(entry.name), extractServiceTier(content));
|
|
@@ -8093,13 +8180,13 @@ async function linkCachedPluginAgents(input) {
|
|
|
8093
8180
|
await writeManifest(input.pluginRoot, []);
|
|
8094
8181
|
return [];
|
|
8095
8182
|
}
|
|
8096
|
-
const agentsDir =
|
|
8183
|
+
const agentsDir = join17(input.codexHome, "agents");
|
|
8097
8184
|
await mkdir6(agentsDir, { recursive: true });
|
|
8098
8185
|
const linked = [];
|
|
8099
8186
|
for (const agentPath of bundledAgents) {
|
|
8100
8187
|
const agentFileName = basename4(agentPath);
|
|
8101
8188
|
const agentName = agentNameFromToml(agentFileName);
|
|
8102
|
-
const linkPath =
|
|
8189
|
+
const linkPath = join17(agentsDir, agentFileName);
|
|
8103
8190
|
await replaceWithCopy(linkPath, agentPath);
|
|
8104
8191
|
await restorePreservedReasoning({
|
|
8105
8192
|
agentName,
|
|
@@ -8120,7 +8207,7 @@ async function linkCachedPluginAgents(input) {
|
|
|
8120
8207
|
async function restorePreservedServiceTier(input) {
|
|
8121
8208
|
if (!input.preserved)
|
|
8122
8209
|
return;
|
|
8123
|
-
const content = await
|
|
8210
|
+
const content = await readFile13(input.linkPath, "utf8");
|
|
8124
8211
|
if (extractServiceTier(content) === input.value)
|
|
8125
8212
|
return;
|
|
8126
8213
|
const replacement = replaceServiceTier(content, input.value);
|
|
@@ -8129,7 +8216,7 @@ async function restorePreservedServiceTier(input) {
|
|
|
8129
8216
|
await writeFile6(input.linkPath, replacement.content);
|
|
8130
8217
|
}
|
|
8131
8218
|
async function discoverBundledAgents(pluginRoot) {
|
|
8132
|
-
const componentsRoot =
|
|
8219
|
+
const componentsRoot = join17(pluginRoot, "components");
|
|
8133
8220
|
if (!await exists4(componentsRoot))
|
|
8134
8221
|
return [];
|
|
8135
8222
|
const componentEntries = await readdir4(componentsRoot, { withFileTypes: true });
|
|
@@ -8137,14 +8224,14 @@ async function discoverBundledAgents(pluginRoot) {
|
|
|
8137
8224
|
for (const entry of componentEntries) {
|
|
8138
8225
|
if (!entry.isDirectory())
|
|
8139
8226
|
continue;
|
|
8140
|
-
const agentsRoot =
|
|
8227
|
+
const agentsRoot = join17(componentsRoot, entry.name, "agents");
|
|
8141
8228
|
if (!await exists4(agentsRoot))
|
|
8142
8229
|
continue;
|
|
8143
8230
|
const agentEntries = await readdir4(agentsRoot, { withFileTypes: true });
|
|
8144
8231
|
for (const file2 of agentEntries) {
|
|
8145
8232
|
if (!file2.isFile() || !file2.name.endsWith(".toml"))
|
|
8146
8233
|
continue;
|
|
8147
|
-
agents.push(
|
|
8234
|
+
agents.push(join17(agentsRoot, file2.name));
|
|
8148
8235
|
}
|
|
8149
8236
|
}
|
|
8150
8237
|
agents.sort();
|
|
@@ -8164,7 +8251,7 @@ async function prepareReplacement(linkPath) {
|
|
|
8164
8251
|
await rm6(linkPath, { force: true });
|
|
8165
8252
|
}
|
|
8166
8253
|
async function writeManifest(pluginRoot, agentPaths) {
|
|
8167
|
-
const manifestPath =
|
|
8254
|
+
const manifestPath = join17(pluginRoot, MANIFEST_FILE);
|
|
8168
8255
|
const payload = { agents: [...agentPaths].sort() };
|
|
8169
8256
|
await writeFile6(manifestPath, `${JSON.stringify(payload, null, "\t")}
|
|
8170
8257
|
`);
|
|
@@ -8172,7 +8259,7 @@ async function writeManifest(pluginRoot, agentPaths) {
|
|
|
8172
8259
|
async function restorePreservedReasoning(input) {
|
|
8173
8260
|
if (input.value === undefined)
|
|
8174
8261
|
return;
|
|
8175
|
-
const content = await
|
|
8262
|
+
const content = await readFile13(input.target, "utf8");
|
|
8176
8263
|
const bundledEffort = extractReasoningEffort(content);
|
|
8177
8264
|
if (bundledEffort === input.value)
|
|
8178
8265
|
return;
|
|
@@ -8183,7 +8270,7 @@ async function restorePreservedReasoning(input) {
|
|
|
8183
8270
|
}
|
|
8184
8271
|
async function readTextIfExists2(path) {
|
|
8185
8272
|
try {
|
|
8186
|
-
return await
|
|
8273
|
+
return await readFile13(path, "utf8");
|
|
8187
8274
|
} catch (error) {
|
|
8188
8275
|
if (nodeErrorCode2(error) === "ENOENT")
|
|
8189
8276
|
return null;
|
|
@@ -8291,12 +8378,12 @@ function nodeErrorCode2(error) {
|
|
|
8291
8378
|
}
|
|
8292
8379
|
|
|
8293
8380
|
// packages/omo-codex/src/install/codex-marketplace.ts
|
|
8294
|
-
import { readFile as
|
|
8295
|
-
import { join as
|
|
8381
|
+
import { readFile as readFile14 } from "node:fs/promises";
|
|
8382
|
+
import { join as join18 } from "node:path";
|
|
8296
8383
|
var DEFAULT_MARKETPLACE_PATH = "packages/omo-codex/marketplace.json";
|
|
8297
8384
|
async function readMarketplace(repoRoot, options) {
|
|
8298
|
-
const marketplacePath = options?.marketplacePath ??
|
|
8299
|
-
const raw = await
|
|
8385
|
+
const marketplacePath = options?.marketplacePath ?? join18(repoRoot, DEFAULT_MARKETPLACE_PATH);
|
|
8386
|
+
const raw = await readFile14(marketplacePath, "utf8");
|
|
8300
8387
|
const parsed = JSON.parse(raw);
|
|
8301
8388
|
if (!isPlainRecord(parsed))
|
|
8302
8389
|
throw new Error("marketplace.json must be an object");
|
|
@@ -8314,10 +8401,10 @@ async function readMarketplace(repoRoot, options) {
|
|
|
8314
8401
|
function resolvePluginSource(repoRoot, plugin, options) {
|
|
8315
8402
|
const sourcePath = localSourcePath(options?.pathOverride ?? plugin.source);
|
|
8316
8403
|
const relativePath = sourcePath.slice(2);
|
|
8317
|
-
return
|
|
8404
|
+
return join18(repoRoot, ...relativePath.split(/[\\/]/));
|
|
8318
8405
|
}
|
|
8319
8406
|
async function readPluginManifest(pluginRoot) {
|
|
8320
|
-
const raw = await
|
|
8407
|
+
const raw = await readFile14(join18(pluginRoot, ".codex-plugin", "plugin.json"), "utf8");
|
|
8321
8408
|
const parsed = JSON.parse(raw);
|
|
8322
8409
|
if (!isPlainRecord(parsed))
|
|
8323
8410
|
throw new Error(`${pluginRoot} plugin.json must be an object`);
|
|
@@ -8327,15 +8414,27 @@ async function readPluginManifest(pluginRoot) {
|
|
|
8327
8414
|
if (parsed.version !== undefined && (typeof parsed.version !== "string" || parsed.version.trim() === "")) {
|
|
8328
8415
|
throw new Error(`${pluginRoot} plugin.json version must be a non-empty string`);
|
|
8329
8416
|
}
|
|
8330
|
-
if (parsed.hooks !== undefined && (
|
|
8331
|
-
throw new Error(`${pluginRoot} plugin.json hooks must be a non-empty string`);
|
|
8417
|
+
if (parsed.hooks !== undefined && !isPluginHooksManifestValue(parsed.hooks)) {
|
|
8418
|
+
throw new Error(`${pluginRoot} plugin.json hooks must be a non-empty string or string array`);
|
|
8332
8419
|
}
|
|
8333
8420
|
return {
|
|
8334
8421
|
name: parsed.name,
|
|
8335
8422
|
version: typeof parsed.version === "string" ? parsed.version.trim() : undefined,
|
|
8336
|
-
hooks:
|
|
8423
|
+
hooks: normalizePluginHooksManifestValue(parsed.hooks)
|
|
8337
8424
|
};
|
|
8338
8425
|
}
|
|
8426
|
+
function isPluginHooksManifestValue(value) {
|
|
8427
|
+
if (typeof value === "string")
|
|
8428
|
+
return value.trim() !== "";
|
|
8429
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string" && item.trim() !== "");
|
|
8430
|
+
}
|
|
8431
|
+
function normalizePluginHooksManifestValue(value) {
|
|
8432
|
+
if (typeof value === "string")
|
|
8433
|
+
return value.trim();
|
|
8434
|
+
if (Array.isArray(value))
|
|
8435
|
+
return value.map((item) => item.trim());
|
|
8436
|
+
return;
|
|
8437
|
+
}
|
|
8339
8438
|
function validatePathSegment(value, label) {
|
|
8340
8439
|
if (!/^[A-Za-z0-9._+-]+$/.test(value)) {
|
|
8341
8440
|
throw new Error(`${label} contains unsupported characters: ${value}`);
|
|
@@ -8387,7 +8486,7 @@ function validateLocalSourcePath(path) {
|
|
|
8387
8486
|
|
|
8388
8487
|
// packages/omo-codex/src/install/codex-marketplace-snapshot.ts
|
|
8389
8488
|
import { cp as cp3, mkdir as mkdir7, rename as rename3, rm as rm7, writeFile as writeFile7 } from "node:fs/promises";
|
|
8390
|
-
import { join as
|
|
8489
|
+
import { join as join19, sep as sep6 } from "node:path";
|
|
8391
8490
|
var INSTALLED_MARKETPLACES_DIR = ".tmp/marketplaces";
|
|
8392
8491
|
async function writeInstalledMarketplaceSnapshot(input) {
|
|
8393
8492
|
const marketplaceRoot = installedMarketplaceRoot(input.codexHome, input.marketplace.name);
|
|
@@ -8400,21 +8499,21 @@ async function writeInstalledMarketplaceSnapshot(input) {
|
|
|
8400
8499
|
return snapshotPlugins;
|
|
8401
8500
|
}
|
|
8402
8501
|
function installedMarketplaceRoot(codexHome, marketplaceName) {
|
|
8403
|
-
return
|
|
8502
|
+
return join19(codexHome, INSTALLED_MARKETPLACES_DIR, marketplaceName);
|
|
8404
8503
|
}
|
|
8405
8504
|
async function writeMarketplaceManifest(marketplaceRoot, marketplace) {
|
|
8406
|
-
const manifestDir =
|
|
8505
|
+
const manifestDir = join19(marketplaceRoot, ".agents", "plugins");
|
|
8407
8506
|
await mkdir7(manifestDir, { recursive: true });
|
|
8408
|
-
const tempPath =
|
|
8507
|
+
const tempPath = join19(manifestDir, `.marketplace-${process.pid}-${Date.now()}.json.tmp`);
|
|
8409
8508
|
await writeFile7(tempPath, `${JSON.stringify(marketplace, null, "\t")}
|
|
8410
8509
|
`);
|
|
8411
|
-
await rename3(tempPath,
|
|
8510
|
+
await rename3(tempPath, join19(manifestDir, "marketplace.json"));
|
|
8412
8511
|
}
|
|
8413
8512
|
async function writeSnapshotPlugin(marketplaceRoot, plugin) {
|
|
8414
|
-
const pluginsDir =
|
|
8513
|
+
const pluginsDir = join19(marketplaceRoot, "plugins");
|
|
8415
8514
|
await mkdir7(pluginsDir, { recursive: true });
|
|
8416
|
-
const targetPath =
|
|
8417
|
-
const tempPath =
|
|
8515
|
+
const targetPath = join19(pluginsDir, plugin.name);
|
|
8516
|
+
const tempPath = join19(pluginsDir, `.tmp-${plugin.name}-${process.pid}-${Date.now()}`);
|
|
8418
8517
|
await rm7(tempPath, { recursive: true, force: true });
|
|
8419
8518
|
await cp3(plugin.sourcePath, tempPath, {
|
|
8420
8519
|
recursive: true,
|
|
@@ -8427,19 +8526,19 @@ async function writeSnapshotPlugin(marketplaceRoot, plugin) {
|
|
|
8427
8526
|
return { name: plugin.name, path: targetPath };
|
|
8428
8527
|
}
|
|
8429
8528
|
function shouldCopyMarketplaceSourcePath(path, root) {
|
|
8430
|
-
const relative4 = path === root ? "" : path.slice(root.length +
|
|
8529
|
+
const relative4 = path === root ? "" : path.slice(root.length + sep6.length);
|
|
8431
8530
|
if (relative4 === "")
|
|
8432
8531
|
return true;
|
|
8433
|
-
const parts = relative4.split(
|
|
8532
|
+
const parts = relative4.split(sep6);
|
|
8434
8533
|
return !parts.some((part) => part === ".git" || part === "node_modules");
|
|
8435
8534
|
}
|
|
8436
8535
|
|
|
8437
8536
|
// packages/omo-codex/src/install/lazycodex-version-stamp.ts
|
|
8438
|
-
import { readdir as readdir5, readFile as
|
|
8439
|
-
import { join as
|
|
8537
|
+
import { readdir as readdir5, readFile as readFile15, writeFile as writeFile8 } from "node:fs/promises";
|
|
8538
|
+
import { join as join20 } from "node:path";
|
|
8440
8539
|
async function readDistributionManifest(repoRoot) {
|
|
8441
8540
|
try {
|
|
8442
|
-
const parsed = JSON.parse(await
|
|
8541
|
+
const parsed = JSON.parse(await readFile15(join20(repoRoot, "package.json"), "utf8"));
|
|
8443
8542
|
if (!isPlainRecord(parsed) || typeof parsed.version !== "string" || parsed.version.trim().length === 0)
|
|
8444
8543
|
return;
|
|
8445
8544
|
return {
|
|
@@ -8459,15 +8558,19 @@ function resolveLazyCodexPluginVersion(input) {
|
|
|
8459
8558
|
return input.manifestVersion ?? "local";
|
|
8460
8559
|
}
|
|
8461
8560
|
async function stampLazyCodexPluginVersion(input) {
|
|
8462
|
-
|
|
8463
|
-
await
|
|
8464
|
-
await
|
|
8561
|
+
const manifestPath = join20(input.pluginRoot, ".codex-plugin", "plugin.json");
|
|
8562
|
+
const hookPaths = await readPluginHookPaths(manifestPath);
|
|
8563
|
+
await stampJsonVersion(manifestPath, input.version);
|
|
8564
|
+
await stampJsonVersion(join20(input.pluginRoot, "package.json"), input.version);
|
|
8565
|
+
for (const hookPath of hookPaths) {
|
|
8566
|
+
await stampHookStatusMessages(join20(input.pluginRoot, hookPath), input.version);
|
|
8567
|
+
}
|
|
8465
8568
|
await stampComponentVersions(input);
|
|
8466
8569
|
}
|
|
8467
8570
|
async function writeLazyCodexInstallSnapshot(input) {
|
|
8468
8571
|
if (input.distributionManifest === undefined)
|
|
8469
8572
|
return;
|
|
8470
|
-
await writeFile8(
|
|
8573
|
+
await writeFile8(join20(input.pluginRoot, "lazycodex-install.json"), `${JSON.stringify({
|
|
8471
8574
|
packageName: input.distributionManifest.name,
|
|
8472
8575
|
version: input.distributionManifest.version
|
|
8473
8576
|
}, null, "\t")}
|
|
@@ -8475,7 +8578,7 @@ async function writeLazyCodexInstallSnapshot(input) {
|
|
|
8475
8578
|
}
|
|
8476
8579
|
async function stampJsonVersion(path, version) {
|
|
8477
8580
|
try {
|
|
8478
|
-
const parsed = JSON.parse(await
|
|
8581
|
+
const parsed = JSON.parse(await readFile15(path, "utf8"));
|
|
8479
8582
|
if (!isPlainRecord(parsed))
|
|
8480
8583
|
return;
|
|
8481
8584
|
parsed.version = version;
|
|
@@ -8487,9 +8590,29 @@ async function stampJsonVersion(path, version) {
|
|
|
8487
8590
|
throw error;
|
|
8488
8591
|
}
|
|
8489
8592
|
}
|
|
8593
|
+
async function readPluginHookPaths(manifestPath) {
|
|
8594
|
+
try {
|
|
8595
|
+
const parsed = JSON.parse(await readFile15(manifestPath, "utf8"));
|
|
8596
|
+
if (!isPlainRecord(parsed))
|
|
8597
|
+
return [];
|
|
8598
|
+
if (typeof parsed.hooks === "string" && parsed.hooks.trim().length > 0)
|
|
8599
|
+
return [stripDotSlash3(parsed.hooks)];
|
|
8600
|
+
if (Array.isArray(parsed.hooks)) {
|
|
8601
|
+
return parsed.hooks.filter((hookPath) => typeof hookPath === "string" && hookPath.trim().length > 0).map(stripDotSlash3);
|
|
8602
|
+
}
|
|
8603
|
+
return [];
|
|
8604
|
+
} catch (error) {
|
|
8605
|
+
if (error instanceof Error)
|
|
8606
|
+
return [];
|
|
8607
|
+
throw error;
|
|
8608
|
+
}
|
|
8609
|
+
}
|
|
8610
|
+
function stripDotSlash3(path) {
|
|
8611
|
+
return path.startsWith("./") ? path.slice(2) : path;
|
|
8612
|
+
}
|
|
8490
8613
|
async function stampHookStatusMessages(path, version) {
|
|
8491
8614
|
try {
|
|
8492
|
-
const parsed = JSON.parse(await
|
|
8615
|
+
const parsed = JSON.parse(await readFile15(path, "utf8"));
|
|
8493
8616
|
if (!isPlainRecord(parsed))
|
|
8494
8617
|
return;
|
|
8495
8618
|
stampHookGroups(parsed.hooks, version);
|
|
@@ -8504,16 +8627,16 @@ async function stampHookStatusMessages(path, version) {
|
|
|
8504
8627
|
async function stampComponentVersions(input) {
|
|
8505
8628
|
let entries;
|
|
8506
8629
|
try {
|
|
8507
|
-
entries = await readdir5(
|
|
8630
|
+
entries = await readdir5(join20(input.pluginRoot, "components"));
|
|
8508
8631
|
} catch (error) {
|
|
8509
8632
|
if (error instanceof Error)
|
|
8510
8633
|
return;
|
|
8511
8634
|
throw error;
|
|
8512
8635
|
}
|
|
8513
8636
|
for (const entry of entries) {
|
|
8514
|
-
const componentRoot =
|
|
8515
|
-
await stampJsonVersion(
|
|
8516
|
-
await stampHookStatusMessages(
|
|
8637
|
+
const componentRoot = join20(input.pluginRoot, "components", entry);
|
|
8638
|
+
await stampJsonVersion(join20(componentRoot, "package.json"), input.version);
|
|
8639
|
+
await stampHookStatusMessages(join20(componentRoot, "hooks", "hooks.json"), input.version);
|
|
8517
8640
|
}
|
|
8518
8641
|
}
|
|
8519
8642
|
function stampHookGroups(hooks, version) {
|
|
@@ -8534,12 +8657,12 @@ function stampHookGroups(hooks, version) {
|
|
|
8534
8657
|
function stampHookStatusMessage(hook, version) {
|
|
8535
8658
|
if (!isPlainRecord(hook) || typeof hook.statusMessage !== "string")
|
|
8536
8659
|
return;
|
|
8537
|
-
hook.statusMessage = hook.statusMessage.replace(/^LazyCodex\([^)]+\)
|
|
8660
|
+
hook.statusMessage = hook.statusMessage.replace(/^LazyCodex\([^)]+\):\s*/, "(OmO) ");
|
|
8538
8661
|
}
|
|
8539
8662
|
|
|
8540
8663
|
// packages/omo-codex/src/install/codex-project-local-cleanup.ts
|
|
8541
|
-
import { copyFile as copyFile2, lstat as lstat8, readFile as
|
|
8542
|
-
import { dirname as dirname6, join as
|
|
8664
|
+
import { copyFile as copyFile2, lstat as lstat8, readFile as readFile16, writeFile as writeFile9 } from "node:fs/promises";
|
|
8665
|
+
import { dirname as dirname6, join as join21, resolve as resolve6 } from "node:path";
|
|
8543
8666
|
var LEGACY_AGENT_CONFLICT_KEYS = ["max_threads"];
|
|
8544
8667
|
var PROJECT_LOCAL_ARTIFACT_PATHS = [
|
|
8545
8668
|
".codex/hooks.json",
|
|
@@ -8558,7 +8681,7 @@ async function repairNearestProjectLocalCodexArtifacts(input) {
|
|
|
8558
8681
|
const artifacts = await collectProjectLocalArtifacts(project.artifactRoots);
|
|
8559
8682
|
const configs = [];
|
|
8560
8683
|
for (const configPath of project.configPaths) {
|
|
8561
|
-
const original = await
|
|
8684
|
+
const original = await readFile16(configPath, "utf8");
|
|
8562
8685
|
const repair = repairProjectLocalCodexConfigText(original);
|
|
8563
8686
|
if (!repair.changed) {
|
|
8564
8687
|
configs.push({
|
|
@@ -8642,17 +8765,17 @@ async function findProjectLocalCodexConfigs(startDirectory, codexHome) {
|
|
|
8642
8765
|
if (startDirectoryStat !== null && !startDirectoryStat.isDirectory()) {
|
|
8643
8766
|
throw new ProjectLocalCleanupStartDirectoryError(startDirectory);
|
|
8644
8767
|
}
|
|
8645
|
-
const codexHomeConfigPath = codexHome === undefined ? null :
|
|
8768
|
+
const codexHomeConfigPath = codexHome === undefined ? null : join21(resolve6(codexHome), "config.toml");
|
|
8646
8769
|
let current = resolve6(startDirectory);
|
|
8647
8770
|
const configPathsFromCwd = [];
|
|
8648
8771
|
while (true) {
|
|
8649
|
-
const configPath =
|
|
8772
|
+
const configPath = join21(current, ".codex", "config.toml");
|
|
8650
8773
|
if (await isRegularProjectLocalConfig(current, configPath)) {
|
|
8651
8774
|
if (codexHomeConfigPath === null || resolve6(configPath) !== codexHomeConfigPath) {
|
|
8652
8775
|
configPathsFromCwd.push(configPath);
|
|
8653
8776
|
}
|
|
8654
8777
|
}
|
|
8655
|
-
if (await exists5(
|
|
8778
|
+
if (await exists5(join21(current, ".git"))) {
|
|
8656
8779
|
return configPathsFromCwd.length === 0 ? null : {
|
|
8657
8780
|
projectRoot: current,
|
|
8658
8781
|
configPaths: [...configPathsFromCwd].reverse(),
|
|
@@ -8672,7 +8795,7 @@ async function findProjectLocalCodexConfigs(startDirectory, codexHome) {
|
|
|
8672
8795
|
}
|
|
8673
8796
|
}
|
|
8674
8797
|
async function isRegularProjectLocalConfig(directory, configPath) {
|
|
8675
|
-
const codexDirStat = await maybeLstat(
|
|
8798
|
+
const codexDirStat = await maybeLstat(join21(directory, ".codex"));
|
|
8676
8799
|
if (codexDirStat === null || !codexDirStat.isDirectory() || codexDirStat.isSymbolicLink())
|
|
8677
8800
|
return false;
|
|
8678
8801
|
const configStat = await maybeLstat(configPath);
|
|
@@ -8692,7 +8815,7 @@ async function collectProjectLocalArtifacts(projectRoots) {
|
|
|
8692
8815
|
const seenPaths = new Set;
|
|
8693
8816
|
for (const projectRoot of projectRoots) {
|
|
8694
8817
|
for (const relativePath of PROJECT_LOCAL_ARTIFACT_PATHS) {
|
|
8695
|
-
const artifactPath =
|
|
8818
|
+
const artifactPath = join21(projectRoot, relativePath);
|
|
8696
8819
|
if (seenPaths.has(artifactPath))
|
|
8697
8820
|
continue;
|
|
8698
8821
|
const entryStat = await maybeLstat(artifactPath);
|
|
@@ -8767,13 +8890,13 @@ function formatUnknownError(error) {
|
|
|
8767
8890
|
}
|
|
8768
8891
|
|
|
8769
8892
|
// packages/omo-codex/src/install/lsp-daemon-reaper.ts
|
|
8770
|
-
import { readFile as
|
|
8893
|
+
import { readFile as readFile17, readdir as readdir6, rm as rm8 } from "node:fs/promises";
|
|
8771
8894
|
import { connect } from "node:net";
|
|
8772
|
-
import { join as
|
|
8895
|
+
import { join as join22 } from "node:path";
|
|
8773
8896
|
async function reapLspDaemons(codexHome, deps = {}) {
|
|
8774
8897
|
const killProcess = deps.killProcess ?? sendSigterm;
|
|
8775
8898
|
const isDaemonLive = deps.isDaemonLive ?? probeSocketLive;
|
|
8776
|
-
const daemonRoot =
|
|
8899
|
+
const daemonRoot = join22(codexHome, "codex-lsp", "daemon");
|
|
8777
8900
|
const reaped = [];
|
|
8778
8901
|
let entries;
|
|
8779
8902
|
try {
|
|
@@ -8782,9 +8905,9 @@ async function reapLspDaemons(codexHome, deps = {}) {
|
|
|
8782
8905
|
return reaped;
|
|
8783
8906
|
}
|
|
8784
8907
|
for (const entry of entries) {
|
|
8785
|
-
const versionDir =
|
|
8786
|
-
const pid = await readPidFile(
|
|
8787
|
-
const socketPath = await readEndpointFile(
|
|
8908
|
+
const versionDir = join22(daemonRoot, entry);
|
|
8909
|
+
const pid = await readPidFile(join22(versionDir, "daemon.pid"));
|
|
8910
|
+
const socketPath = await readEndpointFile(join22(versionDir, "daemon.endpoint"));
|
|
8788
8911
|
if (pid !== null && socketPath !== null && await isDaemonLive(socketPath) && killProcess(pid)) {
|
|
8789
8912
|
reaped.push(pid);
|
|
8790
8913
|
}
|
|
@@ -8794,7 +8917,7 @@ async function reapLspDaemons(codexHome, deps = {}) {
|
|
|
8794
8917
|
}
|
|
8795
8918
|
async function readEndpointFile(path) {
|
|
8796
8919
|
try {
|
|
8797
|
-
const content = (await
|
|
8920
|
+
const content = (await readFile17(path, "utf8")).trim();
|
|
8798
8921
|
return content.length > 0 ? content : null;
|
|
8799
8922
|
} catch {
|
|
8800
8923
|
return null;
|
|
@@ -8802,7 +8925,7 @@ async function readEndpointFile(path) {
|
|
|
8802
8925
|
}
|
|
8803
8926
|
async function readPidFile(path) {
|
|
8804
8927
|
try {
|
|
8805
|
-
const pid = Number.parseInt((await
|
|
8928
|
+
const pid = Number.parseInt((await readFile17(path, "utf8")).trim(), 10);
|
|
8806
8929
|
return Number.isInteger(pid) && pid > 0 ? pid : null;
|
|
8807
8930
|
} catch {
|
|
8808
8931
|
return null;
|
|
@@ -8838,7 +8961,7 @@ function sendSigterm(pid) {
|
|
|
8838
8961
|
|
|
8839
8962
|
// packages/omo-codex/src/install/codex-installer-bin-dir.ts
|
|
8840
8963
|
import { homedir } from "node:os";
|
|
8841
|
-
import { join as
|
|
8964
|
+
import { join as join23, resolve as resolve7 } from "node:path";
|
|
8842
8965
|
function resolveCodexInstallerBinDir(input) {
|
|
8843
8966
|
const explicitBinDir = input.binDir ?? input.env?.CODEX_LOCAL_BIN_DIR;
|
|
8844
8967
|
if (explicitBinDir !== undefined && explicitBinDir.trim().length > 0)
|
|
@@ -8847,15 +8970,15 @@ function resolveCodexInstallerBinDir(input) {
|
|
|
8847
8970
|
const defaultCodexHome = resolve7(homeDir, ".codex");
|
|
8848
8971
|
const resolvedCodexHome = resolve7(input.codexHome);
|
|
8849
8972
|
if (resolvedCodexHome !== defaultCodexHome)
|
|
8850
|
-
return
|
|
8973
|
+
return join23(resolvedCodexHome, "bin");
|
|
8851
8974
|
return resolve7(homeDir, ".local", "bin");
|
|
8852
8975
|
}
|
|
8853
8976
|
|
|
8854
8977
|
// packages/omo-codex/src/install/omo-sot-migration.ts
|
|
8855
|
-
import { join as
|
|
8978
|
+
import { join as join24 } from "node:path";
|
|
8856
8979
|
async function seedAndMigrateOmoSot(input) {
|
|
8857
8980
|
const commandEnv = { ...input.env };
|
|
8858
|
-
const scriptPath =
|
|
8981
|
+
const scriptPath = join24(input.repoRoot, "packages", "omo-codex", "plugin", "scripts", "migrate-omo-sot.mjs");
|
|
8859
8982
|
try {
|
|
8860
8983
|
await input.runCommand(process.execPath, [scriptPath, "--seed"], {
|
|
8861
8984
|
cwd: input.repoRoot,
|
|
@@ -8869,7 +8992,7 @@ async function seedAndMigrateOmoSot(input) {
|
|
|
8869
8992
|
}
|
|
8870
8993
|
|
|
8871
8994
|
// packages/omo-codex/src/install/install-ast-grep-sg.ts
|
|
8872
|
-
import { join as
|
|
8995
|
+
import { join as join26 } from "node:path";
|
|
8873
8996
|
|
|
8874
8997
|
// packages/utils/src/deep-merge.ts
|
|
8875
8998
|
var DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
|
@@ -11841,11 +11964,11 @@ function runtimeSlug(platform = process.platform, arch = process.arch) {
|
|
|
11841
11964
|
// packages/utils/src/ast-grep/install-script.ts
|
|
11842
11965
|
import { spawn as spawn3 } from "node:child_process";
|
|
11843
11966
|
import { existsSync as existsSync3 } from "node:fs";
|
|
11844
|
-
import { join as
|
|
11967
|
+
import { join as join25 } from "node:path";
|
|
11845
11968
|
var AST_GREP_BIN_DIR_ENV_KEY = "OMO_AST_GREP_BIN_DIR";
|
|
11846
11969
|
var AST_GREP_INSTALL_TIMEOUT_MS = 30000;
|
|
11847
11970
|
function astGrepRuntimeDir(baseDir, platform = process.platform, arch = process.arch) {
|
|
11848
|
-
return
|
|
11971
|
+
return join25(baseDir, "runtime", "ast-grep", runtimeSlug(platform, arch));
|
|
11849
11972
|
}
|
|
11850
11973
|
function isMissingExecutable(error) {
|
|
11851
11974
|
if (!("code" in error))
|
|
@@ -11883,7 +12006,7 @@ function defaultSpawnProcess(command, args, options) {
|
|
|
11883
12006
|
};
|
|
11884
12007
|
}
|
|
11885
12008
|
function scriptPathForPlatform(skillDir, platform) {
|
|
11886
|
-
return
|
|
12009
|
+
return join25(skillDir, platform === "win32" ? "install.ps1" : "install.sh");
|
|
11887
12010
|
}
|
|
11888
12011
|
function invocationsForPlatform(scriptPath, platform) {
|
|
11889
12012
|
if (platform !== "win32")
|
|
@@ -12651,7 +12774,7 @@ async function installAstGrepForCodex(options) {
|
|
|
12651
12774
|
return;
|
|
12652
12775
|
const platform = options.platform ?? process.platform;
|
|
12653
12776
|
const targetDir = astGrepRuntimeDir(options.codexHome, platform, options.arch ?? process.arch);
|
|
12654
|
-
const skillDir =
|
|
12777
|
+
const skillDir = join26(plugin.path, "skills", "ast-grep");
|
|
12655
12778
|
const installer = options.installer ?? runAstGrepSkillInstall;
|
|
12656
12779
|
try {
|
|
12657
12780
|
const result = await installer({ platform, skillDir, targetDir });
|
|
@@ -12684,7 +12807,7 @@ async function runCodexInstaller(options = {}) {
|
|
|
12684
12807
|
const env3 = options.env ?? process.env;
|
|
12685
12808
|
const platform = options.platform ?? process.platform;
|
|
12686
12809
|
const repoRoot = resolve10(options.repoRoot ?? findRepoRoot({ importerDir: import.meta.dir, env: env3 }));
|
|
12687
|
-
const codexHome = resolve10(options.codexHome ?? env3.CODEX_HOME ??
|
|
12810
|
+
const codexHome = resolve10(options.codexHome ?? env3.CODEX_HOME ?? join29(homedir2(), ".codex"));
|
|
12688
12811
|
const projectDirectory = resolve10(options.projectDirectory ?? env3.OMO_CODEX_PROJECT ?? process.cwd());
|
|
12689
12812
|
const binDir = resolveCodexInstallerBinDir({ binDir: options.binDir, codexHome, env: env3 });
|
|
12690
12813
|
const runCommand = options.runCommand ?? defaultRunCommand;
|
|
@@ -12702,9 +12825,9 @@ async function runCodexInstaller(options = {}) {
|
|
|
12702
12825
|
if (!gitBashResolution.found) {
|
|
12703
12826
|
throw new Error(gitBashResolution.installHint);
|
|
12704
12827
|
}
|
|
12705
|
-
const codexPackageRoot =
|
|
12828
|
+
const codexPackageRoot = join29(repoRoot, "packages", "omo-codex");
|
|
12706
12829
|
const marketplace = await readMarketplace(repoRoot, {
|
|
12707
|
-
marketplacePath:
|
|
12830
|
+
marketplacePath: join29(codexPackageRoot, "marketplace.json")
|
|
12708
12831
|
});
|
|
12709
12832
|
const distributionManifest = await readDistributionManifest(repoRoot);
|
|
12710
12833
|
const installed = [];
|
|
@@ -12746,7 +12869,7 @@ async function runCodexInstaller(options = {}) {
|
|
|
12746
12869
|
if (runtimeLink !== null)
|
|
12747
12870
|
log2(`Linked ${runtimeLink.name} -> ${runtimeLink.target}`);
|
|
12748
12871
|
else
|
|
12749
|
-
log2(`Warning: skipped the omo runtime wrapper because ${
|
|
12872
|
+
log2(`Warning: skipped the omo runtime wrapper because ${join29(repoRoot, "dist", "cli", "index.js")} is missing; omo sparkshell/ulw-loop commands will be unavailable until a package shipping dist/cli is installed`);
|
|
12750
12873
|
}
|
|
12751
12874
|
pluginSources.push({ name: entry.name, sourcePath });
|
|
12752
12875
|
installed.push(plugin);
|
|
@@ -12799,13 +12922,13 @@ async function runCodexInstaller(options = {}) {
|
|
|
12799
12922
|
});
|
|
12800
12923
|
}
|
|
12801
12924
|
await reapLspDaemons(codexHome).catch(() => []);
|
|
12802
|
-
const marketplaceRoot =
|
|
12925
|
+
const marketplaceRoot = join29(codexHome, "plugins", "cache", marketplace.name);
|
|
12803
12926
|
await writeCachedMarketplaceManifest({
|
|
12804
12927
|
marketplaceName: marketplace.name,
|
|
12805
12928
|
marketplaceRoot,
|
|
12806
12929
|
plugins: installed
|
|
12807
12930
|
});
|
|
12808
|
-
const configPath =
|
|
12931
|
+
const configPath = join29(codexHome, "config.toml");
|
|
12809
12932
|
await updateCodexConfig({
|
|
12810
12933
|
configPath,
|
|
12811
12934
|
repoRoot: codexPackageRoot,
|
|
@@ -12864,7 +12987,7 @@ function findRepoRootFromImporter(importerDir) {
|
|
|
12864
12987
|
for (let depth = 0;depth <= 7; depth += 1) {
|
|
12865
12988
|
if (isRepoRootWithCodexPlugin(current))
|
|
12866
12989
|
return current;
|
|
12867
|
-
for (const wrapperPackageRoot of [
|
|
12990
|
+
for (const wrapperPackageRoot of [join29(current, "node_modules", "oh-my-openagent"), join29(current, "oh-my-openagent")]) {
|
|
12868
12991
|
if (isRepoRootWithCodexPlugin(wrapperPackageRoot))
|
|
12869
12992
|
return wrapperPackageRoot;
|
|
12870
12993
|
}
|
|
@@ -12882,7 +13005,7 @@ function findRepoRoot(input) {
|
|
|
12882
13005
|
return findRepoRootFromImporter(input.importerDir);
|
|
12883
13006
|
}
|
|
12884
13007
|
function isRepoRootWithCodexPlugin(repoRoot) {
|
|
12885
|
-
return existsSync6(
|
|
13008
|
+
return existsSync6(join29(repoRoot, "packages", "omo-codex", "plugin", ".codex-plugin", "plugin.json"));
|
|
12886
13009
|
}
|
|
12887
13010
|
function codexMarketplaceSource(marketplaceRoot) {
|
|
12888
13011
|
return { sourceType: "local", source: marketplaceRoot };
|
|
@@ -13092,11 +13215,48 @@ function buildDelegatedOmoInvocation(parsed) {
|
|
|
13092
13215
|
// packages/omo-codex/src/install/lazycodex-manual-update.ts
|
|
13093
13216
|
import { spawn as spawn4, spawnSync as spawnSync2 } from "node:child_process";
|
|
13094
13217
|
import { readFileSync as readFileSync3 } from "node:fs";
|
|
13095
|
-
import { dirname as dirname8, join as
|
|
13218
|
+
import { dirname as dirname8, join as join31 } from "node:path";
|
|
13219
|
+
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
13096
13220
|
import { fileURLToPath } from "node:url";
|
|
13221
|
+
|
|
13222
|
+
// packages/omo-codex/src/install/lazycodex-bun-global-paths.ts
|
|
13223
|
+
import { join as join30 } from "node:path";
|
|
13224
|
+
function isBunGlobalEntrypointPath(invokedPath, env3) {
|
|
13225
|
+
if (typeof invokedPath !== "string" || invokedPath.trim().length === 0)
|
|
13226
|
+
return false;
|
|
13227
|
+
const normalizedPath = normalizePathForPrefix(invokedPath);
|
|
13228
|
+
return resolveBunGlobalRoots(env3).some((root) => normalizedPath.startsWith(root));
|
|
13229
|
+
}
|
|
13230
|
+
function resolveBunGlobalRoots(env3) {
|
|
13231
|
+
const bunInstallRoot = env3.BUN_INSTALL?.trim();
|
|
13232
|
+
const homeRoot = env3.HOME?.trim();
|
|
13233
|
+
return [
|
|
13234
|
+
...bunInstallRoot ? [join30(bunInstallRoot, "bin"), join30(bunInstallRoot, "install", "global", "node_modules")] : [],
|
|
13235
|
+
...homeRoot ? [join30(homeRoot, ".bun", "bin"), join30(homeRoot, ".bun", "install", "global", "node_modules")] : []
|
|
13236
|
+
].map(normalizePathForPrefix);
|
|
13237
|
+
}
|
|
13238
|
+
function normalizePathForPrefix(path2) {
|
|
13239
|
+
const normalized = path2.replaceAll("\\", "/").replace(/\/+$/, "");
|
|
13240
|
+
return normalized.endsWith("/node_modules") || normalized.endsWith("/bin") ? `${normalized}/` : normalized;
|
|
13241
|
+
}
|
|
13242
|
+
|
|
13243
|
+
// packages/omo-codex/src/install/lazycodex-manual-update.ts
|
|
13097
13244
|
var DEFAULT_UPDATE_COMMAND = "npx";
|
|
13098
13245
|
var DEFAULT_UPDATE_ARGS = ["--yes", "lazycodex-ai@latest", "install", "--no-tui", "--codex-autonomous"];
|
|
13246
|
+
var BUN_UPDATE_COMMAND = "bun";
|
|
13247
|
+
var BUN_GLOBAL_UPDATE_ARGS = ["update", "-g", "lazycodex-ai@latest"];
|
|
13248
|
+
var BUN_GLOBAL_UNTRUSTED_ARGS = ["pm", "-g", "untrusted"];
|
|
13249
|
+
var BUN_GLOBAL_TRUST_ARGS = ["pm", "-g", "trust"];
|
|
13099
13250
|
var INSTALLED_VERSION_FILE = "lazycodex-install.json";
|
|
13251
|
+
var KNOWN_LAZYCODEX_BUN_TRUST_PACKAGES = new Set([
|
|
13252
|
+
"@ast-grep/cli",
|
|
13253
|
+
"@code-yeongyu/comment-checker",
|
|
13254
|
+
"@sisyphuslabs/omo-codex-plugin",
|
|
13255
|
+
"lazycodex-ai",
|
|
13256
|
+
"oh-my-openagent",
|
|
13257
|
+
"oh-my-opencode"
|
|
13258
|
+
]);
|
|
13259
|
+
var KNOWN_LAZYCODEX_BUN_TRUST_PREFIXES = ["@oh-my-opencode/", "oh-my-openagent-", "oh-my-opencode-"];
|
|
13100
13260
|
async function runLazyCodexManualUpdate(input = {}) {
|
|
13101
13261
|
const env3 = input.env ?? process.env;
|
|
13102
13262
|
const log2 = input.log ?? console.log;
|
|
@@ -13107,7 +13267,9 @@ async function runLazyCodexManualUpdate(input = {}) {
|
|
|
13107
13267
|
currentVersion,
|
|
13108
13268
|
latestVersion,
|
|
13109
13269
|
command: resolveCommand2(env3),
|
|
13110
|
-
args: resolveArgs(env3)
|
|
13270
|
+
args: resolveArgs(env3),
|
|
13271
|
+
env: env3,
|
|
13272
|
+
invokedPath: input.invokedPath ?? process.argv[1]
|
|
13111
13273
|
});
|
|
13112
13274
|
if (!plan.shouldUpdate) {
|
|
13113
13275
|
const printableVersion = currentVersion ?? "unknown";
|
|
@@ -13116,9 +13278,20 @@ async function runLazyCodexManualUpdate(input = {}) {
|
|
|
13116
13278
|
}
|
|
13117
13279
|
if (input.dryRun) {
|
|
13118
13280
|
log2(`${plan.command} ${plan.args.join(" ")}`);
|
|
13281
|
+
if (plan.postUpdate === "bun-global-trust")
|
|
13282
|
+
log2(`${DEFAULT_UPDATE_COMMAND} ${DEFAULT_UPDATE_ARGS.join(" ")}`);
|
|
13119
13283
|
return 0;
|
|
13120
13284
|
}
|
|
13121
13285
|
await commandRunner(plan.command, plan.args, { cwd: process.cwd(), env: env3 });
|
|
13286
|
+
if (plan.postUpdate === "bun-global-trust") {
|
|
13287
|
+
await handleBunGlobalTrust({
|
|
13288
|
+
env: env3,
|
|
13289
|
+
log: log2,
|
|
13290
|
+
commandRunner,
|
|
13291
|
+
isInteractive: input.isInteractive ?? (process.stdin.isTTY === true && process.stdout.isTTY === true)
|
|
13292
|
+
});
|
|
13293
|
+
await commandRunner(DEFAULT_UPDATE_COMMAND, DEFAULT_UPDATE_ARGS, { cwd: process.cwd(), env: env3 });
|
|
13294
|
+
}
|
|
13122
13295
|
return 0;
|
|
13123
13296
|
}
|
|
13124
13297
|
function resolveLazyCodexUpdatePlan(input = {}) {
|
|
@@ -13130,7 +13303,10 @@ function resolveLazyCodexUpdatePlan(input = {}) {
|
|
|
13130
13303
|
return { shouldUpdate: false, reason: "unknown-latest" };
|
|
13131
13304
|
if (compareVersions(latest, current) <= 0)
|
|
13132
13305
|
return { shouldUpdate: false, reason: "up-to-date" };
|
|
13133
|
-
|
|
13306
|
+
if (isBunGlobalEntrypoint(input.invokedPath, input.env ?? process.env)) {
|
|
13307
|
+
return { shouldUpdate: true, command: BUN_UPDATE_COMMAND, args: BUN_GLOBAL_UPDATE_ARGS, postUpdate: "bun-global-trust" };
|
|
13308
|
+
}
|
|
13309
|
+
return { shouldUpdate: true, command: input.command ?? DEFAULT_UPDATE_COMMAND, args: input.args ?? DEFAULT_UPDATE_ARGS, postUpdate: "none" };
|
|
13134
13310
|
}
|
|
13135
13311
|
function resolveCommand2(env3) {
|
|
13136
13312
|
return env3.LAZYCODEX_AUTO_UPDATE_COMMAND?.trim() || DEFAULT_UPDATE_COMMAND;
|
|
@@ -13149,7 +13325,7 @@ function resolveCurrentVersion(env3) {
|
|
|
13149
13325
|
if (env3.LAZYCODEX_CURRENT_VERSION?.trim())
|
|
13150
13326
|
return env3.LAZYCODEX_CURRENT_VERSION.trim();
|
|
13151
13327
|
const pluginRoot = dirname8(dirname8(fileURLToPath(import.meta.url)));
|
|
13152
|
-
return readVersionManifest(resolveInstalledVersionPath(env3, pluginRoot)) ?? readVersionManifest(
|
|
13328
|
+
return readVersionManifest(resolveInstalledVersionPath(env3, pluginRoot)) ?? readVersionManifest(join31(pluginRoot, "..", "..", "..", "package.json")) ?? readVersionManifest(join31(pluginRoot, ".codex-plugin", "plugin.json"));
|
|
13153
13329
|
}
|
|
13154
13330
|
function resolveLatestVersion(env3) {
|
|
13155
13331
|
if (env3.LAZYCODEX_LATEST_VERSION?.trim())
|
|
@@ -13163,6 +13339,57 @@ function resolveLatestVersion(env3) {
|
|
|
13163
13339
|
const version2 = result.stdout.trim();
|
|
13164
13340
|
return version2.length > 0 ? version2 : undefined;
|
|
13165
13341
|
}
|
|
13342
|
+
async function handleBunGlobalTrust(input) {
|
|
13343
|
+
const packageNames = resolveKnownBunGlobalUntrustedPackages(input.env);
|
|
13344
|
+
if (packageNames.length === 0)
|
|
13345
|
+
return;
|
|
13346
|
+
const trustArgs = [...BUN_GLOBAL_TRUST_ARGS, ...packageNames];
|
|
13347
|
+
const trustCommand = [BUN_UPDATE_COMMAND, ...trustArgs].join(" ");
|
|
13348
|
+
if (!input.isInteractive) {
|
|
13349
|
+
input.log(`Bun blocked LazyCodex-related postinstall scripts. Run this command to trust them:
|
|
13350
|
+
${trustCommand}`);
|
|
13351
|
+
return;
|
|
13352
|
+
}
|
|
13353
|
+
if (await confirmBunGlobalTrust(packageNames)) {
|
|
13354
|
+
await input.commandRunner(BUN_UPDATE_COMMAND, trustArgs, { cwd: process.cwd(), env: input.env });
|
|
13355
|
+
return;
|
|
13356
|
+
}
|
|
13357
|
+
input.log(`Skipped Bun postinstall trust. To run it later:
|
|
13358
|
+
${trustCommand}`);
|
|
13359
|
+
}
|
|
13360
|
+
function resolveKnownBunGlobalUntrustedPackages(env3) {
|
|
13361
|
+
const result = spawnSync2(BUN_UPDATE_COMMAND, BUN_GLOBAL_UNTRUSTED_ARGS, {
|
|
13362
|
+
encoding: "utf8",
|
|
13363
|
+
env: env3,
|
|
13364
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
13365
|
+
});
|
|
13366
|
+
if (result.status !== 0)
|
|
13367
|
+
return [];
|
|
13368
|
+
const names = [];
|
|
13369
|
+
for (const match of result.stdout.matchAll(/^\.\/node_modules\/((?:@[^/\s]+\/)?[^\s]+)\s+@/gm)) {
|
|
13370
|
+
const packageName = match[1];
|
|
13371
|
+
if (packageName !== undefined && isKnownLazyCodexBunTrustPackage(packageName) && !names.includes(packageName)) {
|
|
13372
|
+
names.push(packageName);
|
|
13373
|
+
}
|
|
13374
|
+
}
|
|
13375
|
+
return names;
|
|
13376
|
+
}
|
|
13377
|
+
async function confirmBunGlobalTrust(packageNames) {
|
|
13378
|
+
const prompt = `Trust Bun postinstall scripts for ${packageNames.join(", ")}? [y/N] `;
|
|
13379
|
+
const readline = createInterface2({ input: process.stdin, output: process.stdout });
|
|
13380
|
+
try {
|
|
13381
|
+
const answer = (await readline.question(prompt)).trim().toLowerCase();
|
|
13382
|
+
return answer === "y" || answer === "yes";
|
|
13383
|
+
} finally {
|
|
13384
|
+
readline.close();
|
|
13385
|
+
}
|
|
13386
|
+
}
|
|
13387
|
+
function isKnownLazyCodexBunTrustPackage(packageName) {
|
|
13388
|
+
return KNOWN_LAZYCODEX_BUN_TRUST_PACKAGES.has(packageName) || KNOWN_LAZYCODEX_BUN_TRUST_PREFIXES.some((prefix) => packageName.startsWith(prefix));
|
|
13389
|
+
}
|
|
13390
|
+
function isBunGlobalEntrypoint(invokedPath, env3) {
|
|
13391
|
+
return isBunGlobalEntrypointPath(invokedPath, env3);
|
|
13392
|
+
}
|
|
13166
13393
|
function defaultRunCommandForManualUpdate(command, args, options) {
|
|
13167
13394
|
return new Promise((resolve11, reject) => {
|
|
13168
13395
|
const child = spawn4(command, args, {
|
|
@@ -13214,7 +13441,7 @@ function compareVersions(left, right) {
|
|
|
13214
13441
|
function resolveInstalledVersionPath(env3, pluginRoot) {
|
|
13215
13442
|
if (env3.LAZYCODEX_INSTALLED_VERSION_FILE?.trim())
|
|
13216
13443
|
return env3.LAZYCODEX_INSTALLED_VERSION_FILE.trim();
|
|
13217
|
-
return
|
|
13444
|
+
return join31(pluginRoot, INSTALLED_VERSION_FILE);
|
|
13218
13445
|
}
|
|
13219
13446
|
function readVersionManifest(path2) {
|
|
13220
13447
|
try {
|
|
@@ -13230,15 +13457,15 @@ function readVersionManifest(path2) {
|
|
|
13230
13457
|
}
|
|
13231
13458
|
}
|
|
13232
13459
|
// packages/omo-codex/src/install/codex-git-bash-mcp-env.ts
|
|
13233
|
-
import { readFile as
|
|
13234
|
-
import { join as
|
|
13460
|
+
import { readFile as readFile18, writeFile as writeFile10 } from "node:fs/promises";
|
|
13461
|
+
import { join as join32 } from "node:path";
|
|
13235
13462
|
var GIT_BASH_ENV_KEY2 = "OMO_CODEX_GIT_BASH_PATH";
|
|
13236
13463
|
var CODEGRAPH_RELATIVE_ARGS2 = new Set(["components/codegraph/dist/serve.js", "./components/codegraph/dist/serve.js"]);
|
|
13237
13464
|
async function stampGitBashMcpEnv(input) {
|
|
13238
|
-
const manifestPath =
|
|
13465
|
+
const manifestPath = join32(input.pluginRoot, ".mcp.json");
|
|
13239
13466
|
if (!await fileExistsStrict(manifestPath))
|
|
13240
13467
|
return false;
|
|
13241
|
-
const parsed = JSON.parse(await
|
|
13468
|
+
const parsed = JSON.parse(await readFile18(manifestPath, "utf8"));
|
|
13242
13469
|
if (!isPlainRecord(parsed) || !isPlainRecord(parsed["mcpServers"]))
|
|
13243
13470
|
return false;
|
|
13244
13471
|
let changed = stampCodegraphMcpPath(parsed["mcpServers"], input.pluginRoot);
|
|
@@ -13268,57 +13495,9 @@ function stampCodegraphMcpPath(mcpServers, pluginRoot) {
|
|
|
13268
13495
|
const entrypoint = args[0];
|
|
13269
13496
|
if (typeof entrypoint !== "string" || !CODEGRAPH_RELATIVE_ARGS2.has(entrypoint))
|
|
13270
13497
|
return false;
|
|
13271
|
-
codegraphServer["args"] = [
|
|
13498
|
+
codegraphServer["args"] = [join32(pluginRoot, "components", "codegraph", "dist", "serve.js"), ...args.slice(1)];
|
|
13272
13499
|
return true;
|
|
13273
13500
|
}
|
|
13274
|
-
// packages/omo-codex/src/install/codex-hook-targets.ts
|
|
13275
|
-
import { readFile as readFile18 } from "node:fs/promises";
|
|
13276
|
-
import { join as join31, sep as sep8 } from "node:path";
|
|
13277
|
-
var PLUGIN_ROOT_TARGET_PATTERN = /\$\{PLUGIN_ROOT\}\/([^"']+)/g;
|
|
13278
|
-
async function findMissingHookCommandTargets(pluginRoot) {
|
|
13279
|
-
const manifestPath = join31(pluginRoot, "hooks", "hooks.json");
|
|
13280
|
-
if (!await fileExistsStrict(manifestPath))
|
|
13281
|
-
return [];
|
|
13282
|
-
const commands = [];
|
|
13283
|
-
const parsed = JSON.parse(await readFile18(manifestPath, "utf8"));
|
|
13284
|
-
collectCommands(parsed, commands);
|
|
13285
|
-
const missing = [];
|
|
13286
|
-
const seen = new Set;
|
|
13287
|
-
for (const command of commands) {
|
|
13288
|
-
for (const match of command.matchAll(PLUGIN_ROOT_TARGET_PATTERN)) {
|
|
13289
|
-
const targetSuffix = match[1];
|
|
13290
|
-
if (targetSuffix === undefined)
|
|
13291
|
-
continue;
|
|
13292
|
-
const target = join31(pluginRoot, ...targetSuffix.split("/"));
|
|
13293
|
-
if (seen.has(target))
|
|
13294
|
-
continue;
|
|
13295
|
-
seen.add(target);
|
|
13296
|
-
if (!await fileExistsStrict(target))
|
|
13297
|
-
missing.push(target);
|
|
13298
|
-
}
|
|
13299
|
-
}
|
|
13300
|
-
return missing;
|
|
13301
|
-
}
|
|
13302
|
-
async function assertHookCommandTargets(pluginRoot) {
|
|
13303
|
-
const missing = await findMissingHookCommandTargets(pluginRoot);
|
|
13304
|
-
if (missing.length === 0)
|
|
13305
|
-
return;
|
|
13306
|
-
const relativeMissing = missing.map((path2) => path2.split(`${pluginRoot}${sep8}`).join("").split(sep8).join("/"));
|
|
13307
|
-
throw new Error(`Plugin payload is missing ${missing.length} hook command target(s) referenced by hooks.json: ${relativeMissing.join(", ")}. ` + "The previous plugin cache was left untouched; this payload was not activated.");
|
|
13308
|
-
}
|
|
13309
|
-
function collectCommands(value, commands) {
|
|
13310
|
-
if (Array.isArray(value)) {
|
|
13311
|
-
for (const entry of value)
|
|
13312
|
-
collectCommands(entry, commands);
|
|
13313
|
-
return;
|
|
13314
|
-
}
|
|
13315
|
-
if (!isPlainRecord(value))
|
|
13316
|
-
return;
|
|
13317
|
-
if (value["type"] === "command" && typeof value["command"] === "string")
|
|
13318
|
-
commands.push(value["command"]);
|
|
13319
|
-
for (const entry of Object.values(value))
|
|
13320
|
-
collectCommands(entry, commands);
|
|
13321
|
-
}
|
|
13322
13501
|
|
|
13323
13502
|
// packages/omo-codex/src/install/install-local-cli.ts
|
|
13324
13503
|
async function installMarketplaceLocally(options = {}) {
|
|
@@ -13337,7 +13516,7 @@ async function runLazyCodexInstallLocalCli(input) {
|
|
|
13337
13516
|
return 0;
|
|
13338
13517
|
}
|
|
13339
13518
|
if (parsed.kind === "version") {
|
|
13340
|
-
const packageJson = JSON.parse(await readFile19(
|
|
13519
|
+
const packageJson = JSON.parse(await readFile19(join33(input.defaultRepoRoot, "package.json"), "utf8"));
|
|
13341
13520
|
const version2 = typeof packageJson.version === "string" ? packageJson.version : "unknown";
|
|
13342
13521
|
input.log(`lazycodex-ai ${version2}`);
|
|
13343
13522
|
return 0;
|
|
@@ -13360,7 +13539,7 @@ async function runLazyCodexInstallLocalCli(input) {
|
|
|
13360
13539
|
input.log(`Installed ${result2.installed.length} plugin(s) from ${result2.marketplaceName}.`);
|
|
13361
13540
|
return 0;
|
|
13362
13541
|
}
|
|
13363
|
-
return runLazyCodexManualUpdate({ env: input.env, dryRun: parsed.dryRun, log: input.log });
|
|
13542
|
+
return runLazyCodexManualUpdate({ env: input.env, dryRun: parsed.dryRun, log: input.log, invokedPath: input.invokedPath });
|
|
13364
13543
|
}
|
|
13365
13544
|
const repoRoot = parsed.repoRoot ? resolve11(parsed.repoRoot) : input.defaultRepoRoot;
|
|
13366
13545
|
const result = await installMarketplaceLocally({
|