oh-my-openagent 4.17.1 → 4.18.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/SKILL.md +2 -0
- package/dist/cli/get-local-version/types.d.ts +1 -1
- package/dist/cli/index.js +55 -25
- package/dist/cli-node/index.js +55 -25
- package/dist/index.js +23 -17
- package/dist/skills/frontend/SKILL.md +1 -1
- package/dist/skills/frontend/references/design/README.md +9 -0
- package/dist/skills/frontend/references/design/design-system-architecture.md +4 -2
- package/dist/skills/frontend/references/design/layout-skill.md +107 -0
- package/dist/skills/programming/SKILL.md +12 -2
- package/package.json +14 -13
- 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/gpt-5.6.md +7 -5
- 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/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +37 -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 +37 -10
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +37 -10
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +4 -4
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-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/skills/frontend/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +9 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +4 -2
- package/packages/omo-codex/plugin/skills/frontend/references/design/layout-skill.md +107 -0
- package/packages/omo-codex/plugin/skills/programming/SKILL.md +12 -2
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +37 -10
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +4 -4
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +24 -12
- package/packages/shared-skills/skills/frontend/SKILL.md +1 -1
- package/packages/shared-skills/skills/frontend/references/design/README.md +9 -0
- package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +4 -2
- package/packages/shared-skills/skills/frontend/references/design/layout-skill.md +107 -0
- package/packages/shared-skills/skills/programming/SKILL.md +12 -2
|
@@ -69,6 +69,8 @@ Windows.
|
|
|
69
69
|
| `scripts/hook-unit-probe.sh` | the `ultrawork` component injects `<ultrawork-mode>` on an `ulw` UserPromptSubmit (also a manual `--component/--event` mode) |
|
|
70
70
|
| `scripts/tui-smoke.sh` | the real codex TUI boots in the isolated home, renders, and survives (no early exit); captures the pane |
|
|
71
71
|
|
|
72
|
+
To tell a dev dogfood build apart from a published one on a REAL `~/.codex` (NOT the isolated QA home), the repo ships `bun run install:codex-dev`, which stamps the plugin version as `dev` — visible as the `(OmO dev)` hook-status prefix every turn and as a `[DEV]` badge in `omo get-local-version`. Use it to confirm which build is loaded during manual dogfooding; it writes to the real home, so it is NEVER part of the isolated QA flow above.
|
|
73
|
+
|
|
72
74
|
When TUI visual QA evidence is needed, follow
|
|
73
75
|
`docs/reference/web-terminal-visual-qa.md`: render the TUI through the real
|
|
74
76
|
xterm.js web terminal - NEVER the `tmux capture-pane` frame, which degrades
|
|
@@ -5,7 +5,7 @@ export interface VersionInfo {
|
|
|
5
5
|
isLocalDev: boolean;
|
|
6
6
|
isPinned: boolean;
|
|
7
7
|
pinnedVersion: string | null;
|
|
8
|
-
status: "up-to-date" | "outdated" | "local-dev" | "pinned" | "pinned-mismatch" | "error" | "unknown";
|
|
8
|
+
status: "up-to-date" | "outdated" | "local-dev" | "dev" | "pinned" | "pinned-mismatch" | "error" | "unknown";
|
|
9
9
|
}
|
|
10
10
|
export interface GetLocalVersionOptions {
|
|
11
11
|
directory?: string;
|
package/dist/cli/index.js
CHANGED
|
@@ -2145,7 +2145,7 @@ var package_default;
|
|
|
2145
2145
|
var init_package = __esm(() => {
|
|
2146
2146
|
package_default = {
|
|
2147
2147
|
name: "oh-my-opencode",
|
|
2148
|
-
version: "4.
|
|
2148
|
+
version: "4.18.0",
|
|
2149
2149
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
2150
2150
|
main: "./dist/index.js",
|
|
2151
2151
|
types: "dist/index.d.ts",
|
|
@@ -2252,6 +2252,7 @@ var init_package = __esm(() => {
|
|
|
2252
2252
|
build: "bun run script/build.ts",
|
|
2253
2253
|
"build:cli-node": "bun run script/build-cli-node.ts",
|
|
2254
2254
|
"build:codex-install": "bun run script/build-codex-install.ts",
|
|
2255
|
+
"install:codex-dev": "bun run script/build-codex-install.ts && bun run script/install-codex-dev.ts",
|
|
2255
2256
|
"build:codex-plugin": "npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build",
|
|
2256
2257
|
"build:senpi-plugin": "node packages/omo-senpi/plugin/scripts/build-extension.mjs && node packages/omo-senpi/plugin/scripts/sync-skills.mjs && node packages/omo-senpi/plugin/scripts/embed-directive.mjs --check",
|
|
2257
2258
|
"build:materialize-frontend": "node packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs --strict",
|
|
@@ -2356,18 +2357,18 @@ var init_package = __esm(() => {
|
|
|
2356
2357
|
typescript: "^6.0.3"
|
|
2357
2358
|
},
|
|
2358
2359
|
optionalDependencies: {
|
|
2359
|
-
"oh-my-opencode-darwin-arm64": "4.
|
|
2360
|
-
"oh-my-opencode-darwin-x64": "4.
|
|
2361
|
-
"oh-my-opencode-darwin-x64-baseline": "4.
|
|
2362
|
-
"oh-my-opencode-linux-arm64": "4.
|
|
2363
|
-
"oh-my-opencode-linux-arm64-musl": "4.
|
|
2364
|
-
"oh-my-opencode-linux-x64": "4.
|
|
2365
|
-
"oh-my-opencode-linux-x64-baseline": "4.
|
|
2366
|
-
"oh-my-opencode-linux-x64-musl": "4.
|
|
2367
|
-
"oh-my-opencode-linux-x64-musl-baseline": "4.
|
|
2368
|
-
"oh-my-opencode-windows-arm64": "4.
|
|
2369
|
-
"oh-my-opencode-windows-x64": "4.
|
|
2370
|
-
"oh-my-opencode-windows-x64-baseline": "4.
|
|
2360
|
+
"oh-my-opencode-darwin-arm64": "4.18.0",
|
|
2361
|
+
"oh-my-opencode-darwin-x64": "4.18.0",
|
|
2362
|
+
"oh-my-opencode-darwin-x64-baseline": "4.18.0",
|
|
2363
|
+
"oh-my-opencode-linux-arm64": "4.18.0",
|
|
2364
|
+
"oh-my-opencode-linux-arm64-musl": "4.18.0",
|
|
2365
|
+
"oh-my-opencode-linux-x64": "4.18.0",
|
|
2366
|
+
"oh-my-opencode-linux-x64-baseline": "4.18.0",
|
|
2367
|
+
"oh-my-opencode-linux-x64-musl": "4.18.0",
|
|
2368
|
+
"oh-my-opencode-linux-x64-musl-baseline": "4.18.0",
|
|
2369
|
+
"oh-my-opencode-windows-arm64": "4.18.0",
|
|
2370
|
+
"oh-my-opencode-windows-x64": "4.18.0",
|
|
2371
|
+
"oh-my-opencode-windows-x64-baseline": "4.18.0"
|
|
2371
2372
|
},
|
|
2372
2373
|
overrides: {
|
|
2373
2374
|
"@earendil-works/pi-agent-core": "0.80.3",
|
|
@@ -72601,7 +72602,7 @@ var package_default2;
|
|
|
72601
72602
|
var init_package2 = __esm(() => {
|
|
72602
72603
|
package_default2 = {
|
|
72603
72604
|
name: "@oh-my-opencode/omo-codex",
|
|
72604
|
-
version: "4.
|
|
72605
|
+
version: "4.18.0",
|
|
72605
72606
|
type: "module",
|
|
72606
72607
|
private: true,
|
|
72607
72608
|
description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
|
|
@@ -75325,9 +75326,11 @@ function collectCommands(value, commands) {
|
|
|
75325
75326
|
|
|
75326
75327
|
// packages/omo-codex/src/install/codex-cache-install.ts
|
|
75327
75328
|
async function installCachedPlugin(input) {
|
|
75329
|
+
const env2 = input.env ?? process.env;
|
|
75330
|
+
const npmInstallEnv = sanitizeNpmInstallEnv(env2);
|
|
75328
75331
|
if (input.buildSource !== false) {
|
|
75329
|
-
await maybeRunNpmInstall(input.sourcePath, input.runCommand);
|
|
75330
|
-
await maybeRunNpmBuild(input.sourcePath, input.runCommand);
|
|
75332
|
+
await maybeRunNpmInstall(input.sourcePath, input.runCommand, npmInstallEnv);
|
|
75333
|
+
await maybeRunNpmBuild(input.sourcePath, input.runCommand, env2);
|
|
75331
75334
|
}
|
|
75332
75335
|
const targetPath = join33(input.codexHome, "plugins", "cache", input.marketplaceName, input.name, input.version);
|
|
75333
75336
|
const tempPath = createTempSiblingPath(targetPath);
|
|
@@ -75337,10 +75340,10 @@ async function installCachedPlugin(input) {
|
|
|
75337
75340
|
await rewriteCachedPackageLocalFileDependencies(tempPath, input.sourcePath);
|
|
75338
75341
|
await copyBundledMcpRuntimeDists({ pluginRoot: tempPath, sourceRoot: input.sourcePath });
|
|
75339
75342
|
await copyRootRuntimeDists({ pluginRoot: tempPath, sourcePath: input.sourcePath });
|
|
75340
|
-
await maybeRunNpmInstall(tempPath, input.runCommand, ["ci", "--omit=dev"]);
|
|
75343
|
+
await maybeRunNpmInstall(tempPath, input.runCommand, npmInstallEnv, ["ci", "--omit=dev"]);
|
|
75341
75344
|
await removeCachedManagedNpmBinShims(tempPath);
|
|
75342
75345
|
if (input.buildSource === false)
|
|
75343
|
-
await maybeRunNpmSyncSkills(tempPath, input.runCommand);
|
|
75346
|
+
await maybeRunNpmSyncSkills(tempPath, input.runCommand, env2);
|
|
75344
75347
|
await assertNoRemovedSparkshellPromptReferences(tempPath);
|
|
75345
75348
|
await rewriteCachedMcpManifest(tempPath, input.sourcePath);
|
|
75346
75349
|
await rewriteCachedManifestRoot(tempPath, tempPath, targetPath);
|
|
@@ -75352,12 +75355,12 @@ async function installCachedPlugin(input) {
|
|
|
75352
75355
|
}
|
|
75353
75356
|
return { name: input.name, version: input.version, path: targetPath };
|
|
75354
75357
|
}
|
|
75355
|
-
async function maybeRunNpmInstall(cwd, runCommand, args = ["install"]) {
|
|
75358
|
+
async function maybeRunNpmInstall(cwd, runCommand, env2, args = ["install"]) {
|
|
75356
75359
|
if (!await fileExistsStrict(join33(cwd, "package.json")))
|
|
75357
75360
|
return;
|
|
75358
|
-
await runCommand("npm", args, { cwd });
|
|
75361
|
+
await runCommand("npm", args, { cwd, env: env2 });
|
|
75359
75362
|
}
|
|
75360
|
-
async function maybeRunNpmBuild(cwd, runCommand) {
|
|
75363
|
+
async function maybeRunNpmBuild(cwd, runCommand, env2) {
|
|
75361
75364
|
if (!await fileExistsStrict(join33(cwd, "package.json")))
|
|
75362
75365
|
return;
|
|
75363
75366
|
const packageJson = JSON.parse(await readFile8(join33(cwd, "package.json"), "utf8"));
|
|
@@ -75366,9 +75369,9 @@ async function maybeRunNpmBuild(cwd, runCommand) {
|
|
|
75366
75369
|
const scripts = packageJson.scripts;
|
|
75367
75370
|
if (!isPlainRecord3(scripts) || typeof scripts.build !== "string")
|
|
75368
75371
|
return;
|
|
75369
|
-
await runCommand("npm", ["run", "build"], { cwd });
|
|
75372
|
+
await runCommand("npm", ["run", "build"], { cwd, env: env2 });
|
|
75370
75373
|
}
|
|
75371
|
-
async function maybeRunNpmSyncSkills(cwd, runCommand) {
|
|
75374
|
+
async function maybeRunNpmSyncSkills(cwd, runCommand, env2) {
|
|
75372
75375
|
if (!await fileExistsStrict(join33(cwd, "package.json")))
|
|
75373
75376
|
return;
|
|
75374
75377
|
const packageJson = JSON.parse(await readFile8(join33(cwd, "package.json"), "utf8"));
|
|
@@ -75377,7 +75380,10 @@ async function maybeRunNpmSyncSkills(cwd, runCommand) {
|
|
|
75377
75380
|
const scripts = packageJson.scripts;
|
|
75378
75381
|
if (!isPlainRecord3(scripts) || typeof scripts["sync:skills"] !== "string")
|
|
75379
75382
|
return;
|
|
75380
|
-
await runCommand("npm", ["run", "sync:skills"], { cwd });
|
|
75383
|
+
await runCommand("npm", ["run", "sync:skills"], { cwd, env: env2 });
|
|
75384
|
+
}
|
|
75385
|
+
function sanitizeNpmInstallEnv(env2) {
|
|
75386
|
+
return Object.fromEntries(Object.entries(env2).filter(([key]) => key.toLowerCase() !== "npm_config_allow_scripts"));
|
|
75381
75387
|
}
|
|
75382
75388
|
function createTempSiblingPath(targetPath) {
|
|
75383
75389
|
return join33(dirname13(targetPath), `.tmp-${basename7(targetPath)}-${process.pid}-${Date.now()}`);
|
|
@@ -77407,6 +77413,10 @@ async function readDistributionManifest(repoRoot) {
|
|
|
77407
77413
|
}
|
|
77408
77414
|
}
|
|
77409
77415
|
function resolveLazyCodexPluginVersion(input) {
|
|
77416
|
+
const override = input.versionOverride?.trim();
|
|
77417
|
+
if (override !== undefined && override.length > 0) {
|
|
77418
|
+
return override;
|
|
77419
|
+
}
|
|
77410
77420
|
if (input.marketplaceName === "sisyphuslabs" && input.pluginName === "omo" && input.distributionManifest !== undefined) {
|
|
77411
77421
|
return input.distributionManifest.version;
|
|
77412
77422
|
}
|
|
@@ -77957,6 +77967,7 @@ async function runCodexInstaller(options = {}) {
|
|
|
77957
77967
|
return;
|
|
77958
77968
|
});
|
|
77959
77969
|
const buildSource = await shouldBuildSourcePackages(repoRoot);
|
|
77970
|
+
const versionOverride = env3.LAZYCODEX_DEV_VERSION?.trim() || undefined;
|
|
77960
77971
|
const gitBashResolution = await prepareGitBashForInstall({
|
|
77961
77972
|
platform,
|
|
77962
77973
|
env: env3,
|
|
@@ -77983,13 +77994,15 @@ async function runCodexInstaller(options = {}) {
|
|
|
77983
77994
|
manifestVersion: manifest.version,
|
|
77984
77995
|
marketplaceName: marketplace.name,
|
|
77985
77996
|
pluginName: entry.name,
|
|
77986
|
-
distributionManifest
|
|
77997
|
+
distributionManifest,
|
|
77998
|
+
versionOverride
|
|
77987
77999
|
});
|
|
77988
78000
|
validatePathSegment(version2, "plugin version");
|
|
77989
78001
|
log4(`Building ${entry.name}@${version2}`);
|
|
77990
78002
|
const plugin = await installCachedPlugin({
|
|
77991
78003
|
buildSource,
|
|
77992
78004
|
codexHome,
|
|
78005
|
+
env: env3,
|
|
77993
78006
|
marketplaceName: marketplace.name,
|
|
77994
78007
|
name: entry.name,
|
|
77995
78008
|
runCommand,
|
|
@@ -99070,6 +99083,10 @@ function formatVersionOutput(info) {
|
|
|
99070
99083
|
lines.push(` ${SYMBOLS3.dev} ${import_picocolors17.default.cyan("Running in local development mode")}`);
|
|
99071
99084
|
lines.push(` ${import_picocolors17.default.dim("Using file:// protocol from config")}`);
|
|
99072
99085
|
break;
|
|
99086
|
+
case "dev":
|
|
99087
|
+
lines.push(` ${SYMBOLS3.dev} ${import_picocolors17.default.cyan("Running a local dev build")}`);
|
|
99088
|
+
lines.push(` ${import_picocolors17.default.dim("Installed from source; update checks are skipped")}`);
|
|
99089
|
+
break;
|
|
99073
99090
|
case "pinned":
|
|
99074
99091
|
lines.push(` ${SYMBOLS3.pin} ${import_picocolors17.default.magenta(`Version pinned to ${info.pinnedVersion}`)}`);
|
|
99075
99092
|
lines.push(` ${import_picocolors17.default.dim("Update check skipped for pinned versions")}`);
|
|
@@ -99142,6 +99159,19 @@ async function getLocalVersion(options = {}) {
|
|
|
99142
99159
|
console.log(options.json ? formatJsonOutput(info2) : formatVersionOutput(info2));
|
|
99143
99160
|
return 1;
|
|
99144
99161
|
}
|
|
99162
|
+
if (!/^\d+\.\d+\.\d+/.test(currentVersion)) {
|
|
99163
|
+
const info2 = {
|
|
99164
|
+
currentVersion,
|
|
99165
|
+
latestVersion: null,
|
|
99166
|
+
isUpToDate: false,
|
|
99167
|
+
isLocalDev: true,
|
|
99168
|
+
isPinned: false,
|
|
99169
|
+
pinnedVersion: null,
|
|
99170
|
+
status: "dev"
|
|
99171
|
+
};
|
|
99172
|
+
console.log(options.json ? formatJsonOutput(info2) : formatVersionOutput(info2));
|
|
99173
|
+
return 0;
|
|
99174
|
+
}
|
|
99145
99175
|
const { extractChannel: extractChannel2 } = await Promise.resolve().then(() => (init_auto_update_checker(), exports_auto_update_checker));
|
|
99146
99176
|
const channel = extractChannel2(pluginInfo?.pinnedVersion ?? currentVersion);
|
|
99147
99177
|
const latestVersion = await getLatestVersion(channel);
|
package/dist/cli-node/index.js
CHANGED
|
@@ -2146,7 +2146,7 @@ var package_default;
|
|
|
2146
2146
|
var init_package = __esm(() => {
|
|
2147
2147
|
package_default = {
|
|
2148
2148
|
name: "oh-my-opencode",
|
|
2149
|
-
version: "4.
|
|
2149
|
+
version: "4.18.0",
|
|
2150
2150
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
2151
2151
|
main: "./dist/index.js",
|
|
2152
2152
|
types: "dist/index.d.ts",
|
|
@@ -2253,6 +2253,7 @@ var init_package = __esm(() => {
|
|
|
2253
2253
|
build: "bun run script/build.ts",
|
|
2254
2254
|
"build:cli-node": "bun run script/build-cli-node.ts",
|
|
2255
2255
|
"build:codex-install": "bun run script/build-codex-install.ts",
|
|
2256
|
+
"install:codex-dev": "bun run script/build-codex-install.ts && bun run script/install-codex-dev.ts",
|
|
2256
2257
|
"build:codex-plugin": "npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build",
|
|
2257
2258
|
"build:senpi-plugin": "node packages/omo-senpi/plugin/scripts/build-extension.mjs && node packages/omo-senpi/plugin/scripts/sync-skills.mjs && node packages/omo-senpi/plugin/scripts/embed-directive.mjs --check",
|
|
2258
2259
|
"build:materialize-frontend": "node packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs --strict",
|
|
@@ -2357,18 +2358,18 @@ var init_package = __esm(() => {
|
|
|
2357
2358
|
typescript: "^6.0.3"
|
|
2358
2359
|
},
|
|
2359
2360
|
optionalDependencies: {
|
|
2360
|
-
"oh-my-opencode-darwin-arm64": "4.
|
|
2361
|
-
"oh-my-opencode-darwin-x64": "4.
|
|
2362
|
-
"oh-my-opencode-darwin-x64-baseline": "4.
|
|
2363
|
-
"oh-my-opencode-linux-arm64": "4.
|
|
2364
|
-
"oh-my-opencode-linux-arm64-musl": "4.
|
|
2365
|
-
"oh-my-opencode-linux-x64": "4.
|
|
2366
|
-
"oh-my-opencode-linux-x64-baseline": "4.
|
|
2367
|
-
"oh-my-opencode-linux-x64-musl": "4.
|
|
2368
|
-
"oh-my-opencode-linux-x64-musl-baseline": "4.
|
|
2369
|
-
"oh-my-opencode-windows-arm64": "4.
|
|
2370
|
-
"oh-my-opencode-windows-x64": "4.
|
|
2371
|
-
"oh-my-opencode-windows-x64-baseline": "4.
|
|
2361
|
+
"oh-my-opencode-darwin-arm64": "4.18.0",
|
|
2362
|
+
"oh-my-opencode-darwin-x64": "4.18.0",
|
|
2363
|
+
"oh-my-opencode-darwin-x64-baseline": "4.18.0",
|
|
2364
|
+
"oh-my-opencode-linux-arm64": "4.18.0",
|
|
2365
|
+
"oh-my-opencode-linux-arm64-musl": "4.18.0",
|
|
2366
|
+
"oh-my-opencode-linux-x64": "4.18.0",
|
|
2367
|
+
"oh-my-opencode-linux-x64-baseline": "4.18.0",
|
|
2368
|
+
"oh-my-opencode-linux-x64-musl": "4.18.0",
|
|
2369
|
+
"oh-my-opencode-linux-x64-musl-baseline": "4.18.0",
|
|
2370
|
+
"oh-my-opencode-windows-arm64": "4.18.0",
|
|
2371
|
+
"oh-my-opencode-windows-x64": "4.18.0",
|
|
2372
|
+
"oh-my-opencode-windows-x64-baseline": "4.18.0"
|
|
2372
2373
|
},
|
|
2373
2374
|
overrides: {
|
|
2374
2375
|
"@earendil-works/pi-agent-core": "0.80.3",
|
|
@@ -72657,7 +72658,7 @@ var package_default2;
|
|
|
72657
72658
|
var init_package2 = __esm(() => {
|
|
72658
72659
|
package_default2 = {
|
|
72659
72660
|
name: "@oh-my-opencode/omo-codex",
|
|
72660
|
-
version: "4.
|
|
72661
|
+
version: "4.18.0",
|
|
72661
72662
|
type: "module",
|
|
72662
72663
|
private: true,
|
|
72663
72664
|
description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
|
|
@@ -75381,9 +75382,11 @@ function collectCommands(value, commands) {
|
|
|
75381
75382
|
|
|
75382
75383
|
// packages/omo-codex/src/install/codex-cache-install.ts
|
|
75383
75384
|
async function installCachedPlugin(input) {
|
|
75385
|
+
const env2 = input.env ?? process.env;
|
|
75386
|
+
const npmInstallEnv = sanitizeNpmInstallEnv(env2);
|
|
75384
75387
|
if (input.buildSource !== false) {
|
|
75385
|
-
await maybeRunNpmInstall(input.sourcePath, input.runCommand);
|
|
75386
|
-
await maybeRunNpmBuild(input.sourcePath, input.runCommand);
|
|
75388
|
+
await maybeRunNpmInstall(input.sourcePath, input.runCommand, npmInstallEnv);
|
|
75389
|
+
await maybeRunNpmBuild(input.sourcePath, input.runCommand, env2);
|
|
75387
75390
|
}
|
|
75388
75391
|
const targetPath = join33(input.codexHome, "plugins", "cache", input.marketplaceName, input.name, input.version);
|
|
75389
75392
|
const tempPath = createTempSiblingPath(targetPath);
|
|
@@ -75393,10 +75396,10 @@ async function installCachedPlugin(input) {
|
|
|
75393
75396
|
await rewriteCachedPackageLocalFileDependencies(tempPath, input.sourcePath);
|
|
75394
75397
|
await copyBundledMcpRuntimeDists({ pluginRoot: tempPath, sourceRoot: input.sourcePath });
|
|
75395
75398
|
await copyRootRuntimeDists({ pluginRoot: tempPath, sourcePath: input.sourcePath });
|
|
75396
|
-
await maybeRunNpmInstall(tempPath, input.runCommand, ["ci", "--omit=dev"]);
|
|
75399
|
+
await maybeRunNpmInstall(tempPath, input.runCommand, npmInstallEnv, ["ci", "--omit=dev"]);
|
|
75397
75400
|
await removeCachedManagedNpmBinShims(tempPath);
|
|
75398
75401
|
if (input.buildSource === false)
|
|
75399
|
-
await maybeRunNpmSyncSkills(tempPath, input.runCommand);
|
|
75402
|
+
await maybeRunNpmSyncSkills(tempPath, input.runCommand, env2);
|
|
75400
75403
|
await assertNoRemovedSparkshellPromptReferences(tempPath);
|
|
75401
75404
|
await rewriteCachedMcpManifest(tempPath, input.sourcePath);
|
|
75402
75405
|
await rewriteCachedManifestRoot(tempPath, tempPath, targetPath);
|
|
@@ -75408,12 +75411,12 @@ async function installCachedPlugin(input) {
|
|
|
75408
75411
|
}
|
|
75409
75412
|
return { name: input.name, version: input.version, path: targetPath };
|
|
75410
75413
|
}
|
|
75411
|
-
async function maybeRunNpmInstall(cwd, runCommand, args = ["install"]) {
|
|
75414
|
+
async function maybeRunNpmInstall(cwd, runCommand, env2, args = ["install"]) {
|
|
75412
75415
|
if (!await fileExistsStrict(join33(cwd, "package.json")))
|
|
75413
75416
|
return;
|
|
75414
|
-
await runCommand("npm", args, { cwd });
|
|
75417
|
+
await runCommand("npm", args, { cwd, env: env2 });
|
|
75415
75418
|
}
|
|
75416
|
-
async function maybeRunNpmBuild(cwd, runCommand) {
|
|
75419
|
+
async function maybeRunNpmBuild(cwd, runCommand, env2) {
|
|
75417
75420
|
if (!await fileExistsStrict(join33(cwd, "package.json")))
|
|
75418
75421
|
return;
|
|
75419
75422
|
const packageJson = JSON.parse(await readFile8(join33(cwd, "package.json"), "utf8"));
|
|
@@ -75422,9 +75425,9 @@ async function maybeRunNpmBuild(cwd, runCommand) {
|
|
|
75422
75425
|
const scripts = packageJson.scripts;
|
|
75423
75426
|
if (!isPlainRecord3(scripts) || typeof scripts.build !== "string")
|
|
75424
75427
|
return;
|
|
75425
|
-
await runCommand("npm", ["run", "build"], { cwd });
|
|
75428
|
+
await runCommand("npm", ["run", "build"], { cwd, env: env2 });
|
|
75426
75429
|
}
|
|
75427
|
-
async function maybeRunNpmSyncSkills(cwd, runCommand) {
|
|
75430
|
+
async function maybeRunNpmSyncSkills(cwd, runCommand, env2) {
|
|
75428
75431
|
if (!await fileExistsStrict(join33(cwd, "package.json")))
|
|
75429
75432
|
return;
|
|
75430
75433
|
const packageJson = JSON.parse(await readFile8(join33(cwd, "package.json"), "utf8"));
|
|
@@ -75433,7 +75436,10 @@ async function maybeRunNpmSyncSkills(cwd, runCommand) {
|
|
|
75433
75436
|
const scripts = packageJson.scripts;
|
|
75434
75437
|
if (!isPlainRecord3(scripts) || typeof scripts["sync:skills"] !== "string")
|
|
75435
75438
|
return;
|
|
75436
|
-
await runCommand("npm", ["run", "sync:skills"], { cwd });
|
|
75439
|
+
await runCommand("npm", ["run", "sync:skills"], { cwd, env: env2 });
|
|
75440
|
+
}
|
|
75441
|
+
function sanitizeNpmInstallEnv(env2) {
|
|
75442
|
+
return Object.fromEntries(Object.entries(env2).filter(([key]) => key.toLowerCase() !== "npm_config_allow_scripts"));
|
|
75437
75443
|
}
|
|
75438
75444
|
function createTempSiblingPath(targetPath) {
|
|
75439
75445
|
return join33(dirname13(targetPath), `.tmp-${basename7(targetPath)}-${process.pid}-${Date.now()}`);
|
|
@@ -77463,6 +77469,10 @@ async function readDistributionManifest(repoRoot) {
|
|
|
77463
77469
|
}
|
|
77464
77470
|
}
|
|
77465
77471
|
function resolveLazyCodexPluginVersion(input) {
|
|
77472
|
+
const override = input.versionOverride?.trim();
|
|
77473
|
+
if (override !== undefined && override.length > 0) {
|
|
77474
|
+
return override;
|
|
77475
|
+
}
|
|
77466
77476
|
if (input.marketplaceName === "sisyphuslabs" && input.pluginName === "omo" && input.distributionManifest !== undefined) {
|
|
77467
77477
|
return input.distributionManifest.version;
|
|
77468
77478
|
}
|
|
@@ -78013,6 +78023,7 @@ async function runCodexInstaller(options = {}) {
|
|
|
78013
78023
|
return;
|
|
78014
78024
|
});
|
|
78015
78025
|
const buildSource = await shouldBuildSourcePackages(repoRoot);
|
|
78026
|
+
const versionOverride = env3.LAZYCODEX_DEV_VERSION?.trim() || undefined;
|
|
78016
78027
|
const gitBashResolution = await prepareGitBashForInstall({
|
|
78017
78028
|
platform,
|
|
78018
78029
|
env: env3,
|
|
@@ -78039,13 +78050,15 @@ async function runCodexInstaller(options = {}) {
|
|
|
78039
78050
|
manifestVersion: manifest.version,
|
|
78040
78051
|
marketplaceName: marketplace.name,
|
|
78041
78052
|
pluginName: entry.name,
|
|
78042
|
-
distributionManifest
|
|
78053
|
+
distributionManifest,
|
|
78054
|
+
versionOverride
|
|
78043
78055
|
});
|
|
78044
78056
|
validatePathSegment(version2, "plugin version");
|
|
78045
78057
|
log4(`Building ${entry.name}@${version2}`);
|
|
78046
78058
|
const plugin = await installCachedPlugin({
|
|
78047
78059
|
buildSource,
|
|
78048
78060
|
codexHome,
|
|
78061
|
+
env: env3,
|
|
78049
78062
|
marketplaceName: marketplace.name,
|
|
78050
78063
|
name: entry.name,
|
|
78051
78064
|
runCommand,
|
|
@@ -99126,6 +99139,10 @@ function formatVersionOutput(info) {
|
|
|
99126
99139
|
lines.push(` ${SYMBOLS3.dev} ${import_picocolors17.default.cyan("Running in local development mode")}`);
|
|
99127
99140
|
lines.push(` ${import_picocolors17.default.dim("Using file:// protocol from config")}`);
|
|
99128
99141
|
break;
|
|
99142
|
+
case "dev":
|
|
99143
|
+
lines.push(` ${SYMBOLS3.dev} ${import_picocolors17.default.cyan("Running a local dev build")}`);
|
|
99144
|
+
lines.push(` ${import_picocolors17.default.dim("Installed from source; update checks are skipped")}`);
|
|
99145
|
+
break;
|
|
99129
99146
|
case "pinned":
|
|
99130
99147
|
lines.push(` ${SYMBOLS3.pin} ${import_picocolors17.default.magenta(`Version pinned to ${info.pinnedVersion}`)}`);
|
|
99131
99148
|
lines.push(` ${import_picocolors17.default.dim("Update check skipped for pinned versions")}`);
|
|
@@ -99198,6 +99215,19 @@ async function getLocalVersion(options = {}) {
|
|
|
99198
99215
|
console.log(options.json ? formatJsonOutput(info2) : formatVersionOutput(info2));
|
|
99199
99216
|
return 1;
|
|
99200
99217
|
}
|
|
99218
|
+
if (!/^\d+\.\d+\.\d+/.test(currentVersion)) {
|
|
99219
|
+
const info2 = {
|
|
99220
|
+
currentVersion,
|
|
99221
|
+
latestVersion: null,
|
|
99222
|
+
isUpToDate: false,
|
|
99223
|
+
isLocalDev: true,
|
|
99224
|
+
isPinned: false,
|
|
99225
|
+
pinnedVersion: null,
|
|
99226
|
+
status: "dev"
|
|
99227
|
+
};
|
|
99228
|
+
console.log(options.json ? formatJsonOutput(info2) : formatVersionOutput(info2));
|
|
99229
|
+
return 0;
|
|
99230
|
+
}
|
|
99201
99231
|
const { extractChannel: extractChannel2 } = await Promise.resolve().then(() => (init_auto_update_checker(), exports_auto_update_checker));
|
|
99202
99232
|
const channel = extractChannel2(pluginInfo?.pinnedVersion ?? currentVersion);
|
|
99203
99233
|
const latestVersion = await getLatestVersion(channel);
|
package/dist/index.js
CHANGED
|
@@ -6777,11 +6777,17 @@ function toGitFileStatus(statusToken) {
|
|
|
6777
6777
|
return "deleted";
|
|
6778
6778
|
return "modified";
|
|
6779
6779
|
}
|
|
6780
|
+
function normalizeGitStatusPath(statusToken, filePath) {
|
|
6781
|
+
if (statusToken !== "R" && statusToken !== "C")
|
|
6782
|
+
return filePath;
|
|
6783
|
+
const arrowIndex = filePath.lastIndexOf(" -> ");
|
|
6784
|
+
return arrowIndex === -1 ? filePath : filePath.slice(arrowIndex + 4);
|
|
6785
|
+
}
|
|
6780
6786
|
function parseGitStatusPorcelainLine(line) {
|
|
6781
6787
|
if (!line)
|
|
6782
6788
|
return null;
|
|
6783
6789
|
const statusToken = line.substring(0, 2).trim();
|
|
6784
|
-
const filePath = line.substring(3);
|
|
6790
|
+
const filePath = normalizeGitStatusPath(statusToken, line.substring(3));
|
|
6785
6791
|
if (!filePath)
|
|
6786
6792
|
return null;
|
|
6787
6793
|
return {
|
|
@@ -89664,7 +89670,7 @@ function getCachedVersion(options = {}) {
|
|
|
89664
89670
|
// package.json
|
|
89665
89671
|
var package_default = {
|
|
89666
89672
|
name: "oh-my-opencode",
|
|
89667
|
-
version: "4.
|
|
89673
|
+
version: "4.18.0",
|
|
89668
89674
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
89669
89675
|
main: "./dist/index.js",
|
|
89670
89676
|
types: "dist/index.d.ts",
|
|
@@ -89771,6 +89777,7 @@ var package_default = {
|
|
|
89771
89777
|
build: "bun run script/build.ts",
|
|
89772
89778
|
"build:cli-node": "bun run script/build-cli-node.ts",
|
|
89773
89779
|
"build:codex-install": "bun run script/build-codex-install.ts",
|
|
89780
|
+
"install:codex-dev": "bun run script/build-codex-install.ts && bun run script/install-codex-dev.ts",
|
|
89774
89781
|
"build:codex-plugin": "npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build",
|
|
89775
89782
|
"build:senpi-plugin": "node packages/omo-senpi/plugin/scripts/build-extension.mjs && node packages/omo-senpi/plugin/scripts/sync-skills.mjs && node packages/omo-senpi/plugin/scripts/embed-directive.mjs --check",
|
|
89776
89783
|
"build:materialize-frontend": "node packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs --strict",
|
|
@@ -89875,18 +89882,18 @@ var package_default = {
|
|
|
89875
89882
|
typescript: "^6.0.3"
|
|
89876
89883
|
},
|
|
89877
89884
|
optionalDependencies: {
|
|
89878
|
-
"oh-my-opencode-darwin-arm64": "4.
|
|
89879
|
-
"oh-my-opencode-darwin-x64": "4.
|
|
89880
|
-
"oh-my-opencode-darwin-x64-baseline": "4.
|
|
89881
|
-
"oh-my-opencode-linux-arm64": "4.
|
|
89882
|
-
"oh-my-opencode-linux-arm64-musl": "4.
|
|
89883
|
-
"oh-my-opencode-linux-x64": "4.
|
|
89884
|
-
"oh-my-opencode-linux-x64-baseline": "4.
|
|
89885
|
-
"oh-my-opencode-linux-x64-musl": "4.
|
|
89886
|
-
"oh-my-opencode-linux-x64-musl-baseline": "4.
|
|
89887
|
-
"oh-my-opencode-windows-arm64": "4.
|
|
89888
|
-
"oh-my-opencode-windows-x64": "4.
|
|
89889
|
-
"oh-my-opencode-windows-x64-baseline": "4.
|
|
89885
|
+
"oh-my-opencode-darwin-arm64": "4.18.0",
|
|
89886
|
+
"oh-my-opencode-darwin-x64": "4.18.0",
|
|
89887
|
+
"oh-my-opencode-darwin-x64-baseline": "4.18.0",
|
|
89888
|
+
"oh-my-opencode-linux-arm64": "4.18.0",
|
|
89889
|
+
"oh-my-opencode-linux-arm64-musl": "4.18.0",
|
|
89890
|
+
"oh-my-opencode-linux-x64": "4.18.0",
|
|
89891
|
+
"oh-my-opencode-linux-x64-baseline": "4.18.0",
|
|
89892
|
+
"oh-my-opencode-linux-x64-musl": "4.18.0",
|
|
89893
|
+
"oh-my-opencode-linux-x64-musl-baseline": "4.18.0",
|
|
89894
|
+
"oh-my-opencode-windows-arm64": "4.18.0",
|
|
89895
|
+
"oh-my-opencode-windows-x64": "4.18.0",
|
|
89896
|
+
"oh-my-opencode-windows-x64-baseline": "4.18.0"
|
|
89890
89897
|
},
|
|
89891
89898
|
overrides: {
|
|
89892
89899
|
"@earendil-works/pi-agent-core": "0.80.3",
|
|
@@ -117697,9 +117704,8 @@ async function getSdkAllSessions(client3) {
|
|
|
117697
117704
|
return sessions.map((session) => session.id);
|
|
117698
117705
|
}
|
|
117699
117706
|
async function sdkSessionExists(client3, sessionID) {
|
|
117700
|
-
const
|
|
117701
|
-
|
|
117702
|
-
return sessions.some((session) => session.id === sessionID);
|
|
117707
|
+
const messages = await getSdkSessionMessages(client3, sessionID);
|
|
117708
|
+
return messages.length > 0;
|
|
117703
117709
|
}
|
|
117704
117710
|
async function getSdkSessionMessages(client3, sessionID) {
|
|
117705
117711
|
const response = await fetchSdkResponse(() => client3.session.messages({ path: { id: sessionID } }));
|
|
@@ -32,7 +32,7 @@ Every implementation must choose one of these branches before UI code changes:
|
|
|
32
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
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
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.
|
|
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. Before laying out sections, inventory the content blocks and assign each a job — hook, explain, prove, compare, convert, navigate, retain — then order sections by the visitor's decision path, not by visual symmetry. 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
|
|
|
@@ -169,6 +169,12 @@ Triggers (mid-conversation, not initial): "you keep leaving placeholders", "stop
|
|
|
169
169
|
|
|
170
170
|
**Action:** Add `output-skill.md` on top of whatever is currently loaded. This stacks cleanly — it is purely about output completeness, not visual style.
|
|
171
171
|
|
|
172
|
+
### Step 8 — Is the screen an app shell, not a scroll-the-page site?
|
|
173
|
+
|
|
174
|
+
Triggers: dashboard, settings, mail/inbox, list-detail, command surface, split panes, fixed sidebar + scrolling body, admin console — or the user reports a layout that breaks when content gets long, empty, or unbroken (panel won't scroll, footer pushed off-screen, horizontal overflow on mobile).
|
|
175
|
+
|
|
176
|
+
**Action:** Add `layout-skill.md` on top of whatever style skill you selected in Steps 1-2. It carries scroll-ownership doctrine, the two silently-failing CSS contracts (`min-block-size: 0` scroll shells, `minmax(min(…),100%)` grids), the named-primitive vocabulary, container-vs-viewport routing, and the content-stress matrix. It adds no visual direction — the style skill still owns taste. Skip it for pure scroll-the-document marketing pages, where `taste-skill` layout guidance already fits.
|
|
177
|
+
|
|
172
178
|
## Stacking rules (read this once, internalize it)
|
|
173
179
|
|
|
174
180
|
1. **At most one Layer A *style* skill at a time.** A layout cannot be both `minimalist-skill` and `brutalist-skill` simultaneously — they encode opposite spacing and typography philosophies. Pick one.
|
|
@@ -177,6 +183,7 @@ Triggers (mid-conversation, not initial): "you keep leaving placeholders", "stop
|
|
|
177
183
|
4. **`redesign-skill.md` replaces a style-skill** when the task is auditing, not building. Stack a Layer B brand if the user wants a specific direction.
|
|
178
184
|
5. **`image-to-code-skill.md` pairs with one imagegen skill** for the full flow.
|
|
179
185
|
6. **Layer B (brand DESIGN.md) is orthogonal to Layer A.** You can pair any Layer A skill with any Layer B brand. Use Layer B as the source of color/type/component tokens; let Layer A drive the execution discipline.
|
|
186
|
+
7. **`layout-skill.md` stacks on top of any style skill** for app-shell / dashboard / split-pane work. It owns spatial structure and scroll ownership only — no visual direction — so it never conflicts with the style skill you picked.
|
|
180
187
|
|
|
181
188
|
## Anti-patterns — do not do these
|
|
182
189
|
|
|
@@ -218,6 +225,8 @@ Once references are loaded, before writing any UI code:
|
|
|
218
225
|
| "Generate a brand identity board for {company}" | `imagegen-brandkit.md` |
|
|
219
226
|
| "Stop using placeholders" | Add `output-skill.md` to current stack |
|
|
220
227
|
| "Also output a DESIGN.md doc" | Add `stitch-skill.md` to current stack |
|
|
228
|
+
| "Build a dashboard / settings / inbox / app shell" | one style skill (usually `taste-skill.md`) + `layout-skill.md` |
|
|
229
|
+
| "Panel won't scroll / footer pushed off-screen / mobile overflow" | Add `layout-skill.md` to current stack |
|
|
221
230
|
|
|
222
231
|
## Phase Final — Design QA (MANDATORY, runs after implementation)
|
|
223
232
|
|
|
@@ -116,7 +116,7 @@ All spacing derives from a base of **4px**.
|
|
|
116
116
|
- Breakpoints: sm 640px, md 768px, lg 1024px, xl 1280px, 2xl 1536px
|
|
117
117
|
|
|
118
118
|
### Rules
|
|
119
|
-
-
|
|
119
|
+
- Tokenize design *intent* — spacing steps, content width, gutters, section gaps, density steps. Keep browser *mechanics* raw: `auto`, `%`, `min-content`, `max-content`, `fit-content`, `clamp()`, viewport/container units, intrinsic sizing. A `clamp(1rem, 4vw, 2rem)` gap or a `minmax(min(16rem, 100%), 1fr)` track is mechanics, not a magic number — do not force it into a token.
|
|
120
120
|
- Asymmetric spacing is intentional, not accidental — document why.
|
|
121
121
|
|
|
122
122
|
## 5. Components
|
|
@@ -130,6 +130,7 @@ Document reusable patterns before implementation for greenfield work, and as the
|
|
|
130
130
|
- **States**: default, hover, active, focus, disabled, loading, empty, error
|
|
131
131
|
- **Accessibility**: keyboard, ARIA, contrast
|
|
132
132
|
- **Motion**: entry/exit animations
|
|
133
|
+
- **Layout**: spatial primitive (stack / cluster / sidebar / grid / shell…) and, if the component scrolls or pins anything, its scroll owner
|
|
133
134
|
|
|
134
135
|
Greenfield starts with the primitives you are about to build, assembled from
|
|
135
136
|
the selected references' component anatomy and adapted to the user's product.
|
|
@@ -214,13 +215,14 @@ After every component implementation, check:
|
|
|
214
215
|
|
|
215
216
|
- [ ] All colors reference tokens from Section 2. No raw hex outside `DESIGN.md`.
|
|
216
217
|
- [ ] All font sizes match Section 3 scale. No arbitrary sizes.
|
|
217
|
-
- [ ]
|
|
218
|
+
- [ ] Spacing intent maps to a token (Section 4); browser mechanics (`clamp()`, intrinsic sizing, container units) stay raw. No arbitrary px.
|
|
218
219
|
- [ ] Interactive elements have all required states from Section 5 and Section 6.
|
|
219
220
|
- [ ] Depth treatment matches the chosen strategy from Section 7.
|
|
220
221
|
- [ ] Component reused 2+ times? Documented in Section 5.
|
|
221
222
|
- [ ] Motion follows the timing table. No arbitrary durations.
|
|
222
223
|
- [ ] Component visual QA passed for each primitive and required state before product screens were composed.
|
|
223
224
|
- [ ] Section 8 accessibility constraints hold for the new component; any new debt is recorded in Section 8, not silently accepted.
|
|
225
|
+
- [ ] Survives content stress: empty, long label, unbroken string. Reflows to one readable column at 375px with no horizontal scroll of primary content.
|
|
224
226
|
|
|
225
227
|
## Memory Management
|
|
226
228
|
|