@bastani/atomic 0.9.5-alpha.8 → 0.9.5
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/CHANGELOG.md +122 -0
- package/README.md +2 -2
- package/dist/builtin/cursor/CHANGELOG.md +12 -0
- package/dist/builtin/cursor/package.json +3 -3
- package/dist/builtin/cursor/src/model-mapper.ts +6 -3
- package/dist/builtin/intercom/CHANGELOG.md +37 -0
- package/dist/builtin/intercom/README.md +4 -2
- package/dist/builtin/intercom/broker/broker.ts +6 -114
- package/dist/builtin/intercom/broker/client.ts +29 -54
- package/dist/builtin/intercom/broker/delivered-message-cache.ts +44 -0
- package/dist/builtin/intercom/broker/pending-send-registry.ts +142 -0
- package/dist/builtin/intercom/broker/send-handler.ts +106 -0
- package/dist/builtin/intercom/broker/send-signature.ts +37 -0
- package/dist/builtin/intercom/foreground-detach-handoff.ts +136 -0
- package/dist/builtin/intercom/index-heavy.ts +49 -53
- package/dist/builtin/intercom/index.ts +278 -262
- package/dist/builtin/intercom/lazy-heavy-proxy.ts +114 -0
- package/dist/builtin/intercom/lazy-subagent-ack.ts +20 -0
- package/dist/builtin/intercom/lazy-tool-execution.ts +39 -0
- package/dist/builtin/intercom/lifecycle-lease.ts +51 -0
- package/dist/builtin/intercom/lifecycle.ts +37 -20
- package/dist/builtin/intercom/package.json +3 -6
- package/dist/builtin/intercom/reply-routing.ts +17 -0
- package/dist/builtin/intercom/subagent-relay.ts +58 -12
- package/dist/builtin/intercom/types.ts +3 -3
- package/dist/builtin/mcp/CHANGELOG.md +38 -0
- package/dist/builtin/mcp/OAUTH.md +1 -0
- package/dist/builtin/mcp/README.md +10 -6
- package/dist/builtin/mcp/apps-cancellation.ts +32 -0
- package/dist/builtin/mcp/call-tool-result.ts +9 -0
- package/dist/builtin/mcp/caller-wait.ts +50 -0
- package/dist/builtin/mcp/command-registration.ts +82 -0
- package/dist/builtin/mcp/direct-tool-executor.ts +279 -0
- package/dist/builtin/mcp/direct-tools.ts +40 -255
- package/dist/builtin/mcp/host-html-template.ts +4 -2
- package/dist/builtin/mcp/index.ts +274 -239
- package/dist/builtin/mcp/init.ts +96 -126
- package/dist/builtin/mcp/mcp-auth-flow.ts +247 -237
- package/dist/builtin/mcp/mcp-callback-server.ts +89 -68
- package/dist/builtin/mcp/mcp-oauth-provider.ts +23 -1
- package/dist/builtin/mcp/metadata-hydration.ts +52 -0
- package/dist/builtin/mcp/package.json +3 -3
- package/dist/builtin/mcp/proxy-auth.ts +4 -4
- package/dist/builtin/mcp/proxy-call.ts +111 -40
- package/dist/builtin/mcp/proxy-connect.ts +35 -15
- package/dist/builtin/mcp/proxy-info-modes.ts +106 -23
- package/dist/builtin/mcp/proxy-modes.ts +3 -3
- package/dist/builtin/mcp/session-cleanup-barrier.ts +43 -0
- package/dist/builtin/mcp/startup-warmup.ts +98 -0
- package/dist/builtin/mcp/state-lease.ts +12 -0
- package/dist/builtin/mcp/tool-result-renderer.ts +3 -3
- package/dist/builtin/mcp/ui-server.ts +8 -8
- package/dist/builtin/mcp/ui-session.ts +9 -18
- package/dist/builtin/subagents/CHANGELOG.md +78 -0
- package/dist/builtin/subagents/README.md +30 -29
- package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
- package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
- package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
- package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -2
- package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
- package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
- package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
- package/dist/builtin/subagents/agents/debugger.md +2 -2
- package/dist/builtin/subagents/agents/worker.md +2 -2
- package/dist/builtin/subagents/package.json +5 -5
- package/dist/builtin/subagents/prompts/review-loop.md +1 -1
- package/dist/builtin/subagents/skills/subagent/SKILL.md +37 -36
- package/dist/builtin/subagents/src/extension/api-lifecycle.ts +64 -0
- package/dist/builtin/subagents/src/extension/fanout-child.ts +44 -51
- package/dist/builtin/subagents/src/extension/index.ts +289 -320
- package/dist/builtin/subagents/src/extension/prompt-guidance.ts +7 -10
- package/dist/builtin/subagents/src/extension/schemas.ts +22 -5
- package/dist/builtin/subagents/src/extension/startup-maintenance.ts +89 -0
- package/dist/builtin/subagents/src/extension/tool-description.ts +29 -0
- package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +13 -2
- package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -4
- package/dist/builtin/subagents/src/runs/background/async-event-journal.ts +106 -0
- package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +26 -20
- package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +13 -2
- package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +3 -0
- package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +1 -1
- package/dist/builtin/subagents/src/runs/background/completion-claims.ts +189 -0
- package/dist/builtin/subagents/src/runs/background/completion-dedupe.ts +44 -7
- package/dist/builtin/subagents/src/runs/background/completion-notification.ts +34 -0
- package/dist/builtin/subagents/src/runs/background/notify.ts +72 -22
- package/dist/builtin/subagents/src/runs/background/result-delivery-processor.ts +232 -0
- package/dist/builtin/subagents/src/runs/background/result-file-claims.ts +151 -0
- package/dist/builtin/subagents/src/runs/background/result-quarantine.ts +72 -0
- package/dist/builtin/subagents/src/runs/background/result-retry-scheduler.ts +48 -0
- package/dist/builtin/subagents/src/runs/background/result-status.ts +81 -0
- package/dist/builtin/subagents/src/runs/background/result-watcher-data.ts +59 -0
- package/dist/builtin/subagents/src/runs/background/result-watcher.ts +177 -233
- package/dist/builtin/subagents/src/runs/background/run-id-resolver.ts +3 -2
- package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +73 -14
- package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +29 -15
- package/dist/builtin/subagents/src/runs/background/top-level-async.ts +1 -2
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +1 -0
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +1 -0
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +1 -0
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +7 -9
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-types.ts +3 -13
- package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +2 -15
- package/dist/builtin/subagents/src/runs/foreground/execution-attempt-finalize.ts +2 -2
- package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +63 -46
- package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +48 -0
- package/dist/builtin/subagents/src/runs/foreground/execution-detach-route.ts +17 -0
- package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +39 -26
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +3 -1
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-chain.ts +3 -51
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +6 -11
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +11 -2
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +5 -112
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +68 -118
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +79 -7
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +2 -2
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +3 -0
- package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -2
- package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +55 -12
- package/dist/builtin/subagents/src/shared/artifacts.ts +22 -11
- package/dist/builtin/subagents/src/shared/event-jsonl-writer.ts +294 -0
- package/dist/builtin/subagents/src/shared/exclusive-file-publication.ts +44 -0
- package/dist/builtin/subagents/src/shared/jsonl-writer.ts +1 -0
- package/dist/builtin/subagents/src/shared/model-info.ts +2 -2
- package/dist/builtin/subagents/src/shared/settings.ts +20 -10
- package/dist/builtin/subagents/src/shared/types-async.ts +3 -1
- package/dist/builtin/subagents/src/shared/types-config.ts +2 -0
- package/dist/builtin/subagents/src/shared/types-runtime.ts +3 -2
- package/dist/builtin/subagents/src/slash/slash-commands.ts +9 -12
- package/dist/builtin/subagents/src/slash/slash-live-state.ts +63 -32
- package/dist/builtin/subagents/src/tui/render-result.ts +7 -0
- package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -0
- package/dist/builtin/subagents/src/tui/render-widget.ts +157 -89
- package/dist/builtin/web-access/CHANGELOG.md +28 -0
- package/dist/builtin/web-access/README.md +4 -0
- package/dist/builtin/web-access/content-tools.ts +8 -3
- package/dist/builtin/web-access/index-heavy.ts +1 -1
- package/dist/builtin/web-access/index.ts +190 -46
- package/dist/builtin/web-access/lifecycle-lease.ts +38 -0
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/web-access/result-renderers.ts +1 -1
- package/dist/builtin/web-access/summary-review.ts +1 -1
- package/dist/builtin/web-access/web-search-activity.ts +1 -1
- package/dist/builtin/web-access/web-search-return.ts +7 -0
- package/dist/builtin/web-access/web-search-summary.ts +1 -1
- package/dist/builtin/web-access/web-search-tool.ts +4 -2
- package/dist/builtin/workflows/CHANGELOG.md +86 -0
- package/dist/builtin/workflows/README.md +5 -5
- package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +27 -4
- package/dist/builtin/workflows/builtin/goal-runner.ts +86 -27
- package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +10 -0
- package/dist/builtin/workflows/builtin/ralph-core.ts +9 -9
- package/dist/builtin/workflows/builtin/ralph-models.ts +71 -36
- package/dist/builtin/workflows/builtin/ralph-runner.ts +20 -31
- package/dist/builtin/workflows/package.json +2 -2
- package/dist/builtin/workflows/skills/impeccable/SKILL.md +16 -13
- package/dist/builtin/workflows/skills/impeccable/reference/adapt.md +1 -0
- package/dist/builtin/workflows/skills/impeccable/reference/adapt.native.md +58 -0
- package/dist/builtin/workflows/skills/impeccable/reference/android.md +40 -0
- package/dist/builtin/workflows/skills/impeccable/reference/animate.md +2 -0
- package/dist/builtin/workflows/skills/impeccable/reference/audit.md +2 -0
- package/dist/builtin/workflows/skills/impeccable/reference/audit.native.md +139 -0
- package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +69 -62
- package/dist/builtin/workflows/skills/impeccable/reference/critique.md +21 -7
- package/dist/builtin/workflows/skills/impeccable/reference/document.md +1 -1
- package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +92 -0
- package/dist/builtin/workflows/skills/impeccable/reference/init.md +29 -7
- package/dist/builtin/workflows/skills/impeccable/reference/ios.md +45 -0
- package/dist/builtin/workflows/skills/impeccable/reference/layout.md +25 -1
- package/dist/builtin/workflows/skills/impeccable/reference/typeset.md +23 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/context-signals.mjs +2 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/context.mjs +75 -14
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/browser/injected/index.mjs +1 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/cli/main.mjs +31 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/design-system.mjs +64 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +118 -11
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +16 -11
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/registry/antipatterns.mjs +66 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/rules/checks.mjs +42 -10
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/fonts.mjs +30 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/page.mjs +4 -6
- package/dist/builtin/workflows/skills/impeccable/scripts/hook-admin.mjs +660 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/hook-before-edit.mjs +516 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/hook-lib.mjs +1764 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/hook.mjs +61 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/impeccable-config.mjs +4 -2
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/is-generated.mjs +2 -2
- package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-component.mjs +13 -16
- package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +17 -11
- package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +104 -37
- package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +9 -0
- package/dist/builtin/workflows/src/durable/backend.ts +12 -0
- package/dist/builtin/workflows/src/durable/dbos-backend.ts +17 -1
- package/dist/builtin/workflows/src/durable/resume-catalog.ts +12 -0
- package/dist/builtin/workflows/src/durable/resume-runtime.ts +5 -2
- package/dist/builtin/workflows/src/durable/stage-primitive.ts +2 -1
- package/dist/builtin/workflows/src/durable/types.ts +16 -0
- package/dist/builtin/workflows/src/engine/primitives/task.ts +3 -1
- package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +1 -2
- package/dist/builtin/workflows/src/engine/run-returned-status.ts +50 -16
- package/dist/builtin/workflows/src/engine/run.ts +20 -19
- package/dist/builtin/workflows/src/engine/runtime.ts +5 -0
- package/dist/builtin/workflows/src/extension/extension-factory.ts +3 -0
- package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +9 -2
- package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +137 -27
- package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +22 -6
- package/dist/builtin/workflows/src/extension/public-types.ts +1 -1
- package/dist/builtin/workflows/src/extension/workflow-command-completions.ts +13 -1
- package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +19 -4
- package/dist/builtin/workflows/src/extension/workflow-command-surfaces.ts +9 -0
- package/dist/builtin/workflows/src/extension/workflow-prompts.ts +17 -22
- package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +48 -23
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +15 -2
- package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +20 -8
- package/dist/builtin/workflows/src/extension/workflow-tool.ts +24 -8
- package/dist/builtin/workflows/src/runs/background/status.ts +4 -3
- package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +29 -8
- package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +3 -2
- package/dist/builtin/workflows/src/runs/shared/model-fallback-candidates.ts +1 -1
- package/dist/builtin/workflows/src/runs/shared/worktree-git.ts +155 -20
- package/dist/builtin/workflows/src/runs/shared/worktree-types.ts +6 -0
- package/dist/builtin/workflows/src/runs/shared/worktree.ts +2 -1
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -2
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +2 -2
- package/dist/builtin/workflows/src/shared/resume-continuation.ts +2 -0
- package/dist/builtin/workflows/src/shared/returned-run-status.ts +116 -0
- package/dist/builtin/workflows/src/shared/workflow-failures-decisions.ts +2 -0
- package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +21 -3
- package/dist/builtin/workflows/src/tui/graph-view-state.ts +3 -0
- package/dist/builtin/workflows/src/tui/graph-view-types.ts +3 -0
- package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +1 -23
- package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +54 -9
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +5 -2
- package/dist/builtin/workflows/src/tui/status-list.ts +22 -15
- package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +4 -4
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-auto-compaction.d.ts +23 -3
- package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-auto-compaction.js +129 -17
- package/dist/core/agent-session-auto-compaction.js.map +1 -1
- package/dist/core/agent-session-events.d.ts.map +1 -1
- package/dist/core/agent-session-events.js +9 -1
- package/dist/core/agent-session-events.js.map +1 -1
- package/dist/core/agent-session-message-queue.d.ts.map +1 -1
- package/dist/core/agent-session-message-queue.js +1 -1
- package/dist/core/agent-session-message-queue.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +6 -3
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +2 -2
- package/dist/core/agent-session-prompt.js.map +1 -1
- package/dist/core/agent-session-retry.d.ts.map +1 -1
- package/dist/core/agent-session-retry.js +1 -1
- package/dist/core/agent-session-retry.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +3 -2
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/agent-session.d.ts +4 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +4 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/anthropic-thinking-guard.d.ts +5 -5
- package/dist/core/anthropic-thinking-guard.d.ts.map +1 -1
- package/dist/core/anthropic-thinking-guard.js +42 -32
- package/dist/core/anthropic-thinking-guard.js.map +1 -1
- package/dist/core/atomic-guide-command.d.ts.map +1 -1
- package/dist/core/atomic-guide-command.js +15 -15
- package/dist/core/atomic-guide-command.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +14 -9
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +2 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +79 -46
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/context-assistant-turns.d.ts +42 -0
- package/dist/core/compaction/context-assistant-turns.d.ts.map +1 -0
- package/dist/core/compaction/context-assistant-turns.js +87 -0
- package/dist/core/compaction/context-assistant-turns.js.map +1 -0
- package/dist/core/compaction/context-compaction-critical.d.ts +1 -1
- package/dist/core/compaction/context-compaction-critical.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-critical.js +2 -2
- package/dist/core/compaction/context-compaction-critical.js.map +1 -1
- package/dist/core/compaction/context-compaction-eviction-alternates.d.ts +18 -0
- package/dist/core/compaction/context-compaction-eviction-alternates.d.ts.map +1 -0
- package/dist/core/compaction/context-compaction-eviction-alternates.js +186 -0
- package/dist/core/compaction/context-compaction-eviction-alternates.js.map +1 -0
- package/dist/core/compaction/context-compaction-eviction.d.ts +10 -2
- package/dist/core/compaction/context-compaction-eviction.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-eviction.js +196 -146
- package/dist/core/compaction/context-compaction-eviction.js.map +1 -1
- package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-prompt.js +1 -1
- package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
- package/dist/core/compaction/context-compaction-types.d.ts +2 -0
- package/dist/core/compaction/context-compaction-types.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-types.js.map +1 -1
- package/dist/core/compaction/context-deletion-application.d.ts +5 -4
- package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-application.js +17 -15
- package/dist/core/compaction/context-deletion-application.js.map +1 -1
- package/dist/core/compaction/context-deletion-store.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-store.js +1 -1
- package/dist/core/compaction/context-deletion-store.js.map +1 -1
- package/dist/core/compaction/context-deletion-targets.d.ts +2 -1
- package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-targets.js +36 -31
- package/dist/core/compaction/context-deletion-targets.js.map +1 -1
- package/dist/core/compaction/context-deletion-tool-helpers.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-tool-helpers.js +116 -43
- package/dist/core/compaction/context-deletion-tool-helpers.js.map +1 -1
- package/dist/core/compaction/context-transcript-analysis.d.ts +1 -2
- package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
- package/dist/core/compaction/context-transcript-analysis.js +33 -37
- package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
- package/dist/core/copilot-model-synthesis.d.ts.map +1 -1
- package/dist/core/copilot-model-synthesis.js +3 -1
- package/dist/core/copilot-model-synthesis.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts +8 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +2 -1
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/extensions/provider-types.d.ts +2 -7
- package/dist/core/extensions/provider-types.d.ts.map +1 -1
- package/dist/core/extensions/provider-types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +6 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +72 -29
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/messages.d.ts +9 -0
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +100 -18
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-registry-builtins.d.ts.map +1 -1
- package/dist/core/model-registry-builtins.js +5 -0
- package/dist/core/model-registry-builtins.js.map +1 -1
- package/dist/core/model-registry-custom-loader.d.ts.map +1 -1
- package/dist/core/model-registry-custom-loader.js +49 -8
- package/dist/core/model-registry-custom-loader.js.map +1 -1
- package/dist/core/model-registry-dynamic.d.ts.map +1 -1
- package/dist/core/model-registry-dynamic.js +11 -5
- package/dist/core/model-registry-dynamic.js.map +1 -1
- package/dist/core/model-registry-loader.d.ts.map +1 -1
- package/dist/core/model-registry-loader.js +8 -0
- package/dist/core/model-registry-loader.js.map +1 -1
- package/dist/core/model-registry-schemas.d.ts +93 -8
- package/dist/core/model-registry-schemas.d.ts.map +1 -1
- package/dist/core/model-registry-schemas.js +24 -12
- package/dist/core/model-registry-schemas.js.map +1 -1
- package/dist/core/model-registry-types.d.ts +7 -6
- package/dist/core/model-registry-types.d.ts.map +1 -1
- package/dist/core/model-registry-types.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +23 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver-cli.d.ts.map +1 -1
- package/dist/core/model-resolver-cli.js +33 -5
- package/dist/core/model-resolver-cli.js.map +1 -1
- package/dist/core/model-resolver-initial.d.ts +6 -1
- package/dist/core/model-resolver-initial.d.ts.map +1 -1
- package/dist/core/model-resolver-initial.js +12 -7
- package/dist/core/model-resolver-initial.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/openai-responses-payload-sanitizer.d.ts +1 -0
- package/dist/core/openai-responses-payload-sanitizer.d.ts.map +1 -1
- package/dist/core/openai-responses-payload-sanitizer.js +24 -9
- package/dist/core/openai-responses-payload-sanitizer.js.map +1 -1
- package/dist/core/resource-loader-context-files.d.ts +1 -0
- package/dist/core/resource-loader-context-files.d.ts.map +1 -1
- package/dist/core/resource-loader-context-files.js +13 -10
- package/dist/core/resource-loader-context-files.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +2 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-entry-normalization.d.ts +7 -0
- package/dist/core/session-entry-normalization.d.ts.map +1 -0
- package/dist/core/session-entry-normalization.js +14 -0
- package/dist/core/session-entry-normalization.js.map +1 -0
- package/dist/core/session-manager-core.d.ts.map +1 -1
- package/dist/core/session-manager-core.js +1 -0
- package/dist/core/session-manager-core.js.map +1 -1
- package/dist/core/session-manager-history.d.ts +2 -2
- package/dist/core/session-manager-history.d.ts.map +1 -1
- package/dist/core/session-manager-history.js +127 -108
- package/dist/core/session-manager-history.js.map +1 -1
- package/dist/core/settings-manager-basic-accessors.d.ts +2 -2
- package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-basic-accessors.js.map +1 -1
- package/dist/core/settings-types.d.ts +1 -1
- package/dist/core/settings-types.d.ts.map +1 -1
- package/dist/core/settings-types.js.map +1 -1
- package/dist/core/slash-commands.d.ts +2 -0
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +141 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +11 -8
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/main-deferred-startup.d.ts.map +1 -1
- package/dist/main-deferred-startup.js +2 -2
- package/dist/main-deferred-startup.js.map +1 -1
- package/dist/main-early-input.d.ts.map +1 -1
- package/dist/main-early-input.js +7 -0
- package/dist/main-early-input.js.map +1 -1
- package/dist/main-session.d.ts.map +1 -1
- package/dist/main-session.js +1 -0
- package/dist/main-session.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-actions.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-actions.js +0 -1
- package/dist/modes/interactive/components/chat-session-host-actions.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-options.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector-options.js +3 -1
- package/dist/modes/interactive/components/settings-selector-options.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +2 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.js +3 -1
- package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
- package/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-autocomplete.js +21 -9
- package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
- package/dist/modes/interactive/interactive-child-ordering.d.ts +7 -0
- package/dist/modes/interactive/interactive-child-ordering.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-child-ordering.js +26 -0
- package/dist/modes/interactive/interactive-child-ordering.js.map +1 -0
- package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-deferred-startup.js +43 -30
- package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
- package/dist/modes/interactive/interactive-hotkeys-debug.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-hotkeys-debug.js +1 -0
- package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.js +41 -6
- package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts +3 -0
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +3 -0
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +2 -2
- package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js +2 -2
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -2
- package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.js +11 -4
- package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-process-lifecycle.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-process-lifecycle.js +0 -3
- package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.js +15 -1
- package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
- package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-session-routing.js +5 -1
- package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +20 -21
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/modes/interactive/theme/global-theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/global-theme.js +26 -2
- package/dist/modes/interactive/theme/global-theme.js.map +1 -1
- package/dist/modes/interactive/theme/theme-class.d.ts +1 -1
- package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-class.js +2 -0
- package/dist/modes/interactive/theme/theme-class.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +3 -0
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/fs-watch.d.ts +24 -1
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js +60 -5
- package/dist/utils/fs-watch.js.map +1 -1
- package/docs/changelog.mdx +19 -0
- package/docs/compaction.md +60 -49
- package/docs/custom-provider.md +18 -5
- package/docs/development.md +4 -0
- package/docs/extensions.md +11 -2
- package/docs/json.md +1 -1
- package/docs/models.md +69 -10
- package/docs/providers.md +1 -1
- package/docs/quickstart.md +12 -8
- package/docs/rpc.md +2 -2
- package/docs/sdk.md +1 -1
- package/docs/settings.md +4 -4
- package/docs/subagents.md +40 -5
- package/docs/tools.md +1 -1
- package/docs/usage.md +4 -2
- package/docs/windows.md +4 -0
- package/docs/workflows.md +33 -48
- package/examples/extensions/preset.ts +2 -2
- package/examples/extensions/subagent/README.md +2 -2
- package/examples/extensions/subagent/index.ts +1 -2
- package/examples/extensions/subagent/schemas.ts +4 -1
- package/examples/sdk/12-full-control.ts +1 -1
- package/npm-shrinkwrap.json +48 -51
- package/package.json +7 -7
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-behavior.ts +0 -75
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-component.ts +0 -202
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-edit.ts +0 -97
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-editor.ts +0 -160
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-frame.ts +0 -72
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-modes.ts +0 -161
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-selectors.ts +0 -203
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-selectors.ts +0 -234
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-state.ts +0 -103
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-types.ts +0 -29
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify.ts +0 -9
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-clarify.ts +0 -117
package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js
CHANGED
|
@@ -123,6 +123,7 @@ const ANTIPATTERNS = [
|
|
|
123
123
|
{
|
|
124
124
|
id: 'overused-font',
|
|
125
125
|
category: 'slop',
|
|
126
|
+
scopes: ['type'],
|
|
126
127
|
name: 'Overused font',
|
|
127
128
|
description:
|
|
128
129
|
'Inter, Roboto, Fraunces, Geist, Plus Jakarta Sans, and Space Grotesk are used on so many sites they no longer feel distinctive. Each new wave of AI-generated UIs converges on the same handful of faces. Choose a face that gives your interface personality.',
|
|
@@ -132,6 +133,7 @@ const ANTIPATTERNS = [
|
|
|
132
133
|
{
|
|
133
134
|
id: 'single-font',
|
|
134
135
|
category: 'slop',
|
|
136
|
+
scopes: ['type'],
|
|
135
137
|
name: 'Single font for everything',
|
|
136
138
|
description:
|
|
137
139
|
'Only one font family is used for the entire page. Pair a distinctive display font with a refined body font to create typographic hierarchy.',
|
|
@@ -141,6 +143,7 @@ const ANTIPATTERNS = [
|
|
|
141
143
|
{
|
|
142
144
|
id: 'flat-type-hierarchy',
|
|
143
145
|
category: 'slop',
|
|
146
|
+
scopes: ['type'],
|
|
144
147
|
name: 'Flat type hierarchy',
|
|
145
148
|
description:
|
|
146
149
|
'Font sizes are too close together — no clear visual hierarchy. Use fewer sizes with more contrast (aim for at least a 1.25 ratio between steps).',
|
|
@@ -177,6 +180,7 @@ const ANTIPATTERNS = [
|
|
|
177
180
|
{
|
|
178
181
|
id: 'nested-cards',
|
|
179
182
|
category: 'slop',
|
|
183
|
+
scopes: ['layout'],
|
|
180
184
|
name: 'Nested cards',
|
|
181
185
|
description:
|
|
182
186
|
'Cards inside cards create visual noise and excessive depth. Flatten the hierarchy — use spacing, typography, and dividers instead of nesting containers.',
|
|
@@ -186,6 +190,7 @@ const ANTIPATTERNS = [
|
|
|
186
190
|
{
|
|
187
191
|
id: 'monotonous-spacing',
|
|
188
192
|
category: 'slop',
|
|
193
|
+
scopes: ['layout'],
|
|
189
194
|
name: 'Monotonous spacing',
|
|
190
195
|
description:
|
|
191
196
|
'The same spacing value used everywhere — no rhythm, no variation. Use tight groupings for related items and generous separations between sections.',
|
|
@@ -213,6 +218,7 @@ const ANTIPATTERNS = [
|
|
|
213
218
|
{
|
|
214
219
|
id: 'icon-tile-stack',
|
|
215
220
|
category: 'slop',
|
|
221
|
+
scopes: ['layout'],
|
|
216
222
|
name: 'Icon tile stacked above heading',
|
|
217
223
|
description:
|
|
218
224
|
'A small rounded-square icon container above a heading is the universal AI feature-card template — every generator outputs this exact shape. Try a side-by-side icon and heading, or let the icon sit in flow without its own container.',
|
|
@@ -222,6 +228,7 @@ const ANTIPATTERNS = [
|
|
|
222
228
|
{
|
|
223
229
|
id: 'italic-serif-display',
|
|
224
230
|
category: 'slop',
|
|
231
|
+
scopes: ['type'],
|
|
225
232
|
name: 'Italic serif display headline',
|
|
226
233
|
description:
|
|
227
234
|
'Oversized italic serif (Fraunces, Recoleta, Playfair, Newsreader-italic) as the primary hero headline reads as taste in isolation but has become the universal AI-startup landing page hero. Set roman, or move to a non-serif display face. Editorial / magazine register may legitimately want this — judge by context.',
|
|
@@ -231,6 +238,7 @@ const ANTIPATTERNS = [
|
|
|
231
238
|
{
|
|
232
239
|
id: 'hero-eyebrow-chip',
|
|
233
240
|
category: 'slop',
|
|
241
|
+
scopes: ['type'],
|
|
234
242
|
name: 'Hero eyebrow / pill chip',
|
|
235
243
|
description:
|
|
236
244
|
'A tiny uppercase letter-spaced label sitting immediately above an oversized hero headline — or the same shape rendered as a pill chip — is now the default AI SaaS hero. Drop the eyebrow, integrate the kicker into the headline, or run it as a navigation breadcrumb instead.',
|
|
@@ -240,6 +248,7 @@ const ANTIPATTERNS = [
|
|
|
240
248
|
{
|
|
241
249
|
id: 'repeated-section-kickers',
|
|
242
250
|
category: 'slop',
|
|
251
|
+
scopes: ['type'],
|
|
243
252
|
severity: 'advisory',
|
|
244
253
|
name: 'Repeated section kicker labels',
|
|
245
254
|
description:
|
|
@@ -250,6 +259,7 @@ const ANTIPATTERNS = [
|
|
|
250
259
|
{
|
|
251
260
|
id: 'numbered-section-markers',
|
|
252
261
|
category: 'slop',
|
|
262
|
+
scopes: ['layout'],
|
|
253
263
|
severity: 'advisory',
|
|
254
264
|
name: 'Numbered section markers (01 / 02 / 03)',
|
|
255
265
|
description:
|
|
@@ -287,6 +297,7 @@ const ANTIPATTERNS = [
|
|
|
287
297
|
{
|
|
288
298
|
id: 'oversized-h1',
|
|
289
299
|
category: 'slop',
|
|
300
|
+
scopes: ['type'],
|
|
290
301
|
name: 'Oversized hero headline',
|
|
291
302
|
description:
|
|
292
303
|
'A full-sentence headline set at display size ends up dominating the viewport, leaving no room for anything else above the fold. A punchy one- or two-word headline at that size is fine — the problem is a long headline blown up too large. Set long headlines smaller, or tighten the copy.',
|
|
@@ -296,6 +307,7 @@ const ANTIPATTERNS = [
|
|
|
296
307
|
{
|
|
297
308
|
id: 'extreme-negative-tracking',
|
|
298
309
|
category: 'slop',
|
|
310
|
+
scopes: ['type'],
|
|
299
311
|
name: 'Crushed letter spacing',
|
|
300
312
|
description:
|
|
301
313
|
'Letter-spacing pulled tighter than the point where characters keep their own shapes costs legibility. Tighten display type optically, not destructively.',
|
|
@@ -341,6 +353,7 @@ const ANTIPATTERNS = [
|
|
|
341
353
|
{
|
|
342
354
|
id: 'line-length',
|
|
343
355
|
category: 'quality',
|
|
356
|
+
scopes: ['type', 'layout'],
|
|
344
357
|
name: 'Line length too long',
|
|
345
358
|
description:
|
|
346
359
|
'Text lines wider than ~80 characters are hard to read. The eye loses its place tracking back to the start of the next line. Add a max-width (65ch to 75ch) to text containers.',
|
|
@@ -350,6 +363,7 @@ const ANTIPATTERNS = [
|
|
|
350
363
|
{
|
|
351
364
|
id: 'cramped-padding',
|
|
352
365
|
category: 'quality',
|
|
366
|
+
scopes: ['layout'],
|
|
353
367
|
name: 'Cramped padding',
|
|
354
368
|
description:
|
|
355
369
|
'Text is too close to the edge of its container. Two shapes: (1) an element with its own text where the padding is too low for the font size, and (2) a wrapper with text-bearing children and near-zero padding against a visible boundary (border, outline, or non-transparent background) — children land flush against the boundary line. Add at least 8px (ideally 12–16px) of padding inside bordered, outlined, or colored containers.',
|
|
@@ -359,6 +373,7 @@ const ANTIPATTERNS = [
|
|
|
359
373
|
{
|
|
360
374
|
id: 'body-text-viewport-edge',
|
|
361
375
|
category: 'quality',
|
|
376
|
+
scopes: ['layout'],
|
|
362
377
|
name: 'Body text touching viewport edge',
|
|
363
378
|
description:
|
|
364
379
|
'Body paragraphs render flush against the left or right viewport edge with no container providing horizontal padding. Wrap content in a container with at least 16px (ideally 24-32px) of horizontal padding, or apply max-width with mx-auto.',
|
|
@@ -366,6 +381,7 @@ const ANTIPATTERNS = [
|
|
|
366
381
|
{
|
|
367
382
|
id: 'tight-leading',
|
|
368
383
|
category: 'quality',
|
|
384
|
+
scopes: ['type'],
|
|
369
385
|
name: 'Tight line height',
|
|
370
386
|
description:
|
|
371
387
|
'Line height below 1.3x the font size makes multi-line text hard to read. Use 1.5 to 1.7 for body text so lines have room to breathe.',
|
|
@@ -373,6 +389,7 @@ const ANTIPATTERNS = [
|
|
|
373
389
|
{
|
|
374
390
|
id: 'skipped-heading',
|
|
375
391
|
category: 'quality',
|
|
392
|
+
scopes: ['type'],
|
|
376
393
|
name: 'Skipped heading level',
|
|
377
394
|
description:
|
|
378
395
|
'Heading levels should not skip (e.g. h1 then h3 with no h2). Screen readers use heading hierarchy for navigation. Skipping levels breaks the document outline.',
|
|
@@ -380,6 +397,7 @@ const ANTIPATTERNS = [
|
|
|
380
397
|
{
|
|
381
398
|
id: 'justified-text',
|
|
382
399
|
category: 'quality',
|
|
400
|
+
scopes: ['type'],
|
|
383
401
|
name: 'Justified text',
|
|
384
402
|
description:
|
|
385
403
|
'Justified text without hyphenation creates uneven word spacing ("rivers of white"). Use text-align: left for body text, or enable hyphens: auto if you must justify.',
|
|
@@ -387,6 +405,7 @@ const ANTIPATTERNS = [
|
|
|
387
405
|
{
|
|
388
406
|
id: 'tiny-text',
|
|
389
407
|
category: 'quality',
|
|
408
|
+
scopes: ['type'],
|
|
390
409
|
name: 'Tiny body text',
|
|
391
410
|
description:
|
|
392
411
|
'Body text below 12px is hard to read, especially on high-DPI screens. Use at least 14px for body content, 16px is ideal.',
|
|
@@ -394,6 +413,7 @@ const ANTIPATTERNS = [
|
|
|
394
413
|
{
|
|
395
414
|
id: 'all-caps-body',
|
|
396
415
|
category: 'quality',
|
|
416
|
+
scopes: ['type'],
|
|
397
417
|
name: 'All-caps body text',
|
|
398
418
|
description:
|
|
399
419
|
'Long passages in uppercase are hard to read. We recognize words by shape (ascenders and descenders), which all-caps removes. Reserve uppercase for short labels and headings.',
|
|
@@ -403,6 +423,7 @@ const ANTIPATTERNS = [
|
|
|
403
423
|
{
|
|
404
424
|
id: 'wide-tracking',
|
|
405
425
|
category: 'quality',
|
|
426
|
+
scopes: ['type'],
|
|
406
427
|
name: 'Wide letter spacing on body text',
|
|
407
428
|
description:
|
|
408
429
|
'Letter spacing above 0.05em on body text disrupts natural character groupings and slows reading. Reserve wide tracking for short uppercase labels only.',
|
|
@@ -410,6 +431,7 @@ const ANTIPATTERNS = [
|
|
|
410
431
|
{
|
|
411
432
|
id: 'text-overflow',
|
|
412
433
|
category: 'quality',
|
|
434
|
+
scopes: ['layout'],
|
|
413
435
|
name: 'Content overflowing its container',
|
|
414
436
|
description:
|
|
415
437
|
'Content renders wider than its container, spilling out or forcing a horizontal scrollbar. Let text wrap, constrain widths, or give the region a deliberate scroll affordance.',
|
|
@@ -419,6 +441,7 @@ const ANTIPATTERNS = [
|
|
|
419
441
|
{
|
|
420
442
|
id: 'clipped-overflow-container',
|
|
421
443
|
category: 'quality',
|
|
444
|
+
scopes: ['layout'],
|
|
422
445
|
name: 'Positioned child clipped by overflow container',
|
|
423
446
|
description:
|
|
424
447
|
'A clipping container (overflow hidden or clip) wrapping an absolutely-positioned child cuts off tooltips, menus, and popovers that need to escape. Let the overflow be visible, or move the positioned layer out of the clip.',
|
|
@@ -428,6 +451,7 @@ const ANTIPATTERNS = [
|
|
|
428
451
|
{
|
|
429
452
|
id: 'design-system-font',
|
|
430
453
|
category: 'quality',
|
|
454
|
+
scopes: ['type'],
|
|
431
455
|
name: 'Font outside DESIGN.md',
|
|
432
456
|
description:
|
|
433
457
|
'A font is used that is not declared in DESIGN.md typography. Use the documented type system or update DESIGN.md if this is an intentional brand addition.',
|
|
@@ -454,6 +478,17 @@ const ANTIPATTERNS = [
|
|
|
454
478
|
skillSection: 'Visual Details',
|
|
455
479
|
skillGuideline: 'border radius outside the project design system',
|
|
456
480
|
},
|
|
481
|
+
{
|
|
482
|
+
id: 'design-system-font-size',
|
|
483
|
+
category: 'quality',
|
|
484
|
+
severity: 'advisory',
|
|
485
|
+
scopes: ['type'],
|
|
486
|
+
name: 'Font size outside DESIGN.md',
|
|
487
|
+
description:
|
|
488
|
+
'A literal font-size is off the type ramp documented in DESIGN.md typography. Use a documented size step or update the design system if the new step is intentional.',
|
|
489
|
+
skillSection: 'Typography',
|
|
490
|
+
skillGuideline: 'font size outside the project design system',
|
|
491
|
+
},
|
|
457
492
|
|
|
458
493
|
// ── Provider tells: opt-in via --gpt / --gemini (gated off by default) ──
|
|
459
494
|
{
|
|
@@ -478,6 +513,17 @@ const ANTIPATTERNS = [
|
|
|
478
513
|
skillSection: 'Visual Details',
|
|
479
514
|
skillGuideline: 'repeating-gradient decorative stripes',
|
|
480
515
|
},
|
|
516
|
+
{
|
|
517
|
+
id: 'codex-grid-background',
|
|
518
|
+
category: 'slop',
|
|
519
|
+
severity: 'advisory',
|
|
520
|
+
gated: 'gpt',
|
|
521
|
+
name: 'Decorative grid-line background',
|
|
522
|
+
description:
|
|
523
|
+
'A two-axis grid drawn with hairline linear-gradient layers ("1px, transparent 1px" on both axes) is a recurring generated-UI signature. Reserve grid overlays for actual canvas, map, blueprint, or measurement surfaces; elsewhere use product structure or a plain surface.',
|
|
524
|
+
skillSection: 'Visual Details',
|
|
525
|
+
skillGuideline: 'two-axis grid-line gradient background',
|
|
526
|
+
},
|
|
481
527
|
{
|
|
482
528
|
id: 'theater-slop-phrase',
|
|
483
529
|
category: 'slop',
|
|
@@ -617,6 +663,36 @@ function colorToHex(c) {
|
|
|
617
663
|
return '#' + [c.r, c.g, c.b].map(v => v.toString(16).padStart(2, '0')).join('');
|
|
618
664
|
}
|
|
619
665
|
|
|
666
|
+
// --- cli/engine/shared/fonts.mjs ---
|
|
667
|
+
const GOOGLE_FONTS_URL_RE = /fonts\.googleapis\.com\/css2?\?[^"'\s)<>]*/gi;
|
|
668
|
+
|
|
669
|
+
function normalizeGoogleFontFamilyParam(value) {
|
|
670
|
+
return String(value || '')
|
|
671
|
+
.split('|')
|
|
672
|
+
.map(part => part.split(':')[0].trim().toLowerCase())
|
|
673
|
+
.filter(Boolean);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
function extractGoogleFontFamilies(text) {
|
|
677
|
+
const families = [];
|
|
678
|
+
if (!text) return families;
|
|
679
|
+
|
|
680
|
+
GOOGLE_FONTS_URL_RE.lastIndex = 0;
|
|
681
|
+
let urlMatch;
|
|
682
|
+
while ((urlMatch = GOOGLE_FONTS_URL_RE.exec(text)) !== null) {
|
|
683
|
+
const url = urlMatch[0];
|
|
684
|
+
const queryStart = url.indexOf('?');
|
|
685
|
+
if (queryStart === -1) continue;
|
|
686
|
+
|
|
687
|
+
const params = new URLSearchParams(url.slice(queryStart + 1).replace(/&/g, '&'));
|
|
688
|
+
for (const value of params.getAll('family')) {
|
|
689
|
+
families.push(...normalizeGoogleFontFamilyParam(value));
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
return families;
|
|
694
|
+
}
|
|
695
|
+
|
|
620
696
|
// --- cli/engine/rules/checks.mjs ---
|
|
621
697
|
const DETECTOR_IS_BROWSER = typeof window !== 'undefined';
|
|
622
698
|
|
|
@@ -1172,13 +1248,49 @@ function checkHtmlPatterns(html) {
|
|
|
1172
1248
|
findings.push({ id: 'repeating-stripes-gradient', snippet: 'repeating-gradient decorative stripes' });
|
|
1173
1249
|
}
|
|
1174
1250
|
|
|
1251
|
+
// --- Provider tells (gated): two-axis grid-line background (Codex/GPT) ---
|
|
1252
|
+
// The Codex grid tell is two hairline `linear-gradient(... <color> 1px,
|
|
1253
|
+
// transparent 1px)` layers (one per axis) tiled by a repeating
|
|
1254
|
+
// `background-size` cell. Both signals must co-occur in the SAME style block
|
|
1255
|
+
// (a CSS rule body or one inline `style="..."`): two hairline stops WITHOUT a
|
|
1256
|
+
// tiling background-size is a fixed crosshair, not a grid, and a single
|
|
1257
|
+
// hairline is a legitimate ruled line. Scoping to one block also stops
|
|
1258
|
+
// unrelated single-axis rules on separate elements from adding up across the
|
|
1259
|
+
// page. Count hairlines only inside `background`/`background-image` values so
|
|
1260
|
+
// a hairline in an unrelated property (mask-image, border-image) can't stand
|
|
1261
|
+
// in for the second axis. Colors like `oklch(96% 0.012 82 / 0.055)` carry
|
|
1262
|
+
// nested parens, so match the hairline stop directly rather than parsing
|
|
1263
|
+
// whole gradient layers.
|
|
1264
|
+
{
|
|
1265
|
+
const hairlineRe = /\b\d{1,3}px\s*,\s*transparent\s+\d{1,3}px/gi;
|
|
1266
|
+
const gridSizeRe = /background-size\s*:[^;{}"']*\b\d{1,3}px\b/i;
|
|
1267
|
+
const bgDeclRe = /\bbackground(?:-image)?\s*:\s*([^;{}"']*)/gi;
|
|
1268
|
+
const blockRe = /\{([^{}]*)\}|style\s*=\s*"([^"]*)"|style\s*=\s*'([^']*)'/gi;
|
|
1269
|
+
let blk;
|
|
1270
|
+
while ((blk = blockRe.exec(html)) !== null) {
|
|
1271
|
+
const block = blk[1] || blk[2] || blk[3] || '';
|
|
1272
|
+
if (!gridSizeRe.test(block)) continue;
|
|
1273
|
+
let hairlineCount = 0;
|
|
1274
|
+
let bm;
|
|
1275
|
+
bgDeclRe.lastIndex = 0;
|
|
1276
|
+
while ((bm = bgDeclRe.exec(block)) !== null) {
|
|
1277
|
+
const stops = bm[1].match(hairlineRe);
|
|
1278
|
+
if (stops) hairlineCount += stops.length;
|
|
1279
|
+
}
|
|
1280
|
+
if (hairlineCount >= 2) {
|
|
1281
|
+
findings.push({ id: 'codex-grid-background', snippet: 'two-axis grid-line gradient background' });
|
|
1282
|
+
break;
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1175
1287
|
// --- Provider tells (gated): "X theater" framing copy (GPT) ---
|
|
1176
1288
|
// Lives here (regex-on-HTML) rather than in the text-content analyzers so it
|
|
1177
1289
|
// runs in the bundled browser path too, not just the CLI/static path.
|
|
1178
1290
|
{
|
|
1179
1291
|
const bodyText = html
|
|
1180
|
-
.replace(/<script\b[^>]*>[\s\S]*?<\/script[^>]*>/gi, ' ')
|
|
1181
|
-
.replace(/<style\b[^>]*>[\s\S]*?<\/style[^>]*>/gi, ' ')
|
|
1292
|
+
.replace(/<script\b[^>]*>[\s\S]*?<\/script\b[^>]*>/gi, ' ')
|
|
1293
|
+
.replace(/<style\b[^>]*>[\s\S]*?<\/style\b[^>]*>/gi, ' ')
|
|
1182
1294
|
.replace(/<[^>]+>/g, ' ');
|
|
1183
1295
|
const tm = /\b(\w+)\s+theater\b/i.exec(bodyText);
|
|
1184
1296
|
if (tm) findings.push({ id: 'theater-slop-phrase', snippet: `"${tm[0].trim()}"` });
|
|
@@ -2635,14 +2747,9 @@ function checkPageTypography(doc, win) {
|
|
|
2635
2747
|
|
|
2636
2748
|
// Check Google Fonts links in HTML
|
|
2637
2749
|
const html = doc.documentElement?.outerHTML || '';
|
|
2638
|
-
const
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
const families = m[1].split('|').map(f => f.split(':')[0].replace(/\+/g, ' ').toLowerCase());
|
|
2642
|
-
for (const f of families) {
|
|
2643
|
-
fonts.add(f);
|
|
2644
|
-
if (OVERUSED_FONTS.has(f)) overusedFound.add(f);
|
|
2645
|
-
}
|
|
2750
|
+
for (const f of extractGoogleFontFamilies(html)) {
|
|
2751
|
+
fonts.add(f);
|
|
2752
|
+
if (OVERUSED_FONTS.has(f)) overusedFound.add(f);
|
|
2646
2753
|
}
|
|
2647
2754
|
|
|
2648
2755
|
// Also parse raw HTML/style content for font-family (jsdom may not expose all via CSSOM)
|
|
@@ -4475,7 +4582,7 @@ if (IS_BROWSER) {
|
|
|
4475
4582
|
|
|
4476
4583
|
function browserPrimaryFont(stack) {
|
|
4477
4584
|
if (!stack || /var\(/i.test(stack)) return '';
|
|
4478
|
-
return String(stack)
|
|
4585
|
+
return String(stack || '')
|
|
4479
4586
|
.split(',')
|
|
4480
4587
|
.map(normalizeBrowserFontName)
|
|
4481
4588
|
.find(font => font && !GENERIC_FONTS.has(font)) || '';
|
package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { GENERIC_FONTS } from '../../shared/constants.mjs';
|
|
1
|
+
import { GENERIC_FONTS, OVERUSED_FONTS } from '../../shared/constants.mjs';
|
|
2
2
|
import { isNeutralColor } from '../../shared/color.mjs';
|
|
3
|
+
import { extractGoogleFontFamilies } from '../../shared/fonts.mjs';
|
|
3
4
|
import { checkSourceDesignSystem } from '../../design-system.mjs';
|
|
4
5
|
import { isFullPage } from '../../shared/page.mjs';
|
|
5
6
|
import { applyInlineIgnores } from '../../shared/inline-ignores.mjs';
|
|
@@ -19,8 +20,8 @@ const isSafeElement = (line) => /<(?:blockquote|nav[\s>]|pre[\s>]|code[\s>]|a\s|
|
|
|
19
20
|
* content-text analyzers don't false-positive on code or CSS. */
|
|
20
21
|
function stripHtmlToText(html) {
|
|
21
22
|
return html
|
|
22
|
-
.replace(/<script\b[^>]*>[\s\S]*?<\/script[^>]*>/gi, ' ')
|
|
23
|
-
.replace(/<style\b[^>]*>[\s\S]*?<\/style[^>]*>/gi, ' ')
|
|
23
|
+
.replace(/<script\b[^>]*>[\s\S]*?<\/script\b[^>]*>/gi, ' ')
|
|
24
|
+
.replace(/<style\b[^>]*>[\s\S]*?<\/style\b[^>]*>/gi, ' ')
|
|
24
25
|
.replace(/<!--[\s\S]*?-->/g, ' ')
|
|
25
26
|
.replace(/<[^>]+>/g, ' ')
|
|
26
27
|
.replace(/\s+/g, ' ');
|
|
@@ -38,6 +39,10 @@ function shouldRunPageAnalyzers(content, filePath) {
|
|
|
38
39
|
return !ext || PAGE_ANALYZER_EXTS.has(ext);
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
function firstOverusedGoogleFont(text) {
|
|
43
|
+
return extractGoogleFontFamilies(text).find(f => OVERUSED_FONTS.has(f)) || '';
|
|
44
|
+
}
|
|
45
|
+
|
|
41
46
|
function isNeutralBorderColor(str) {
|
|
42
47
|
const m = str.match(/solid\s+((?:rgba?|hsla?|oklch|oklab|lab|lch|hwb|color)\([^)]*\)|#[0-9a-f]{3,8}\b|[a-z]+)/i);
|
|
43
48
|
if (!m) return false;
|
|
@@ -88,9 +93,12 @@ const REGEX_MATCHERS = [
|
|
|
88
93
|
{ id: 'overused-font', regex: /font-family\s*:\s*['"]?(Inter|Roboto|Open Sans|Lato|Montserrat|Arial|Helvetica|Fraunces|Geist Sans|Geist Mono|Geist|Mona Sans|Plus Jakarta Sans|Space Grotesk|Recoleta|Instrument Sans|Instrument Serif)\b/gi,
|
|
89
94
|
test: () => true,
|
|
90
95
|
fmt: (m) => m[0] },
|
|
91
|
-
{ id: 'overused-font', regex: /fonts\.googleapis\.com\/css2?\?
|
|
92
|
-
test: () =>
|
|
93
|
-
|
|
96
|
+
{ id: 'overused-font', regex: /fonts\.googleapis\.com\/css2?\?[^"'\s)<>]*/gi,
|
|
97
|
+
test: (m) => {
|
|
98
|
+
m.overusedGoogleFont = firstOverusedGoogleFont(m[0]);
|
|
99
|
+
return Boolean(m.overusedGoogleFont);
|
|
100
|
+
},
|
|
101
|
+
fmt: (m) => `Google Fonts: ${m.overusedGoogleFont || firstOverusedGoogleFont(m[0])}` },
|
|
94
102
|
// --- Gradient text ---
|
|
95
103
|
{ id: 'gradient-text', regex: /background-clip\s*:\s*text|-webkit-background-clip\s*:\s*text/gi,
|
|
96
104
|
test: (m, line) => /gradient/i.test(line),
|
|
@@ -170,10 +178,7 @@ const REGEX_ANALYZERS = [
|
|
|
170
178
|
if (f && !GENERIC_FONTS.has(f)) fonts.add(f);
|
|
171
179
|
}
|
|
172
180
|
}
|
|
173
|
-
const
|
|
174
|
-
while ((m = gfRe.exec(content)) !== null) {
|
|
175
|
-
for (const f of m[1].split('|').map(f => f.split(':')[0].replace(/\+/g, ' ').toLowerCase())) fonts.add(f);
|
|
176
|
-
}
|
|
181
|
+
for (const f of extractGoogleFontFamilies(content)) fonts.add(f);
|
|
177
182
|
if (fonts.size !== 1 || content.split('\n').length < 20) return [];
|
|
178
183
|
const name = [...fonts][0];
|
|
179
184
|
const lines = content.split('\n');
|
|
@@ -347,7 +352,7 @@ function extractStyleBlocks(content, ext) {
|
|
|
347
352
|
ext = ext.toLowerCase();
|
|
348
353
|
if (ext !== '.vue' && ext !== '.svelte') return [];
|
|
349
354
|
const blocks = [];
|
|
350
|
-
const re = /<style[^>]*>([\s\S]*?)<\/style[^>]*>/gi;
|
|
355
|
+
const re = /<style[^>]*>([\s\S]*?)<\/style\b[^>]*>/gi;
|
|
351
356
|
let m;
|
|
352
357
|
while ((m = re.exec(content)) !== null) {
|
|
353
358
|
const before = content.substring(0, m.index);
|
|
@@ -21,6 +21,7 @@ const ANTIPATTERNS = [
|
|
|
21
21
|
{
|
|
22
22
|
id: 'overused-font',
|
|
23
23
|
category: 'slop',
|
|
24
|
+
scopes: ['type'],
|
|
24
25
|
name: 'Overused font',
|
|
25
26
|
description:
|
|
26
27
|
'Inter, Roboto, Fraunces, Geist, Plus Jakarta Sans, and Space Grotesk are used on so many sites they no longer feel distinctive. Each new wave of AI-generated UIs converges on the same handful of faces. Choose a face that gives your interface personality.',
|
|
@@ -30,6 +31,7 @@ const ANTIPATTERNS = [
|
|
|
30
31
|
{
|
|
31
32
|
id: 'single-font',
|
|
32
33
|
category: 'slop',
|
|
34
|
+
scopes: ['type'],
|
|
33
35
|
name: 'Single font for everything',
|
|
34
36
|
description:
|
|
35
37
|
'Only one font family is used for the entire page. Pair a distinctive display font with a refined body font to create typographic hierarchy.',
|
|
@@ -39,6 +41,7 @@ const ANTIPATTERNS = [
|
|
|
39
41
|
{
|
|
40
42
|
id: 'flat-type-hierarchy',
|
|
41
43
|
category: 'slop',
|
|
44
|
+
scopes: ['type'],
|
|
42
45
|
name: 'Flat type hierarchy',
|
|
43
46
|
description:
|
|
44
47
|
'Font sizes are too close together — no clear visual hierarchy. Use fewer sizes with more contrast (aim for at least a 1.25 ratio between steps).',
|
|
@@ -75,6 +78,7 @@ const ANTIPATTERNS = [
|
|
|
75
78
|
{
|
|
76
79
|
id: 'nested-cards',
|
|
77
80
|
category: 'slop',
|
|
81
|
+
scopes: ['layout'],
|
|
78
82
|
name: 'Nested cards',
|
|
79
83
|
description:
|
|
80
84
|
'Cards inside cards create visual noise and excessive depth. Flatten the hierarchy — use spacing, typography, and dividers instead of nesting containers.',
|
|
@@ -84,6 +88,7 @@ const ANTIPATTERNS = [
|
|
|
84
88
|
{
|
|
85
89
|
id: 'monotonous-spacing',
|
|
86
90
|
category: 'slop',
|
|
91
|
+
scopes: ['layout'],
|
|
87
92
|
name: 'Monotonous spacing',
|
|
88
93
|
description:
|
|
89
94
|
'The same spacing value used everywhere — no rhythm, no variation. Use tight groupings for related items and generous separations between sections.',
|
|
@@ -111,6 +116,7 @@ const ANTIPATTERNS = [
|
|
|
111
116
|
{
|
|
112
117
|
id: 'icon-tile-stack',
|
|
113
118
|
category: 'slop',
|
|
119
|
+
scopes: ['layout'],
|
|
114
120
|
name: 'Icon tile stacked above heading',
|
|
115
121
|
description:
|
|
116
122
|
'A small rounded-square icon container above a heading is the universal AI feature-card template — every generator outputs this exact shape. Try a side-by-side icon and heading, or let the icon sit in flow without its own container.',
|
|
@@ -120,6 +126,7 @@ const ANTIPATTERNS = [
|
|
|
120
126
|
{
|
|
121
127
|
id: 'italic-serif-display',
|
|
122
128
|
category: 'slop',
|
|
129
|
+
scopes: ['type'],
|
|
123
130
|
name: 'Italic serif display headline',
|
|
124
131
|
description:
|
|
125
132
|
'Oversized italic serif (Fraunces, Recoleta, Playfair, Newsreader-italic) as the primary hero headline reads as taste in isolation but has become the universal AI-startup landing page hero. Set roman, or move to a non-serif display face. Editorial / magazine register may legitimately want this — judge by context.',
|
|
@@ -129,6 +136,7 @@ const ANTIPATTERNS = [
|
|
|
129
136
|
{
|
|
130
137
|
id: 'hero-eyebrow-chip',
|
|
131
138
|
category: 'slop',
|
|
139
|
+
scopes: ['type'],
|
|
132
140
|
name: 'Hero eyebrow / pill chip',
|
|
133
141
|
description:
|
|
134
142
|
'A tiny uppercase letter-spaced label sitting immediately above an oversized hero headline — or the same shape rendered as a pill chip — is now the default AI SaaS hero. Drop the eyebrow, integrate the kicker into the headline, or run it as a navigation breadcrumb instead.',
|
|
@@ -138,6 +146,7 @@ const ANTIPATTERNS = [
|
|
|
138
146
|
{
|
|
139
147
|
id: 'repeated-section-kickers',
|
|
140
148
|
category: 'slop',
|
|
149
|
+
scopes: ['type'],
|
|
141
150
|
severity: 'advisory',
|
|
142
151
|
name: 'Repeated section kicker labels',
|
|
143
152
|
description:
|
|
@@ -148,6 +157,7 @@ const ANTIPATTERNS = [
|
|
|
148
157
|
{
|
|
149
158
|
id: 'numbered-section-markers',
|
|
150
159
|
category: 'slop',
|
|
160
|
+
scopes: ['layout'],
|
|
151
161
|
severity: 'advisory',
|
|
152
162
|
name: 'Numbered section markers (01 / 02 / 03)',
|
|
153
163
|
description:
|
|
@@ -185,6 +195,7 @@ const ANTIPATTERNS = [
|
|
|
185
195
|
{
|
|
186
196
|
id: 'oversized-h1',
|
|
187
197
|
category: 'slop',
|
|
198
|
+
scopes: ['type'],
|
|
188
199
|
name: 'Oversized hero headline',
|
|
189
200
|
description:
|
|
190
201
|
'A full-sentence headline set at display size ends up dominating the viewport, leaving no room for anything else above the fold. A punchy one- or two-word headline at that size is fine — the problem is a long headline blown up too large. Set long headlines smaller, or tighten the copy.',
|
|
@@ -194,6 +205,7 @@ const ANTIPATTERNS = [
|
|
|
194
205
|
{
|
|
195
206
|
id: 'extreme-negative-tracking',
|
|
196
207
|
category: 'slop',
|
|
208
|
+
scopes: ['type'],
|
|
197
209
|
name: 'Crushed letter spacing',
|
|
198
210
|
description:
|
|
199
211
|
'Letter-spacing pulled tighter than the point where characters keep their own shapes costs legibility. Tighten display type optically, not destructively.',
|
|
@@ -239,6 +251,7 @@ const ANTIPATTERNS = [
|
|
|
239
251
|
{
|
|
240
252
|
id: 'line-length',
|
|
241
253
|
category: 'quality',
|
|
254
|
+
scopes: ['type', 'layout'],
|
|
242
255
|
name: 'Line length too long',
|
|
243
256
|
description:
|
|
244
257
|
'Text lines wider than ~80 characters are hard to read. The eye loses its place tracking back to the start of the next line. Add a max-width (65ch to 75ch) to text containers.',
|
|
@@ -248,6 +261,7 @@ const ANTIPATTERNS = [
|
|
|
248
261
|
{
|
|
249
262
|
id: 'cramped-padding',
|
|
250
263
|
category: 'quality',
|
|
264
|
+
scopes: ['layout'],
|
|
251
265
|
name: 'Cramped padding',
|
|
252
266
|
description:
|
|
253
267
|
'Text is too close to the edge of its container. Two shapes: (1) an element with its own text where the padding is too low for the font size, and (2) a wrapper with text-bearing children and near-zero padding against a visible boundary (border, outline, or non-transparent background) — children land flush against the boundary line. Add at least 8px (ideally 12–16px) of padding inside bordered, outlined, or colored containers.',
|
|
@@ -257,6 +271,7 @@ const ANTIPATTERNS = [
|
|
|
257
271
|
{
|
|
258
272
|
id: 'body-text-viewport-edge',
|
|
259
273
|
category: 'quality',
|
|
274
|
+
scopes: ['layout'],
|
|
260
275
|
name: 'Body text touching viewport edge',
|
|
261
276
|
description:
|
|
262
277
|
'Body paragraphs render flush against the left or right viewport edge with no container providing horizontal padding. Wrap content in a container with at least 16px (ideally 24-32px) of horizontal padding, or apply max-width with mx-auto.',
|
|
@@ -264,6 +279,7 @@ const ANTIPATTERNS = [
|
|
|
264
279
|
{
|
|
265
280
|
id: 'tight-leading',
|
|
266
281
|
category: 'quality',
|
|
282
|
+
scopes: ['type'],
|
|
267
283
|
name: 'Tight line height',
|
|
268
284
|
description:
|
|
269
285
|
'Line height below 1.3x the font size makes multi-line text hard to read. Use 1.5 to 1.7 for body text so lines have room to breathe.',
|
|
@@ -271,6 +287,7 @@ const ANTIPATTERNS = [
|
|
|
271
287
|
{
|
|
272
288
|
id: 'skipped-heading',
|
|
273
289
|
category: 'quality',
|
|
290
|
+
scopes: ['type'],
|
|
274
291
|
name: 'Skipped heading level',
|
|
275
292
|
description:
|
|
276
293
|
'Heading levels should not skip (e.g. h1 then h3 with no h2). Screen readers use heading hierarchy for navigation. Skipping levels breaks the document outline.',
|
|
@@ -278,6 +295,7 @@ const ANTIPATTERNS = [
|
|
|
278
295
|
{
|
|
279
296
|
id: 'justified-text',
|
|
280
297
|
category: 'quality',
|
|
298
|
+
scopes: ['type'],
|
|
281
299
|
name: 'Justified text',
|
|
282
300
|
description:
|
|
283
301
|
'Justified text without hyphenation creates uneven word spacing ("rivers of white"). Use text-align: left for body text, or enable hyphens: auto if you must justify.',
|
|
@@ -285,6 +303,7 @@ const ANTIPATTERNS = [
|
|
|
285
303
|
{
|
|
286
304
|
id: 'tiny-text',
|
|
287
305
|
category: 'quality',
|
|
306
|
+
scopes: ['type'],
|
|
288
307
|
name: 'Tiny body text',
|
|
289
308
|
description:
|
|
290
309
|
'Body text below 12px is hard to read, especially on high-DPI screens. Use at least 14px for body content, 16px is ideal.',
|
|
@@ -292,6 +311,7 @@ const ANTIPATTERNS = [
|
|
|
292
311
|
{
|
|
293
312
|
id: 'all-caps-body',
|
|
294
313
|
category: 'quality',
|
|
314
|
+
scopes: ['type'],
|
|
295
315
|
name: 'All-caps body text',
|
|
296
316
|
description:
|
|
297
317
|
'Long passages in uppercase are hard to read. We recognize words by shape (ascenders and descenders), which all-caps removes. Reserve uppercase for short labels and headings.',
|
|
@@ -301,6 +321,7 @@ const ANTIPATTERNS = [
|
|
|
301
321
|
{
|
|
302
322
|
id: 'wide-tracking',
|
|
303
323
|
category: 'quality',
|
|
324
|
+
scopes: ['type'],
|
|
304
325
|
name: 'Wide letter spacing on body text',
|
|
305
326
|
description:
|
|
306
327
|
'Letter spacing above 0.05em on body text disrupts natural character groupings and slows reading. Reserve wide tracking for short uppercase labels only.',
|
|
@@ -308,6 +329,7 @@ const ANTIPATTERNS = [
|
|
|
308
329
|
{
|
|
309
330
|
id: 'text-overflow',
|
|
310
331
|
category: 'quality',
|
|
332
|
+
scopes: ['layout'],
|
|
311
333
|
name: 'Content overflowing its container',
|
|
312
334
|
description:
|
|
313
335
|
'Content renders wider than its container, spilling out or forcing a horizontal scrollbar. Let text wrap, constrain widths, or give the region a deliberate scroll affordance.',
|
|
@@ -317,6 +339,7 @@ const ANTIPATTERNS = [
|
|
|
317
339
|
{
|
|
318
340
|
id: 'clipped-overflow-container',
|
|
319
341
|
category: 'quality',
|
|
342
|
+
scopes: ['layout'],
|
|
320
343
|
name: 'Positioned child clipped by overflow container',
|
|
321
344
|
description:
|
|
322
345
|
'A clipping container (overflow hidden or clip) wrapping an absolutely-positioned child cuts off tooltips, menus, and popovers that need to escape. Let the overflow be visible, or move the positioned layer out of the clip.',
|
|
@@ -326,6 +349,7 @@ const ANTIPATTERNS = [
|
|
|
326
349
|
{
|
|
327
350
|
id: 'design-system-font',
|
|
328
351
|
category: 'quality',
|
|
352
|
+
scopes: ['type'],
|
|
329
353
|
name: 'Font outside DESIGN.md',
|
|
330
354
|
description:
|
|
331
355
|
'A font is used that is not declared in DESIGN.md typography. Use the documented type system or update DESIGN.md if this is an intentional brand addition.',
|
|
@@ -352,6 +376,17 @@ const ANTIPATTERNS = [
|
|
|
352
376
|
skillSection: 'Visual Details',
|
|
353
377
|
skillGuideline: 'border radius outside the project design system',
|
|
354
378
|
},
|
|
379
|
+
{
|
|
380
|
+
id: 'design-system-font-size',
|
|
381
|
+
category: 'quality',
|
|
382
|
+
severity: 'advisory',
|
|
383
|
+
scopes: ['type'],
|
|
384
|
+
name: 'Font size outside DESIGN.md',
|
|
385
|
+
description:
|
|
386
|
+
'A literal font-size is off the type ramp documented in DESIGN.md typography. Use a documented size step or update the design system if the new step is intentional.',
|
|
387
|
+
skillSection: 'Typography',
|
|
388
|
+
skillGuideline: 'font size outside the project design system',
|
|
389
|
+
},
|
|
355
390
|
|
|
356
391
|
// ── Provider tells: opt-in via --gpt / --gemini (gated off by default) ──
|
|
357
392
|
{
|
|
@@ -376,6 +411,17 @@ const ANTIPATTERNS = [
|
|
|
376
411
|
skillSection: 'Visual Details',
|
|
377
412
|
skillGuideline: 'repeating-gradient decorative stripes',
|
|
378
413
|
},
|
|
414
|
+
{
|
|
415
|
+
id: 'codex-grid-background',
|
|
416
|
+
category: 'slop',
|
|
417
|
+
severity: 'advisory',
|
|
418
|
+
gated: 'gpt',
|
|
419
|
+
name: 'Decorative grid-line background',
|
|
420
|
+
description:
|
|
421
|
+
'A two-axis grid drawn with hairline linear-gradient layers ("1px, transparent 1px" on both axes) is a recurring generated-UI signature. Reserve grid overlays for actual canvas, map, blueprint, or measurement surfaces; elsewhere use product structure or a plain surface.',
|
|
422
|
+
skillSection: 'Visual Details',
|
|
423
|
+
skillGuideline: 'two-axis grid-line gradient background',
|
|
424
|
+
},
|
|
379
425
|
{
|
|
380
426
|
id: 'theater-slop-phrase',
|
|
381
427
|
category: 'slop',
|
|
@@ -437,12 +483,32 @@ function filterByProviders(findings, providers = []) {
|
|
|
437
483
|
});
|
|
438
484
|
}
|
|
439
485
|
|
|
486
|
+
|
|
487
|
+
// Set of scope tags rules can declare (e.g. 'type', 'layout'). Used by the
|
|
488
|
+
// CLI --scope flag to narrow output to one design domain.
|
|
489
|
+
const RULE_SCOPES = new Set(
|
|
490
|
+
ANTIPATTERNS.flatMap(rule => rule.scopes || []),
|
|
491
|
+
);
|
|
492
|
+
|
|
493
|
+
// Keep only findings whose rule declares at least one of the requested
|
|
494
|
+
// scopes. An empty scope list means no filtering (default CLI behavior).
|
|
495
|
+
function filterByScopes(findings, scopes = []) {
|
|
496
|
+
if (!scopes || scopes.length === 0) return findings;
|
|
497
|
+
const enabled = new Set(scopes);
|
|
498
|
+
return findings.filter(f => {
|
|
499
|
+
const rule = getAntipattern(f.antipattern);
|
|
500
|
+
return (rule?.scopes || []).some(scope => enabled.has(scope));
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
|
|
440
504
|
export {
|
|
441
505
|
ANTIPATTERNS,
|
|
506
|
+
RULE_SCOPES,
|
|
442
507
|
RULE_ENGINE_SUPPORT,
|
|
443
508
|
GATED_PROVIDERS,
|
|
444
509
|
getAntipattern,
|
|
445
510
|
getRulesForCategory,
|
|
446
511
|
getRuleEngineSupport,
|
|
447
512
|
filterByProviders,
|
|
513
|
+
filterByScopes,
|
|
448
514
|
};
|