verbolab 0.1.0-alpha.1
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/LICENSE +21 -0
- package/README.md +71 -0
- package/dist/bin/verbo.d.ts +3 -0
- package/dist/bin/verbo.d.ts.map +1 -0
- package/dist/bin/verbo.js +1156 -0
- package/dist/bin/verbo.js.map +1 -0
- package/dist/relay/index.d.ts +2 -0
- package/dist/relay/index.d.ts.map +1 -0
- package/dist/relay/index.js +15 -0
- package/dist/relay/index.js.map +1 -0
- package/dist/src/agent/agent-launcher.d.ts +64 -0
- package/dist/src/agent/agent-launcher.d.ts.map +1 -0
- package/dist/src/agent/agent-launcher.js +326 -0
- package/dist/src/agent/agent-launcher.js.map +1 -0
- package/dist/src/agent/agent-monitor.d.ts +16 -0
- package/dist/src/agent/agent-monitor.d.ts.map +1 -0
- package/dist/src/agent/agent-monitor.js +41 -0
- package/dist/src/agent/agent-monitor.js.map +1 -0
- package/dist/src/agent/fun-names.d.ts +9 -0
- package/dist/src/agent/fun-names.d.ts.map +1 -0
- package/dist/src/agent/fun-names.js +118 -0
- package/dist/src/agent/fun-names.js.map +1 -0
- package/dist/src/agent/mcp-shim.d.ts +45 -0
- package/dist/src/agent/mcp-shim.d.ts.map +1 -0
- package/dist/src/agent/mcp-shim.js +192 -0
- package/dist/src/agent/mcp-shim.js.map +1 -0
- package/dist/src/agent/personas.d.ts +47 -0
- package/dist/src/agent/personas.d.ts.map +1 -0
- package/dist/src/agent/personas.js +86 -0
- package/dist/src/agent/personas.js.map +1 -0
- package/dist/src/agent/provider-detection.d.ts +21 -0
- package/dist/src/agent/provider-detection.d.ts.map +1 -0
- package/dist/src/agent/provider-detection.js +47 -0
- package/dist/src/agent/provider-detection.js.map +1 -0
- package/dist/src/agent/providers/claude-provider.d.ts +3 -0
- package/dist/src/agent/providers/claude-provider.d.ts.map +1 -0
- package/dist/src/agent/providers/claude-provider.js +119 -0
- package/dist/src/agent/providers/claude-provider.js.map +1 -0
- package/dist/src/agent/providers/gemini-provider.d.ts +13 -0
- package/dist/src/agent/providers/gemini-provider.d.ts.map +1 -0
- package/dist/src/agent/providers/gemini-provider.js +143 -0
- package/dist/src/agent/providers/gemini-provider.js.map +1 -0
- package/dist/src/agent/providers/openai-provider.d.ts +3 -0
- package/dist/src/agent/providers/openai-provider.d.ts.map +1 -0
- package/dist/src/agent/providers/openai-provider.js +127 -0
- package/dist/src/agent/providers/openai-provider.js.map +1 -0
- package/dist/src/agent/providers/registry.d.ts +19 -0
- package/dist/src/agent/providers/registry.d.ts.map +1 -0
- package/dist/src/agent/providers/registry.js +30 -0
- package/dist/src/agent/providers/registry.js.map +1 -0
- package/dist/src/agent/providers/types.d.ts +118 -0
- package/dist/src/agent/providers/types.d.ts.map +1 -0
- package/dist/src/agent/providers/types.js +2 -0
- package/dist/src/agent/providers/types.js.map +1 -0
- package/dist/src/approval/approval-server.d.ts +17 -0
- package/dist/src/approval/approval-server.d.ts.map +1 -0
- package/dist/src/approval/approval-server.js +90 -0
- package/dist/src/approval/approval-server.js.map +1 -0
- package/dist/src/approval/approval-store.d.ts +29 -0
- package/dist/src/approval/approval-store.d.ts.map +1 -0
- package/dist/src/approval/approval-store.js +94 -0
- package/dist/src/approval/approval-store.js.map +1 -0
- package/dist/src/auth/auth-store.d.ts +18 -0
- package/dist/src/auth/auth-store.d.ts.map +1 -0
- package/dist/src/auth/auth-store.js +34 -0
- package/dist/src/auth/auth-store.js.map +1 -0
- package/dist/src/auth/device-code-client.d.ts +32 -0
- package/dist/src/auth/device-code-client.d.ts.map +1 -0
- package/dist/src/auth/device-code-client.js +41 -0
- package/dist/src/auth/device-code-client.js.map +1 -0
- package/dist/src/auth/plan-enforcer.d.ts +8 -0
- package/dist/src/auth/plan-enforcer.d.ts.map +1 -0
- package/dist/src/auth/plan-enforcer.js +14 -0
- package/dist/src/auth/plan-enforcer.js.map +1 -0
- package/dist/src/commands/audit.d.ts +7 -0
- package/dist/src/commands/audit.d.ts.map +1 -0
- package/dist/src/commands/audit.js +92 -0
- package/dist/src/commands/audit.js.map +1 -0
- package/dist/src/commands/team.d.ts +48 -0
- package/dist/src/commands/team.d.ts.map +1 -0
- package/dist/src/commands/team.js +175 -0
- package/dist/src/commands/team.js.map +1 -0
- package/dist/src/config/verbo-config.d.ts +43 -0
- package/dist/src/config/verbo-config.d.ts.map +1 -0
- package/dist/src/config/verbo-config.js +111 -0
- package/dist/src/config/verbo-config.js.map +1 -0
- package/dist/src/core/agent-session-store.d.ts +69 -0
- package/dist/src/core/agent-session-store.d.ts.map +1 -0
- package/dist/src/core/agent-session-store.js +168 -0
- package/dist/src/core/agent-session-store.js.map +1 -0
- package/dist/src/core/audit-log-store.d.ts +33 -0
- package/dist/src/core/audit-log-store.d.ts.map +1 -0
- package/dist/src/core/audit-log-store.js +104 -0
- package/dist/src/core/audit-log-store.js.map +1 -0
- package/dist/src/core/compliance.d.ts +50 -0
- package/dist/src/core/compliance.d.ts.map +1 -0
- package/dist/src/core/compliance.js +59 -0
- package/dist/src/core/compliance.js.map +1 -0
- package/dist/src/core/conflict-detector.d.ts +19 -0
- package/dist/src/core/conflict-detector.d.ts.map +1 -0
- package/dist/src/core/conflict-detector.js +87 -0
- package/dist/src/core/conflict-detector.js.map +1 -0
- package/dist/src/core/conflict-enforcer.d.ts +37 -0
- package/dist/src/core/conflict-enforcer.d.ts.map +1 -0
- package/dist/src/core/conflict-enforcer.js +139 -0
- package/dist/src/core/conflict-enforcer.js.map +1 -0
- package/dist/src/core/cost-store.d.ts +55 -0
- package/dist/src/core/cost-store.d.ts.map +1 -0
- package/dist/src/core/cost-store.js +140 -0
- package/dist/src/core/cost-store.js.map +1 -0
- package/dist/src/core/hot-files.d.ts +19 -0
- package/dist/src/core/hot-files.d.ts.map +1 -0
- package/dist/src/core/hot-files.js +64 -0
- package/dist/src/core/hot-files.js.map +1 -0
- package/dist/src/core/human-action-store.d.ts +33 -0
- package/dist/src/core/human-action-store.d.ts.map +1 -0
- package/dist/src/core/human-action-store.js +92 -0
- package/dist/src/core/human-action-store.js.map +1 -0
- package/dist/src/core/learning-store.d.ts +32 -0
- package/dist/src/core/learning-store.d.ts.map +1 -0
- package/dist/src/core/learning-store.js +95 -0
- package/dist/src/core/learning-store.js.map +1 -0
- package/dist/src/core/merge-queue.d.ts +28 -0
- package/dist/src/core/merge-queue.d.ts.map +1 -0
- package/dist/src/core/merge-queue.js +92 -0
- package/dist/src/core/merge-queue.js.map +1 -0
- package/dist/src/core/notification-service.d.ts +13 -0
- package/dist/src/core/notification-service.d.ts.map +1 -0
- package/dist/src/core/notification-service.js +126 -0
- package/dist/src/core/notification-service.js.map +1 -0
- package/dist/src/core/notifications.d.ts +10 -0
- package/dist/src/core/notifications.d.ts.map +1 -0
- package/dist/src/core/notifications.js +33 -0
- package/dist/src/core/notifications.js.map +1 -0
- package/dist/src/core/orchestrator-store.d.ts +44 -0
- package/dist/src/core/orchestrator-store.d.ts.map +1 -0
- package/dist/src/core/orchestrator-store.js +69 -0
- package/dist/src/core/orchestrator-store.js.map +1 -0
- package/dist/src/core/parallelizer.d.ts +47 -0
- package/dist/src/core/parallelizer.d.ts.map +1 -0
- package/dist/src/core/parallelizer.js +224 -0
- package/dist/src/core/parallelizer.js.map +1 -0
- package/dist/src/core/pipeline-rollback.d.ts +29 -0
- package/dist/src/core/pipeline-rollback.d.ts.map +1 -0
- package/dist/src/core/pipeline-rollback.js +84 -0
- package/dist/src/core/pipeline-rollback.js.map +1 -0
- package/dist/src/core/pipeline-runner.d.ts +73 -0
- package/dist/src/core/pipeline-runner.d.ts.map +1 -0
- package/dist/src/core/pipeline-runner.js +165 -0
- package/dist/src/core/pipeline-runner.js.map +1 -0
- package/dist/src/core/pr-creator.d.ts +22 -0
- package/dist/src/core/pr-creator.d.ts.map +1 -0
- package/dist/src/core/pr-creator.js +55 -0
- package/dist/src/core/pr-creator.js.map +1 -0
- package/dist/src/core/rbac.d.ts +27 -0
- package/dist/src/core/rbac.d.ts.map +1 -0
- package/dist/src/core/rbac.js +76 -0
- package/dist/src/core/rbac.js.map +1 -0
- package/dist/src/core/startup-cleanup.d.ts +47 -0
- package/dist/src/core/startup-cleanup.d.ts.map +1 -0
- package/dist/src/core/startup-cleanup.js +150 -0
- package/dist/src/core/startup-cleanup.js.map +1 -0
- package/dist/src/core/task-store.d.ts +96 -0
- package/dist/src/core/task-store.d.ts.map +1 -0
- package/dist/src/core/task-store.js +309 -0
- package/dist/src/core/task-store.js.map +1 -0
- package/dist/src/core/verbo-config-editor.d.ts +44 -0
- package/dist/src/core/verbo-config-editor.d.ts.map +1 -0
- package/dist/src/core/verbo-config-editor.js +204 -0
- package/dist/src/core/verbo-config-editor.js.map +1 -0
- package/dist/src/core/verbo-config.d.ts +35 -0
- package/dist/src/core/verbo-config.d.ts.map +1 -0
- package/dist/src/core/verbo-config.js +55 -0
- package/dist/src/core/verbo-config.js.map +1 -0
- package/dist/src/core/verbo-md.d.ts +96 -0
- package/dist/src/core/verbo-md.d.ts.map +1 -0
- package/dist/src/core/verbo-md.js +410 -0
- package/dist/src/core/verbo-md.js.map +1 -0
- package/dist/src/db/database.d.ts +9 -0
- package/dist/src/db/database.d.ts.map +1 -0
- package/dist/src/db/database.js +37 -0
- package/dist/src/db/database.js.map +1 -0
- package/dist/src/db/migrations/001-personas-subtasks.d.ts +10 -0
- package/dist/src/db/migrations/001-personas-subtasks.d.ts.map +1 -0
- package/dist/src/db/migrations/001-personas-subtasks.js +32 -0
- package/dist/src/db/migrations/001-personas-subtasks.js.map +1 -0
- package/dist/src/db/migrations/002-rbac.d.ts +9 -0
- package/dist/src/db/migrations/002-rbac.d.ts.map +1 -0
- package/dist/src/db/migrations/002-rbac.js +31 -0
- package/dist/src/db/migrations/002-rbac.js.map +1 -0
- package/dist/src/db/migrations/003-provider-column.d.ts +8 -0
- package/dist/src/db/migrations/003-provider-column.d.ts.map +1 -0
- package/dist/src/db/migrations/003-provider-column.js +12 -0
- package/dist/src/db/migrations/003-provider-column.js.map +1 -0
- package/dist/src/db/migrations/004-pipeline-cost.d.ts +8 -0
- package/dist/src/db/migrations/004-pipeline-cost.d.ts.map +1 -0
- package/dist/src/db/migrations/004-pipeline-cost.js +23 -0
- package/dist/src/db/migrations/004-pipeline-cost.js.map +1 -0
- package/dist/src/db/migrations/005-audit-log-timestamp.d.ts +10 -0
- package/dist/src/db/migrations/005-audit-log-timestamp.d.ts.map +1 -0
- package/dist/src/db/migrations/005-audit-log-timestamp.js +39 -0
- package/dist/src/db/migrations/005-audit-log-timestamp.js.map +1 -0
- package/dist/src/db/migrations/006-human-action-type.d.ts +9 -0
- package/dist/src/db/migrations/006-human-action-type.d.ts.map +1 -0
- package/dist/src/db/migrations/006-human-action-type.js +16 -0
- package/dist/src/db/migrations/006-human-action-type.js.map +1 -0
- package/dist/src/db/schema.d.ts +6 -0
- package/dist/src/db/schema.d.ts.map +1 -0
- package/dist/src/db/schema.js +255 -0
- package/dist/src/db/schema.js.map +1 -0
- package/dist/src/deps/dependabot-generator.d.ts +22 -0
- package/dist/src/deps/dependabot-generator.d.ts.map +1 -0
- package/dist/src/deps/dependabot-generator.js +83 -0
- package/dist/src/deps/dependabot-generator.js.map +1 -0
- package/dist/src/deps/dependabot-monitor.d.ts +22 -0
- package/dist/src/deps/dependabot-monitor.d.ts.map +1 -0
- package/dist/src/deps/dependabot-monitor.js +28 -0
- package/dist/src/deps/dependabot-monitor.js.map +1 -0
- package/dist/src/deps/package-auditor.d.ts +24 -0
- package/dist/src/deps/package-auditor.d.ts.map +1 -0
- package/dist/src/deps/package-auditor.js +118 -0
- package/dist/src/deps/package-auditor.js.map +1 -0
- package/dist/src/init/ensure-init.d.ts +6 -0
- package/dist/src/init/ensure-init.d.ts.map +1 -0
- package/dist/src/init/ensure-init.js +27 -0
- package/dist/src/init/ensure-init.js.map +1 -0
- package/dist/src/init/project-detector.d.ts +11 -0
- package/dist/src/init/project-detector.d.ts.map +1 -0
- package/dist/src/init/project-detector.js +117 -0
- package/dist/src/init/project-detector.js.map +1 -0
- package/dist/src/init/questionnaire.d.ts +5 -0
- package/dist/src/init/questionnaire.d.ts.map +1 -0
- package/dist/src/init/questionnaire.js +112 -0
- package/dist/src/init/questionnaire.js.map +1 -0
- package/dist/src/init/template.d.ts +17 -0
- package/dist/src/init/template.d.ts.map +1 -0
- package/dist/src/init/template.js +46 -0
- package/dist/src/init/template.js.map +1 -0
- package/dist/src/intelligence/claude-client.d.ts +3 -0
- package/dist/src/intelligence/claude-client.d.ts.map +1 -0
- package/dist/src/intelligence/claude-client.js +12 -0
- package/dist/src/intelligence/claude-client.js.map +1 -0
- package/dist/src/intelligence/conflict-mediator.d.ts +17 -0
- package/dist/src/intelligence/conflict-mediator.d.ts.map +1 -0
- package/dist/src/intelligence/conflict-mediator.js +83 -0
- package/dist/src/intelligence/conflict-mediator.js.map +1 -0
- package/dist/src/intelligence/github-orchestrator.d.ts +30 -0
- package/dist/src/intelligence/github-orchestrator.d.ts.map +1 -0
- package/dist/src/intelligence/github-orchestrator.js +270 -0
- package/dist/src/intelligence/github-orchestrator.js.map +1 -0
- package/dist/src/intelligence/kill-switch.d.ts +10 -0
- package/dist/src/intelligence/kill-switch.d.ts.map +1 -0
- package/dist/src/intelligence/kill-switch.js +12 -0
- package/dist/src/intelligence/kill-switch.js.map +1 -0
- package/dist/src/intelligence/learnings-extractor.d.ts +13 -0
- package/dist/src/intelligence/learnings-extractor.d.ts.map +1 -0
- package/dist/src/intelligence/learnings-extractor.js +74 -0
- package/dist/src/intelligence/learnings-extractor.js.map +1 -0
- package/dist/src/intelligence/project-scanner.d.ts +2 -0
- package/dist/src/intelligence/project-scanner.d.ts.map +1 -0
- package/dist/src/intelligence/project-scanner.js +28 -0
- package/dist/src/intelligence/project-scanner.js.map +1 -0
- package/dist/src/intelligence/task-decomposer.d.ts +14 -0
- package/dist/src/intelligence/task-decomposer.d.ts.map +1 -0
- package/dist/src/intelligence/task-decomposer.js +97 -0
- package/dist/src/intelligence/task-decomposer.js.map +1 -0
- package/dist/src/intelligence/types.d.ts +14 -0
- package/dist/src/intelligence/types.d.ts.map +1 -0
- package/dist/src/intelligence/types.js +2 -0
- package/dist/src/intelligence/types.js.map +1 -0
- package/dist/src/mcp/server.d.ts +63 -0
- package/dist/src/mcp/server.d.ts.map +1 -0
- package/dist/src/mcp/server.js +537 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/mcp/stdio-entry.d.ts +2 -0
- package/dist/src/mcp/stdio-entry.d.ts.map +1 -0
- package/dist/src/mcp/stdio-entry.js +124 -0
- package/dist/src/mcp/stdio-entry.js.map +1 -0
- package/dist/src/mcp/subtask-handlers.d.ts +7 -0
- package/dist/src/mcp/subtask-handlers.d.ts.map +1 -0
- package/dist/src/mcp/subtask-handlers.js +50 -0
- package/dist/src/mcp/subtask-handlers.js.map +1 -0
- package/dist/src/security/network-proxy.d.ts +20 -0
- package/dist/src/security/network-proxy.d.ts.map +1 -0
- package/dist/src/security/network-proxy.js +125 -0
- package/dist/src/security/network-proxy.js.map +1 -0
- package/dist/src/security/network-sandbox.d.ts +19 -0
- package/dist/src/security/network-sandbox.d.ts.map +1 -0
- package/dist/src/security/network-sandbox.js +100 -0
- package/dist/src/security/network-sandbox.js.map +1 -0
- package/dist/src/security/sanitize.d.ts +13 -0
- package/dist/src/security/sanitize.d.ts.map +1 -0
- package/dist/src/security/sanitize.js +19 -0
- package/dist/src/security/sanitize.js.map +1 -0
- package/dist/src/security/secrets-patterns.d.ts +29 -0
- package/dist/src/security/secrets-patterns.d.ts.map +1 -0
- package/dist/src/security/secrets-patterns.js +430 -0
- package/dist/src/security/secrets-patterns.js.map +1 -0
- package/dist/src/security/secrets-scanner.d.ts +26 -0
- package/dist/src/security/secrets-scanner.d.ts.map +1 -0
- package/dist/src/security/secrets-scanner.js +62 -0
- package/dist/src/security/secrets-scanner.js.map +1 -0
- package/dist/src/skills/classifier.d.ts +9 -0
- package/dist/src/skills/classifier.d.ts.map +1 -0
- package/dist/src/skills/classifier.js +41 -0
- package/dist/src/skills/classifier.js.map +1 -0
- package/dist/src/skills/registry.d.ts +16 -0
- package/dist/src/skills/registry.d.ts.map +1 -0
- package/dist/src/skills/registry.js +61 -0
- package/dist/src/skills/registry.js.map +1 -0
- package/dist/src/sync/events.d.ts +9 -0
- package/dist/src/sync/events.d.ts.map +1 -0
- package/dist/src/sync/events.js +2 -0
- package/dist/src/sync/events.js.map +1 -0
- package/dist/src/sync/relay-server.d.ts +18 -0
- package/dist/src/sync/relay-server.d.ts.map +1 -0
- package/dist/src/sync/relay-server.js +131 -0
- package/dist/src/sync/relay-server.js.map +1 -0
- package/dist/src/sync/sync-client.d.ts +31 -0
- package/dist/src/sync/sync-client.d.ts.map +1 -0
- package/dist/src/sync/sync-client.js +314 -0
- package/dist/src/sync/sync-client.js.map +1 -0
- package/dist/src/tui/app.d.ts +35 -0
- package/dist/src/tui/app.d.ts.map +1 -0
- package/dist/src/tui/app.js +676 -0
- package/dist/src/tui/app.js.map +1 -0
- package/dist/src/tui/components/activity-feed.d.ts +12 -0
- package/dist/src/tui/components/activity-feed.d.ts.map +1 -0
- package/dist/src/tui/components/activity-feed.js +82 -0
- package/dist/src/tui/components/activity-feed.js.map +1 -0
- package/dist/src/tui/components/agent-list.d.ts +19 -0
- package/dist/src/tui/components/agent-list.d.ts.map +1 -0
- package/dist/src/tui/components/agent-list.js +33 -0
- package/dist/src/tui/components/agent-list.js.map +1 -0
- package/dist/src/tui/components/agent-row.d.ts +12 -0
- package/dist/src/tui/components/agent-row.d.ts.map +1 -0
- package/dist/src/tui/components/agent-row.js +37 -0
- package/dist/src/tui/components/agent-row.js.map +1 -0
- package/dist/src/tui/components/approval-terminal.d.ts +13 -0
- package/dist/src/tui/components/approval-terminal.d.ts.map +1 -0
- package/dist/src/tui/components/approval-terminal.js +34 -0
- package/dist/src/tui/components/approval-terminal.js.map +1 -0
- package/dist/src/tui/components/audit-viewer.d.ts +16 -0
- package/dist/src/tui/components/audit-viewer.d.ts.map +1 -0
- package/dist/src/tui/components/audit-viewer.js +46 -0
- package/dist/src/tui/components/audit-viewer.js.map +1 -0
- package/dist/src/tui/components/auth-gate.d.ts +9 -0
- package/dist/src/tui/components/auth-gate.d.ts.map +1 -0
- package/dist/src/tui/components/auth-gate.js +112 -0
- package/dist/src/tui/components/auth-gate.js.map +1 -0
- package/dist/src/tui/components/command-palette.d.ts +12 -0
- package/dist/src/tui/components/command-palette.d.ts.map +1 -0
- package/dist/src/tui/components/command-palette.js +51 -0
- package/dist/src/tui/components/command-palette.js.map +1 -0
- package/dist/src/tui/components/compliance-badge.d.ts +11 -0
- package/dist/src/tui/components/compliance-badge.d.ts.map +1 -0
- package/dist/src/tui/components/compliance-badge.js +12 -0
- package/dist/src/tui/components/compliance-badge.js.map +1 -0
- package/dist/src/tui/components/decomposition-review.d.ts +10 -0
- package/dist/src/tui/components/decomposition-review.d.ts.map +1 -0
- package/dist/src/tui/components/decomposition-review.js +19 -0
- package/dist/src/tui/components/decomposition-review.js.map +1 -0
- package/dist/src/tui/components/dependency-graph.d.ts +13 -0
- package/dist/src/tui/components/dependency-graph.d.ts.map +1 -0
- package/dist/src/tui/components/dependency-graph.js +143 -0
- package/dist/src/tui/components/dependency-graph.js.map +1 -0
- package/dist/src/tui/components/diff-viewer.d.ts +11 -0
- package/dist/src/tui/components/diff-viewer.d.ts.map +1 -0
- package/dist/src/tui/components/diff-viewer.js +82 -0
- package/dist/src/tui/components/diff-viewer.js.map +1 -0
- package/dist/src/tui/components/edit-task-input.d.ts +10 -0
- package/dist/src/tui/components/edit-task-input.d.ts.map +1 -0
- package/dist/src/tui/components/edit-task-input.js +20 -0
- package/dist/src/tui/components/edit-task-input.js.map +1 -0
- package/dist/src/tui/components/footer.d.ts +12 -0
- package/dist/src/tui/components/footer.d.ts.map +1 -0
- package/dist/src/tui/components/footer.js +41 -0
- package/dist/src/tui/components/footer.js.map +1 -0
- package/dist/src/tui/components/header.d.ts +8 -0
- package/dist/src/tui/components/header.d.ts.map +1 -0
- package/dist/src/tui/components/header.js +20 -0
- package/dist/src/tui/components/header.js.map +1 -0
- package/dist/src/tui/components/human-actions.d.ts +14 -0
- package/dist/src/tui/components/human-actions.d.ts.map +1 -0
- package/dist/src/tui/components/human-actions.js +43 -0
- package/dist/src/tui/components/human-actions.js.map +1 -0
- package/dist/src/tui/components/log-panel.d.ts +10 -0
- package/dist/src/tui/components/log-panel.d.ts.map +1 -0
- package/dist/src/tui/components/log-panel.js +38 -0
- package/dist/src/tui/components/log-panel.js.map +1 -0
- package/dist/src/tui/components/memory-viewer.d.ts +10 -0
- package/dist/src/tui/components/memory-viewer.d.ts.map +1 -0
- package/dist/src/tui/components/memory-viewer.js +44 -0
- package/dist/src/tui/components/memory-viewer.js.map +1 -0
- package/dist/src/tui/components/new-task-input.d.ts +9 -0
- package/dist/src/tui/components/new-task-input.d.ts.map +1 -0
- package/dist/src/tui/components/new-task-input.js +21 -0
- package/dist/src/tui/components/new-task-input.js.map +1 -0
- package/dist/src/tui/components/orchestrator-status.d.ts +9 -0
- package/dist/src/tui/components/orchestrator-status.d.ts.map +1 -0
- package/dist/src/tui/components/orchestrator-status.js +15 -0
- package/dist/src/tui/components/orchestrator-status.js.map +1 -0
- package/dist/src/tui/components/parallelize-banner.d.ts +8 -0
- package/dist/src/tui/components/parallelize-banner.d.ts.map +1 -0
- package/dist/src/tui/components/parallelize-banner.js +9 -0
- package/dist/src/tui/components/parallelize-banner.js.map +1 -0
- package/dist/src/tui/components/progress-bar.d.ts +9 -0
- package/dist/src/tui/components/progress-bar.d.ts.map +1 -0
- package/dist/src/tui/components/progress-bar.js +15 -0
- package/dist/src/tui/components/progress-bar.js.map +1 -0
- package/dist/src/tui/components/review-queue.d.ts +13 -0
- package/dist/src/tui/components/review-queue.d.ts.map +1 -0
- package/dist/src/tui/components/review-queue.js +78 -0
- package/dist/src/tui/components/review-queue.js.map +1 -0
- package/dist/src/tui/components/rich-header.d.ts +11 -0
- package/dist/src/tui/components/rich-header.d.ts.map +1 -0
- package/dist/src/tui/components/rich-header.js +25 -0
- package/dist/src/tui/components/rich-header.js.map +1 -0
- package/dist/src/tui/components/spinner.d.ts +7 -0
- package/dist/src/tui/components/spinner.d.ts.map +1 -0
- package/dist/src/tui/components/spinner.js +8 -0
- package/dist/src/tui/components/spinner.js.map +1 -0
- package/dist/src/tui/components/status-bar.d.ts +23 -0
- package/dist/src/tui/components/status-bar.d.ts.map +1 -0
- package/dist/src/tui/components/status-bar.js +28 -0
- package/dist/src/tui/components/status-bar.js.map +1 -0
- package/dist/src/tui/components/task-queue.d.ts +11 -0
- package/dist/src/tui/components/task-queue.d.ts.map +1 -0
- package/dist/src/tui/components/task-queue.js +30 -0
- package/dist/src/tui/components/task-queue.js.map +1 -0
- package/dist/src/tui/components/team-view.d.ts +13 -0
- package/dist/src/tui/components/team-view.d.ts.map +1 -0
- package/dist/src/tui/components/team-view.js +12 -0
- package/dist/src/tui/components/team-view.js.map +1 -0
- package/dist/src/tui/graph-renderer.d.ts +11 -0
- package/dist/src/tui/graph-renderer.d.ts.map +1 -0
- package/dist/src/tui/graph-renderer.js +296 -0
- package/dist/src/tui/graph-renderer.js.map +1 -0
- package/dist/src/tui/hooks/use-bell.d.ts +21 -0
- package/dist/src/tui/hooks/use-bell.d.ts.map +1 -0
- package/dist/src/tui/hooks/use-bell.js +38 -0
- package/dist/src/tui/hooks/use-bell.js.map +1 -0
- package/dist/src/tui/hooks/use-ci-status.d.ts +16 -0
- package/dist/src/tui/hooks/use-ci-status.d.ts.map +1 -0
- package/dist/src/tui/hooks/use-ci-status.js +97 -0
- package/dist/src/tui/hooks/use-ci-status.js.map +1 -0
- package/dist/src/tui/hooks/use-command-palette.d.ts +37 -0
- package/dist/src/tui/hooks/use-command-palette.d.ts.map +1 -0
- package/dist/src/tui/hooks/use-command-palette.js +108 -0
- package/dist/src/tui/hooks/use-command-palette.js.map +1 -0
- package/dist/src/tui/hooks/use-diff-view.d.ts +16 -0
- package/dist/src/tui/hooks/use-diff-view.d.ts.map +1 -0
- package/dist/src/tui/hooks/use-diff-view.js +75 -0
- package/dist/src/tui/hooks/use-diff-view.js.map +1 -0
- package/dist/src/tui/hooks/use-keyboard.d.ts +3 -0
- package/dist/src/tui/hooks/use-keyboard.d.ts.map +1 -0
- package/dist/src/tui/hooks/use-keyboard.js +70 -0
- package/dist/src/tui/hooks/use-keyboard.js.map +1 -0
- package/dist/src/tui/hooks/use-log-stream.d.ts +25 -0
- package/dist/src/tui/hooks/use-log-stream.d.ts.map +1 -0
- package/dist/src/tui/hooks/use-log-stream.js +83 -0
- package/dist/src/tui/hooks/use-log-stream.js.map +1 -0
- package/dist/src/tui/hooks/use-spinner.d.ts +3 -0
- package/dist/src/tui/hooks/use-spinner.d.ts.map +1 -0
- package/dist/src/tui/hooks/use-spinner.js +13 -0
- package/dist/src/tui/hooks/use-spinner.js.map +1 -0
- package/dist/src/tui/hooks/use-store.d.ts +33 -0
- package/dist/src/tui/hooks/use-store.d.ts.map +1 -0
- package/dist/src/tui/hooks/use-store.js +21 -0
- package/dist/src/tui/hooks/use-store.js.map +1 -0
- package/dist/src/tui/lib/diff-parser.d.ts +24 -0
- package/dist/src/tui/lib/diff-parser.d.ts.map +1 -0
- package/dist/src/tui/lib/diff-parser.js +115 -0
- package/dist/src/tui/lib/diff-parser.js.map +1 -0
- package/dist/src/tui/lib/palette-commands.d.ts +14 -0
- package/dist/src/tui/lib/palette-commands.d.ts.map +1 -0
- package/dist/src/tui/lib/palette-commands.js +101 -0
- package/dist/src/tui/lib/palette-commands.js.map +1 -0
- package/dist/src/tui/tui.d.ts +8 -0
- package/dist/src/tui/tui.d.ts.map +1 -0
- package/dist/src/tui/tui.js +8 -0
- package/dist/src/tui/tui.js.map +1 -0
- package/package.json +66 -0
- package/skills/api-design.md +84 -0
- package/skills/backend-typescript.md +76 -0
- package/skills/data-modeling.md +73 -0
- package/skills/devops-ci.md +82 -0
- package/skills/frontend-design.md +69 -0
- package/skills/observability.md +73 -0
- package/skills/react-nextjs.md +76 -0
- package/skills/refactoring.md +77 -0
- package/skills/security.md +75 -0
- package/skills/testing.md +69 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: devops-ci
|
|
3
|
+
description: CI/CD pipelines, deployment strategies, rollback triggers, DORA metrics
|
|
4
|
+
domain: engineering
|
|
5
|
+
subdomain: devops
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# DevOps & CI/CD
|
|
9
|
+
|
|
10
|
+
## Context
|
|
11
|
+
You are setting up CI/CD pipelines, configuring deployment workflows, defining branch protection, or improving delivery performance. Apply these patterns to GitHub Actions workflows and production deployment infrastructure.
|
|
12
|
+
|
|
13
|
+
## Core Principles
|
|
14
|
+
|
|
15
|
+
**Trunk-Based Development** (Forsgren, Humble, Kim — *Accelerate*): High-performing teams merge to trunk at least daily. Long-lived branches correlate with lower deployment frequency and higher change failure rates. Keep branches short, merge through PRs with CI gates.
|
|
16
|
+
|
|
17
|
+
**Deployment Is Not Release** (Humble & Farley — *Continuous Delivery*): Decouple deploying code from exposing features. Deploy frequently behind feature flags; release when ready. This reduces batch size and makes rollbacks trivial.
|
|
18
|
+
|
|
19
|
+
**DORA Four Key Metrics** (*Accelerate*): Measure delivery performance with deployment frequency (how often you ship), lead time for changes (commit to production), mean time to restore (MTTR when failures happen), and change failure rate (% of deployments causing incidents). Elite teams: multiple deploys/day, <1hr lead time, <1hr MTTR, <5% failure rate.
|
|
20
|
+
|
|
21
|
+
**Automate the Pain** (*Continuous Delivery*): If a process is painful, do it more often and automate it. Manual gates create bottlenecks and drift. Every step from commit to production should be scripted and repeatable.
|
|
22
|
+
|
|
23
|
+
## Patterns
|
|
24
|
+
|
|
25
|
+
**Branch protection rules:**
|
|
26
|
+
Require PR + CI green + 1 reviewer before merge to trunk. Block force-pushes. Require linear history (squash or rebase). This prevents broken code from reaching production.
|
|
27
|
+
|
|
28
|
+
**Deployment strategies — pick by constraint:**
|
|
29
|
+
- **Blue/green**: instant cutover between identical environments. Use when you need instant rollback. Costs 2x infrastructure.
|
|
30
|
+
- **Canary**: route a small % of traffic to the new version, increase gradually. Use when you need risk-limited validation with real traffic. Requires traffic splitting (feature flags or load balancer rules).
|
|
31
|
+
- **Rolling**: replace instances one at a time. Use for stateless services where zero-downtime matters and infra cost is a constraint.
|
|
32
|
+
|
|
33
|
+
**Automatic rollback triggers:**
|
|
34
|
+
```yaml
|
|
35
|
+
# Roll back when error rate or latency crosses thresholds
|
|
36
|
+
rollback_conditions:
|
|
37
|
+
error_rate_threshold: 0.01 # >1% errors → rollback
|
|
38
|
+
p99_latency_multiplier: 2.0 # >2x baseline p99 → rollback
|
|
39
|
+
evaluation_window: 5m # observe for 5 minutes after deploy
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**GitHub Actions — fast, cacheable, separated:**
|
|
43
|
+
```yaml
|
|
44
|
+
jobs:
|
|
45
|
+
lint:
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/cache@v4
|
|
48
|
+
with:
|
|
49
|
+
path: node_modules
|
|
50
|
+
key: deps-${{ hashFiles('package-lock.json') }}
|
|
51
|
+
- run: npm ci
|
|
52
|
+
- run: npm run lint
|
|
53
|
+
test:
|
|
54
|
+
needs: [lint] # fail fast: no tests if lint fails
|
|
55
|
+
steps:
|
|
56
|
+
- run: npm ci
|
|
57
|
+
- run: npm test
|
|
58
|
+
build:
|
|
59
|
+
needs: [test]
|
|
60
|
+
steps:
|
|
61
|
+
- run: npm run build
|
|
62
|
+
```
|
|
63
|
+
Cache `node_modules` by lockfile hash. Separate lint/test/build into distinct jobs. Fail fast — lint runs first, everything else gates behind it.
|
|
64
|
+
|
|
65
|
+
## Anti-patterns
|
|
66
|
+
- Manual deploys via SSH or "run this script" — breaks auditability and repeatability.
|
|
67
|
+
- CI pipeline that takes >15 minutes — developers stop waiting and batch changes, increasing risk.
|
|
68
|
+
- No rollback plan before deploying — every deploy must have a known, tested rollback path.
|
|
69
|
+
- Alerting on causes (CPU%, disk%) instead of symptoms (error rate, latency) — causes mislead; symptoms reflect user impact.
|
|
70
|
+
- Environment drift between staging and production — use identical infra-as-code for both.
|
|
71
|
+
|
|
72
|
+
## Checklist
|
|
73
|
+
- [ ] Branch protection enabled: PR required, CI must pass, 1+ reviewer
|
|
74
|
+
- [ ] Deployment strategy chosen and documented (blue/green, canary, or rolling)
|
|
75
|
+
- [ ] Rollback triggers defined: error rate >1% or p99 >2x baseline
|
|
76
|
+
- [ ] CI jobs separated: lint → test → build, with caching by lockfile hash
|
|
77
|
+
- [ ] DORA metrics tracked: deployment frequency, lead time, MTTR, change failure rate
|
|
78
|
+
- [ ] No manual steps between merge and production deploy
|
|
79
|
+
|
|
80
|
+
## References
|
|
81
|
+
- *Accelerate* — Nicole Forsgren, Jez Humble, Gene Kim
|
|
82
|
+
- *Continuous Delivery* — Jez Humble, David Farley
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: frontend-design
|
|
3
|
+
description: Distinctive, production-grade frontend interfaces with high design quality
|
|
4
|
+
domain: engineering
|
|
5
|
+
subdomain: frontend
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Frontend Design
|
|
9
|
+
|
|
10
|
+
## Context
|
|
11
|
+
You are building web UI — components, pages, or full applications. Produce distinctive, polished interfaces that avoid generic AI aesthetics. Apply typographic hierarchy, purposeful motion, and Gestalt grouping to guide the user's eye.
|
|
12
|
+
|
|
13
|
+
## Core Principles
|
|
14
|
+
|
|
15
|
+
**Typographic Scale** (Bringhurst, *The Elements of Typographic Style*): Use a ratio-based scale (major third: ×1.25) for type sizes — `12 / 15 / 19 / 24 / 30px`. Consistent ratios create harmony without manual tuning.
|
|
16
|
+
|
|
17
|
+
**Visual Hierarchy via Size, Weight, Color** (Wathan & Schoger, *Refactoring UI*): Guide attention with three levers in order — size first, then weight, then color. Reserve color for interactive elements and status; don't use it as the primary differentiator.
|
|
18
|
+
|
|
19
|
+
**Motion Discipline** (Wathan & Schoger, *Refactoring UI*): UI transitions ≤ 300ms with ease-out easing. Entrances (200ms ease-out), exits (150ms ease-in). Slower = sluggish; faster = jarring. Never animate layout properties (width/height) — use transform/opacity only.
|
|
20
|
+
|
|
21
|
+
**Gestalt Laws** (proximity, similarity, closure): Elements close together are perceived as related — use spacing to form visual groups before reaching for borders or backgrounds. Similar visual treatment implies same category.
|
|
22
|
+
|
|
23
|
+
**Committed Palette**: One dominant color, one sharp accent, neutrals for surfaces. Timid palettes with 6+ accent colors create visual noise; commit to 2 and own them.
|
|
24
|
+
|
|
25
|
+
## Patterns
|
|
26
|
+
|
|
27
|
+
**Typographic scale via CSS variables:**
|
|
28
|
+
```css
|
|
29
|
+
:root {
|
|
30
|
+
--text-sm: 0.75rem; /* 12px */
|
|
31
|
+
--text-base: 1rem; /* 16px */
|
|
32
|
+
--text-lg: 1.25rem; /* 20px */
|
|
33
|
+
--text-xl: 1.563rem; /* 25px */
|
|
34
|
+
--text-2xl: 1.953rem; /* 31px */
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Motion: entrance/exit with transform:**
|
|
39
|
+
```css
|
|
40
|
+
.card { opacity: 0; transform: translateY(8px);
|
|
41
|
+
transition: opacity 200ms ease-out, transform 200ms ease-out; }
|
|
42
|
+
.card.visible { opacity: 1; transform: translateY(0); }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Gestalt grouping with spacing:**
|
|
46
|
+
```css
|
|
47
|
+
/* related fields share tight gap; unrelated sections have larger gap */
|
|
48
|
+
.form-group { display: flex; flex-direction: column; gap: 0.5rem; }
|
|
49
|
+
.form-section + .form-section { margin-top: 2rem; }
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Anti-patterns
|
|
53
|
+
- Inter font + purple gradient + white background — the "AI default".
|
|
54
|
+
- Animations on every element — causes motion sickness and hurts performance.
|
|
55
|
+
- Inline styles scattered across components — use CSS variables or utility classes.
|
|
56
|
+
- Fixed pixel widths without responsive breakpoints — always mobile-first.
|
|
57
|
+
- Animating `width`, `height`, or `margin` — causes layout thrash; use `transform` instead.
|
|
58
|
+
|
|
59
|
+
## Checklist
|
|
60
|
+
- [ ] Font choice is intentional — not Inter/Roboto as default
|
|
61
|
+
- [ ] Color palette defined as CSS variables with dominant + accent
|
|
62
|
+
- [ ] Type sizes follow a consistent ratio-based scale
|
|
63
|
+
- [ ] Motion limited to transform/opacity, duration ≤ 300ms
|
|
64
|
+
- [ ] Responsive at 375px / 768px / 1280px breakpoints
|
|
65
|
+
- [ ] Contrast ratios pass WCAG AA; focus states visible
|
|
66
|
+
|
|
67
|
+
## References
|
|
68
|
+
- *Refactoring UI* — Adam Wathan & Steve Schoger
|
|
69
|
+
- *The Elements of Typographic Style* — Robert Bringhurst
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: observability
|
|
3
|
+
description: Structured logging, metrics, distributed tracing, alerting on SLIs, OpenTelemetry instrumentation
|
|
4
|
+
domain: engineering
|
|
5
|
+
subdomain: observability
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Observability
|
|
9
|
+
|
|
10
|
+
## Context
|
|
11
|
+
You are adding logging, metrics, or tracing to a service — or designing alerts, dashboards, or SLOs. Apply these patterns whenever instrumenting code, diagnosing production issues, or setting up monitoring infrastructure.
|
|
12
|
+
|
|
13
|
+
## Core Principles
|
|
14
|
+
|
|
15
|
+
**Three Pillars** (Majors, Fong-Jones, Miranda — *Observability Engineering*): Logs tell you *what happened* (discrete events), metrics tell you *how much / how long* (aggregated numbers over time), traces tell you *where time went* (request flow across service boundaries). Each pillar answers a different question — use all three together, not as substitutes.
|
|
16
|
+
|
|
17
|
+
**Alert on Symptoms, Not Causes** (Google — *Site Reliability Engineering*): Alert on user-facing SLIs — error rate, latency, availability. Never alert on CPU%, disk%, or thread count directly. Causes are for dashboards during investigation; symptoms are what page the oncall. A server at 95% CPU serving all requests within SLO is not an incident.
|
|
18
|
+
|
|
19
|
+
**Instrument at Boundaries** (OpenTelemetry specification): Place instrumentation at system boundaries — HTTP handlers, outgoing HTTP calls, database queries, queue produce/consume. Business logic internals rarely need spans. Boundary instrumentation captures the signals that matter with minimal noise.
|
|
20
|
+
|
|
21
|
+
**Structured Logging** (*Observability Engineering*): Every log entry must be a key-value object, never an interpolated string. Required fields: `level`, `timestamp` (ISO 8601), `service`, `traceId`, `msg`. Structured logs are queryable; string-concatenated messages are not.
|
|
22
|
+
|
|
23
|
+
## Patterns
|
|
24
|
+
|
|
25
|
+
**Structured log entry:**
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"level": "error",
|
|
29
|
+
"timestamp": "2026-03-27T14:05:32.123Z",
|
|
30
|
+
"service": "payment-api",
|
|
31
|
+
"traceId": "abc123def456",
|
|
32
|
+
"msg": "charge failed",
|
|
33
|
+
"userId": "u_982",
|
|
34
|
+
"errorCode": "card_declined"
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
Never use `logger.error(\`charge failed for ${userId}\`)` — use `logger.error({ msg: "charge failed", userId })`. String interpolation destroys queryability.
|
|
38
|
+
|
|
39
|
+
**USE method for resources** (Brendan Gregg): For every resource (CPU, memory, disk, network), measure Utilization (% busy), Saturation (queue depth), and Errors (fault count). This systematically covers resource bottlenecks.
|
|
40
|
+
|
|
41
|
+
**RED method for services** (Tom Wilkie): For every service endpoint, measure Rate (requests/sec), Errors (failed requests/sec), and Duration (latency distribution). RED gives instant service health at a glance.
|
|
42
|
+
|
|
43
|
+
**OpenTelemetry boundary instrumentation:**
|
|
44
|
+
```typescript
|
|
45
|
+
// Instrument at HTTP boundary — not inside calculateTotal()
|
|
46
|
+
app.post("/orders", async (req, res) => {
|
|
47
|
+
const span = tracer.startSpan("POST /orders");
|
|
48
|
+
const result = await db.query("INSERT INTO orders ...");
|
|
49
|
+
// db.query is auto-instrumented by otel-plugin-pg
|
|
50
|
+
span.end();
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Anti-patterns
|
|
55
|
+
- Using user IDs, request IDs, or URLs as metric label values — unbounded cardinality explodes storage and query cost. Use bounded enums (status code, endpoint name, region).
|
|
56
|
+
- Logging inside tight loops — generates noise, hurts performance, buries signal.
|
|
57
|
+
- Alerting on causes like CPU > 80% — leads to false pages and alert fatigue. Alert on SLI breach instead.
|
|
58
|
+
- Tracing every internal function call — creates massive trace trees with no diagnostic value. Trace boundaries only.
|
|
59
|
+
- Unstructured log messages with string concatenation — impossible to filter, aggregate, or correlate.
|
|
60
|
+
|
|
61
|
+
## Checklist
|
|
62
|
+
- [ ] Logs are structured JSON with `level`, `timestamp`, `service`, `traceId`, `msg`
|
|
63
|
+
- [ ] No string interpolation in log calls — all values passed as key-value fields
|
|
64
|
+
- [ ] Metric labels use bounded enums only — no user IDs, request paths, or unbounded values
|
|
65
|
+
- [ ] HTTP handlers, DB queries, and queue operations have tracing spans
|
|
66
|
+
- [ ] Alerts fire on user-facing symptoms (error rate, latency SLI), not infrastructure causes
|
|
67
|
+
- [ ] USE method applied to resources, RED method applied to service endpoints
|
|
68
|
+
- [ ] `traceId` propagated across service boundaries for distributed correlation
|
|
69
|
+
|
|
70
|
+
## References
|
|
71
|
+
- *Site Reliability Engineering* — Betsy Beyer, Chris Jones, Jennifer Petoff, Niall Richard Murphy (Google)
|
|
72
|
+
- *Observability Engineering* — Charity Majors, Liz Fong-Jones, George Miranda
|
|
73
|
+
- OpenTelemetry Specification — OpenTelemetry Authors
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: react-nextjs
|
|
3
|
+
description: Server/client component architecture, data fetching, hydration safety, and Next.js performance patterns
|
|
4
|
+
domain: engineering
|
|
5
|
+
subdomain: frontend
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# React & Next.js
|
|
9
|
+
|
|
10
|
+
## Context
|
|
11
|
+
You are building or modifying a React application using Next.js App Router. Apply server-first rendering, avoid unnecessary client boundaries, fetch data in server components, and use Next.js built-in optimizations for images, fonts, and code splitting.
|
|
12
|
+
|
|
13
|
+
## Core Principles
|
|
14
|
+
|
|
15
|
+
**Server-First Component Model** (Next.js docs, Vercel): Every component is a server component by default. Add `'use client'` only when the component needs interactivity, browser APIs, or React hooks. Keep the client boundary as low in the tree as possible — wrap the interactive leaf, not the parent.
|
|
16
|
+
|
|
17
|
+
**Collocated Data Fetching** (React docs, Meta): Fetch data directly in the server component that needs it using `async/await` — no useEffect, no client-side fetch libraries. Use `Suspense` boundaries to stream async subtrees without blocking the entire page.
|
|
18
|
+
|
|
19
|
+
**Hydration Determinism** (*Fluent React*, Strimpel): Server-rendered HTML must match the initial client render exactly. Non-deterministic content (dates, random values, user-agent checks) causes hydration mismatches. Move these into client components or use `suppressHydrationWarning`.
|
|
20
|
+
|
|
21
|
+
**Composition Over Prop Drilling** (React docs, Meta): When props pass through more than two intermediaries, restructure. Use the `children` prop to compose layouts, or lift state to the closest common ancestor.
|
|
22
|
+
|
|
23
|
+
## Patterns
|
|
24
|
+
|
|
25
|
+
**Server vs client decision tree:**
|
|
26
|
+
```
|
|
27
|
+
Does the component need hooks, event handlers, or browser APIs?
|
|
28
|
+
→ YES: 'use client' on that component (not the parent)
|
|
29
|
+
→ NO: Keep as server component — fetch data directly
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Data fetching with Suspense:**
|
|
33
|
+
```tsx
|
|
34
|
+
// page.tsx — server component, no 'use client'
|
|
35
|
+
async function TaskList() {
|
|
36
|
+
const tasks = await db.tasks.findMany(); // runs on server, zero client JS
|
|
37
|
+
return <ul>{tasks.map(t => <li key={t.id}>{t.title}</li>)}</ul>;
|
|
38
|
+
}
|
|
39
|
+
export default function Page() {
|
|
40
|
+
return (
|
|
41
|
+
<Suspense fallback={<TaskListSkeleton />}>
|
|
42
|
+
<TaskList />
|
|
43
|
+
</Suspense>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Performance optimizations:**
|
|
49
|
+
```tsx
|
|
50
|
+
import Image from 'next/image'; // automatic WebP/AVIF, lazy loading, no CLS
|
|
51
|
+
import { Inter } from 'next/font/google'; // eliminates font CLS, self-hosted
|
|
52
|
+
import dynamic from 'next/dynamic';
|
|
53
|
+
const HeavyChart = dynamic(() => import('./Chart'), { ssr: false }); // client-only bundle
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Anti-patterns
|
|
57
|
+
- Adding `'use client'` at the layout or page level — pushes the entire subtree to the client, losing server rendering benefits.
|
|
58
|
+
- Fetching data in useEffect when the component could be a server component — adds a client-server waterfall.
|
|
59
|
+
- Rendering `new Date()` or `Math.random()` in server components without handling hydration mismatch.
|
|
60
|
+
- Passing props through 3+ intermediate components instead of composing with children or context.
|
|
61
|
+
- Using `<img>` tags instead of `next/image` — loses automatic optimization, lazy loading, and CLS prevention.
|
|
62
|
+
- Importing heavy client-only libraries (chart libs, rich editors) without `dynamic(() => import(...), { ssr: false })`.
|
|
63
|
+
|
|
64
|
+
## Checklist
|
|
65
|
+
- [ ] `'use client'` only on components that need interactivity — never on pages or layouts
|
|
66
|
+
- [ ] Data fetched in server components, not via useEffect
|
|
67
|
+
- [ ] Suspense boundaries wrap async server components with skeleton fallbacks
|
|
68
|
+
- [ ] No hydration mismatches — non-deterministic values handled in client components
|
|
69
|
+
- [ ] All images use `next/image`, all fonts use `next/font`
|
|
70
|
+
- [ ] Heavy client-only libraries loaded with `dynamic({ ssr: false })`
|
|
71
|
+
- [ ] Props pass through ≤2 levels — deeper needs are composed via children or context
|
|
72
|
+
|
|
73
|
+
## References
|
|
74
|
+
- *React Documentation* — Meta
|
|
75
|
+
- *Next.js Documentation* — Vercel
|
|
76
|
+
- *Fluent React* — Tejas Kumar (Strimpel)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: refactoring
|
|
3
|
+
description: Code smell detection, safe refactoring patterns, large-scale restructuring
|
|
4
|
+
domain: engineering
|
|
5
|
+
subdomain: code-quality
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Refactoring
|
|
9
|
+
|
|
10
|
+
## Context
|
|
11
|
+
You are restructuring existing code — improving design without changing behavior. Apply when code smells signal structural problems, or when a large refactor needs a safe incremental strategy. Every refactoring must preserve all existing tests (green-to-green).
|
|
12
|
+
|
|
13
|
+
## Core Principles
|
|
14
|
+
|
|
15
|
+
**Smell-Driven Refactoring** (Fowler, *Refactoring*): Don't refactor by intuition. Identify a specific smell, apply the named refactoring that addresses it, then verify tests still pass. One smell, one move, one commit.
|
|
16
|
+
|
|
17
|
+
**Seams Over Rewrites** (Feathers, *Working Effectively with Legacy Code*): A seam is a place where you can alter behavior without editing the code at that point. Insert seams (interfaces, dependency injection, config flags) to make untested code testable before restructuring it.
|
|
18
|
+
|
|
19
|
+
**Mikado Method** (Ellnestam & Brolund): For entangled changes — attempt the target refactoring, note what breaks, revert, then fix prerequisites bottom-up. Build a dependency graph of changes; merge leaves first. Never push a broken intermediate state.
|
|
20
|
+
|
|
21
|
+
## Patterns
|
|
22
|
+
|
|
23
|
+
**Smell: Long Method** (>20 lines or >2 levels of nesting)
|
|
24
|
+
Extract Method — pull coherent blocks into named functions:
|
|
25
|
+
```typescript
|
|
26
|
+
// Before: 30-line handler mixing validation, logic, response
|
|
27
|
+
// After:
|
|
28
|
+
const errors = validateInput(req.body);
|
|
29
|
+
if (errors) return res.status(400).json(errors);
|
|
30
|
+
const result = processOrder(req.body);
|
|
31
|
+
return res.json(formatResponse(result));
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Smell: Large Class** (>200 lines or >5 unrelated responsibilities)
|
|
35
|
+
Extract Class — group related fields and methods into a new cohesive unit.
|
|
36
|
+
|
|
37
|
+
**Smell: Feature Envy** (method uses another class's data more than its own)
|
|
38
|
+
Move Method — relocate to the class whose data it actually needs.
|
|
39
|
+
|
|
40
|
+
**Smell: Data Clumps** (3+ fields always passed together)
|
|
41
|
+
Extract Class or introduce a Value Object:
|
|
42
|
+
```typescript
|
|
43
|
+
// Before: createUser(street, city, zip, country)
|
|
44
|
+
// After:
|
|
45
|
+
createUser(address: Address)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Smell: Primitive Obsession** (strings/numbers carrying domain meaning)
|
|
49
|
+
Replace with Value Object — `Email`, `Money`, `TaskId` instead of raw primitives. Validation lives in the constructor.
|
|
50
|
+
|
|
51
|
+
**Smell: Divergent Change** (one class changes for unrelated reasons)
|
|
52
|
+
Split into cohesive units — each class should have exactly one reason to change (SRP).
|
|
53
|
+
|
|
54
|
+
**Safe Large Refactor: Strangler Fig**
|
|
55
|
+
Wrap old module behind a new interface, redirect callers gradually, delete old code when traffic reaches zero. Never maintain two active implementations — one is always the canonical path.
|
|
56
|
+
|
|
57
|
+
**Safe Large Refactor: Seam Insertion**
|
|
58
|
+
Add an interface at the boundary between the code you want to change and its dependents. Dependents program to the interface; you swap the implementation behind it.
|
|
59
|
+
|
|
60
|
+
## Anti-patterns
|
|
61
|
+
- Big-bang rewrite — replacing a working module in one PR is the highest-risk pattern; use strangler fig instead.
|
|
62
|
+
- Refactoring without tests — if no tests exist, write characterization tests first (Feathers) to lock current behavior.
|
|
63
|
+
- Mixing refactoring with feature work in the same commit — makes rollback impossible and review confusing.
|
|
64
|
+
- Renaming everything for style consistency when only fixing one smell — scope creep undermines safety.
|
|
65
|
+
- Speculative generalization — extracting abstractions for future needs that may never arrive.
|
|
66
|
+
|
|
67
|
+
## Checklist
|
|
68
|
+
- [ ] Specific smell identified before refactoring started
|
|
69
|
+
- [ ] All existing tests pass before AND after each refactoring step
|
|
70
|
+
- [ ] No behavior change introduced (refactoring only)
|
|
71
|
+
- [ ] Each commit contains exactly one refactoring move
|
|
72
|
+
- [ ] For large refactors: incremental strategy chosen (strangler fig, seam, or mikado)
|
|
73
|
+
- [ ] Characterization tests written for any untested code before restructuring
|
|
74
|
+
|
|
75
|
+
## References
|
|
76
|
+
- *Refactoring: Improving the Design of Existing Code* — Martin Fowler
|
|
77
|
+
- *Working Effectively with Legacy Code* — Michael Feathers
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security
|
|
3
|
+
description: Auth, vulnerabilities, permissions, trust levels, hardening
|
|
4
|
+
domain: engineering
|
|
5
|
+
subdomain: security
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Security
|
|
9
|
+
|
|
10
|
+
## Context
|
|
11
|
+
You are working on security-sensitive code: authentication, authorization, input handling, or trust boundaries. Apply defense in depth — validate at every layer, store secrets safely, and model threats before writing code.
|
|
12
|
+
|
|
13
|
+
## Core Principles
|
|
14
|
+
|
|
15
|
+
**Validate at System Boundaries** (Anderson, *Security Engineering*): Trust nothing that crosses a trust boundary. Validate and sanitize all external input — user input, API payloads, webhook bodies, file paths — before passing it inward. Internal calls between trusted modules do not need re-validation.
|
|
16
|
+
|
|
17
|
+
**OWASP Top 10 → Code Patterns** (OWASP Foundation, *OWASP Top 10*):
|
|
18
|
+
- Injection → parameterized queries, never string-concatenated SQL
|
|
19
|
+
- Broken authentication → short-lived tokens (≤1h) + rotation; httpOnly cookies, not localStorage
|
|
20
|
+
- XSS → Content-Security-Policy headers + output encoding; never `innerHTML = userInput`
|
|
21
|
+
- Broken access control → deny by default; check permissions before every data access
|
|
22
|
+
|
|
23
|
+
**Threat Modeling 4-Question Checklist** (Shostack, *Threat Modeling*): Before implementing auth/permissions code, ask: (1) What are we building? (2) What can go wrong? (3) What do we do about it? (4) Did we do a good job? Document answers in a comment or ADR.
|
|
24
|
+
|
|
25
|
+
**Least Privilege Per Layer**: Each service, agent, and DB role gets minimum required permissions. An agent that reads tasks must not have write access to secrets. Escalate explicitly, not by default.
|
|
26
|
+
|
|
27
|
+
**Defense in Depth** (Anderson, *Security Engineering*): No single control is sufficient. Layer validation + parameterized queries + least privilege + audit logging. Assume any one layer can fail.
|
|
28
|
+
|
|
29
|
+
## Patterns
|
|
30
|
+
|
|
31
|
+
**Parameterized query (never concatenate):**
|
|
32
|
+
```typescript
|
|
33
|
+
// Safe
|
|
34
|
+
const stmt = db.prepare('SELECT * FROM users WHERE id = ?');
|
|
35
|
+
const user = stmt.get(userId);
|
|
36
|
+
|
|
37
|
+
// Unsafe — never do this
|
|
38
|
+
const user = db.exec(`SELECT * FROM users WHERE id = '${userId}'`);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Short-lived token + rotation:**
|
|
42
|
+
```typescript
|
|
43
|
+
// Issue token with short TTL; refresh before expiry
|
|
44
|
+
const token = jwt.sign({ sub: userId }, secret, { expiresIn: '1h' });
|
|
45
|
+
// Store in httpOnly cookie, not localStorage
|
|
46
|
+
res.cookie('token', token, { httpOnly: true, secure: true, sameSite: 'strict' });
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**CSP header + output encoding:**
|
|
50
|
+
```typescript
|
|
51
|
+
res.setHeader("Content-Security-Policy", "default-src 'self'");
|
|
52
|
+
// Encode before rendering user content
|
|
53
|
+
const safe = escapeHtml(userInput); // never innerHTML = userInput
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Anti-patterns
|
|
57
|
+
- Logging secrets, tokens, or API keys — even partial values leak.
|
|
58
|
+
- Trusting agent-supplied file paths without validation — path traversal risk.
|
|
59
|
+
- `localStorage` for session tokens — accessible to XSS.
|
|
60
|
+
- Hardcoded credentials anywhere in the codebase.
|
|
61
|
+
- Running agents with `high` trust by default — explicit escalation only.
|
|
62
|
+
- Catching and swallowing auth errors silently.
|
|
63
|
+
|
|
64
|
+
## Checklist
|
|
65
|
+
- [ ] All user/agent input validated with zod at the boundary
|
|
66
|
+
- [ ] SQL queries use prepared statements
|
|
67
|
+
- [ ] Secrets in environment variables only — not in code or logs
|
|
68
|
+
- [ ] File paths validated against allowed directories
|
|
69
|
+
- [ ] Tokens short-lived (≤1h) and stored in httpOnly cookies
|
|
70
|
+
- [ ] CSP headers set on all HTML responses
|
|
71
|
+
- [ ] Trust level explicitly set per agent/service — not defaulted
|
|
72
|
+
|
|
73
|
+
## References
|
|
74
|
+
- *Security Engineering* — Ross Anderson
|
|
75
|
+
- *OWASP Top 10* — OWASP Foundation
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testing
|
|
3
|
+
description: Test strategy, Vitest patterns, mocking, coverage
|
|
4
|
+
domain: engineering
|
|
5
|
+
subdomain: testing
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Testing
|
|
9
|
+
|
|
10
|
+
## Context
|
|
11
|
+
You are writing or improving tests. Use Vitest as the test runner. Apply the test pyramid ratios, use precise test doubles (not blanket mocks), and follow TDD when adding new behavior.
|
|
12
|
+
|
|
13
|
+
## Core Principles
|
|
14
|
+
|
|
15
|
+
**Test Pyramid** (Fowler, cited in *xUnit Test Patterns*): Aim for ~70% unit / ~20% integration / ~10% e2e. Heavy e2e suites are slow and brittle; over-mocked unit tests miss integration bugs. Balance matters.
|
|
16
|
+
|
|
17
|
+
**Test Double Taxonomy** (Meszaros, *xUnit Test Patterns*): Use the right double for the job — **stub** (returns canned data, no assertions), **spy** (records calls for after-the-fact assertions), **mock** (expectations set upfront, verified on call), **fake** (working lightweight implementation, e.g. in-memory DB). Overusing mocks couples tests to implementation.
|
|
18
|
+
|
|
19
|
+
**Listen to the Tests** (Freeman & Pryce, *Growing Object-Oriented Software, Guided by Tests*): Hard-to-test code signals bad design. Painful DI = missing abstraction. Deep nesting = missing object. Let test pain guide refactoring.
|
|
20
|
+
|
|
21
|
+
**Property-Based Testing Trigger**: When a function processes unbounded input (parsers, encoders, validators), write at least one property test: for all valid inputs, invariants hold (e.g., `encode(decode(x)) === x`).
|
|
22
|
+
|
|
23
|
+
**Isolation as a Constraint**: Each test must pass when run alone (`vitest run <file>`). If it depends on test order, there is shared mutable state to fix.
|
|
24
|
+
|
|
25
|
+
## Patterns
|
|
26
|
+
|
|
27
|
+
**Arrange-Act-Assert with descriptive names:**
|
|
28
|
+
```typescript
|
|
29
|
+
it('should return NotFoundError when task id does not exist', () => {
|
|
30
|
+
// Arrange
|
|
31
|
+
const repo = createTaskRepo({ db: createDatabase(':memory:') });
|
|
32
|
+
// Act
|
|
33
|
+
const result = repo.findById('nonexistent-id');
|
|
34
|
+
// Assert
|
|
35
|
+
expect(result).toBeInstanceOf(NotFoundError);
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Spy vs stub distinction:**
|
|
40
|
+
```typescript
|
|
41
|
+
const notifySpy = vi.fn(); // spy: assert it was called
|
|
42
|
+
const getUser = vi.fn().mockReturnValue({ id: '1' }); // stub: returns canned data
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Fake for DB isolation:**
|
|
46
|
+
```typescript
|
|
47
|
+
// Fake: real SQL, but in-memory — no mocking internals
|
|
48
|
+
const db = createDatabase(':memory:');
|
|
49
|
+
runMigrations(db);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Anti-patterns
|
|
53
|
+
- Testing private methods or internal state — test through the public interface only.
|
|
54
|
+
- Shared mutable state between tests — always reset in `beforeEach`.
|
|
55
|
+
- Mocking the module under test — if you need to mock it, it shouldn't be under test.
|
|
56
|
+
- `test.skip` left in production code — fix or delete.
|
|
57
|
+
- Snapshots for logic tests — use explicit assertions; snapshots are for serialized output only.
|
|
58
|
+
|
|
59
|
+
## Checklist
|
|
60
|
+
- [ ] Every new function has happy-path + error-path test
|
|
61
|
+
- [ ] Mocks/spies reset in `beforeEach` or `afterEach`
|
|
62
|
+
- [ ] No test depends on another test's state
|
|
63
|
+
- [ ] Temp files and in-memory DBs cleaned up after each test
|
|
64
|
+
- [ ] Correct double type used: stub/spy/mock/fake — not blanket `vi.mock`
|
|
65
|
+
- [ ] `vitest run <file>` passes in isolation
|
|
66
|
+
|
|
67
|
+
## References
|
|
68
|
+
- *xUnit Test Patterns* — Gerard Meszaros
|
|
69
|
+
- *Growing Object-Oriented Software, Guided by Tests* — Steve Freeman & Nat Pryce
|