oh-my-opencode 4.12.0 → 4.13.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/README.md +1 -1
- package/THIRD-PARTY-NOTICES.md +1 -1
- package/dist/agents/sisyphus-agent-factory.d.ts +9 -0
- package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +31 -0
- package/dist/cli/index.js +916 -670
- package/dist/cli-node/index.js +916 -670
- package/dist/config/schema/codegraph.d.ts +1 -0
- package/dist/config/schema/oh-my-opencode-config.d.ts +2 -0
- package/dist/config/schema/runtime-fallback.d.ts +1 -0
- package/dist/features/background-agent/background-task-marker.d.ts +8 -0
- package/dist/features/background-agent/fallback-retry-handler.d.ts +1 -0
- package/dist/features/background-agent/manager.d.ts +1 -0
- package/dist/features/background-agent/parent-wake-dedupe.d.ts +1 -0
- package/dist/features/background-agent/parent-wake-notifier-types.d.ts +2 -0
- package/dist/features/background-agent/parent-wake-notifier.d.ts +1 -0
- package/dist/features/background-agent/parent-wake-window-recovery.d.ts +2 -0
- package/dist/hooks/runtime-fallback/auto-retry-dispatch.d.ts +2 -2
- package/dist/hooks/runtime-fallback/auto-retry-timeout.d.ts +2 -2
- package/dist/hooks/runtime-fallback/auto-retry.d.ts +1 -1
- package/dist/hooks/runtime-fallback/fallback-state-snapshot.d.ts +13 -0
- package/dist/hooks/runtime-fallback/types.d.ts +8 -0
- package/dist/index.js +1042 -640
- package/dist/oh-my-opencode.schema.json +8 -0
- package/dist/plugin/runtime-skill-resolver.d.ts +35 -0
- package/dist/plugin/skill-context.d.ts +9 -0
- package/dist/skills/frontend/ATTRIBUTION.md +32 -8
- package/dist/skills/frontend/references/design/airbnb.md +3 -0
- package/dist/skills/frontend/references/design/airtable.md +3 -0
- package/dist/skills/frontend/references/design/apple.md +3 -0
- package/dist/skills/frontend/references/design/binance.md +3 -0
- package/dist/skills/frontend/references/design/bmw.md +3 -0
- package/dist/skills/frontend/references/design/bugatti.md +3 -0
- package/dist/skills/frontend/references/design/cal.md +3 -0
- package/dist/skills/frontend/references/design/claude.md +3 -0
- package/dist/skills/frontend/references/design/clay.md +3 -0
- package/dist/skills/frontend/references/design/clickhouse.md +3 -0
- package/dist/skills/frontend/references/design/cohere.md +3 -0
- package/dist/skills/frontend/references/design/coinbase.md +3 -0
- package/dist/skills/frontend/references/design/composio.md +3 -0
- package/dist/skills/frontend/references/design/cursor.md +3 -0
- package/dist/skills/frontend/references/design/elevenlabs.md +3 -0
- package/dist/skills/frontend/references/design/expo.md +3 -0
- package/dist/skills/frontend/references/design/ferrari.md +3 -0
- package/dist/skills/frontend/references/design/figma.md +3 -0
- package/dist/skills/frontend/references/design/framer.md +3 -0
- package/dist/skills/frontend/references/design/hashicorp.md +3 -0
- package/dist/skills/frontend/references/design/ibm.md +3 -0
- package/dist/skills/frontend/references/design/imagegen-frontend-web.md +380 -79
- package/dist/skills/frontend/references/design/intercom.md +3 -0
- package/dist/skills/frontend/references/design/kraken.md +3 -0
- package/dist/skills/frontend/references/design/lamborghini.md +3 -0
- package/dist/skills/frontend/references/design/linear.app.md +3 -0
- package/dist/skills/frontend/references/design/lovable.md +3 -0
- package/dist/skills/frontend/references/design/mastercard.md +3 -0
- package/dist/skills/frontend/references/design/meta.md +3 -0
- package/dist/skills/frontend/references/design/minimax.md +3 -0
- package/dist/skills/frontend/references/design/mintlify.md +3 -0
- package/dist/skills/frontend/references/design/miro.md +3 -0
- package/dist/skills/frontend/references/design/mistral.ai.md +3 -0
- package/dist/skills/frontend/references/design/mongodb.md +3 -0
- package/dist/skills/frontend/references/design/nike.md +3 -0
- package/dist/skills/frontend/references/design/notion.md +3 -0
- package/dist/skills/frontend/references/design/nvidia.md +3 -0
- package/dist/skills/frontend/references/design/ollama.md +3 -0
- package/dist/skills/frontend/references/design/opencode.ai.md +3 -0
- package/dist/skills/frontend/references/design/pinterest.md +3 -0
- package/dist/skills/frontend/references/design/playstation.md +3 -0
- package/dist/skills/frontend/references/design/posthog.md +3 -0
- package/dist/skills/frontend/references/design/raycast.md +3 -0
- package/dist/skills/frontend/references/design/renault.md +3 -0
- package/dist/skills/frontend/references/design/replicate.md +3 -0
- package/dist/skills/frontend/references/design/resend.md +3 -0
- package/dist/skills/frontend/references/design/revolut.md +3 -0
- package/dist/skills/frontend/references/design/runwayml.md +3 -0
- package/dist/skills/frontend/references/design/sanity.md +3 -0
- package/dist/skills/frontend/references/design/sentry.md +3 -0
- package/dist/skills/frontend/references/design/shopify.md +3 -0
- package/dist/skills/frontend/references/design/spacex.md +3 -0
- package/dist/skills/frontend/references/design/spotify.md +3 -0
- package/dist/skills/frontend/references/design/starbucks.md +3 -0
- package/dist/skills/frontend/references/design/stitch-skill.md +1 -1
- package/dist/skills/frontend/references/design/stripe.md +3 -0
- package/dist/skills/frontend/references/design/supabase.md +3 -0
- package/dist/skills/frontend/references/design/superhuman.md +3 -0
- package/dist/skills/frontend/references/design/taste-skill.md +1188 -208
- package/dist/skills/frontend/references/design/tesla.md +3 -0
- package/dist/skills/frontend/references/design/theverge.md +3 -0
- package/dist/skills/frontend/references/design/together.ai.md +3 -0
- package/dist/skills/frontend/references/design/uber.md +3 -0
- package/dist/skills/frontend/references/design/vercel.md +3 -0
- package/dist/skills/frontend/references/design/vodafone.md +3 -0
- package/dist/skills/frontend/references/design/voltagent.md +3 -0
- package/dist/skills/frontend/references/design/warp.md +3 -0
- package/dist/skills/frontend/references/design/webflow.md +3 -0
- package/dist/skills/frontend/references/design/wired.md +3 -0
- package/dist/skills/frontend/references/design/wise.md +3 -0
- package/dist/skills/frontend/references/design/x.ai.md +3 -0
- package/dist/skills/frontend/references/design/zapier.md +3 -0
- package/dist/skills/frontend/references/ui-ux-db/README.md +501 -115
- package/dist/skills/frontend/references/ui-ux-db/data/charts.csv +26 -26
- package/dist/skills/frontend/references/ui-ux-db/data/colors.csv +162 -97
- package/dist/skills/frontend/references/ui-ux-db/data/icons.csv +105 -100
- package/dist/skills/frontend/references/ui-ux-db/data/landing.csv +22 -18
- package/dist/skills/frontend/references/ui-ux-db/data/products.csv +162 -97
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/flutter.csv +53 -53
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/html-tailwind.csv +56 -56
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/nextjs.csv +53 -53
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/react.csv +54 -54
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/svelte.csv +54 -54
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/swiftui.csv +51 -51
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/vue.csv +50 -50
- package/dist/skills/frontend/references/ui-ux-db/data/styles.csv +17 -0
- package/dist/skills/frontend/references/ui-ux-db/data/typography.csv +17 -1
- package/dist/skills/frontend/references/ui-ux-db/data/ui-reasoning.csv +162 -101
- package/dist/skills/frontend/references/ui-ux-db/data/web-interface.csv +30 -30
- package/dist/skills/frontend/references/ui-ux-db/scripts/core.py +31 -22
- package/dist/skills/frontend/references/ui-ux-db/scripts/design_system.py +150 -69
- package/dist/skills/frontend/references/ui-ux-db/scripts/search.py +3 -3
- package/dist/skills/lcx-doctor/SKILL.md +1 -1
- package/dist/skills/ultimate-browsing/ATTRIBUTION.md +105 -0
- package/dist/skills/ultimate-browsing/SKILL.md +140 -0
- package/dist/skills/ultimate-browsing/engine/__init__.py +24 -0
- package/dist/skills/ultimate-browsing/engine/__main__.py +106 -0
- package/dist/skills/ultimate-browsing/engine/bias_check.py +174 -0
- package/dist/skills/ultimate-browsing/engine/curl_probe.py +91 -0
- package/dist/skills/ultimate-browsing/engine/executor.py +192 -0
- package/dist/skills/ultimate-browsing/engine/fetch_chain.py +268 -0
- package/dist/skills/ultimate-browsing/engine/referers.py +15 -0
- package/dist/skills/ultimate-browsing/engine/result_schema.py +45 -0
- package/dist/skills/ultimate-browsing/engine/summary.py +37 -0
- package/dist/skills/ultimate-browsing/engine/templates/package.json +11 -0
- package/dist/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +129 -0
- package/dist/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +167 -0
- package/dist/skills/ultimate-browsing/engine/tests/test_fetch_chain.py +77 -0
- package/dist/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +282 -0
- package/dist/skills/ultimate-browsing/engine/url_transforms.py +98 -0
- package/dist/skills/ultimate-browsing/engine/validators.py +216 -0
- package/dist/skills/ultimate-browsing/engine/waf_detector.py +214 -0
- package/dist/skills/ultimate-browsing/engine/waf_profiles.yaml +162 -0
- package/dist/skills/ultimate-browsing/references/agent-reach/README.md +79 -0
- package/dist/skills/ultimate-browsing/references/agent-reach/career.md +29 -0
- package/dist/skills/ultimate-browsing/references/agent-reach/dev.md +62 -0
- package/dist/skills/ultimate-browsing/references/agent-reach/search.md +33 -0
- package/dist/skills/ultimate-browsing/references/agent-reach/social.md +207 -0
- package/dist/skills/ultimate-browsing/references/agent-reach/video.md +115 -0
- package/dist/skills/ultimate-browsing/references/agent-reach/web.md +76 -0
- package/dist/skills/ultimate-browsing/references/chrome-stealth.md +120 -0
- package/dist/skills/ultimate-browsing/references/insane-search/README.md +319 -0
- package/dist/skills/ultimate-browsing/references/insane-search/cache-archive.md +83 -0
- package/dist/skills/ultimate-browsing/references/insane-search/fallback.md +159 -0
- package/dist/skills/ultimate-browsing/references/insane-search/jina.md +130 -0
- package/dist/skills/ultimate-browsing/references/insane-search/json-api.md +133 -0
- package/dist/skills/ultimate-browsing/references/insane-search/media.md +123 -0
- package/dist/skills/ultimate-browsing/references/insane-search/metadata.md +116 -0
- package/dist/skills/ultimate-browsing/references/insane-search/naver.md +107 -0
- package/dist/skills/ultimate-browsing/references/insane-search/playwright.md +142 -0
- package/dist/skills/ultimate-browsing/references/insane-search/public-api.md +119 -0
- package/dist/skills/ultimate-browsing/references/insane-search/rss.md +123 -0
- package/dist/skills/ultimate-browsing/references/insane-search/tls-impersonate.md +186 -0
- package/dist/skills/ultimate-browsing/references/insane-search/twitter.md +104 -0
- package/dist/skills/ultimate-browsing/scripts/cookie_crypto.py +75 -0
- package/dist/skills/ultimate-browsing/scripts/cookie_domains.py +38 -0
- package/dist/skills/ultimate-browsing/scripts/cookie_paths.py +112 -0
- package/dist/skills/ultimate-browsing/scripts/extract_cookies.py +280 -0
- package/dist/skills/ultimate-browsing/scripts/tests/test_cookie_domain_filter.py +110 -0
- package/dist/skills/ultimate-browsing/scripts/tests/test_extract_cookies.py +245 -0
- package/dist/skills/ultraresearch/ATTRIBUTION.md +49 -0
- package/dist/skills/ultraresearch/SKILL.md +34 -6
- package/dist/skills/ulw-plan/SKILL.md +4 -1
- package/dist/tools/background-task/constants.d.ts +1 -1
- package/dist/tools/delegate-task/sync-task-deps.d.ts +8 -6
- package/dist/tools/skill-mcp/tools.d.ts +1 -1
- package/dist/tui.js +18 -4
- package/package.json +16 -14
- package/packages/omo-codex/THIRD-PARTY-NOTICES.md +27 -4
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +3 -1
- package/packages/omo-codex/plugin/README.md +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +134 -42
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/LICENSE +21 -0
- package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +2951 -0
- package/packages/omo-codex/plugin/components/codegraph/NOTICE +16 -0
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +633 -193
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +561 -44
- package/packages/omo-codex/plugin/components/codegraph/package.json +9 -3
- package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +11 -0
- package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +12 -0
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +34 -0
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +75 -0
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +66 -13
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +26 -12
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +50 -330
- package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +91 -0
- package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +2 -2
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +68 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +11 -1
- package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +48 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +133 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +1 -112
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +149 -0
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +63 -0
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +106 -0
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +150 -0
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +3 -3
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +3 -3
- package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +33 -9
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/dist/cli.js +94 -0
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +17 -0
- package/packages/omo-codex/plugin/components/teammode/package.json +26 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +59 -32
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs +17 -16
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-state.mjs +70 -3
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-worktree.mjs +113 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +63 -4
- package/packages/omo-codex/plugin/components/teammode/src/cli.ts +12 -0
- package/packages/omo-codex/plugin/components/teammode/src/codex-hook.ts +125 -0
- package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +116 -0
- package/packages/omo-codex/plugin/components/teammode/tsconfig.json +25 -0
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +5 -4
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +24 -3
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +8 -7
- package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +17 -0
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +129 -12
- package/packages/omo-codex/plugin/package.json +3 -2
- package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +133 -0
- package/packages/omo-codex/plugin/scripts/auto-update-release-notes.mjs +135 -0
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +33 -133
- package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +1 -0
- package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +41 -0
- package/packages/omo-codex/plugin/shared/src/config-loader.ts +20 -2
- package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +16 -0
- package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +32 -8
- package/packages/omo-codex/plugin/skills/frontend/references/design/airbnb.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/airtable.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/apple.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/binance.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/bmw.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/bugatti.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/cal.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/claude.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/clay.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/clickhouse.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/cohere.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/coinbase.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/composio.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/cursor.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/elevenlabs.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/expo.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/ferrari.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/figma.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/framer.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/hashicorp.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/ibm.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/imagegen-frontend-web.md +380 -79
- package/packages/omo-codex/plugin/skills/frontend/references/design/intercom.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/kraken.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/lamborghini.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/linear.app.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/lovable.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/mastercard.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/meta.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/minimax.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/mintlify.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/miro.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/mistral.ai.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/mongodb.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/nike.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/notion.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/nvidia.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/ollama.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/opencode.ai.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/pinterest.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/playstation.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/posthog.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/raycast.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/renault.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/replicate.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/resend.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/revolut.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/runwayml.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/sanity.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/sentry.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/shopify.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/spacex.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/spotify.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/starbucks.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/stitch-skill.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/design/stripe.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/supabase.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/superhuman.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/taste-skill.md +1188 -208
- package/packages/omo-codex/plugin/skills/frontend/references/design/tesla.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/theverge.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/together.ai.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/uber.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/vercel.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/vodafone.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/voltagent.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/warp.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/webflow.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/wired.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/wise.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/x.ai.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/zapier.md +3 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/README.md +501 -115
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/charts.csv +26 -26
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/colors.csv +162 -97
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/icons.csv +105 -100
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/landing.csv +22 -18
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/products.csv +162 -97
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/flutter.csv +53 -53
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/html-tailwind.csv +56 -56
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/nextjs.csv +53 -53
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/react.csv +54 -54
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/svelte.csv +54 -54
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/swiftui.csv +51 -51
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/vue.csv +50 -50
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/styles.csv +17 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/typography.csv +17 -1
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/ui-reasoning.csv +162 -101
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/web-interface.csv +30 -30
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/core.py +31 -22
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/design_system.py +150 -69
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/search.py +3 -3
- package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/teammode/SKILL.md +59 -32
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-guide.mjs +17 -16
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-state.mjs +70 -3
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-worktree.mjs +113 -0
- package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +63 -4
- package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +105 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +140 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/__init__.py +24 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/__main__.py +106 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/bias_check.py +174 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/curl_probe.py +91 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/executor.py +192 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/fetch_chain.py +268 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/referers.py +15 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/result_schema.py +45 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/summary.py +37 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +11 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +129 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +167 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_fetch_chain.py +77 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +282 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/url_transforms.py +98 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/validators.py +216 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/waf_detector.py +214 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/waf_profiles.yaml +162 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/README.md +79 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/career.md +29 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/dev.md +62 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/search.md +33 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/social.md +207 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/video.md +115 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/web.md +76 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +120 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +319 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/cache-archive.md +83 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/fallback.md +159 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/jina.md +130 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/json-api.md +133 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/media.md +123 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/metadata.md +116 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/naver.md +107 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/playwright.md +142 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/public-api.md +119 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/rss.md +123 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/tls-impersonate.md +186 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/twitter.md +104 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/cookie_crypto.py +75 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/cookie_domains.py +38 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/cookie_paths.py +112 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/extract_cookies.py +280 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/tests/test_cookie_domain_filter.py +110 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/tests/test_extract_cookies.py +245 -0
- package/packages/omo-codex/plugin/skills/ultraresearch/ATTRIBUTION.md +49 -0
- package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +34 -6
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +8 -7
- package/packages/omo-codex/plugin/test/aggregate-build.test.mjs +2 -1
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +36 -0
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -1
- package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +1 -1
- package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +95 -0
- package/packages/omo-codex/plugin/test/auto-update-restart-notice.test.mjs +12 -3
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -0
- package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +76 -0
- package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +24 -0
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +1 -0
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +1 -0
- package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +87 -0
- package/packages/omo-codex/plugin/test/teammode-thread-title.test.mjs +169 -0
- package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +246 -0
- package/packages/omo-codex/plugin/test/ultraresearch-skill-contract.test.mjs +78 -0
- package/packages/omo-codex/scripts/install-cli-args.test.mjs +1 -1
- package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +23 -0
- package/packages/omo-codex/scripts/install-delegated-command.test.mjs +76 -4
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +531 -214
- package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +40 -3
- package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +32 -8
- package/packages/shared-skills/skills/frontend/references/design/airbnb.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/airtable.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/apple.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/binance.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/bmw.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/bugatti.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/cal.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/claude.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/clay.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/clickhouse.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/cohere.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/coinbase.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/composio.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/cursor.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/elevenlabs.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/expo.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/ferrari.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/figma.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/framer.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/hashicorp.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/ibm.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/imagegen-frontend-web.md +380 -79
- package/packages/shared-skills/skills/frontend/references/design/intercom.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/kraken.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/lamborghini.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/linear.app.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/lovable.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/mastercard.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/meta.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/minimax.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/mintlify.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/miro.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/mistral.ai.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/mongodb.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/nike.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/notion.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/nvidia.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/ollama.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/opencode.ai.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/pinterest.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/playstation.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/posthog.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/raycast.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/renault.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/replicate.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/resend.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/revolut.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/runwayml.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/sanity.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/sentry.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/shopify.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/spacex.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/spotify.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/starbucks.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/stitch-skill.md +1 -1
- package/packages/shared-skills/skills/frontend/references/design/stripe.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/supabase.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/superhuman.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/taste-skill.md +1188 -208
- package/packages/shared-skills/skills/frontend/references/design/tesla.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/theverge.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/together.ai.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/uber.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/vercel.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/vodafone.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/voltagent.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/warp.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/webflow.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/wired.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/wise.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/x.ai.md +3 -0
- package/packages/shared-skills/skills/frontend/references/design/zapier.md +3 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/README.md +501 -115
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/charts.csv +26 -26
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/colors.csv +162 -97
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/icons.csv +105 -100
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/landing.csv +22 -18
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/products.csv +162 -97
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/flutter.csv +53 -53
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/html-tailwind.csv +56 -56
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/nextjs.csv +53 -53
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/react.csv +54 -54
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/svelte.csv +54 -54
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/swiftui.csv +51 -51
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/vue.csv +50 -50
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/styles.csv +17 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/typography.csv +17 -1
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/ui-reasoning.csv +162 -101
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/web-interface.csv +30 -30
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/core.py +31 -22
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/design_system.py +150 -69
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/search.py +3 -3
- package/packages/shared-skills/skills/lcx-doctor/SKILL.md +1 -1
- package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +105 -0
- package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +140 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/__init__.py +24 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/__main__.py +106 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/bias_check.py +174 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/curl_probe.py +91 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/executor.py +192 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/fetch_chain.py +268 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/referers.py +15 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/result_schema.py +45 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/summary.py +37 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +11 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +129 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +167 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_fetch_chain.py +77 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +282 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/url_transforms.py +98 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/validators.py +216 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/waf_detector.py +214 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/waf_profiles.yaml +162 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/README.md +79 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/career.md +29 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/dev.md +62 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/search.md +33 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/social.md +207 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/video.md +115 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/web.md +76 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +120 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +319 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/cache-archive.md +83 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/fallback.md +159 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/jina.md +130 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/json-api.md +133 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/media.md +123 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/metadata.md +116 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/naver.md +107 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/playwright.md +142 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/public-api.md +119 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/rss.md +123 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/tls-impersonate.md +186 -0
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/twitter.md +104 -0
- package/packages/shared-skills/skills/ultimate-browsing/scripts/cookie_crypto.py +75 -0
- package/packages/shared-skills/skills/ultimate-browsing/scripts/cookie_domains.py +38 -0
- package/packages/shared-skills/skills/ultimate-browsing/scripts/cookie_paths.py +112 -0
- package/packages/shared-skills/skills/ultimate-browsing/scripts/extract_cookies.py +280 -0
- package/packages/shared-skills/skills/ultimate-browsing/scripts/tests/test_cookie_domain_filter.py +110 -0
- package/packages/shared-skills/skills/ultimate-browsing/scripts/tests/test_extract_cookies.py +245 -0
- package/packages/shared-skills/skills/ultraresearch/ATTRIBUTION.md +49 -0
- package/packages/shared-skills/skills/ultraresearch/SKILL.md +34 -6
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +4 -1
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.d.ts +0 -2
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.d.ts +0 -32
|
@@ -26,11 +26,15 @@ Use plain subagents (`$ulw` / `multi_agent_v1.spawn_agent`) - NOT a team - when
|
|
|
26
26
|
A team buys cross-member coordination at a real overhead cost; only spend it when coordination
|
|
27
27
|
is the thing you actually need.
|
|
28
28
|
|
|
29
|
-
## You are the leader
|
|
29
|
+
## You are the leader - orchestrate, do not implement
|
|
30
30
|
|
|
31
|
-
The main session is ALWAYS the team leader
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
The main session is ALWAYS the team leader; you orchestrate directly and never spin up a separate
|
|
32
|
+
leader thread. Your job is orchestration, NOT writing product code: split the work and assign each
|
|
33
|
+
slice, hold live situational awareness of every member, verify and QA what they deliver, relay
|
|
34
|
+
findings between members, instruct and unblock, and synthesize the result. DELEGATE every code edit
|
|
35
|
+
to a member - if you catch yourself editing product files while the team runs, that work was a
|
|
36
|
+
member's slice you should have handed off. You own direction, verification, and integration (the
|
|
37
|
+
merge), not the keystrokes.
|
|
34
38
|
|
|
35
39
|
## Compose by part, ownership, or perspective - not by job title
|
|
36
40
|
|
|
@@ -45,6 +49,9 @@ member by a concrete slice: a specific part of the codebase, an ownership area,
|
|
|
45
49
|
perspective/lens. Assigning a vague role ("backend dev", "release analyst", "the tester") is an
|
|
46
50
|
anti-pattern - it gives the member no real boundary and invites overlap. Each member's `focus`
|
|
47
51
|
names what they own concretely; the `lens` is one of `area`, `ownership`, or `perspective`.
|
|
52
|
+
Give each member a short, distinct `--name` too - its role or what it watches (e.g.
|
|
53
|
+
`app-server-lifecycle`, `mailbox-delivery`) - because that name titles its thread; never reuse
|
|
54
|
+
one name for two members.
|
|
48
55
|
|
|
49
56
|
## Run the script - never hand-write team state
|
|
50
57
|
|
|
@@ -54,10 +61,13 @@ Replace `<skill-root>` with this skill's own directory.
|
|
|
54
61
|
|
|
55
62
|
```
|
|
56
63
|
node "<skill-root>/scripts/team.mjs" init --name "<team>" --session-name "<session>" [--session <leader_session_id>] [--worktree] [--base-branch dev]
|
|
57
|
-
node "<skill-root>/scripts/team.mjs" add-member --team <session_id> --id A --focus "<part/ownership/perspective>" --lens area|ownership|perspective --deliverable "<...>" [--branch <branch>]
|
|
64
|
+
node "<skill-root>/scripts/team.mjs" add-member --team <session_id> --id A --name "<short role>" --focus "<part/ownership/perspective>" --lens area|ownership|perspective --deliverable "<...>" [--branch <branch>]
|
|
58
65
|
node "<skill-root>/scripts/team.mjs" bind-thread --team <session_id> --id A --thread <thread_id> [--cwd <path>]
|
|
59
66
|
node "<skill-root>/scripts/team.mjs" member-prompt --team <session_id> --id A
|
|
60
67
|
node "<skill-root>/scripts/team.mjs" set-status --team <session_id> --id A --status reported|blocked|active|archived [--note "<...>"]
|
|
68
|
+
node "<skill-root>/scripts/team.mjs" worktree-add --team <session_id> --id A [--base-branch <branch>]
|
|
69
|
+
node "<skill-root>/scripts/team.mjs" worktree-remove --team <session_id> --id A [--force]
|
|
70
|
+
node "<skill-root>/scripts/team.mjs" integrate --team <session_id> [--id A]
|
|
61
71
|
node "<skill-root>/scripts/team.mjs" archive --team <session_id> [--id A]
|
|
62
72
|
node "<skill-root>/scripts/team.mjs" delete --team <session_id> [--force]
|
|
63
73
|
node "<skill-root>/scripts/team.mjs" status --team <session_id>
|
|
@@ -74,11 +84,11 @@ subcommand rewrites `guide.md`, so the manual always matches the current team.
|
|
|
74
84
|
|
|
75
85
|
1. `init` the team, then `add-member` once per member.
|
|
76
86
|
2. Create a durable thread per member with `codex_app.create_thread` - ALWAYS this tool for every
|
|
77
|
-
member, never a spawned agent - titled
|
|
78
|
-
|
|
79
|
-
accepts a working directory / cwd argument,
|
|
80
|
-
member's manual tells it to `cd` there first.
|
|
81
|
-
did not land at creation.
|
|
87
|
+
member, never a spawned agent - titled `[team name] <member name>`, using THAT member's own
|
|
88
|
+
name (its role / what it watches), so no two threads share a title. `add-member` prints the
|
|
89
|
+
exact title to use. If `codex_app.create_thread` accepts a working directory / cwd argument,
|
|
90
|
+
set it to that member's worktree; otherwise the member's manual tells it to `cd` there first.
|
|
91
|
+
Use `codex_app.set_thread_title` if the title did not land at creation.
|
|
82
92
|
3. `bind-thread` to record each thread id (and `--cwd`), then send that member's bootstrap
|
|
83
93
|
trigger (printed by `add-member` / `member-prompt`) as the thread's first message. The trigger
|
|
84
94
|
is short on purpose: it tells the new thread to READ its `guide.md` and `team.json` rather than
|
|
@@ -87,7 +97,7 @@ subcommand rewrites `guide.md`, so the manual always matches the current team.
|
|
|
87
97
|
Every team member is a real Codex thread created with `codex_app.create_thread` - this is strict,
|
|
88
98
|
not a preference. NEVER substitute `multi_agent_v1.spawn_agent`, or any other in-process subagent,
|
|
89
99
|
for a team member: a spawned agent is an ephemeral helper that does not show up as a team thread,
|
|
90
|
-
cannot carry the `[team name]
|
|
100
|
+
cannot carry the `[team name] <member name>` title, and cannot be inspected, titled, archived, or
|
|
91
101
|
re-opened with the `codex_app.*` thread tools - which defeats the entire point of a durable team.
|
|
92
102
|
A member only counts once you have `bind-thread`-ed it to a real `codex_app.create_thread` thread
|
|
93
103
|
id. If the thread-creation tool is unavailable, STOP and say so (see Stop rules); do not quietly
|
|
@@ -95,24 +105,41 @@ fall back to a spawned agent.
|
|
|
95
105
|
|
|
96
106
|
## Communication
|
|
97
107
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
worktree
|
|
115
|
-
|
|
108
|
+
Members push to you and to one another with `codex_app.send_message_to_thread`; you inspect their
|
|
109
|
+
state with `codex_app.read_thread`. So members can actually reach you, run `init` with
|
|
110
|
+
`--session <your own thread id>` - that makes `leader.sessionId` in team.json a real, messageable
|
|
111
|
+
thread; without it members cannot report to you and you are stuck polling. The generated manual binds
|
|
112
|
+
members to the hard rules, so you mainly keep the channel open: expect frequent small inbound updates
|
|
113
|
+
from each member - findings, `WORKING:`/`BLOCKED:` markers, peer digests - rather than one final
|
|
114
|
+
dump, and act on them as they arrive. All member-to-member and member-to-leader traffic is in English;
|
|
115
|
+
when the END user addresses a member, that member replies in the user's own language. Members hand off
|
|
116
|
+
files and memos through the team `artifacts/` directory and reference them by path. Wait for every
|
|
117
|
+
required member's final report before you declare the team done.
|
|
118
|
+
|
|
119
|
+
## Worktrees - isolate members who would touch the same files
|
|
120
|
+
|
|
121
|
+
The moment two members' slices would edit the same files, give each its own git worktree so they
|
|
122
|
+
cannot clobber each other. Decide this whenever you see the collision - at team creation OR mid-run,
|
|
123
|
+
not only up front. For each colliding member run `worktree-add --team <id> --id <member>`: it creates
|
|
124
|
+
the worktree off the base branch on a derived branch, flips the team into worktree mode, records it in
|
|
125
|
+
`team.json`, and prints the `cd` path to hand that member. The member works and commits only inside
|
|
126
|
+
its own worktree. To land the work, `integrate --team <id>` merges every member branch into your
|
|
127
|
+
current branch with a merge commit (never a squash or rebase); resolve any conflict it reports, then
|
|
128
|
+
`worktree-remove` each worktree at cleanup.
|
|
129
|
+
|
|
130
|
+
## Run a ulw-plan in parallel
|
|
131
|
+
|
|
132
|
+
When a decision-complete plan already exists at `.omo/plans/<slug>.md` (from ulw-plan), execute its
|
|
133
|
+
parallel waves as a team instead of one todo at a time. Map it directly:
|
|
134
|
+
- one wave's independent todos -> one member each; the todo's scope/files become that member's `focus`,
|
|
135
|
+
and its acceptance criteria + QA become the member's `deliverable`.
|
|
136
|
+
- the plan's dependency matrix sets the shape: todos with no unmet dependency inside a wave run as
|
|
137
|
+
concurrent members; a todo that depends on another waits, so launch the next wave only after the
|
|
138
|
+
blocking members report.
|
|
139
|
+
- todos in the same wave that touch overlapping files -> give those members worktrees (see above).
|
|
140
|
+
|
|
141
|
+
Keep the plan file as the shared spec: point each member at its todo by path, and verify the member's
|
|
142
|
+
result against that todo's acceptance criteria before you integrate.
|
|
116
143
|
|
|
117
144
|
## Archive, delete, and cleanup
|
|
118
145
|
|
|
@@ -126,9 +153,9 @@ then delete the team state. A finished team that is never disbanded is a leak.
|
|
|
126
153
|
and tell the user - never pretend a member was archived.
|
|
127
154
|
- `delete` removes `.omo/teams/{session_id}` and refuses while the team is unarchived or any member
|
|
128
155
|
is still active unless `--force`.
|
|
129
|
-
- When the work wraps up,
|
|
130
|
-
or
|
|
131
|
-
user's instruction on how to land it.
|
|
156
|
+
- When the work wraps up, land it the way the user asked: `integrate --team <id>` for a direct merge
|
|
157
|
+
commit, or push each member branch and open a PR. Then `worktree-remove` each worktree, archive, and
|
|
158
|
+
delete. Cleanup is real work; respect the user's instruction on how to land it.
|
|
132
159
|
|
|
133
160
|
## Stop rules
|
|
134
161
|
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
function memberLine(member) {
|
|
9
9
|
const thread = member.threadId ? ` | thread ${member.threadId}` : " | thread not created yet";
|
|
10
10
|
const wt = member.worktree?.path ? ` | worktree ${member.worktree.path}` : "";
|
|
11
|
-
|
|
11
|
+
const name = member.name ? ` "${member.name}"` : "";
|
|
12
|
+
const title = member.threadTitle ? ` | thread title \`${member.threadTitle}\`` : "";
|
|
13
|
+
return `- **${member.id}**${name} (${member.lens}) - ${member.focus}${member.deliverable ? ` -> ${member.deliverable}` : ""}${title}${thread}${wt} [${member.status}]`;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
function worktreeSection(team) {
|
|
@@ -43,7 +45,7 @@ export function buildGuide(team) {
|
|
|
43
45
|
|
|
44
46
|
- Team: **${team.teamName}** (id \`${team.teamId}\`)
|
|
45
47
|
- Team state: \`${teamJson}\`
|
|
46
|
-
- Thread
|
|
48
|
+
- Thread title convention: \`${team.threadTitleConvention}\` - each member's thread takes its OWN title from its name (your row below shows yours); two members never share a title
|
|
47
49
|
|
|
48
50
|
## Who you are (your identity is fixed)
|
|
49
51
|
|
|
@@ -66,18 +68,17 @@ coordinate with each other, but the leader owns the final decision and integrati
|
|
|
66
68
|
is mandatory regardless of the language the task was given in.
|
|
67
69
|
- **Exception: when the END USER addresses you directly, reply in the user's own language.**
|
|
68
70
|
Team-internal traffic stays English; user-facing replies match the user.
|
|
69
|
-
- **
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
idle and never disappear. Being quiet is a failure, not a pause.
|
|
71
|
+
- **Reach the leader and your peers with \`codex_app.send_message_to_thread\` - not by narrating in
|
|
72
|
+
your own thread, where no one reads it.** The address book is in team.json: the leader thread id
|
|
73
|
+
is \`leader.sessionId\`, and each peer thread id is its \`members[].threadId\`.
|
|
74
|
+
- **Push a short message at each of these moments - never batch them into one report at the end:**
|
|
75
|
+
- to the **leader**: every finding or decision, every file or sub-task you finish, a
|
|
76
|
+
\`WORKING: <focus> - <phase>\` heartbeat every few tool calls so you never look stale, a
|
|
77
|
+
\`BLOCKED: <reason>\` the instant you cannot proceed, and your result the moment your slice is done.
|
|
78
|
+
- to a **peer**: the instant you learn anything that touches their slice - a shared finding, a
|
|
79
|
+
changed assumption, an interface they depend on. When unsure who owns it, send it to the leader.
|
|
80
|
+
- **Going quiet is the only failure.** Many small lean messages beat one end-of-work dump; keep
|
|
81
|
+
every message short.
|
|
81
82
|
|
|
82
83
|
## Artifacts (how you hand work off)
|
|
83
84
|
|
|
@@ -103,9 +104,9 @@ export function buildMemberPrompt(team, id) {
|
|
|
103
104
|
const guide = team.paths?.guide ?? ".omo/teams/<session_id>/guide.md";
|
|
104
105
|
const teamJson = team.paths?.team ?? ".omo/teams/<session_id>/team.json";
|
|
105
106
|
const where = member.cwd ? `Work inside \`${member.cwd}\`.` : "Work from the repository root unless your manual assigns a worktree.";
|
|
106
|
-
return `You are member ${member.id} of team ${team.teamName} - owner of: ${member.focus}.
|
|
107
|
+
return `You are member ${member.id}${member.name ? ` (${member.name})` : ""} of team ${team.teamName} - owner of: ${member.focus}. Your thread title is \`${member.threadTitle}\`.
|
|
107
108
|
FIRST read your field manual at \`${guide}\`, then the team state at \`${teamJson}\`; they define your scope, deliverable, the leader, the artifacts directory, and the communication rules.
|
|
108
109
|
${where}
|
|
109
110
|
Communicate with the team and leader in English; reply to the end user in the user's own language.
|
|
110
|
-
Start now
|
|
111
|
+
Start now. Push updates to the leader and relevant peers with \`codex_app.send_message_to_thread\` as you work - findings, \`WORKING:\` heartbeats, and \`BLOCKED:\` the instant you stall - never just one report at the end.`;
|
|
111
112
|
}
|
|
@@ -39,7 +39,7 @@ export function buildTeam({ teamName, sessionName, sessionId = null, dir = null,
|
|
|
39
39
|
teamName: teamName.trim(),
|
|
40
40
|
sessionName: sessionName.trim(),
|
|
41
41
|
sessionId,
|
|
42
|
-
threadTitleConvention: `[${teamName.trim()}]
|
|
42
|
+
threadTitleConvention: `[${teamName.trim()}] <member name>`,
|
|
43
43
|
status: "active",
|
|
44
44
|
createdAt: ts,
|
|
45
45
|
updatedAt: ts,
|
|
@@ -72,6 +72,14 @@ function normalizedFocus(focus) {
|
|
|
72
72
|
return focus.trim().replace(/\s+/g, " ").toLowerCase();
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
function normalizedMemberName(name) {
|
|
76
|
+
return name.trim().replace(/\s+/g, " ").toLowerCase();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function normalizedThreadTitle(title) {
|
|
80
|
+
return title.trim().replace(/\s+/g, " ").toLowerCase();
|
|
81
|
+
}
|
|
82
|
+
|
|
75
83
|
function assertUniqueMemberFocus(team) {
|
|
76
84
|
const seen = new Map();
|
|
77
85
|
for (const member of team.members) {
|
|
@@ -84,6 +92,35 @@ function assertUniqueMemberFocus(team) {
|
|
|
84
92
|
}
|
|
85
93
|
}
|
|
86
94
|
|
|
95
|
+
function assertUniqueMemberName(team) {
|
|
96
|
+
const seen = new Map();
|
|
97
|
+
for (const member of team.members) {
|
|
98
|
+
const memberName = member.name ?? member.focus ?? "";
|
|
99
|
+
const key = normalizedMemberName(memberName);
|
|
100
|
+
const previous = seen.get(key);
|
|
101
|
+
if (previous) {
|
|
102
|
+
throw new Error(`member name "${memberName}" duplicates "${previous.name ?? previous.focus}" (no two members may produce the same thread title)`);
|
|
103
|
+
}
|
|
104
|
+
seen.set(key, member);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function assertUniqueMemberThreadTitle(team) {
|
|
109
|
+
const seen = new Map();
|
|
110
|
+
for (const member of team.members) {
|
|
111
|
+
const threadTitle = member.threadTitle;
|
|
112
|
+
if (typeof threadTitle !== "string" || !threadTitle.trim()) {
|
|
113
|
+
throw new Error(`member "${member.id ?? member.name ?? member.focus ?? "(unknown)"}" has invalid threadTitle (non-empty string required)`);
|
|
114
|
+
}
|
|
115
|
+
const key = normalizedThreadTitle(threadTitle);
|
|
116
|
+
const previous = seen.get(key);
|
|
117
|
+
if (previous) {
|
|
118
|
+
throw new Error(`member threadTitle "${threadTitle}" duplicates "${previous.threadTitle}" (no two members may produce the same thread title)`);
|
|
119
|
+
}
|
|
120
|
+
seen.set(key, member);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
87
124
|
function assertTeamReadyForThreadBinding(team) {
|
|
88
125
|
if (isUnderstaffed(team)) {
|
|
89
126
|
throw new Error(
|
|
@@ -91,24 +128,34 @@ function assertTeamReadyForThreadBinding(team) {
|
|
|
91
128
|
);
|
|
92
129
|
}
|
|
93
130
|
assertUniqueMemberFocus(team);
|
|
131
|
+
assertUniqueMemberName(team);
|
|
132
|
+
assertUniqueMemberThreadTitle(team);
|
|
94
133
|
}
|
|
95
134
|
|
|
96
|
-
export function addMember(team, { id, focus, lens, deliverable = "", branch = null }) {
|
|
135
|
+
export function addMember(team, { id, focus, lens, deliverable = "", branch = null, name = null }) {
|
|
97
136
|
if (!id?.trim()) throw new Error("member id is required");
|
|
98
137
|
if (!focus?.trim()) throw new Error("member focus is required - a concrete part, ownership area, or perspective");
|
|
99
138
|
if (!LENSES.includes(lens)) throw new Error(`invalid lens "${lens}" - use one of: ${LENSES.join(", ")}`);
|
|
100
139
|
const memberId = id.trim();
|
|
101
140
|
const memberFocus = focus.trim();
|
|
141
|
+
// The member name is the short role label that titles this member's thread. Fall back to the
|
|
142
|
+
// focus so the title is ALWAYS per-member and never the shared team-wide session name.
|
|
143
|
+
const memberName = name?.trim() || memberFocus;
|
|
102
144
|
if (team.members.some((m) => m.id === memberId)) throw new Error(`member id "${memberId}" already exists (duplicate)`);
|
|
103
145
|
const duplicate = team.members.find((m) => normalizedFocus(m.focus) === normalizedFocus(memberFocus));
|
|
104
146
|
if (duplicate) throw new Error(`member focus "${memberFocus}" duplicates "${duplicate.focus}" (no two members may own the same thing)`);
|
|
147
|
+
const duplicateName = team.members.find((m) => normalizedMemberName(m.name ?? m.focus ?? "") === normalizedMemberName(memberName));
|
|
148
|
+
if (duplicateName) {
|
|
149
|
+
throw new Error(`member name "${memberName}" duplicates "${duplicateName.name ?? duplicateName.focus}" (no two members may produce the same thread title)`);
|
|
150
|
+
}
|
|
105
151
|
team.members.push({
|
|
106
152
|
id: memberId,
|
|
153
|
+
name: memberName,
|
|
107
154
|
focus: memberFocus,
|
|
108
155
|
lens,
|
|
109
156
|
deliverable: deliverable.trim(),
|
|
110
157
|
threadId: null,
|
|
111
|
-
threadTitle: team.
|
|
158
|
+
threadTitle: `[${team.teamName}] ${memberName}`,
|
|
112
159
|
cwd: null,
|
|
113
160
|
worktree: { path: null, branch: branch ?? null },
|
|
114
161
|
status: "pending",
|
|
@@ -133,6 +180,24 @@ export function setMemberStatus(team, { id, status, note = "" }) {
|
|
|
133
180
|
return touch(team, "set-status", `member ${id} -> ${status}${note ? `: ${note}` : ""}`);
|
|
134
181
|
}
|
|
135
182
|
|
|
183
|
+
// Record a provisioned worktree. Isolation is conflict-triggered: the first worktree-add flips
|
|
184
|
+
// the whole team into worktree mode, so the leader can decide it mid-run, not only at init.
|
|
185
|
+
export function setMemberWorktree(team, { id, path, branch }) {
|
|
186
|
+
const m = memberById(team, id);
|
|
187
|
+
team.worktree.enabled = true;
|
|
188
|
+
m.worktree.path = path;
|
|
189
|
+
m.worktree.branch = branch;
|
|
190
|
+
m.cwd = path;
|
|
191
|
+
return touch(team, "worktree-add", `member ${id} -> ${path} (${branch})`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function clearMemberWorktree(team, { id }) {
|
|
195
|
+
const m = memberById(team, id);
|
|
196
|
+
if (m.cwd === m.worktree?.path) m.cwd = null;
|
|
197
|
+
m.worktree.path = null;
|
|
198
|
+
return touch(team, "worktree-remove", `member ${id}`);
|
|
199
|
+
}
|
|
200
|
+
|
|
136
201
|
export function archive(team, { id = null, note = "" } = {}) {
|
|
137
202
|
if (id) {
|
|
138
203
|
memberById(team, id).status = "archived";
|
|
@@ -150,6 +215,8 @@ export function validateTeam(team) {
|
|
|
150
215
|
if (team.leader?.kind !== "main-session") throw new Error("invalid team: leader.kind must be main-session");
|
|
151
216
|
if (!Array.isArray(team.members)) throw new Error("invalid team: members must be an array");
|
|
152
217
|
assertUniqueMemberFocus(team);
|
|
218
|
+
assertUniqueMemberName(team);
|
|
219
|
+
assertUniqueMemberThreadTitle(team);
|
|
153
220
|
return team;
|
|
154
221
|
}
|
|
155
222
|
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// team-worktree.mjs - git worktree provisioning + merge integration for teammode.
|
|
2
|
+
//
|
|
3
|
+
// Shells out to `git` through node:child_process so the leader never hand-runs worktree or
|
|
4
|
+
// merge commands and never improvises a branch name. Zero npm dependencies, like the rest of
|
|
5
|
+
// the skill. team-state.mjs stays the pure state model; this file owns the git side only.
|
|
6
|
+
|
|
7
|
+
import { spawnSync } from "node:child_process";
|
|
8
|
+
import { realpathSync } from "node:fs";
|
|
9
|
+
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
10
|
+
|
|
11
|
+
// A member id that also names a directory and a branch segment: no "/", no "..", no leading dot.
|
|
12
|
+
const MEMBER_ID_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
13
|
+
|
|
14
|
+
// Compare two on-disk paths regardless of OS. realpathSync canonicalizes separators, Windows
|
|
15
|
+
// 8.3 short names (RUNNER~1) and drive-letter case, and the macOS /var -> /private/var symlink -
|
|
16
|
+
// none of which plain resolve() reconciles. Returns false if either side no longer exists.
|
|
17
|
+
function samePath(a, b) {
|
|
18
|
+
try {
|
|
19
|
+
return realpathSync(a) === realpathSync(b);
|
|
20
|
+
} catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function git(cwd, args) {
|
|
26
|
+
const result = spawnSync("git", args, { cwd, encoding: "utf8" });
|
|
27
|
+
if (result.error) throw new Error(`git ${args.join(" ")} could not run: ${result.error.message}`);
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function gitOrThrow(cwd, args) {
|
|
32
|
+
const result = git(cwd, args);
|
|
33
|
+
if (result.status !== 0) throw new Error(`git ${args.join(" ")} failed: ${(result.stderr || result.stdout || "").trim()}`);
|
|
34
|
+
return result.stdout ?? "";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function deriveMemberBranch(team, member) {
|
|
38
|
+
if (member.worktree?.branch) return member.worktree.branch;
|
|
39
|
+
return `team/${team.sessionId ?? team.teamId}/${member.id}`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Confine a member worktree to <worktree.root>/<member id>; reject any id that would escape it.
|
|
43
|
+
export function memberWorktreePath(team, member) {
|
|
44
|
+
if (!MEMBER_ID_SEGMENT.test(member.id ?? "")) throw new Error(`unsafe member id for a worktree path: "${member.id}"`);
|
|
45
|
+
const root = team.worktree?.root;
|
|
46
|
+
if (!root) throw new Error("team has no worktree root; re-init the team");
|
|
47
|
+
const path = join(root, member.id);
|
|
48
|
+
const rel = relative(root, path);
|
|
49
|
+
if (rel !== member.id || rel.startsWith("..") || isAbsolute(rel)) throw new Error(`refused: worktree path escapes ${root}`);
|
|
50
|
+
return path;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function listWorktrees(cwd) {
|
|
54
|
+
const out = gitOrThrow(cwd, ["worktree", "list", "--porcelain"]);
|
|
55
|
+
const worktrees = [];
|
|
56
|
+
let current = null;
|
|
57
|
+
for (const line of out.split("\n")) {
|
|
58
|
+
if (line.startsWith("worktree ")) {
|
|
59
|
+
current = { path: line.slice("worktree ".length) };
|
|
60
|
+
worktrees.push(current);
|
|
61
|
+
} else if (line.startsWith("branch ") && current) {
|
|
62
|
+
current.branch = line.slice("branch ".length);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return worktrees;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function branchExists(cwd, branch) {
|
|
69
|
+
return git(cwd, ["rev-parse", "--verify", "--quiet", `refs/heads/${branch}`]).status === 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function currentBranch(cwd) {
|
|
73
|
+
return gitOrThrow(cwd, ["rev-parse", "--abbrev-ref", "HEAD"]).trim();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function addMemberWorktree(cwd, team, member, { baseBranch } = {}) {
|
|
77
|
+
const base = baseBranch || team.worktree?.baseBranch || "dev";
|
|
78
|
+
const branch = deriveMemberBranch(team, member);
|
|
79
|
+
const path = memberWorktreePath(team, member);
|
|
80
|
+
// Idempotent: skip if a worktree is already checked out on this member's branch (matched on the
|
|
81
|
+
// branch ref, which is OS-agnostic) or already lives at this path (matched on realpath, so a
|
|
82
|
+
// Windows 8.3 git path vs an 8.3-or-long script path still compares equal). Plain string/resolve
|
|
83
|
+
// comparison missed the 8.3-vs-canonical case and re-`git worktree add`-ed into a fatal error.
|
|
84
|
+
if (listWorktrees(cwd).some((w) => w.branch === `refs/heads/${branch}` || samePath(resolve(cwd, w.path), resolve(cwd, path)))) {
|
|
85
|
+
return { path, branch, base, created: false };
|
|
86
|
+
}
|
|
87
|
+
const add = branchExists(cwd, branch)
|
|
88
|
+
? ["worktree", "add", path, branch]
|
|
89
|
+
: ["worktree", "add", "-b", branch, path, base];
|
|
90
|
+
gitOrThrow(cwd, add);
|
|
91
|
+
return { path, branch, base, created: true };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function removeMemberWorktree(cwd, team, member, { force = false } = {}) {
|
|
95
|
+
const path = memberWorktreePath(team, member);
|
|
96
|
+
gitOrThrow(cwd, ["worktree", "remove", ...(force ? ["--force"] : []), path]);
|
|
97
|
+
return { path };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Land a member branch with a MERGE COMMIT (--no-ff). Never squash, never rebase (repo policy).
|
|
101
|
+
// On conflict the working tree is left mid-merge so the leader can resolve and re-run.
|
|
102
|
+
export function integrateMemberBranch(cwd, branch) {
|
|
103
|
+
const result = git(cwd, ["merge", "--no-ff", "--no-edit", branch]);
|
|
104
|
+
if (result.status === 0) return { branch, merged: true, into: currentBranch(cwd) };
|
|
105
|
+
const conflicts = gitOrThrow(cwd, ["diff", "--name-only", "--diff-filter=U"]).trim();
|
|
106
|
+
return {
|
|
107
|
+
branch,
|
|
108
|
+
merged: false,
|
|
109
|
+
into: currentBranch(cwd),
|
|
110
|
+
conflicts: conflicts ? conflicts.split("\n") : [],
|
|
111
|
+
message: (result.stderr || result.stdout || "").trim(),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// macOS, Linux, and Windows.
|
|
8
8
|
//
|
|
9
9
|
// node "<skill-root>/scripts/team.mjs" init --name "<team>" --session-name "<sess>" [--session <id>] [--worktree] [--base-branch dev]
|
|
10
|
-
// node "<skill-root>/scripts/team.mjs" add-member --team <id> --id A --focus "<part/ownership/perspective>" --lens area|ownership|perspective --deliverable "<...>" [--branch <b>]
|
|
10
|
+
// node "<skill-root>/scripts/team.mjs" add-member --team <id> --id A --name "<short role>" --focus "<part/ownership/perspective>" --lens area|ownership|perspective --deliverable "<...>" [--branch <b>]
|
|
11
11
|
// node "<skill-root>/scripts/team.mjs" bind-thread --team <id> --id A --thread <thread-id> [--cwd <path>]
|
|
12
12
|
// node "<skill-root>/scripts/team.mjs" member-prompt --team <id> --id A
|
|
13
13
|
// node "<skill-root>/scripts/team.mjs" set-status --team <id> --id A --status reported|blocked|active|archived [--note "<...>"]
|
|
@@ -27,16 +27,18 @@ import {
|
|
|
27
27
|
assertSafeTeamDir,
|
|
28
28
|
bindThread,
|
|
29
29
|
buildTeam,
|
|
30
|
+
clearMemberWorktree,
|
|
30
31
|
ensureTeamDir,
|
|
31
32
|
isUnderstaffed,
|
|
32
33
|
MIN_MEMBERS,
|
|
33
34
|
readTeam,
|
|
34
|
-
resolveTeamDir,
|
|
35
35
|
setMemberStatus,
|
|
36
|
+
setMemberWorktree,
|
|
36
37
|
teamExists,
|
|
37
38
|
writeGuideAtomic,
|
|
38
39
|
writeTeamAtomic,
|
|
39
40
|
} from "./team-state.mjs";
|
|
41
|
+
import { addMemberWorktree, integrateMemberBranch, removeMemberWorktree } from "./team-worktree.mjs";
|
|
40
42
|
|
|
41
43
|
function parseFlags(args) {
|
|
42
44
|
const flags = { _: [] };
|
|
@@ -69,6 +71,12 @@ async function loadTeam(cwd, sessionId) {
|
|
|
69
71
|
return { dir, team: await readTeam(dir) };
|
|
70
72
|
}
|
|
71
73
|
|
|
74
|
+
function memberOrThrow(team, id) {
|
|
75
|
+
const member = team.members.find((m) => m.id === id);
|
|
76
|
+
if (!member) throw new Error(`no member with id "${id}"`);
|
|
77
|
+
return member;
|
|
78
|
+
}
|
|
79
|
+
|
|
72
80
|
async function persist(team, dir) {
|
|
73
81
|
await writeTeamAtomic(team, dir);
|
|
74
82
|
await writeGuideAtomic(team, buildGuide(team), dir);
|
|
@@ -95,7 +103,7 @@ const handlers = {
|
|
|
95
103
|
await persist(team, dir);
|
|
96
104
|
process.stdout.write(`created: ${dir}\n`);
|
|
97
105
|
process.stdout.write(`team.json + guide.md written; artifacts/ ready. session id: ${sessionId}\n`);
|
|
98
|
-
process.stdout.write(`next: add-member --team ${sessionId} --id A --focus "<part/ownership/perspective>" --lens area|ownership|perspective --deliverable "<...>"\n`);
|
|
106
|
+
process.stdout.write(`next: add-member --team ${sessionId} --id A --name "<short role>" --focus "<part/ownership/perspective>" --lens area|ownership|perspective --deliverable "<...>"\n`);
|
|
99
107
|
},
|
|
100
108
|
|
|
101
109
|
async "add-member"(cwd, flags) {
|
|
@@ -104,13 +112,15 @@ const handlers = {
|
|
|
104
112
|
const memberId = requireFlag(flags, "id").trim();
|
|
105
113
|
addMember(team, {
|
|
106
114
|
id: memberId,
|
|
115
|
+
name: typeof flags.name === "string" ? flags.name : null,
|
|
107
116
|
focus: requireFlag(flags, "focus"),
|
|
108
117
|
lens: requireFlag(flags, "lens"),
|
|
109
118
|
deliverable: typeof flags.deliverable === "string" ? flags.deliverable : "",
|
|
110
119
|
branch: typeof flags.branch === "string" ? flags.branch : null,
|
|
111
120
|
});
|
|
112
121
|
await persist(team, dir);
|
|
113
|
-
|
|
122
|
+
const member = team.members.find((m) => m.id === memberId);
|
|
123
|
+
process.stdout.write(`added member ${memberId} to team ${sessionId}.\n\nSend this as the new thread's first message (title the thread "${member.threadTitle}"):\n---\n${buildMemberPrompt(team, memberId)}\n---\n`);
|
|
114
124
|
},
|
|
115
125
|
|
|
116
126
|
async "bind-thread"(cwd, flags) {
|
|
@@ -144,6 +154,55 @@ const handlers = {
|
|
|
144
154
|
process.stdout.write(`member ${flags.id} -> ${flags.status}\n`);
|
|
145
155
|
},
|
|
146
156
|
|
|
157
|
+
async "worktree-add"(cwd, flags) {
|
|
158
|
+
const sessionId = requireFlag(flags, "team");
|
|
159
|
+
const { dir, team } = await loadTeam(cwd, sessionId);
|
|
160
|
+
const member = memberOrThrow(team, requireFlag(flags, "id"));
|
|
161
|
+
const result = addMemberWorktree(cwd, team, member, {
|
|
162
|
+
baseBranch: typeof flags["base-branch"] === "string" ? flags["base-branch"] : null,
|
|
163
|
+
});
|
|
164
|
+
setMemberWorktree(team, { id: member.id, path: result.path, branch: result.branch });
|
|
165
|
+
await persist(team, dir);
|
|
166
|
+
const note = result.created ? "" : " (already exists)";
|
|
167
|
+
process.stdout.write(
|
|
168
|
+
`worktree for member ${member.id}${note}: ${result.path} on branch ${result.branch} (off ${result.base}).\nTell that member to: cd "${result.path}"\n`,
|
|
169
|
+
);
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
async "worktree-remove"(cwd, flags) {
|
|
173
|
+
const sessionId = requireFlag(flags, "team");
|
|
174
|
+
const { dir, team } = await loadTeam(cwd, sessionId);
|
|
175
|
+
const member = memberOrThrow(team, requireFlag(flags, "id"));
|
|
176
|
+
removeMemberWorktree(cwd, team, member, { force: flags.force === true });
|
|
177
|
+
clearMemberWorktree(team, { id: member.id });
|
|
178
|
+
await persist(team, dir);
|
|
179
|
+
process.stdout.write(`removed worktree for member ${member.id}\n`);
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
async integrate(cwd, flags) {
|
|
183
|
+
const sessionId = requireFlag(flags, "team");
|
|
184
|
+
const { team } = await loadTeam(cwd, sessionId);
|
|
185
|
+
const targets = typeof flags.id === "string" ? [memberOrThrow(team, flags.id)] : team.members.filter((m) => m.worktree?.branch);
|
|
186
|
+
if (targets.length === 0) throw new Error("no member has a worktree branch to integrate; run worktree-add first");
|
|
187
|
+
for (const member of targets) {
|
|
188
|
+
const result = integrateMemberBranch(cwd, member.worktree.branch);
|
|
189
|
+
if (!result.merged) {
|
|
190
|
+
if (result.conflicts.length > 0) {
|
|
191
|
+
process.stdout.write(`member ${member.id} (${member.worktree.branch}): CONFLICT into ${result.into}\n`);
|
|
192
|
+
throw new Error(
|
|
193
|
+
`merge conflict integrating member ${member.id} (branch ${member.worktree.branch}). Resolve the conflict, commit the merge, then re-run integrate. Conflicting files: ${result.conflicts.join(", ")}`,
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
process.stdout.write(`member ${member.id} (${member.worktree.branch}): could not start merge into ${result.into}\n`);
|
|
197
|
+
throw new Error(
|
|
198
|
+
`could not integrate member ${member.id} (branch ${member.worktree.branch}): ${result.message || "git merge failed; see git status"}`,
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
process.stdout.write(`member ${member.id} (${member.worktree.branch}): merged into ${result.into}\n`);
|
|
202
|
+
}
|
|
203
|
+
process.stdout.write(`integrated ${targets.length} member branch(es) with merge commits\n`);
|
|
204
|
+
},
|
|
205
|
+
|
|
147
206
|
async archive(cwd, flags) {
|
|
148
207
|
const sessionId = requireFlag(flags, "team");
|
|
149
208
|
const { dir, team } = await loadTeam(cwd, sessionId);
|