oh-my-opencode 4.16.0 → 4.16.2
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/SKILL.md +9 -7
- package/.agents/skills/codex-qa/references/logging-debug.md +6 -4
- package/.agents/skills/opencode-qa/SKILL.md +9 -9
- package/.agents/skills/opencode-qa/references/tui-tmux.md +10 -8
- package/dist/cli/codex-ulw-loop.d.ts +8 -0
- package/dist/cli/get-local-version/types.d.ts +1 -1
- package/dist/cli/index.js +260 -207
- package/dist/cli-node/index.js +260 -207
- package/dist/features/background-agent/parent-wake-dedupe.d.ts +1 -0
- package/dist/features/background-agent/parent-wake-flush-runner.d.ts +2 -0
- package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -0
- package/dist/features/builtin-commands/templates/refactor-sections/intro-and-analysis.d.ts +1 -1
- package/dist/features/builtin-commands/templates/remove-ai-slops.d.ts +1 -1
- package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
- package/dist/features/monitor/process.d.ts +17 -1
- package/dist/index.js +1098 -1020
- package/dist/skills/frontend/SKILL.md +9 -9
- package/dist/skills/frontend/references/design/README.md +7 -3
- package/dist/skills/frontend/references/design/_INDEX.md +1 -1
- package/dist/skills/frontend/references/design/design-system-architecture.md +24 -2
- package/dist/skills/frontend/references/designpowers/README.md +2 -2
- package/dist/skills/frontend/references/designpowers/lane-b-execution.md +1 -1
- package/dist/skills/review-work/SKILL.md +3 -1
- package/dist/skills/start-work/SKILL.md +4 -2
- package/dist/skills/ulw-research/SKILL.md +3 -1
- package/dist/skills/visual-qa/SKILL.md +13 -17
- package/docs/reference/web-terminal-visual-qa.md +39 -45
- package/package.json +31 -25
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus.md +1 -1
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +3 -3
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +1 -1
- package/packages/omo-codex/plugin/components/teammode/AGENTS.md +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +3 -3
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +19 -10
- 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/ultrawork/SKILL.md +19 -10
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +13 -0
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +2 -0
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +22 -1
- package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +4 -0
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +19 -10
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +15 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +2 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +89 -27
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +6 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +55 -9
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-snapshot.d.ts +15 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-snapshot.js +33 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.d.ts +10 -3
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +15 -11
- 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/SKILL.md +3 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +7 -7
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +17 -2
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +2 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +59 -11
- package/packages/omo-codex/plugin/components/ulw-loop/src/steering-snapshot.ts +38 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/steering-types.ts +11 -3
- package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +15 -7
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +16 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +260 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/steering-snapshot.test.ts +124 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +101 -2
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +13 -13
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +64 -17
- package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +10 -6
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +186 -20
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +51 -3
- package/packages/omo-codex/plugin/scripts/migrate-codex-config.mjs +33 -5
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +1 -1
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +9 -9
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +7 -3
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +24 -2
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +2 -2
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +1 -1
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/refactor/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +3 -3
- package/packages/omo-codex/plugin/skills/teammode/SKILL.md +3 -3
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +19 -10
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +3 -1
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +7 -7
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +13 -0
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +2 -0
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +14 -18
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +4 -4
- package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +1 -1
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +35 -1
- package/packages/omo-codex/plugin/test/bootstrap-hooks.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +22 -9
- package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +275 -19
- package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +33 -0
- package/packages/omo-codex/plugin/test/sync-hook-status-messages.test.mjs +6 -6
- package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +4 -2
- package/packages/omo-codex/plugin/test/ulw-plan-skill-contract.test.mjs +52 -0
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +65 -39
- package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +2 -2
- package/packages/shared-skills/skills/frontend/SKILL.md +9 -9
- package/packages/shared-skills/skills/frontend/references/design/README.md +7 -3
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -1
- package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +24 -2
- package/packages/shared-skills/skills/frontend/references/designpowers/README.md +2 -2
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +1 -1
- package/packages/shared-skills/skills/review-work/SKILL.md +3 -1
- package/packages/shared-skills/skills/start-work/SKILL.md +4 -2
- package/packages/shared-skills/skills/ulw-research/SKILL.md +3 -1
- package/packages/shared-skills/skills/visual-qa/SKILL.md +13 -17
- package/script/qa/strip-ansi.mjs +10 -0
- package/script/qa/web-terminal-visual-qa.mjs +112 -195
- package/script/qa/xterm-live-terminal.mjs +180 -0
- package/script/qa/web-terminal-renderer.mjs +0 -218
|
@@ -1,20 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Runtime migration
|
|
2
|
+
* Runtime migration for `[features.multi_agent_v2]`.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `multi_agent_v2 = true` (removed here because a boolean key and a
|
|
9
|
-
* `[features.multi_agent_v2]` table for the same name are conflicting TOML).
|
|
4
|
+
* Historical behavior (openai/codex#26753): force `enabled = false` on every
|
|
5
|
+
* SessionStart because enabling V2 made every turn 400 with encrypted
|
|
6
|
+
* spawn_agent parameters on models that were not configured for encrypted
|
|
7
|
+
* tool use. OpenAI closed that as NOT_PLANNED (V2 under development).
|
|
10
8
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
9
|
+
* GPT-5.6 models that declare `multi_agent_version: "v2"` in the Codex model
|
|
10
|
+
* catalog invert that failure mode: forcing `enabled = false` makes every
|
|
11
|
+
* turn 400 with a reserved `collaboration.spawn_agent` schema mismatch
|
|
12
|
+
* (lazycodex#118 / oh-my-openagent#6002 / openai/codex#31097), and
|
|
13
|
+
* `hide_spawn_agent_metadata = false` (written by OMO installers <= 4.15.x)
|
|
14
|
+
* mismatches the same reserved schema by re-adding agent_type/model
|
|
15
|
+
* properties to spawn_agent. For those models this guard clears the managed
|
|
16
|
+
* disable and the stale metadata override, leaving V2 unset so Codex can
|
|
17
|
+
* follow model metadata.
|
|
18
|
+
*
|
|
19
|
+
* When the selected model is unknown or declares V1, keep the #26753
|
|
20
|
+
* force-disable path.
|
|
21
|
+
*
|
|
22
|
+
* Opt out of the whole migration with LAZYCODEX_CONFIG_MIGRATION_DISABLED=1
|
|
23
|
+
* (or OMO_CODEX_CONFIG_MIGRATION_DISABLED=1).
|
|
17
24
|
*/
|
|
25
|
+
import { readFileSync } from "node:fs";
|
|
26
|
+
import { homedir } from "node:os";
|
|
27
|
+
import { join } from "node:path";
|
|
28
|
+
|
|
18
29
|
const MANAGED_COMMENT_MARKER = "openai/codex#26753";
|
|
19
30
|
const MANAGED_DISABLE_COMMENT = [
|
|
20
31
|
"# Managed by LazyCodex: multi_agent_v2 is re-disabled on every Codex session start",
|
|
@@ -23,26 +34,157 @@ const MANAGED_DISABLE_COMMENT = [
|
|
|
23
34
|
"",
|
|
24
35
|
].join("\n");
|
|
25
36
|
|
|
26
|
-
|
|
27
|
-
|
|
37
|
+
/**
|
|
38
|
+
* @param {string} config
|
|
39
|
+
* @param {{
|
|
40
|
+
* multiAgentVersion?: string | null,
|
|
41
|
+
* sessionModel?: string | null,
|
|
42
|
+
* requireSessionModel?: boolean,
|
|
43
|
+
* env?: NodeJS.ProcessEnv,
|
|
44
|
+
* modelsCachePath?: string,
|
|
45
|
+
* }} [options]
|
|
46
|
+
*/
|
|
47
|
+
export function forceDisableMultiAgentV2(config, options = {}) {
|
|
48
|
+
// Always normalize the legacy `[features]` boolean shorthand first: leaving
|
|
49
|
+
// `multi_agent_v2 = true|false` in place while a later guard appends the
|
|
50
|
+
// `[features.multi_agent_v2]` table would define the same name as both a
|
|
51
|
+
// scalar and a table, which Codex rejects as invalid TOML.
|
|
52
|
+
const normalized = removeFeaturesShorthand(config);
|
|
53
|
+
const sessionModel = normalizeModel(options.sessionModel);
|
|
54
|
+
const multiAgentVersion =
|
|
55
|
+
options.multiAgentVersion !== undefined
|
|
56
|
+
? options.multiAgentVersion
|
|
57
|
+
: resolveMultiAgentVersionFromConfig(normalized, options);
|
|
58
|
+
|
|
59
|
+
if (prefersMultiAgentV2(multiAgentVersion, sessionModel)) {
|
|
60
|
+
return clearMultiAgentV2DisableForReservedSchema(normalized);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// SessionStart can run with an override model (`codex -m gpt-5.6-terra`) while
|
|
64
|
+
// config.toml still lists a different default. If we cannot see the effective
|
|
65
|
+
// session model, do not force-disable — writing enabled=false would break a
|
|
66
|
+
// GPT-5.6 reserved collaboration.spawn_agent session.
|
|
67
|
+
if (options.requireSessionModel === true && !sessionModel) {
|
|
68
|
+
return normalized;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Unknown catalog entry for an explicit session model: skip force-disable
|
|
72
|
+
// rather than assume the legacy encrypted-V2 failure mode.
|
|
73
|
+
if (sessionModel && multiAgentVersion == null) {
|
|
74
|
+
return normalized;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return forceDisableLegacyEncryptedV2(normalized);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* True when the effective model should run MultiAgentV2: the catalog says
|
|
82
|
+
* "v2", or the catalog is unavailable but the model is a GPT-5.6 family
|
|
83
|
+
* model (which reserves the collaboration.spawn_agent schema).
|
|
84
|
+
* @param {"v1" | "v2" | null | undefined} multiAgentVersion
|
|
85
|
+
* @param {string | null | undefined} sessionModel
|
|
86
|
+
*/
|
|
87
|
+
export function prefersMultiAgentV2(multiAgentVersion, sessionModel) {
|
|
88
|
+
return multiAgentVersion === "v2" || (multiAgentVersion == null && isGpt56Family(normalizeModel(sessionModel)));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Resolve the effective model against Codex `models_cache.json`.
|
|
93
|
+
* Prefers SessionStart `model` over the root `model` in config.toml.
|
|
94
|
+
* @param {string} config
|
|
95
|
+
* @param {{ sessionModel?: string | null, env?: NodeJS.ProcessEnv, modelsCachePath?: string }} [options]
|
|
96
|
+
* @returns {"v1" | "v2" | null}
|
|
97
|
+
*/
|
|
98
|
+
export function resolveMultiAgentVersionFromConfig(config, options = {}) {
|
|
99
|
+
const model = normalizeModel(options.sessionModel) || readRootModel(config);
|
|
100
|
+
if (!model) return null;
|
|
101
|
+
return resolveMultiAgentVersionForModel(model, options);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @param {string} model
|
|
106
|
+
* @param {{ env?: NodeJS.ProcessEnv, modelsCachePath?: string }} [options]
|
|
107
|
+
* @returns {"v1" | "v2" | null}
|
|
108
|
+
*/
|
|
109
|
+
export function resolveMultiAgentVersionForModel(model, options = {}) {
|
|
110
|
+
const cachePath =
|
|
111
|
+
options.modelsCachePath?.trim() ||
|
|
112
|
+
join(options.env?.CODEX_HOME?.trim() || join(homedir(), ".codex"), "models_cache.json");
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
const cache = JSON.parse(readFileSync(cachePath, "utf8"));
|
|
116
|
+
const models = Array.isArray(cache?.models) ? cache.models : [];
|
|
117
|
+
const entry = models.find((item) => item?.slug === model || item?.id === model);
|
|
118
|
+
const version = entry?.multi_agent_version;
|
|
119
|
+
if (version === "v1" || version === "v2") return version;
|
|
120
|
+
return null;
|
|
121
|
+
} catch {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function readRootModel(config) {
|
|
127
|
+
const double = config.match(/^\s*model\s*=\s*"([^"]+)"/m);
|
|
128
|
+
if (double) return double[1];
|
|
129
|
+
const single = config.match(/^\s*model\s*=\s*'([^']+)'/m);
|
|
130
|
+
return single?.[1] ?? null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function normalizeModel(value) {
|
|
134
|
+
if (typeof value !== "string") return null;
|
|
135
|
+
const trimmed = value.trim();
|
|
136
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function isGpt56Family(model) {
|
|
140
|
+
return typeof model === "string" && /^gpt-5\.6\b/i.test(model);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function clearMultiAgentV2DisableForReservedSchema(config) {
|
|
144
|
+
// `config` arrives shorthand-normalized from forceDisableMultiAgentV2.
|
|
145
|
+
const result = removeManagedDisableComments(config);
|
|
146
|
+
|
|
28
147
|
const section = findSection(result, "[features.multi_agent_v2]");
|
|
148
|
+
if (!section) return result;
|
|
149
|
+
|
|
150
|
+
// Two settings poison the reserved collaboration.spawn_agent schema on V2
|
|
151
|
+
// models (verified against codex-cli 0.144.1 + gpt-5.6-sol):
|
|
152
|
+
// - `enabled = false` forces the legacy V1 tool surface on some Codex
|
|
153
|
+
// versions (#6002's failure shape);
|
|
154
|
+
// - `hide_spawn_agent_metadata = false` (written by OMO installers
|
|
155
|
+
// <= 4.15.x to expose agent_type) re-adds agent_type/model/... to
|
|
156
|
+
// spawn_agent, mismatching the reserved schema -> HTTP 400 every turn.
|
|
157
|
+
// Remove both; `hide_spawn_agent_metadata = true` matches the Codex
|
|
158
|
+
// default and is left alone.
|
|
159
|
+
const cleared = section.text
|
|
160
|
+
.replace(/^\s*enabled\s*=\s*false[ \t]*(?:#[^\n]*)?\n?/gm, "")
|
|
161
|
+
.replace(/^\s*hide_spawn_agent_metadata\s*=\s*false[ \t]*(?:#[^\n]*)?\n?/gm, "");
|
|
162
|
+
if (cleared === section.text) return result;
|
|
163
|
+
return result.slice(0, section.start) + cleared + result.slice(section.end);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// `config` arrives shorthand-normalized from forceDisableMultiAgentV2.
|
|
167
|
+
function forceDisableLegacyEncryptedV2(config) {
|
|
168
|
+
const section = findSection(config, "[features.multi_agent_v2]");
|
|
29
169
|
|
|
30
170
|
if (!section) {
|
|
31
|
-
return ensureManagedComment(appendDisabledSection(
|
|
171
|
+
return ensureManagedComment(appendDisabledSection(config));
|
|
32
172
|
}
|
|
33
173
|
|
|
34
174
|
const enabledTruePattern = /^(\s*)enabled\s*=\s*true[ \t]*(#[^\n]*)?$/m;
|
|
35
175
|
if (enabledTruePattern.test(section.text)) {
|
|
36
|
-
const patched = section.text.replace(enabledTruePattern, (_match, indent, comment) =>
|
|
37
|
-
|
|
176
|
+
const patched = section.text.replace(enabledTruePattern, (_match, indent, comment) =>
|
|
177
|
+
comment ? `${indent}enabled = false ${comment}` : `${indent}enabled = false`,
|
|
178
|
+
);
|
|
179
|
+
return ensureManagedComment(config.slice(0, section.start) + patched + config.slice(section.end));
|
|
38
180
|
}
|
|
39
181
|
|
|
40
|
-
if (/^\s*enabled\s*=\s*false[ \t]*(?:#[^\n]*)?$/m.test(section.text)) return
|
|
182
|
+
if (/^\s*enabled\s*=\s*false[ \t]*(?:#[^\n]*)?$/m.test(section.text)) return config;
|
|
41
183
|
|
|
42
184
|
const headerEnd = section.text.indexOf("\n");
|
|
43
185
|
const insertAt = headerEnd === -1 ? section.text.length : headerEnd + 1;
|
|
44
186
|
const patched = `${section.text.slice(0, insertAt)}${headerEnd === -1 ? "\n" : ""}enabled = false\n${section.text.slice(insertAt)}`;
|
|
45
|
-
return ensureManagedComment(
|
|
187
|
+
return ensureManagedComment(config.slice(0, section.start) + patched + config.slice(section.end));
|
|
46
188
|
}
|
|
47
189
|
|
|
48
190
|
function ensureManagedComment(config) {
|
|
@@ -52,6 +194,30 @@ function ensureManagedComment(config) {
|
|
|
52
194
|
return config.slice(0, section.start) + MANAGED_DISABLE_COMMENT + config.slice(section.start);
|
|
53
195
|
}
|
|
54
196
|
|
|
197
|
+
function removeManagedDisableComments(config) {
|
|
198
|
+
if (!config.includes(MANAGED_COMMENT_MARKER) && !config.includes("Managed by LazyCodex: multi_agent_v2")) {
|
|
199
|
+
return config;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const lines = config.split("\n");
|
|
203
|
+
const kept = [];
|
|
204
|
+
for (const line of lines) {
|
|
205
|
+
const trimmed = line.trim();
|
|
206
|
+
if (
|
|
207
|
+
trimmed.startsWith("#") &&
|
|
208
|
+
(trimmed.includes(MANAGED_COMMENT_MARKER) ||
|
|
209
|
+
trimmed.includes("Managed by LazyCodex: multi_agent_v2") ||
|
|
210
|
+
trimmed.includes("because enabling it fails every turn with HTTP 400") ||
|
|
211
|
+
trimmed.includes("LAZYCODEX_CONFIG_MIGRATION_DISABLED=1") ||
|
|
212
|
+
trimmed.includes("OMO_CODEX_CONFIG_MIGRATION_DISABLED=1"))
|
|
213
|
+
) {
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
kept.push(line);
|
|
217
|
+
}
|
|
218
|
+
return kept.join("\n").replace(/\n{3,}/g, "\n\n");
|
|
219
|
+
}
|
|
220
|
+
|
|
55
221
|
function removeFeaturesShorthand(config) {
|
|
56
222
|
const section = findSection(config, "[features]");
|
|
57
223
|
if (!section) return config;
|
|
@@ -1,9 +1,39 @@
|
|
|
1
|
+
import { prefersMultiAgentV2, resolveMultiAgentVersionFromConfig } from "./multi-agent-v2-guard.mjs";
|
|
2
|
+
|
|
1
3
|
const CODEX_AGENTS_HEADER = "[agents]";
|
|
2
4
|
const CODEX_MULTI_AGENT_V2_HEADER = "[features.multi_agent_v2]";
|
|
3
5
|
const CODEX_SUBAGENT_THREAD_LIMIT = "1000";
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Ensure subagent concurrency limits without writing settings that conflict
|
|
9
|
+
* with MultiAgentV2. When the selected model prefers V2 (catalog `v2`, or a
|
|
10
|
+
* GPT-5.6 family session model with the catalog unavailable) or V2 is already
|
|
11
|
+
* enabled in config, skip `agents.max_threads` because Codex rejects that key
|
|
12
|
+
* while features.multi_agent_v2 is enabled.
|
|
13
|
+
*
|
|
14
|
+
* @param {string} config
|
|
15
|
+
* @param {{ multiAgentVersion?: string | null, sessionModel?: string | null, env?: NodeJS.ProcessEnv, modelsCachePath?: string }} [options]
|
|
16
|
+
*/
|
|
17
|
+
export function ensureSubagentConcurrencyLimit(config, options = {}) {
|
|
18
|
+
const multiAgentVersion =
|
|
19
|
+
options.multiAgentVersion !== undefined
|
|
20
|
+
? options.multiAgentVersion
|
|
21
|
+
: resolveMultiAgentVersionFromConfig(config, options);
|
|
22
|
+
const v2Preferred = prefersMultiAgentV2(multiAgentVersion, options.sessionModel) || isMultiAgentV2Enabled(config);
|
|
23
|
+
|
|
24
|
+
let result = config;
|
|
25
|
+
if (!v2Preferred) {
|
|
26
|
+
result = ensureAgentsMaxThreads(result);
|
|
27
|
+
} else {
|
|
28
|
+
result = removeAgentsMaxThreads(result);
|
|
29
|
+
}
|
|
30
|
+
return ensureMultiAgentV2ThreadLimit(result);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function isMultiAgentV2Enabled(config) {
|
|
34
|
+
const section = findSection(config, CODEX_MULTI_AGENT_V2_HEADER);
|
|
35
|
+
if (!section) return false;
|
|
36
|
+
return /^\s*enabled\s*=\s*true[ \t]*(?:#[^\n]*)?$/m.test(section.text);
|
|
7
37
|
}
|
|
8
38
|
|
|
9
39
|
function ensureAgentsMaxThreads(config) {
|
|
@@ -12,6 +42,22 @@ function ensureAgentsMaxThreads(config) {
|
|
|
12
42
|
return replaceOrInsertSetting(config, section, "max_threads", CODEX_SUBAGENT_THREAD_LIMIT);
|
|
13
43
|
}
|
|
14
44
|
|
|
45
|
+
function removeAgentsMaxThreads(config) {
|
|
46
|
+
const section = findSection(config, CODEX_AGENTS_HEADER);
|
|
47
|
+
if (!section) return config;
|
|
48
|
+
if (!/^\s*max_threads\s*=/m.test(section.text)) return config;
|
|
49
|
+
|
|
50
|
+
const patched = section.text.replace(/^\s*max_threads\s*=\s*[^\n]*\n?/m, "");
|
|
51
|
+
const bodyLines = patched
|
|
52
|
+
.split("\n")
|
|
53
|
+
.slice(1)
|
|
54
|
+
.filter((line) => line.trim() !== "");
|
|
55
|
+
if (bodyLines.length === 0) {
|
|
56
|
+
return config.slice(0, section.start) + config.slice(section.end).replace(/^\n+/, "");
|
|
57
|
+
}
|
|
58
|
+
return config.slice(0, section.start) + patched + config.slice(section.end);
|
|
59
|
+
}
|
|
60
|
+
|
|
15
61
|
function ensureMultiAgentV2ThreadLimit(config) {
|
|
16
62
|
const section = findSection(config, CODEX_MULTI_AGENT_V2_HEADER);
|
|
17
63
|
if (!section) {
|
|
@@ -26,7 +72,9 @@ function ensureMultiAgentV2ThreadLimit(config) {
|
|
|
26
72
|
function replaceOrInsertSetting(config, section, key, value) {
|
|
27
73
|
const pattern = new RegExp(`^(\\s*)${escapeRegExp(key)}\\s*=\\s*[^\\n#]*(#[^\\n]*)?$`, "m");
|
|
28
74
|
if (pattern.test(section.text)) {
|
|
29
|
-
const patched = section.text.replace(pattern, (_match, indent, comment) =>
|
|
75
|
+
const patched = section.text.replace(pattern, (_match, indent, comment) =>
|
|
76
|
+
comment ? `${indent}${key} = ${value} ${comment}` : `${indent}${key} = ${value}`,
|
|
77
|
+
);
|
|
30
78
|
return config.slice(0, section.start) + patched + config.slice(section.end);
|
|
31
79
|
}
|
|
32
80
|
|
|
@@ -8,7 +8,10 @@ import { FALLBACK_CATALOG, readModelCatalog } from "./migrate-codex-config/catal
|
|
|
8
8
|
import { configPaths } from "./migrate-codex-config/config-paths.mjs";
|
|
9
9
|
import { removeStaleContext7PlaceholderMcpServer } from "./migrate-codex-config/context7-placeholder-guard.mjs";
|
|
10
10
|
import { removeUnsupportedRootMultiAgentMode } from "./migrate-codex-config/multi-agent-mode-guard.mjs";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
forceDisableMultiAgentV2,
|
|
13
|
+
resolveMultiAgentVersionFromConfig,
|
|
14
|
+
} from "./migrate-codex-config/multi-agent-v2-guard.mjs";
|
|
12
15
|
import { ensureCodexReasoningConfig as applyReasoningProfile, readRootSettings } from "./migrate-codex-config/root-settings.mjs";
|
|
13
16
|
import { readState, resolveStatePath, writeState } from "./migrate-codex-config/state.mjs";
|
|
14
17
|
import { ensureSubagentConcurrencyLimit } from "./migrate-codex-config/subagent-limit-guard.mjs";
|
|
@@ -19,7 +22,12 @@ export function ensureCodexReasoningConfig(config, profile = FALLBACK_CATALOG.cu
|
|
|
19
22
|
return applyReasoningProfile(config, profile);
|
|
20
23
|
}
|
|
21
24
|
|
|
22
|
-
export async function migrateCodexConfig({
|
|
25
|
+
export async function migrateCodexConfig({
|
|
26
|
+
env = process.env,
|
|
27
|
+
cwd = process.cwd(),
|
|
28
|
+
sessionModel = null,
|
|
29
|
+
requireSessionModel = false,
|
|
30
|
+
} = {}) {
|
|
23
31
|
const catalog = await readModelCatalog(env);
|
|
24
32
|
const statePath = resolveStatePath(env);
|
|
25
33
|
const state = await readState(statePath);
|
|
@@ -31,6 +39,9 @@ export async function migrateCodexConfig({ env = process.env, cwd = process.cwd(
|
|
|
31
39
|
const result = await migrateConfigFile(configPath, {
|
|
32
40
|
catalog,
|
|
33
41
|
previousState: state.files?.[configPath],
|
|
42
|
+
env,
|
|
43
|
+
sessionModel,
|
|
44
|
+
requireSessionModel,
|
|
34
45
|
});
|
|
35
46
|
if (result.changed) changed.push(configPath);
|
|
36
47
|
if (result.multiAgentModeChanged) modeChanged.push(configPath);
|
|
@@ -44,7 +55,16 @@ export async function migrateCodexConfig({ env = process.env, cwd = process.cwd(
|
|
|
44
55
|
return { changed, modeChanged };
|
|
45
56
|
}
|
|
46
57
|
|
|
47
|
-
export async function migrateConfigFile(
|
|
58
|
+
export async function migrateConfigFile(
|
|
59
|
+
configPath,
|
|
60
|
+
{
|
|
61
|
+
catalog = FALLBACK_CATALOG,
|
|
62
|
+
previousState,
|
|
63
|
+
env = process.env,
|
|
64
|
+
sessionModel = null,
|
|
65
|
+
requireSessionModel = false,
|
|
66
|
+
} = {},
|
|
67
|
+
) {
|
|
48
68
|
const before = await readConfig(configPath);
|
|
49
69
|
const decision = shouldApplyCatalog(before, catalog, previousState);
|
|
50
70
|
|
|
@@ -56,7 +76,12 @@ export async function migrateConfigFile(configPath, { catalog = FALLBACK_CATALOG
|
|
|
56
76
|
reasoningApplied = config !== before;
|
|
57
77
|
}
|
|
58
78
|
|
|
59
|
-
const
|
|
79
|
+
const multiAgentOptions = { env, sessionModel, requireSessionModel };
|
|
80
|
+
const multiAgentVersion = resolveMultiAgentVersionFromConfig(config, multiAgentOptions);
|
|
81
|
+
const afterMultiAgentGuard = forceDisableMultiAgentV2(config, {
|
|
82
|
+
...multiAgentOptions,
|
|
83
|
+
multiAgentVersion,
|
|
84
|
+
});
|
|
60
85
|
const multiAgentChanged = afterMultiAgentGuard !== config;
|
|
61
86
|
if (multiAgentChanged) config = afterMultiAgentGuard;
|
|
62
87
|
|
|
@@ -68,7 +93,10 @@ export async function migrateConfigFile(configPath, { catalog = FALLBACK_CATALOG
|
|
|
68
93
|
const context7PlaceholderChanged = afterContext7PlaceholderGuard !== config;
|
|
69
94
|
if (context7PlaceholderChanged) config = afterContext7PlaceholderGuard;
|
|
70
95
|
|
|
71
|
-
const afterSubagentLimit = ensureSubagentConcurrencyLimit(config
|
|
96
|
+
const afterSubagentLimit = ensureSubagentConcurrencyLimit(config, {
|
|
97
|
+
...multiAgentOptions,
|
|
98
|
+
multiAgentVersion,
|
|
99
|
+
});
|
|
72
100
|
const subagentLimitChanged = afterSubagentLimit !== config;
|
|
73
101
|
if (subagentLimitChanged) config = afterSubagentLimit;
|
|
74
102
|
|
|
@@ -52,7 +52,7 @@ This skill may include examples copied from the OpenCode harness. In Codex, do n
|
|
|
52
52
|
|
|
53
53
|
Role-specific behavior must be described in a self-contained \`message\`. Use \`fork_context: false\` to start the child with only the initial prompt (no parent history); use \`fork_context: true\` only when full parent history is truly required. Include any required conversation context, files, diffs, constraints, and requested skill names directly in the spawned agent's \`message\`. OMO installs these selectable agent roles into \`~/.codex/agents/\`: \`explorer\`, \`librarian\`, \`plan\`, \`momus\`, \`metis\`, \`lazycodex-code-reviewer\`, \`lazycodex-qa-executor\`, and \`lazycodex-gate-reviewer\` - pass the matching name as \`agent_type\` so the child gets that role's model and instructions. If the spawn tool exposes no \`agent_type\` parameter, omit it and describe the role inside \`message\`. If a code block below conflicts with this section, this section wins.
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
Codex exposes ONE of two subagent tool surfaces per session; check your own tool list and route accordingly. If \`multi_agent_v1.*\` tools exist, use the table above as written. If instead a flat \`spawn_agent\` with a required \`task_name\` exists (\`multi_agent_v2\`), rewrite every \`multi_agent_v1.*\` example: \`multi_agent_v1.spawn_agent({...,"fork_context":false})\` becomes \`spawn_agent({"task_name":"<lowercase_digits_underscores>","message":...,"agent_type":...,"fork_turns":"none"})\` (\`"all"\` only when full parent history is truly required); \`send_input\` becomes \`send_message\`; do not call \`close_agent\`/\`resume_agent\` (finished agents end on their own; \`followup_task\` re-tasks one, \`interrupt_agent\` stops one); \`wait_agent\` takes only \`timeout_ms\` and returns on any child mailbox activity. \`agent_type\` works the same on both surfaces. If a code block below conflicts with this section, this section wins.
|
|
56
56
|
|
|
57
57
|
When translating \`load_skills=[...]\`, include the requested skill names in the spawned agent's \`message\`. If a code block below conflicts with this section, this section wins.
|
|
58
58
|
|
|
@@ -16,7 +16,7 @@ This file is a router, not a rulebook. The rules live in four rulesets under `re
|
|
|
16
16
|
| ANY UI implementation, styling, redesign, mockup, or visual decision | `references/design/README.md` FIRST. It enforces two mandatory gates — the Design System Gate (a `DESIGN.md` must exist before any component is written) and the React Dev Tooling Gate (react-grab / react-scan / react-doctor installed by default) — then routes to the taste and brand references below. |
|
|
17
17
|
| Writing or modifying frontend code, OR auditing performance / SEO / accessibility / quality | ALSO `references/perfection/README.md`. Lighthouse 100 in every category, measured on real Playwright Chromium (never the `lighthouse` CLI), achieved through architecture — never by dropping animations or hiding content. |
|
|
18
18
|
| Looking up a concrete style, color palette, font pairing, chart type, landing-page structure, or UX guideline — or generating a project design system from keywords | `references/ui-ux-db/README.md`. A searchable CSV database with a CLI; a lookup tool, not a posture. Load on demand; `design` stays the source of truth for taste and the `DESIGN.md` contract. |
|
|
19
|
-
|
|
|
19
|
+
| ANY implementation or redesign that creates or updates `DESIGN.md` — plus explicit operating-layer asks (personas, critique, debt, handoff, synthetic user testing) | `references/designpowers/README.md` + `references/designpowers/lane-c-review.md`. An internal frontend ruleset, not a separate skill: lane-c is the Phase Final flatness/critique reviewer, and its accessibility-constraints and accepted-debt language fills the required `DESIGN.md` sections. Load other lanes only when their phase applies. |
|
|
20
20
|
|
|
21
21
|
**For implementation work, design + perfection load together.** A page that hits Lighthouse 100 but looks like AI slop has failed; a page that looks beautiful but ships a 2 MB bundle has failed. Both win or neither does.
|
|
22
22
|
|
|
@@ -28,15 +28,15 @@ Every implementation must choose one of these branches before UI code changes:
|
|
|
28
28
|
- **Static visual reference** (screenshot, generated mockup, Stitch/Imagen output, Figma export, overview, or annotated packet): load `references/design/image-to-code-skill.md` plus the relevant design/perfection files, extract the reference's exact tokens, layout geometry, copy, spacing, states, and responsive intent into `DESIGN.md`, then implement reusable primitives against that contract.
|
|
29
29
|
- **Live site or URL reference** (the user names a site to clone or gives a URL): load `references/design/clone-from-url.md`. Drive a real browser and extract the runtime truth via `getComputedStyle` — tokens, layout geometry, default/hover/focus/active states, transitions and keyframes, and downloaded assets — into `DESIGN.md`, then clone-code reusable primitives against that contract.
|
|
30
30
|
Final QA for both runs `/visual-qa` in reference-fidelity mode: compare the actual UI against the reference pixel-by-pixel and verify the code is an extensible design-system implementation, not a screenshot-matched one-off.
|
|
31
|
-
2. **Greenfield or fresh setup:** if the user gave no concrete visual reference, design
|
|
32
|
-
- **Embedded references:** use `references/design/_INDEX.md` to shortlist 2-3 plausible Layer B references, then
|
|
33
|
-
- **Lazyweb real-product screens:**
|
|
34
|
-
- **Imagen concept drafts:** generate 2-3 imagen concept drafts, each seeded with the loaded Layer A + Layer B tokens (palette, type, material); pick the strongest and treat the chosen draft as the reference-fidelity contract.
|
|
35
|
-
Synthesize every lane into `DESIGN.md`. Treat sources as source material, not mood labels: extract tokens, layout grammar, component anatomy, interaction states, motion, and taste decisions, then recombine them into project-specific primitives. Never freestyle past the selected references, never copy logos or brand-specific copy.
|
|
31
|
+
2. **Greenfield or fresh setup:** if the user gave no concrete visual reference, design research is a build step with named deliverables — not exploration to be budgeted. Exploration-stop instincts ("enough exploration", two-wave caps) do not apply here. Fire every research lane IN PARALLEL before `DESIGN.md` is written, and open `DESIGN.md` with a `## 0. Research Log` section recording each lane's deliverable — a lane with no Research Log line did not run. Skip a lane only when its tool or network is genuinely unavailable, and name the skip in `DESIGN.md`:
|
|
32
|
+
- **Embedded references:** use `references/design/_INDEX.md` to shortlist 2-3 plausible Layer B references, then read exactly one Layer A style skill and one Layer B reference in full — every line, no partial reads (they are 200-500 lines; a sliced read produces the flattened token set this gate exists to prevent). Log the shortlist, the pick, and why. Use `open-design` only when the curated set has no fit; add `ui-ux-db` lookups for palette/type/domain questions.
|
|
33
|
+
- **Lazyweb real-product screens:** READ `references/design/lazyweb.md` FIRST and run its recipe verbatim — do not improvise curl calls against lazyweb.com; the recipe mints its own anonymous token. Log the queries run, how many screens you actually VIEWED, and the layout grammar harvested — never pixel copies.
|
|
34
|
+
- **Imagen concept drafts:** generate 2-3 imagen concept drafts, each seeded with the loaded Layer A + Layer B tokens (palette, type, material); pick the strongest and treat the chosen draft as the reference-fidelity contract. Log the draft paths and the pick.
|
|
35
|
+
Synthesize every lane into `DESIGN.md`. Treat sources as source material, not mood labels: extract tokens, layout grammar, component anatomy, interaction states, motion, and taste decisions, then recombine them into project-specific primitives. Never freestyle past the selected references, never copy logos or brand-specific copy. Then run the Primitive Showcase Gate (`references/design/README.md` Phase 0) before any product screen.
|
|
36
36
|
3. **Existing project with `DESIGN.md` or a component system:** read it, follow it, and update it before implementation only when the requested work needs a new token, primitive, state, motion rule, accessibility constraint, accepted debt, or reference-fidelity requirement.
|
|
37
37
|
4. **Existing project with UI but no `DESIGN.md` and no reusable component layer:** STOP and ask the user one focused question: should you preserve the current look with copy-nearby styling, or extract a real `DESIGN.md` plus reusable components before continuing? Do not silently choose.
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
For implementation, redesign, or design-system work that creates or updates `DESIGN.md`, `references/designpowers/README.md` + `lane-c-review.md` are part of the default load — feed their personas, accessibility, critique, debt, handoff, and role-reference guidance into the branch above. The resulting `DESIGN.md` is the implementation contract: tokens, typography, spacing, primitives, motion, responsive behavior, accessibility constraints, and accepted debt must be named there before code uses them. Verify component primitives, states, and final screens with real visual QA evidence; pass design-system decisions, implementation evidence, and unresolved debt into `/review-work` for significant implementation work.
|
|
40
40
|
|
|
41
41
|
## Ruleset 1 — design (`references/design/`)
|
|
42
42
|
|
|
@@ -46,7 +46,7 @@ The reference library has one architecture file, 12 taste skills (Layer A — *h
|
|
|
46
46
|
|
|
47
47
|
| File | Read when |
|
|
48
48
|
|---|---|
|
|
49
|
-
| `design-system-architecture.md` | The project has no `DESIGN.md` (defines the
|
|
49
|
+
| `design-system-architecture.md` | The project has no `DESIGN.md` (defines the structure you must create first — 8 sections plus a greenfield-only `## 0. Research Log`), or you are extracting a design system from existing UI code. |
|
|
50
50
|
|
|
51
51
|
### Layer A — taste skills (pick AT MOST ONE style skill; they encode opposing philosophies)
|
|
52
52
|
|
|
@@ -102,7 +102,7 @@ Domains: `product` `style` `typography` `color` `landing` `chart` `ux` `react` `
|
|
|
102
102
|
|
|
103
103
|
## Ruleset 4 — designpowers (`references/designpowers/`)
|
|
104
104
|
|
|
105
|
-
`README.md` routes design operating-layer guidance from the pinned `Owl-Listener/designpowers` reference corpus into the existing frontend workflow. Load it when a
|
|
105
|
+
`README.md` routes design operating-layer guidance from the pinned `Owl-Listener/designpowers` reference corpus into the existing frontend workflow. Load it — together with `lane-c-review.md` — for every implementation or redesign that creates or updates `DESIGN.md`, and additionally when a task needs explicit personas, accessibility and cognitive constraints, design critique, design debt, handoff, synthetic user testing, motion guidance, or role-reference prompts. It does not replace this frontend skill, `/visual-qa`, `/ulw-plan`, `/start-work`, or `/review-work`; it supplies richer design context that must first be distilled into the project `DESIGN.md`, then used as the design-system contract for implementation and verification.
|
|
106
106
|
|
|
107
107
|
## Quick routes — most common requests
|
|
108
108
|
|
|
@@ -38,12 +38,12 @@ Before touching any UI code, before routing to any reference, before even thinki
|
|
|
38
38
|
|
|
39
39
|
1. Read `design-system-architecture.md` — it defines the exact structure.
|
|
40
40
|
2. Identify the branch: greenfield setup, existing UI with implicit patterns/components, or existing UI with no reusable component layer.
|
|
41
|
-
3. **Greenfield setup:** if the user gave no concrete visual reference, use `_INDEX.md` to shortlist 2-3 plausible Layer B references, then
|
|
41
|
+
3. **Greenfield setup:** if the user gave no concrete visual reference, use `_INDEX.md` to shortlist 2-3 plausible Layer B references, then read exactly one Layer A style skill and one Layer B brand/design-system reference in full — every line, no partial reads; use `open-design` only when the curated set has no fit. Open `DESIGN.md` with a `## 0. Research Log` recording each research lane's deliverable (embedded-reference shortlist + pick, lazyweb screens viewed, imagen drafts — see the SKILL.md workflow); a lane with no line did not run. Treat those references as source material, not mood labels: extract tokens, layout grammar, component anatomy, interaction states, motion, and taste decisions into `DESIGN.md`, then recombine them into project-specific primitives. Customize for the user's product and content, but do not freestyle past the selected references; never copy logos, trademarked assets, or brand-specific copy.
|
|
42
42
|
- **Commit a distinctive direction BEFORE extracting tokens.** In 1-2 sentences, name the atmosphere, the signature material, the color story, and the one moment a visitor will remember. For an expressive brief, sketch 2-3 genuinely different directions and pick the boldest one you can defend with the loaded reference; do not average them, because the average IS the generic default this skill exists to beat. A locked, never-revisited one-shot decision is how a page ends up flat.
|
|
43
43
|
- **The reference's distinctive material MUST survive extraction (expressive briefs).** The common failure is loading a rich reference and then distilling it into a generic dark-SaaS token set. Your `DESIGN.md` must carry the *non-default* decisions forward and name which reference each came from: the actual elevation recipe (the specific layers that make a surface read as glass/glossy, not a single blur), a multi-stop perceptual color ramp (not one brand hex reused at varied opacity), the explicit display/body/mono type choices, and one signature interaction. Self-check before writing code: if your `DESIGN.md` could describe any generic dark SaaS, you flattened the reference — go back and put the specific material in.
|
|
44
44
|
4. **Existing UI with implicit patterns/components:** extract the colors, typography, spacing, primitives, states, and motion already in use. Write `DESIGN.md` to codify what exists before changing UI code.
|
|
45
45
|
5. **Existing UI with no reusable component layer:** STOP and ask whether to preserve the current style with copy-nearby edits or extract a `DESIGN.md` plus reusable components first. Do not silently choose the cheaper path or the larger refactor.
|
|
46
|
-
6.
|
|
46
|
+
6. Finish the triage at the Primitive Showcase Gate below.
|
|
47
47
|
|
|
48
48
|
#### If YES design system exists → READ IT, FOLLOW IT
|
|
49
49
|
|
|
@@ -52,7 +52,11 @@ Before touching any UI code, before routing to any reference, before even thinki
|
|
|
52
52
|
3. If you need a token that doesn't exist, **add it to `DESIGN.md` first**, then use it.
|
|
53
53
|
4. Never introduce raw hex codes, arbitrary px values, or ad-hoc component patterns that bypass the system.
|
|
54
54
|
|
|
55
|
-
**
|
|
55
|
+
**The Design System Gate is non-negotiable. No design system = no UI work. Period.**
|
|
56
|
+
|
|
57
|
+
### Primitive Showcase Gate (MANDATORY)
|
|
58
|
+
|
|
59
|
+
**Do not proceed to product screens until `DESIGN.md` exists, Section 5 names the reusable primitives and their states, and each primitive plus required state passes mobile/tablet/desktop visual QA in a component showcase or equivalent state harness.** Skipping this gate ships ad-hoc-styled product screens and re-enters the redesign loop.
|
|
56
60
|
|
|
57
61
|
|
|
58
62
|
## Phase 0.5 — React Dev Tooling Gate (MANDATORY for React projects)
|
|
@@ -13,7 +13,7 @@ All reference files live flat in this directory. Three layers:
|
|
|
13
13
|
|
|
14
14
|
| File | Purpose | Load when |
|
|
15
15
|
|---|---|---|
|
|
16
|
-
| `design-system-architecture.md` | Defines the
|
|
16
|
+
| `design-system-architecture.md` | Defines the `DESIGN.md` structure — 8 sections plus a greenfield-only `## 0. Research Log` (atmosphere, color tokens, typography scale, spacing system, components, motion, depth, accessibility constraints & accepted debt). Creation workflow for new and existing projects. Validation rules and memory management. | Phase 0 fires and no `DESIGN.md` exists in the project. Also load when extracting a design system from existing code. |
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md
CHANGED
|
@@ -16,11 +16,19 @@ Every frontend project MUST have a `DESIGN.md` at its root. This file is the sin
|
|
|
16
16
|
|
|
17
17
|
## DESIGN.md Structure
|
|
18
18
|
|
|
19
|
-
The file has
|
|
19
|
+
The file has 8 sections plus a greenfield-only `## 0. Research Log`. Every section is mandatory. Skip nothing.
|
|
20
20
|
|
|
21
21
|
```markdown
|
|
22
22
|
# [Project Name] Design System
|
|
23
23
|
|
|
24
|
+
## 0. Research Log (greenfield only)
|
|
25
|
+
|
|
26
|
+
One line per research lane, written before the sections below — a lane with no line did not run:
|
|
27
|
+
- Embedded refs: shortlisted [2-3 Layer B candidates] → picked [Layer A] + [Layer B] because [reason]
|
|
28
|
+
- Lazyweb: [N] queries, [M] screens viewed → [layout grammar taken]
|
|
29
|
+
- Imagen drafts: [paths] → picked [draft] as the reference-fidelity contract
|
|
30
|
+
- Skipped lanes: [lane] — [tool/network reason]
|
|
31
|
+
|
|
24
32
|
## 1. Atmosphere & Identity
|
|
25
33
|
|
|
26
34
|
One paragraph. What this product FEELS like. Not what it does — how it feels to use.
|
|
@@ -165,6 +173,19 @@ If borders:
|
|
|
165
173
|
|
|
166
174
|
If tonal-shift:
|
|
167
175
|
Surfaces use progressively lighter/darker shades. No borders, no shadows.
|
|
176
|
+
|
|
177
|
+
## 8. Accessibility Constraints & Accepted Debt
|
|
178
|
+
|
|
179
|
+
### Constraints
|
|
180
|
+
- WCAG target: [e.g. 2.2 AA] — contrast floor [4.5:1 body / 3:1 large text], visible focus on every
|
|
181
|
+
interactive element, full keyboard reachability, `prefers-reduced-motion` respected (Section 6).
|
|
182
|
+
|
|
183
|
+
### Accepted Debt
|
|
184
|
+
| Item | Location | Why accepted | Owner / Exit |
|
|
185
|
+
|------|----------|--------------|--------------|
|
|
186
|
+
| [debt] | [file/screen] | [reason + user sign-off] | [when it gets fixed] |
|
|
187
|
+
|
|
188
|
+
New debt is recorded here at the moment it is accepted — never silently.
|
|
168
189
|
```
|
|
169
190
|
|
|
170
191
|
## Creation Workflow
|
|
@@ -173,7 +194,7 @@ Surfaces use progressively lighter/darker shades. No borders, no shadows.
|
|
|
173
194
|
|
|
174
195
|
1. **Select references before taste** — no visual reference means `_INDEX.md` shortlist of 2-3 Layer B candidates, then exactly one Layer A style skill and one Layer B brand/design-system reference. Use `open-design` only when the curated set has no fit.
|
|
175
196
|
2. **Assemble from references** — extract tokens, layout grammar, component anatomy, states, motion, and taste decisions, then recombine them into project-specific primitives. Customize for the user's product; never copy logos, trademarked assets, or brand-specific copy.
|
|
176
|
-
3. **Define the system** — atmosphere, palette, typography, spacing, and one depth strategy, grounded in the selected references and product semantics.
|
|
197
|
+
3. **Define the system** — atmosphere, palette, typography, spacing, and one depth strategy, grounded in the selected references and product semantics. Sanity-check the palette and type pairing with one `ui-ux-db` domain search (CLI in `references/ui-ux-db/README.md`).
|
|
177
198
|
4. **Document initial primitives** — only components you are about to build, including variants and states.
|
|
178
199
|
5. **Write it to `DESIGN.md`** at project root.
|
|
179
200
|
6. **Build a primitive showcase first** — exercise each primitive's default, hover, active, focus, disabled, loading, empty, and error states at mobile/tablet/desktop widths before composing product screens.
|
|
@@ -199,6 +220,7 @@ After every component implementation, check:
|
|
|
199
220
|
- [ ] Component reused 2+ times? Documented in Section 5.
|
|
200
221
|
- [ ] Motion follows the timing table. No arbitrary durations.
|
|
201
222
|
- [ ] Component visual QA passed for each primitive and required state before product screens were composed.
|
|
223
|
+
- [ ] Section 8 accessibility constraints hold for the new component; any new debt is recorded in Section 8, not silently accepted.
|
|
202
224
|
|
|
203
225
|
## Memory Management
|
|
204
226
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This is an internal frontend ruleset, not a standalone skill. `/frontend` remains the only public activation point for web UI, UX, visual design, accessibility, design QA, and frontend implementation routing.
|
|
4
4
|
|
|
5
|
-
Load this reference from the frontend router
|
|
5
|
+
Load this reference from the frontend router for EVERY implementation or redesign that creates or updates `DESIGN.md`, and whenever a task needs design operating-layer guidance: personas, cognitive accessibility, critique, design debt, handoff, synthetic user testing, motion guidance, or designpowers-style role references.
|
|
6
6
|
|
|
7
7
|
The purpose of this ruleset is to enrich the existing frontend workflow while preserving its gates:
|
|
8
8
|
|
|
@@ -18,7 +18,7 @@ Read these files before applying designpowers guidance:
|
|
|
18
18
|
1. `README.md` - this frontend integration contract.
|
|
19
19
|
2. `routing.md` - how designpowers context feeds existing frontend, planning, execution, visual QA, and review routes.
|
|
20
20
|
3. `orchestration.md` - shared state, Direct/Auto prompt semantics, safeguards, and role-reference rules.
|
|
21
|
-
4. Phase lane docs
|
|
21
|
+
4. Phase lane docs — `lane-c-review.md` loads with this README for every implementation or redesign heading into Phase Final review (it is the flatness/critique reviewer); the other lanes load only when their phase applies:
|
|
22
22
|
- `lane-a-direction.md` for planning, direction, discovery, personas, taste, and accessibility constraints.
|
|
23
23
|
- `lane-b-execution.md` for execution, UI build prompts, frontend handoff, and implementation evidence.
|
|
24
24
|
- `lane-c-review.md` for visual QA, design critique, review gates, and objective evidence before judgment.
|
package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md
CHANGED
|
@@ -44,7 +44,7 @@ Lane B worker DoneClaims must include:
|
|
|
44
44
|
|
|
45
45
|
- Exact changed files and the `frontend` references loaded.
|
|
46
46
|
- The real-surface QA invocation required by `start-work` for the UI surface, with captured artifact path.
|
|
47
|
-
- Screenshot, browser, HTTP, or
|
|
47
|
+
- Screenshot, browser, HTTP, or xterm.js web-terminal artifacts appropriate to the visible surface.
|
|
48
48
|
- Accessibility evidence from the existing OpenAgent frontend path, such as Lighthouse, react-doctor, keyboard checks, or other plan-required checks.
|
|
49
49
|
- A short design trace: which persona, design principle, token, or state requirement each major UI decision satisfies.
|
|
50
50
|
- Cleanup receipts for any browser session, server, tmux session, temporary artifact, or process used during QA.
|
|
@@ -18,7 +18,7 @@ This skill may include examples copied from the OpenCode harness. In Codex, do n
|
|
|
18
18
|
|
|
19
19
|
Role-specific behavior must be described in a self-contained `message`. Use `fork_context: false` to start the child with only the initial prompt (no parent history); use `fork_context: true` only when full parent history is truly required. Include any required conversation context, files, diffs, constraints, and requested skill names directly in the spawned agent's `message`. OMO installs these selectable agent roles into `~/.codex/agents/`: `explorer`, `librarian`, `plan`, `momus`, `metis`, `lazycodex-code-reviewer`, `lazycodex-qa-executor`, and `lazycodex-gate-reviewer` - pass the matching name as `agent_type` so the child gets that role's model and instructions. If the spawn tool exposes no `agent_type` parameter, omit it and describe the role inside `message`. If a code block below conflicts with this section, this section wins.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
Codex exposes ONE of two subagent tool surfaces per session; check your own tool list and route accordingly. If `multi_agent_v1.*` tools exist, use the table above as written. If instead a flat `spawn_agent` with a required `task_name` exists (`multi_agent_v2`), rewrite every `multi_agent_v1.*` example: `multi_agent_v1.spawn_agent({...,"fork_context":false})` becomes `spawn_agent({"task_name":"<lowercase_digits_underscores>","message":...,"agent_type":...,"fork_turns":"none"})` (`"all"` only when full parent history is truly required); `send_input` becomes `send_message`; do not call `close_agent`/`resume_agent` (finished agents end on their own; `followup_task` re-tasks one, `interrupt_agent` stops one); `wait_agent` takes only `timeout_ms` and returns on any child mailbox activity. `agent_type` works the same on both surfaces. If a code block below conflicts with this section, this section wins.
|
|
22
22
|
|
|
23
23
|
When translating `load_skills=[...]`, include the requested skill names in the spawned agent's `message`. If a code block below conflicts with this section, this section wins.
|
|
24
24
|
|
|
@@ -19,7 +19,7 @@ This skill may include examples copied from the OpenCode harness. In Codex, do n
|
|
|
19
19
|
|
|
20
20
|
Role-specific behavior must be described in a self-contained `message`. Use `fork_context: false` to start the child with only the initial prompt (no parent history); use `fork_context: true` only when full parent history is truly required. Include any required conversation context, files, diffs, constraints, and requested skill names directly in the spawned agent's `message`. OMO installs these selectable agent roles into `~/.codex/agents/`: `explorer`, `librarian`, `plan`, `momus`, `metis`, `lazycodex-code-reviewer`, `lazycodex-qa-executor`, and `lazycodex-gate-reviewer` - pass the matching name as `agent_type` so the child gets that role's model and instructions. If the spawn tool exposes no `agent_type` parameter, omit it and describe the role inside `message`. If a code block below conflicts with this section, this section wins.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Codex exposes ONE of two subagent tool surfaces per session; check your own tool list and route accordingly. If `multi_agent_v1.*` tools exist, use the table above as written. If instead a flat `spawn_agent` with a required `task_name` exists (`multi_agent_v2`), rewrite every `multi_agent_v1.*` example: `multi_agent_v1.spawn_agent({...,"fork_context":false})` becomes `spawn_agent({"task_name":"<lowercase_digits_underscores>","message":...,"agent_type":...,"fork_turns":"none"})` (`"all"` only when full parent history is truly required); `send_input` becomes `send_message`; do not call `close_agent`/`resume_agent` (finished agents end on their own; `followup_task` re-tasks one, `interrupt_agent` stops one); `wait_agent` takes only `timeout_ms` and returns on any child mailbox activity. `agent_type` works the same on both surfaces. If a code block below conflicts with this section, this section wins.
|
|
23
23
|
|
|
24
24
|
When translating `load_skills=[...]`, include the requested skill names in the spawned agent's `message`. If a code block below conflicts with this section, this section wins.
|
|
25
25
|
|