timsquad 2.1.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +288 -0
- package/README.md +170 -763
- package/dist/commands/compile.d.ts +3 -0
- package/dist/commands/compile.d.ts.map +1 -0
- package/dist/commands/compile.js +170 -0
- package/dist/commands/compile.js.map +1 -0
- package/dist/commands/daemon.d.ts +7 -0
- package/dist/commands/daemon.d.ts.map +1 -0
- package/dist/commands/daemon.js +229 -0
- package/dist/commands/daemon.js.map +1 -0
- package/dist/commands/feedback.d.ts +9 -0
- package/dist/commands/feedback.d.ts.map +1 -1
- package/dist/commands/feedback.js +235 -14
- package/dist/commands/feedback.js.map +1 -1
- package/dist/commands/full.js +2 -2
- package/dist/commands/full.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +118 -22
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/knowledge.d.ts +3 -0
- package/dist/commands/knowledge.d.ts.map +1 -0
- package/dist/commands/knowledge.js +316 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/log.d.ts +27 -0
- package/dist/commands/log.d.ts.map +1 -1
- package/dist/commands/log.js +965 -0
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/meta-index.d.ts +3 -0
- package/dist/commands/meta-index.d.ts.map +1 -0
- package/dist/commands/meta-index.js +401 -0
- package/dist/commands/meta-index.js.map +1 -0
- package/dist/commands/metrics.d.ts.map +1 -1
- package/dist/commands/metrics.js +239 -4
- package/dist/commands/metrics.js.map +1 -1
- package/dist/commands/retro.js +154 -6
- package/dist/commands/retro.js.map +1 -1
- package/dist/commands/skills.d.ts +12 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +231 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/upgrade.d.ts +8 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +292 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/workflow.d.ts +3 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +607 -0
- package/dist/commands/workflow.js.map +1 -0
- package/dist/daemon/context-writer.d.ts +16 -0
- package/dist/daemon/context-writer.d.ts.map +1 -0
- package/dist/daemon/context-writer.js +35 -0
- package/dist/daemon/context-writer.js.map +1 -0
- package/dist/daemon/entry.d.ts +7 -0
- package/dist/daemon/entry.d.ts.map +1 -0
- package/dist/daemon/entry.js +17 -0
- package/dist/daemon/entry.js.map +1 -0
- package/dist/daemon/event-queue.d.ts +52 -0
- package/dist/daemon/event-queue.d.ts.map +1 -0
- package/dist/daemon/event-queue.js +255 -0
- package/dist/daemon/event-queue.js.map +1 -0
- package/dist/daemon/file-watcher.d.ts +19 -0
- package/dist/daemon/file-watcher.d.ts.map +1 -0
- package/dist/daemon/file-watcher.js +87 -0
- package/dist/daemon/file-watcher.js.map +1 -0
- package/dist/daemon/index.d.ts +29 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +296 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/jsonl-watcher.d.ts +49 -0
- package/dist/daemon/jsonl-watcher.d.ts.map +1 -0
- package/dist/daemon/jsonl-watcher.js +258 -0
- package/dist/daemon/jsonl-watcher.js.map +1 -0
- package/dist/daemon/meta-cache.d.ts +63 -0
- package/dist/daemon/meta-cache.d.ts.map +1 -0
- package/dist/daemon/meta-cache.js +249 -0
- package/dist/daemon/meta-cache.js.map +1 -0
- package/dist/daemon/session-state.d.ts +19 -0
- package/dist/daemon/session-state.d.ts.map +1 -0
- package/dist/daemon/session-state.js +132 -0
- package/dist/daemon/session-state.js.map +1 -0
- package/dist/daemon/shutdown.d.ts +21 -0
- package/dist/daemon/shutdown.d.ts.map +1 -0
- package/dist/daemon/shutdown.js +164 -0
- package/dist/daemon/shutdown.js.map +1 -0
- package/dist/index.js +24 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-composer.d.ts +38 -0
- package/dist/lib/agent-composer.d.ts.map +1 -0
- package/dist/lib/agent-composer.js +128 -0
- package/dist/lib/agent-composer.js.map +1 -0
- package/dist/lib/agent-generator.d.ts +22 -0
- package/dist/lib/agent-generator.d.ts.map +1 -0
- package/dist/lib/agent-generator.js +150 -0
- package/dist/lib/agent-generator.js.map +1 -0
- package/dist/lib/ast-parser.d.ts +11 -0
- package/dist/lib/ast-parser.d.ts.map +1 -0
- package/dist/lib/ast-parser.js +282 -0
- package/dist/lib/ast-parser.js.map +1 -0
- package/dist/lib/compile-rules.d.ts +66 -0
- package/dist/lib/compile-rules.d.ts.map +1 -0
- package/dist/lib/compile-rules.js +114 -0
- package/dist/lib/compile-rules.js.map +1 -0
- package/dist/lib/compiler.d.ts +105 -0
- package/dist/lib/compiler.d.ts.map +1 -0
- package/dist/lib/compiler.js +368 -0
- package/dist/lib/compiler.js.map +1 -0
- package/dist/lib/config.d.ts +7 -2
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +34 -3
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/meta-index.d.ts +19 -0
- package/dist/lib/meta-index.d.ts.map +1 -0
- package/dist/lib/meta-index.js +573 -0
- package/dist/lib/meta-index.js.map +1 -0
- package/dist/lib/project.js +1 -1
- package/dist/lib/project.js.map +1 -1
- package/dist/lib/skill-generator.d.ts +32 -0
- package/dist/lib/skill-generator.d.ts.map +1 -0
- package/dist/lib/skill-generator.js +187 -0
- package/dist/lib/skill-generator.js.map +1 -0
- package/dist/lib/template.d.ts +16 -2
- package/dist/lib/template.d.ts.map +1 -1
- package/dist/lib/template.js +115 -20
- package/dist/lib/template.js.map +1 -1
- package/dist/lib/ui-index.d.ts +12 -0
- package/dist/lib/ui-index.d.ts.map +1 -0
- package/dist/lib/ui-index.js +239 -0
- package/dist/lib/ui-index.js.map +1 -0
- package/dist/lib/ui-parser.d.ts +12 -0
- package/dist/lib/ui-parser.d.ts.map +1 -0
- package/dist/lib/ui-parser.js +472 -0
- package/dist/lib/ui-parser.js.map +1 -0
- package/dist/lib/update-check.d.ts +6 -0
- package/dist/lib/update-check.d.ts.map +1 -0
- package/dist/lib/update-check.js +121 -0
- package/dist/lib/update-check.js.map +1 -0
- package/dist/lib/upgrade-backup.d.ts +33 -0
- package/dist/lib/upgrade-backup.d.ts.map +1 -0
- package/dist/lib/upgrade-backup.js +101 -0
- package/dist/lib/upgrade-backup.js.map +1 -0
- package/dist/lib/version.d.ts +19 -0
- package/dist/lib/version.d.ts.map +1 -0
- package/dist/lib/version.js +35 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/lib/workflow-state.d.ts +48 -0
- package/dist/lib/workflow-state.d.ts.map +1 -0
- package/dist/lib/workflow-state.js +67 -0
- package/dist/lib/workflow-state.js.map +1 -0
- package/dist/types/config.d.ts +103 -2
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +184 -9
- package/dist/types/config.js.map +1 -1
- package/dist/types/feedback.d.ts +7 -0
- package/dist/types/feedback.d.ts.map +1 -1
- package/dist/types/feedback.js +1 -1
- package/dist/types/feedback.js.map +1 -1
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/meta-index.d.ts +146 -0
- package/dist/types/meta-index.d.ts.map +1 -0
- package/dist/types/meta-index.js +7 -0
- package/dist/types/meta-index.js.map +1 -0
- package/dist/types/project.d.ts +19 -3
- package/dist/types/project.d.ts.map +1 -1
- package/dist/types/project.js +23 -0
- package/dist/types/project.js.map +1 -1
- package/dist/types/task-log.d.ts +208 -0
- package/dist/types/task-log.d.ts.map +1 -0
- package/dist/types/task-log.js +6 -0
- package/dist/types/task-log.js.map +1 -0
- package/dist/types/ui-meta.d.ts +118 -0
- package/dist/types/ui-meta.d.ts.map +1 -0
- package/dist/types/ui-meta.js +7 -0
- package/dist/types/ui-meta.js.map +1 -0
- package/package.json +12 -4
- package/templates/base/agents/base/tsq-architect.md +68 -0
- package/templates/base/agents/base/tsq-dba.md +56 -0
- package/templates/base/agents/base/tsq-designer.md +72 -0
- package/templates/base/agents/base/tsq-developer.md +67 -0
- package/templates/base/agents/base/tsq-qa.md +55 -0
- package/templates/base/agents/base/tsq-security.md +65 -0
- package/templates/base/agents/overlays/domain/general-web/_common.md +11 -0
- package/templates/base/agents/overlays/domain/mobile/_common.md +13 -0
- package/templates/base/agents/overlays/platform/claude-code.md +12 -0
- package/templates/base/config.template.yaml +213 -0
- package/templates/base/knowledge/checklists/accessibility.md +37 -0
- package/templates/base/knowledge/checklists/architecture-review.md +28 -0
- package/templates/base/knowledge/checklists/database-standards.md +84 -0
- package/templates/base/knowledge/checklists/design-reference.md +97 -0
- package/templates/base/knowledge/checklists/security.md +50 -0
- package/templates/base/knowledge/checklists/ssot-validation.md +19 -0
- package/templates/base/knowledge/domains/_template.md +16 -0
- package/templates/base/knowledge/platforms/_template.md +16 -0
- package/templates/base/knowledge/templates/sequence-report.md +44 -0
- package/templates/base/knowledge/templates/task-result.md +105 -0
- package/templates/base/skills/_template/SKILL.md +59 -0
- package/templates/base/skills/_template/references/_template.md +35 -0
- package/templates/base/skills/_template/rules/_sections.md +34 -0
- package/templates/base/skills/_template/rules/_template.md +32 -0
- package/templates/base/skills/_template/scripts/_template.sh +31 -0
- package/templates/base/skills/architecture/SKILL.md +54 -0
- package/templates/base/skills/architecture/references/adr-template.md +50 -0
- package/templates/base/skills/architecture/references/api-design.md +64 -0
- package/templates/base/skills/backend/node/SKILL.md +81 -0
- package/templates/base/skills/backend/node/rules/async-patterns.md +81 -0
- package/templates/base/skills/backend/node/rules/deployment.md +33 -0
- package/templates/base/skills/backend/node/rules/env-config.md +41 -0
- package/templates/base/skills/backend/node/rules/error-handling.md +83 -0
- package/templates/base/skills/backend/node/rules/hono-app-setup.md +98 -0
- package/templates/base/skills/backend/node/rules/jwt-auth.md +76 -0
- package/templates/base/skills/backend/node/rules/middleware.md +56 -0
- package/templates/base/skills/backend/node/rules/testing.md +82 -0
- package/templates/base/skills/coding/SKILL.md +47 -0
- package/templates/base/skills/coding/rules/patterns.md +81 -0
- package/templates/base/skills/controller/SKILL.md +111 -0
- package/templates/base/skills/controller/references/README.md +35 -0
- package/templates/base/skills/controller/rules/README.md +18 -0
- package/templates/base/skills/database/SKILL.md +98 -0
- package/templates/base/skills/database/prisma/SKILL.md +57 -0
- package/templates/base/skills/database/prisma/rules/queries.md +133 -0
- package/templates/base/skills/database/prisma/rules/schema-design.md +80 -0
- package/templates/base/skills/frontend/nextjs/SKILL.md +59 -0
- package/templates/base/skills/frontend/nextjs/rules/app-router.md +138 -0
- package/templates/base/skills/frontend/react/SKILL.md +86 -0
- package/templates/base/skills/frontend/react/rules/_sections.md +88 -0
- package/templates/base/skills/frontend/react/rules/anti-patterns.md +67 -0
- package/templates/base/skills/frontend/react/rules/async-api-routes.md +38 -0
- package/templates/base/skills/frontend/react/rules/async-defer-await.md +80 -0
- package/templates/base/skills/frontend/react/rules/async-dependencies.md +36 -0
- package/templates/base/skills/frontend/react/rules/async-parallel.md +28 -0
- package/templates/base/skills/frontend/react/rules/async-suspense-boundaries.md +99 -0
- package/templates/base/skills/frontend/react/rules/bundle-barrel-imports.md +59 -0
- package/templates/base/skills/frontend/react/rules/bundle-defer-third-party.md +49 -0
- package/templates/base/skills/frontend/react/rules/bundle-dynamic-imports.md +35 -0
- package/templates/base/skills/frontend/react/rules/component-conventions.md +74 -0
- package/templates/base/skills/frontend/react/rules/js-combine-iterations.md +32 -0
- package/templates/base/skills/frontend/react/rules/js-early-exit.md +50 -0
- package/templates/base/skills/frontend/react/rules/js-index-maps.md +37 -0
- package/templates/base/skills/frontend/react/rules/js-set-map-lookups.md +24 -0
- package/templates/base/skills/frontend/react/rules/rendering-conditional-render.md +40 -0
- package/templates/base/skills/frontend/react/rules/rendering-content-visibility.md +38 -0
- package/templates/base/skills/frontend/react/rules/rendering-hoist-jsx.md +46 -0
- package/templates/base/skills/frontend/react/rules/rerender-defer-reads.md +39 -0
- package/templates/base/skills/frontend/react/rules/rerender-derived-state.md +29 -0
- package/templates/base/skills/frontend/react/rules/rerender-memo.md +44 -0
- package/templates/base/skills/frontend/react/rules/rerender-transitions.md +40 -0
- package/templates/base/skills/frontend/react/rules/server-after-nonblocking.md +73 -0
- package/templates/base/skills/frontend/react/rules/server-cache-react.md +26 -0
- package/templates/base/skills/frontend/react/rules/server-parallel-fetching.md +79 -0
- package/templates/base/skills/frontend/react/rules/state-location.md +55 -0
- package/templates/base/skills/methodology/bdd/SKILL.md +69 -0
- package/templates/base/skills/methodology/bdd/rules/gherkin-patterns.md +113 -0
- package/templates/base/skills/methodology/ddd/SKILL.md +74 -0
- package/templates/base/skills/methodology/ddd/rules/strategic-patterns.md +98 -0
- package/templates/base/skills/methodology/debugging/SKILL.md +60 -0
- package/templates/base/skills/methodology/debugging/references/root-cause-tracing.md +84 -0
- package/templates/base/skills/methodology/tdd/SKILL.md +66 -0
- package/templates/base/skills/methodology/tdd/rules/real-world-example.md +88 -0
- package/templates/base/skills/methodology/tdd/rules/techniques.md +185 -0
- package/templates/base/skills/mobile/dart/SKILL.md +69 -0
- package/templates/base/skills/mobile/dart/rules/async-patterns.md +112 -0
- package/templates/base/skills/mobile/dart/rules/code-style.md +96 -0
- package/templates/base/skills/mobile/dart/rules/null-safety.md +84 -0
- package/templates/base/skills/mobile/dart/rules/type-system.md +111 -0
- package/templates/base/skills/mobile/flutter/SKILL.md +89 -0
- package/templates/base/skills/mobile/flutter/ci-cd/SKILL.md +82 -0
- package/templates/base/skills/mobile/flutter/ci-cd/references/ci-cd-pipeline.md +314 -0
- package/templates/base/skills/mobile/flutter/ci-cd/rules/code-signing.md +106 -0
- package/templates/base/skills/mobile/flutter/ci-cd/rules/codemagic-setup.md +116 -0
- package/templates/base/skills/mobile/flutter/ci-cd/rules/fastlane-setup.md +105 -0
- package/templates/base/skills/mobile/flutter/ci-cd/rules/github-actions.md +112 -0
- package/templates/base/skills/mobile/flutter/ci-cd/rules/store-deployment.md +106 -0
- package/templates/base/skills/mobile/flutter/ci-cd/rules/versioning.md +107 -0
- package/templates/base/skills/mobile/flutter/i18n/SKILL.md +78 -0
- package/templates/base/skills/mobile/flutter/i18n/references/i18n-architecture.md +225 -0
- package/templates/base/skills/mobile/flutter/i18n/rules/arb-files.md +182 -0
- package/templates/base/skills/mobile/flutter/i18n/rules/locale-switching.md +226 -0
- package/templates/base/skills/mobile/flutter/i18n/rules/localization-setup.md +137 -0
- package/templates/base/skills/mobile/flutter/i18n/rules/plural-gender.md +159 -0
- package/templates/base/skills/mobile/flutter/i18n/rules/text-direction.md +199 -0
- package/templates/base/skills/mobile/flutter/monitoring/SKILL.md +81 -0
- package/templates/base/skills/mobile/flutter/monitoring/references/monitoring-architecture.md +269 -0
- package/templates/base/skills/mobile/flutter/monitoring/rules/analytics.md +227 -0
- package/templates/base/skills/mobile/flutter/monitoring/rules/crashlytics-setup.md +195 -0
- package/templates/base/skills/mobile/flutter/monitoring/rules/logging.md +258 -0
- package/templates/base/skills/mobile/flutter/monitoring/rules/performance-monitoring.md +248 -0
- package/templates/base/skills/mobile/flutter/monitoring/rules/sentry-integration.md +249 -0
- package/templates/base/skills/mobile/flutter/networking/SKILL.md +88 -0
- package/templates/base/skills/mobile/flutter/networking/references/api-client-architecture.md +305 -0
- package/templates/base/skills/mobile/flutter/networking/rules/caching.md +212 -0
- package/templates/base/skills/mobile/flutter/networking/rules/connectivity.md +213 -0
- package/templates/base/skills/mobile/flutter/networking/rules/dio-setup.md +159 -0
- package/templates/base/skills/mobile/flutter/networking/rules/error-handling.md +209 -0
- package/templates/base/skills/mobile/flutter/networking/rules/interceptors.md +205 -0
- package/templates/base/skills/mobile/flutter/networking/rules/retrofit-patterns.md +194 -0
- package/templates/base/skills/mobile/flutter/push-notifications/SKILL.md +87 -0
- package/templates/base/skills/mobile/flutter/push-notifications/references/notification-architecture.md +340 -0
- package/templates/base/skills/mobile/flutter/push-notifications/references/platform-setup.md +286 -0
- package/templates/base/skills/mobile/flutter/push-notifications/rules/background-processing.md +308 -0
- package/templates/base/skills/mobile/flutter/push-notifications/rules/deep-linking.md +217 -0
- package/templates/base/skills/mobile/flutter/push-notifications/rules/fcm-setup.md +164 -0
- package/templates/base/skills/mobile/flutter/push-notifications/rules/local-notifications.md +262 -0
- package/templates/base/skills/mobile/flutter/push-notifications/rules/notification-handling.md +210 -0
- package/templates/base/skills/mobile/flutter/push-notifications/rules/notification-permissions.md +246 -0
- package/templates/base/skills/mobile/flutter/push-notifications/rules/rich-notifications.md +320 -0
- package/templates/base/skills/mobile/flutter/references/freezed-patterns.md +162 -0
- package/templates/base/skills/mobile/flutter/references/project-structure.md +170 -0
- package/templates/base/skills/mobile/flutter/rules/animations.md +112 -0
- package/templates/base/skills/mobile/flutter/rules/architecture.md +121 -0
- package/templates/base/skills/mobile/flutter/rules/navigation-routing.md +117 -0
- package/templates/base/skills/mobile/flutter/rules/performance.md +112 -0
- package/templates/base/skills/mobile/flutter/rules/platform-adaptive.md +126 -0
- package/templates/base/skills/mobile/flutter/rules/state-management.md +110 -0
- package/templates/base/skills/mobile/flutter/rules/testing.md +131 -0
- package/templates/base/skills/mobile/flutter/rules/widget-conventions.md +122 -0
- package/templates/base/skills/mobile/flutter/security/SKILL.md +86 -0
- package/templates/base/skills/mobile/flutter/security/references/mobile-security-checklist.md +168 -0
- package/templates/base/skills/mobile/flutter/security/rules/api-key-protection.md +206 -0
- package/templates/base/skills/mobile/flutter/security/rules/authentication.md +248 -0
- package/templates/base/skills/mobile/flutter/security/rules/data-protection.md +271 -0
- package/templates/base/skills/mobile/flutter/security/rules/obfuscation.md +213 -0
- package/templates/base/skills/mobile/flutter/security/rules/secure-storage.md +171 -0
- package/templates/base/skills/mobile/flutter/security/rules/ssl-pinning.md +197 -0
- package/templates/base/skills/planning/SKILL.md +58 -0
- package/templates/base/skills/planning/references/prd-guide.md +47 -0
- package/templates/base/skills/planning/references/requirements-guide.md +46 -0
- package/templates/base/skills/prompt-engineering/SKILL.md +103 -0
- package/templates/base/skills/retrospective/SKILL.md +102 -0
- package/templates/base/skills/security/SKILL.md +55 -0
- package/templates/base/skills/security/rules/owasp-examples.md +119 -0
- package/templates/base/skills/security/scripts/check-secrets.sh +55 -0
- package/templates/base/skills/testing/SKILL.md +63 -0
- package/templates/base/skills/testing/references/testing-patterns.md +103 -0
- package/templates/base/skills/tsq-protocol/SKILL.md +51 -0
- package/templates/base/skills/typescript/SKILL.md +67 -0
- package/templates/base/skills/typescript/rules/type-patterns.md +135 -0
- package/templates/base/skills/typescript/rules/utility-types.md +76 -0
- package/templates/base/skills/ui-design/SKILL.md +70 -0
- package/templates/{common → base}/timsquad/feedback/routing-rules.yaml +1 -1
- package/templates/{common → base}/timsquad/retrospective/metrics/metrics-schema.json +46 -1
- package/templates/platforms/claude-code/CLAUDE.md.template +89 -0
- package/templates/platforms/claude-code/rules/adr-rules.md +32 -0
- package/templates/platforms/claude-code/rules/feedback-routing.md +18 -0
- package/templates/platforms/claude-code/rules/phase-management.md +23 -0
- package/templates/platforms/claude-code/rules/reporting-format.md +26 -0
- package/templates/platforms/claude-code/rules/sequence-management.md +72 -0
- package/templates/platforms/claude-code/rules/workspace-sync.md +33 -0
- package/templates/platforms/claude-code/scripts/completion-guard.sh +57 -0
- package/templates/platforms/claude-code/scripts/phase-guard.sh +79 -0
- package/templates/platforms/claude-code/settings.json +98 -0
- package/templates/project-types/api-backend/config.yaml +227 -0
- package/templates/project-types/api-backend/process/workflow.xml +214 -0
- package/templates/project-types/fintech/config.yaml +151 -0
- package/templates/project-types/fintech/process/workflow.xml +316 -0
- package/templates/project-types/infra/config.yaml +327 -0
- package/templates/project-types/infra/process/workflow.xml +296 -0
- package/templates/project-types/mobile-app/config.yaml +123 -0
- package/templates/project-types/mobile-app/process/workflow.xml +191 -0
- package/templates/project-types/platform/config.yaml +254 -0
- package/templates/project-types/platform/process/workflow.xml +254 -0
- package/templates/project-types/web-app/config.yaml +198 -0
- package/templates/project-types/web-app/process/workflow.xml +210 -0
- package/templates/project-types/web-service/config.yaml +136 -0
- package/templates/project-types/web-service/process/workflow.xml +184 -0
- package/templates/common/CLAUDE.md.template +0 -254
- package/templates/common/claude/agents/tsq-dba.md +0 -311
- package/templates/common/claude/agents/tsq-designer.md +0 -323
- package/templates/common/claude/agents/tsq-developer.md +0 -177
- package/templates/common/claude/agents/tsq-planner.md +0 -190
- package/templates/common/claude/agents/tsq-prompter.md +0 -356
- package/templates/common/claude/agents/tsq-qa.md +0 -168
- package/templates/common/claude/agents/tsq-retro.md +0 -193
- package/templates/common/claude/agents/tsq-security.md +0 -221
- package/templates/common/claude/hooks/auto-metrics.sh +0 -165
- package/templates/common/claude/hooks/auto-worklog.sh +0 -245
- package/templates/common/claude/hooks/event-logger.sh +0 -208
- package/templates/common/claude/settings.json +0 -86
- package/templates/common/claude/skills/architecture/SKILL.md +0 -123
- package/templates/common/claude/skills/backend/node/SKILL.md +0 -1015
- package/templates/common/claude/skills/coding/SKILL.md +0 -171
- package/templates/common/claude/skills/database/prisma/SKILL.md +0 -357
- package/templates/common/claude/skills/frontend/nextjs/SKILL.md +0 -279
- package/templates/common/claude/skills/frontend/react/SKILL.md +0 -1729
- package/templates/common/claude/skills/methodology/bdd/SKILL.md +0 -234
- package/templates/common/claude/skills/methodology/ddd/SKILL.md +0 -311
- package/templates/common/claude/skills/methodology/tdd/SKILL.md +0 -512
- package/templates/common/claude/skills/planning/SKILL.md +0 -90
- package/templates/common/claude/skills/security/SKILL.md +0 -234
- package/templates/common/claude/skills/testing/SKILL.md +0 -146
- package/templates/common/claude/skills/typescript/SKILL.md +0 -435
- package/templates/common/config.template.yaml +0 -132
- /package/templates/{common → base}/timsquad/architectures/clean/ARCHITECTURE.md +0 -0
- /package/templates/{common → base}/timsquad/architectures/clean/backend.xml +0 -0
- /package/templates/{common → base}/timsquad/architectures/clean/frontend.xml +0 -0
- /package/templates/{common → base}/timsquad/architectures/fsd/ARCHITECTURE.md +0 -0
- /package/templates/{common → base}/timsquad/architectures/fsd/frontend.xml +0 -0
- /package/templates/{common → base}/timsquad/architectures/hexagonal/ARCHITECTURE.md +0 -0
- /package/templates/{common → base}/timsquad/architectures/hexagonal/backend.xml +0 -0
- /package/templates/{common → base}/timsquad/constraints/competency-framework.xml +0 -0
- /package/templates/{common → base}/timsquad/constraints/ssot-schema.xml +0 -0
- /package/templates/{common → base}/timsquad/feedback/feedback-router.sh +0 -0
- /package/templates/{common → base}/timsquad/generators/data-design.xml +0 -0
- /package/templates/{common → base}/timsquad/generators/prd.xml +0 -0
- /package/templates/{common → base}/timsquad/generators/requirements.xml +0 -0
- /package/templates/{common → base}/timsquad/generators/service-spec.xml +0 -0
- /package/templates/{common → base}/timsquad/logs/_example.md +0 -0
- /package/templates/{common → base}/timsquad/logs/_template.md +0 -0
- /package/templates/{common → base}/timsquad/patterns/cqrs.xml +0 -0
- /package/templates/{common → base}/timsquad/patterns/event-sourcing.xml +0 -0
- /package/templates/{common → base}/timsquad/patterns/repository.xml +0 -0
- /package/templates/{common → base}/timsquad/process/phase-checklist.yaml +0 -0
- /package/templates/{common → base}/timsquad/process/state-machine.xml +0 -0
- /package/templates/{common → base}/timsquad/process/validation-rules.xml +0 -0
- /package/templates/{common → base}/timsquad/process/workflow-base.xml +0 -0
- /package/templates/{common → base}/timsquad/retrospective/cycle-report.template.md +0 -0
- /package/templates/{common → base}/timsquad/retrospective/patterns/failure-patterns.md +0 -0
- /package/templates/{common → base}/timsquad/retrospective/patterns/success-patterns.md +0 -0
- /package/templates/{common → base}/timsquad/retrospective/retrospective-config.xml +0 -0
- /package/templates/{common → base}/timsquad/retrospective/retrospective-state.xml +0 -0
- /package/templates/{common → base}/timsquad/ssot/adr/ADR-000-template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/adr/ADR-001-example.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/data-design.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/deployment-spec.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/env-config.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/error-codes.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/functional-spec.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/glossary.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/integration-spec.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/planning.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/prd.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/requirements.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/security-spec.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/service-spec.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/test-spec.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/ui-ux-spec.template.md +0 -0
- /package/templates/{common → base}/timsquad/state/workspace.xml +0 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: OWASP Top 10 Security Patterns
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
tags: security, owasp, vulnerability
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# OWASP Top 10 — 코드 예시
|
|
8
|
+
|
|
9
|
+
## 1. Injection
|
|
10
|
+
```typescript
|
|
11
|
+
// Bad
|
|
12
|
+
const query = `SELECT * FROM users WHERE email = '${email}'`;
|
|
13
|
+
|
|
14
|
+
// Good: Parameterized Query
|
|
15
|
+
const query = 'SELECT * FROM users WHERE email = $1';
|
|
16
|
+
await db.query(query, [email]);
|
|
17
|
+
// Good: ORM 사용
|
|
18
|
+
await userRepository.findOne({ where: { email } });
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 2. Broken Authentication
|
|
22
|
+
```typescript
|
|
23
|
+
// Bad
|
|
24
|
+
if (password.length >= 4) { ... }
|
|
25
|
+
|
|
26
|
+
// Good
|
|
27
|
+
const passwordPolicy = {
|
|
28
|
+
minLength: 12, requireUppercase: true, requireLowercase: true,
|
|
29
|
+
requireNumber: true, requireSpecialChar: true,
|
|
30
|
+
};
|
|
31
|
+
const hash = await bcrypt.hash(password, 12);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 3. Sensitive Data Exposure
|
|
35
|
+
```typescript
|
|
36
|
+
// Bad
|
|
37
|
+
logger.info('User login', { email, password });
|
|
38
|
+
return { ...user }; // passwordHash 포함
|
|
39
|
+
|
|
40
|
+
// Good
|
|
41
|
+
logger.info('User login', { email, password: '***' });
|
|
42
|
+
return userToDto(user); // passwordHash 제외
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 5. Broken Access Control
|
|
46
|
+
```typescript
|
|
47
|
+
// Bad
|
|
48
|
+
app.get('/api/users/:id', async (req, res) => {
|
|
49
|
+
const user = await userService.getUser(req.params.id);
|
|
50
|
+
return res.json(user);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Good
|
|
54
|
+
app.get('/api/users/:id', authenticate, authorize('user:read'), async (req, res) => {
|
|
55
|
+
if (req.user.id !== req.params.id && !req.user.isAdmin) throw new ForbiddenError();
|
|
56
|
+
const user = await userService.getUser(req.params.id);
|
|
57
|
+
return res.json(user);
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 6. Security Misconfiguration
|
|
62
|
+
```typescript
|
|
63
|
+
app.use(helmet());
|
|
64
|
+
app.use(helmet.contentSecurityPolicy({
|
|
65
|
+
directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'"] },
|
|
66
|
+
}));
|
|
67
|
+
app.use(cors({ origin: ['https://allowed-domain.com'], credentials: true }));
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 7. XSS
|
|
71
|
+
```typescript
|
|
72
|
+
// Bad
|
|
73
|
+
element.innerHTML = userInput;
|
|
74
|
+
// Good
|
|
75
|
+
element.textContent = userInput;
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## 8. Insecure Deserialization
|
|
79
|
+
```typescript
|
|
80
|
+
// Bad
|
|
81
|
+
const data = JSON.parse(userInput);
|
|
82
|
+
// Good
|
|
83
|
+
const schema = z.object({ name: z.string().max(100), age: z.number().min(0) });
|
|
84
|
+
const data = schema.parse(JSON.parse(userInput));
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 9. Known Vulnerabilities
|
|
88
|
+
```bash
|
|
89
|
+
npm audit && npm audit fix
|
|
90
|
+
npm outdated && npm update
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 10. Insufficient Logging
|
|
94
|
+
```typescript
|
|
95
|
+
logger.warn('Login failed', { email, ip: req.ip, timestamp: new Date().toISOString() });
|
|
96
|
+
if (failedAttempts >= 5) {
|
|
97
|
+
logger.error('Possible brute force attack', { email, ip: req.ip });
|
|
98
|
+
await lockAccount(email);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Additional Checks
|
|
103
|
+
|
|
104
|
+
### Rate Limiting
|
|
105
|
+
```typescript
|
|
106
|
+
import rateLimit from 'express-rate-limit';
|
|
107
|
+
app.use('/api/', rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### CSRF 방지
|
|
111
|
+
```typescript
|
|
112
|
+
import csrf from 'csurf';
|
|
113
|
+
app.use(csrf({ cookie: true }));
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 시크릿 관리
|
|
117
|
+
- **금지**: `const apiKey = 'sk-1234567890';`
|
|
118
|
+
- **필수**: `const apiKey = process.env.API_KEY;`
|
|
119
|
+
- **권장**: `await secretManager.getSecret('api-key');`
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# @name check-secrets
|
|
3
|
+
# @description 하드코딩된 시크릿/토큰/비밀번호를 소스코드에서 스캔
|
|
4
|
+
# @args [PROJECT_ROOT] (기본: 현재 디렉토리)
|
|
5
|
+
# @output text (발견된 파일:라인 목록 또는 "No secrets found")
|
|
6
|
+
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
PROJECT_ROOT="${1:-.}"
|
|
10
|
+
FOUND=0
|
|
11
|
+
|
|
12
|
+
echo "Scanning for hardcoded secrets in: $PROJECT_ROOT"
|
|
13
|
+
echo "================================================"
|
|
14
|
+
|
|
15
|
+
# Pattern 1: API keys, tokens, secrets in assignments
|
|
16
|
+
echo ""
|
|
17
|
+
echo "## Hardcoded API Keys / Tokens"
|
|
18
|
+
if grep -rn --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.py" --include="*.go" \
|
|
19
|
+
-E "(api_key|apiKey|API_KEY|secret|SECRET|token|TOKEN|password|PASSWORD)\s*[:=]\s*['\"][^'\"]{8,}" \
|
|
20
|
+
"$PROJECT_ROOT/src" "$PROJECT_ROOT/app" "$PROJECT_ROOT/lib" 2>/dev/null | \
|
|
21
|
+
grep -v "node_modules" | grep -v ".test." | grep -v "__mock__" | grep -v "example" | grep -v "placeholder"; then
|
|
22
|
+
FOUND=1
|
|
23
|
+
else
|
|
24
|
+
echo " (none found)"
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Pattern 2: .env files committed
|
|
28
|
+
echo ""
|
|
29
|
+
echo "## Committed .env Files"
|
|
30
|
+
if find "$PROJECT_ROOT" -name ".env" -o -name ".env.local" -o -name ".env.production" 2>/dev/null | \
|
|
31
|
+
grep -v "node_modules" | grep -v ".example"; then
|
|
32
|
+
FOUND=1
|
|
33
|
+
else
|
|
34
|
+
echo " (none found)"
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Pattern 3: Private keys
|
|
38
|
+
echo ""
|
|
39
|
+
echo "## Private Keys"
|
|
40
|
+
if grep -rn --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.pem" --include="*.key" \
|
|
41
|
+
-l "PRIVATE KEY" "$PROJECT_ROOT" 2>/dev/null | grep -v "node_modules"; then
|
|
42
|
+
FOUND=1
|
|
43
|
+
else
|
|
44
|
+
echo " (none found)"
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
echo ""
|
|
48
|
+
echo "================================================"
|
|
49
|
+
if [ "$FOUND" -eq 1 ]; then
|
|
50
|
+
echo "WARNING: Potential secrets found. Review above results."
|
|
51
|
+
exit 1
|
|
52
|
+
else
|
|
53
|
+
echo "No secrets found."
|
|
54
|
+
exit 0
|
|
55
|
+
fi
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testing
|
|
3
|
+
description: |
|
|
4
|
+
테스트 작성 규칙 및 패턴 가이드라인.
|
|
5
|
+
TDD 사이클, 테스트 피라미드, Given-When-Then 패턴, 커버리지 기준을 다룸.
|
|
6
|
+
Use when: "테스트 작성, TDD, 단위 테스트, 통합 테스트, E2E, 커버리지"
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
tags: [testing, tdd, quality]
|
|
9
|
+
user-invocable: false
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Testing
|
|
13
|
+
|
|
14
|
+
품질 보장을 위한 테스트 작성 가이드라인.
|
|
15
|
+
|
|
16
|
+
## Philosophy
|
|
17
|
+
|
|
18
|
+
- Red-Green-Refactor (TDD 사이클) 준수
|
|
19
|
+
- 테스트 피라미드: Unit(다수) > Integration(중간) > E2E(소수)
|
|
20
|
+
- 행동(behavior) 테스트 — 구현 디테일이 아닌 결과 검증
|
|
21
|
+
|
|
22
|
+
## Resources
|
|
23
|
+
|
|
24
|
+
| Priority | Type | Resource | Description |
|
|
25
|
+
|----------|------|----------|-------------|
|
|
26
|
+
| HIGH | ref | [testing-patterns](references/testing-patterns.md) | Given-When-Then, Mock 가이드, 카테고리별 예시 |
|
|
27
|
+
|
|
28
|
+
## Quick Rules
|
|
29
|
+
|
|
30
|
+
### TDD Cycle
|
|
31
|
+
1. **Red** — 실패하는 테스트 작성
|
|
32
|
+
2. **Green** — 테스트를 통과하는 최소 코드 작성
|
|
33
|
+
3. **Refactor** — 코드 정리 (테스트는 계속 통과)
|
|
34
|
+
|
|
35
|
+
### Test Naming
|
|
36
|
+
- 형식: `should {expected behavior} when {condition}`
|
|
37
|
+
- Good: `should return null when user is not found`
|
|
38
|
+
- Bad: `test getUser`, `works correctly`
|
|
39
|
+
|
|
40
|
+
### Test Categories
|
|
41
|
+
모든 테스트는 3가지 카테고리 커버:
|
|
42
|
+
- **Happy Path** — 정상 흐름
|
|
43
|
+
- **Edge Cases** — 경계 조건 (빈 문자열, 0, null, 최대값)
|
|
44
|
+
- **Error Cases** — 오류 상황
|
|
45
|
+
|
|
46
|
+
### Coverage Standards
|
|
47
|
+
|
|
48
|
+
| Metric | Minimum | Recommended |
|
|
49
|
+
|--------|---------|-------------|
|
|
50
|
+
| Line Coverage | 80% | 90% |
|
|
51
|
+
| Branch Coverage | 70% | 80% |
|
|
52
|
+
| Function Coverage | 80% | 90% |
|
|
53
|
+
|
|
54
|
+
## Checklist
|
|
55
|
+
|
|
56
|
+
| Priority | Item |
|
|
57
|
+
|----------|------|
|
|
58
|
+
| CRITICAL | Given-When-Then 패턴을 따르는가 |
|
|
59
|
+
| CRITICAL | Happy path, Edge case, Error case 커버하는가 |
|
|
60
|
+
| HIGH | 테스트 이름이 `should...when...` 형식인가 |
|
|
61
|
+
| HIGH | 커버리지 기준을 충족하는가 |
|
|
62
|
+
| MEDIUM | Mock이 적절히 사용되었는가 (외부 서비스만) |
|
|
63
|
+
| MEDIUM | 테스트가 독립적인가 (순서 무관) |
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Testing Patterns & Examples
|
|
3
|
+
category: guide
|
|
4
|
+
source: internal
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Testing Patterns & Examples
|
|
8
|
+
|
|
9
|
+
Given-When-Then 패턴, 테스트 카테고리별 예시, Mock 가이드라인을 다루는 심층 가이드.
|
|
10
|
+
|
|
11
|
+
## Given-When-Then Pattern
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
describe('UserService', () => {
|
|
15
|
+
describe('createUser', () => {
|
|
16
|
+
it('should create a new user when email is unique', async () => {
|
|
17
|
+
// Given: 테스트 조건 설정
|
|
18
|
+
const userRepository = createMockRepository();
|
|
19
|
+
userRepository.findByEmail.mockResolvedValue(null);
|
|
20
|
+
const service = new UserService(userRepository);
|
|
21
|
+
|
|
22
|
+
// When: 테스트 대상 실행
|
|
23
|
+
const result = await service.createUser({
|
|
24
|
+
email: 'test@example.com',
|
|
25
|
+
password: 'password123',
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Then: 결과 검증
|
|
29
|
+
expect(result.email).toBe('test@example.com');
|
|
30
|
+
expect(userRepository.save).toHaveBeenCalledTimes(1);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should throw error when email already exists', async () => {
|
|
34
|
+
// Given
|
|
35
|
+
const userRepository = createMockRepository();
|
|
36
|
+
userRepository.findByEmail.mockResolvedValue({ id: '1', email: 'test@example.com' });
|
|
37
|
+
const service = new UserService(userRepository);
|
|
38
|
+
|
|
39
|
+
// When & Then
|
|
40
|
+
await expect(
|
|
41
|
+
service.createUser({ email: 'test@example.com', password: 'password123' })
|
|
42
|
+
).rejects.toThrow('EMAIL_ALREADY_EXISTS');
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Test Categories
|
|
49
|
+
|
|
50
|
+
### Happy Path
|
|
51
|
+
정상적인 흐름 테스트.
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
it('should return user when valid id is provided', async () => {
|
|
55
|
+
const user = await userService.getUser('valid-id');
|
|
56
|
+
expect(user).toBeDefined();
|
|
57
|
+
expect(user.id).toBe('valid-id');
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Edge Cases
|
|
62
|
+
경계 조건: 빈 문자열, 최대 길이 입력, 0 값, null 입력.
|
|
63
|
+
|
|
64
|
+
### Error Cases
|
|
65
|
+
오류 상황 테스트.
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
it('should throw NotFoundError when user does not exist', async () => {
|
|
69
|
+
await expect(userService.getUser('non-existent-id'))
|
|
70
|
+
.rejects
|
|
71
|
+
.toThrow(NotFoundError);
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Mock Guidelines
|
|
76
|
+
|
|
77
|
+
### When to Mock
|
|
78
|
+
- 외부 서비스 (DB, API, 파일시스템)
|
|
79
|
+
- 비결정적 요소 (시간, 랜덤)
|
|
80
|
+
- 느린 작업
|
|
81
|
+
|
|
82
|
+
### Mock Examples
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
// Repository Mock
|
|
86
|
+
const mockUserRepository: jest.Mocked<UserRepository> = {
|
|
87
|
+
findById: jest.fn(),
|
|
88
|
+
findByEmail: jest.fn(),
|
|
89
|
+
save: jest.fn(),
|
|
90
|
+
delete: jest.fn(),
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// 시간 Mock
|
|
94
|
+
jest.useFakeTimers();
|
|
95
|
+
jest.setSystemTime(new Date('2024-01-01'));
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Common Pitfalls
|
|
99
|
+
|
|
100
|
+
- Mock을 과도하게 사용하면 실제 동작과 괴리 발생
|
|
101
|
+
- 테스트 간 상태 공유 → `beforeEach`에서 초기화 필수
|
|
102
|
+
- 구현 디테일을 테스트하면 리팩토링 시 깨짐 → 행동(behavior) 테스트
|
|
103
|
+
- `any` 타입 mock은 타입 안전성 무력화 → 타입 지정 mock 사용
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tsq-protocol
|
|
3
|
+
description: |
|
|
4
|
+
TimSquad 에이전트 공통 프로토콜.
|
|
5
|
+
task-context.json 우선 탐색, TSQ CLI 사용, 로그/피드백 규칙.
|
|
6
|
+
자동 주입 스킬 — 직접 호출하지 마세요.
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
tags: [tsq, protocol, agent]
|
|
9
|
+
user-invocable: false
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# TSQ Agent Protocol
|
|
13
|
+
|
|
14
|
+
## File Access
|
|
15
|
+
코드 탐색 시 `.timsquad/.daemon/task-context.json`을 **먼저** 확인하세요.
|
|
16
|
+
이 파일에 작업 범위의 파일/메서드/클래스 위치가 정리되어 있습니다.
|
|
17
|
+
context 파일이 없거나 범위 밖 파일이 필요할 때만 Grep/Glob을 사용하세요.
|
|
18
|
+
|
|
19
|
+
## TSQ CLI (Required)
|
|
20
|
+
|
|
21
|
+
모든 로그/피드백/커밋은 TSQ CLI를 통해서만 수행합니다. 직접 파일 조작 금지.
|
|
22
|
+
|
|
23
|
+
| 이벤트 | 커맨드 |
|
|
24
|
+
|--------|--------|
|
|
25
|
+
| 작업 시작 | `tsq log add {agent} work "TASK-XXX 시작: {설명}"` |
|
|
26
|
+
| 결정 기록 | `tsq log add {agent} decision "{결정 근거}"` |
|
|
27
|
+
| 이슈 발견 | `tsq feedback "{이슈 설명}"` |
|
|
28
|
+
| 작업 완료 | `tsq log add {agent} work "TASK-XXX 완료: {결과}"` |
|
|
29
|
+
| semantic 보강 | `tsq log enrich {agent} --json '{...}'` |
|
|
30
|
+
| 커밋 | `tsq commit -m "{메시지}"` (developer/dba만) |
|
|
31
|
+
|
|
32
|
+
### Forbidden
|
|
33
|
+
- 직접 `.timsquad/logs/` 파일 생성/수정 금지 → `tsq log` 사용
|
|
34
|
+
- 직접 `.timsquad/feedback/` 파일 생성 금지 → `tsq feedback` 사용
|
|
35
|
+
- 직접 `git commit` 금지 → `tsq commit` 사용 (해당 역할만)
|
|
36
|
+
|
|
37
|
+
## Output Format
|
|
38
|
+
작업 결과는 `knowledge/templates/task-result.md` 형식으로 리턴하세요.
|
|
39
|
+
|
|
40
|
+
## Feedback Routing
|
|
41
|
+
|
|
42
|
+
| Level | 심각도 | 기준 | 라우팅 |
|
|
43
|
+
|-------|--------|------|--------|
|
|
44
|
+
| L1 | Minor | 즉시 수정 가능 (린트, 타입, 스타일) | 자체 수정 또는 @tsq-developer |
|
|
45
|
+
| L2 | Major | 설계 변경 필요 (API 불일치, 성능 구조) | 메인세션(PM) 보고 |
|
|
46
|
+
| L3 | Critical | 요구사항 오류, 스코프 변경, 데이터 손실 위험 | 메인세션(PM) → 사용자 승인 |
|
|
47
|
+
|
|
48
|
+
모든 피드백에 Level 분류와 심각도를 반드시 명시하세요.
|
|
49
|
+
|
|
50
|
+
## Mandatory Skills
|
|
51
|
+
작업 시작 전 에이전트 frontmatter에 지정된 스킬 파일을 반드시 읽고 가이드라인을 준수하세요.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: typescript
|
|
3
|
+
description: TypeScript 개발 가이드라인
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
tags: [typescript, types, strict]
|
|
6
|
+
user-invocable: false
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# TypeScript Guidelines
|
|
10
|
+
|
|
11
|
+
## 철학
|
|
12
|
+
- 타입은 문서다 — 코드만 봐도 의도 파악
|
|
13
|
+
- 컴파일 타임에 버그를 잡는다
|
|
14
|
+
- any는 타입 시스템 포기 선언
|
|
15
|
+
|
|
16
|
+
## 필수 설정 (tsconfig.json)
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"compilerOptions": {
|
|
20
|
+
"strict": true,
|
|
21
|
+
"noImplicitAny": true,
|
|
22
|
+
"strictNullChecks": true,
|
|
23
|
+
"noImplicitReturns": true,
|
|
24
|
+
"noFallthroughCasesInSwitch": true,
|
|
25
|
+
"noUncheckedIndexedAccess": true,
|
|
26
|
+
"exactOptionalPropertyTypes": true
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 핵심 패턴 (상세: `rules/type-patterns.md`)
|
|
32
|
+
|
|
33
|
+
| 패턴 | 용도 |
|
|
34
|
+
|------|------|
|
|
35
|
+
| Discriminated Union | 상태 표현 (불가능한 상태를 불가능하게) |
|
|
36
|
+
| Type Narrowing | typeof, in, type guard로 안전한 접근 |
|
|
37
|
+
| Branded Types | 같은 원시 타입이지만 의미 구분 (UserId vs OrderId) |
|
|
38
|
+
| Template Literal Types | 문자열 패턴 타입 강제 |
|
|
39
|
+
| Infer | 조건부 타입에서 타입 추출 |
|
|
40
|
+
| Zod | 외부 입력 런타임 검증 + 타입 추출 |
|
|
41
|
+
|
|
42
|
+
## Rules
|
|
43
|
+
|
|
44
|
+
### 필수
|
|
45
|
+
- strict 모드 사용
|
|
46
|
+
- 함수 반환 타입 명시
|
|
47
|
+
- 외부 입력(API, 사용자)은 Zod로 런타임 검증
|
|
48
|
+
- Discriminated Union으로 상태 표현
|
|
49
|
+
- Branded Types로 ID 타입 구분
|
|
50
|
+
|
|
51
|
+
### 금지
|
|
52
|
+
- `any` 사용 → `unknown` + type guard
|
|
53
|
+
- 타입 단언 남용 (`as Type`)
|
|
54
|
+
- `@ts-ignore`, `@ts-expect-error` 남용
|
|
55
|
+
- `!` non-null assertion 남용
|
|
56
|
+
|
|
57
|
+
## Checklist
|
|
58
|
+
- [ ] strict 모드 활성화
|
|
59
|
+
- [ ] any 타입 없음
|
|
60
|
+
- [ ] 함수 반환 타입 명시
|
|
61
|
+
- [ ] 외부 입력 Zod 검증
|
|
62
|
+
- [ ] Discriminated Union으로 상태 표현
|
|
63
|
+
- [ ] Branded Types로 ID 구분
|
|
64
|
+
|
|
65
|
+
## 참조
|
|
66
|
+
- `rules/type-patterns.md` — 각 패턴의 코드 예시
|
|
67
|
+
- `rules/utility-types.md` — DTO 조합, DeepPartial, 타입 안전 API 클라이언트
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TypeScript Type Patterns
|
|
3
|
+
impact: HIGH
|
|
4
|
+
tags: typescript, types, patterns
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# TypeScript Type Patterns
|
|
8
|
+
|
|
9
|
+
## Discriminated Union (상태 표현의 정석)
|
|
10
|
+
status 필드로 타입을 구분하여 불가능한 상태를 불가능하게.
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
// Bad: 불가능한 상태가 가능함
|
|
14
|
+
interface ApiResponse { data?: User; error?: string; loading: boolean; }
|
|
15
|
+
|
|
16
|
+
// Good: 불가능한 상태는 타입으로 불가능
|
|
17
|
+
type ApiResponse<T> =
|
|
18
|
+
| { status: 'idle' }
|
|
19
|
+
| { status: 'loading' }
|
|
20
|
+
| { status: 'success'; data: T }
|
|
21
|
+
| { status: 'error'; error: Error };
|
|
22
|
+
|
|
23
|
+
function renderUser(state: ApiResponse<User>) {
|
|
24
|
+
switch (state.status) {
|
|
25
|
+
case 'idle': return null;
|
|
26
|
+
case 'loading': return <Spinner />;
|
|
27
|
+
case 'success': return <UserCard user={state.data} />;
|
|
28
|
+
case 'error': return <ErrorMessage error={state.error} />;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Type Narrowing (타입 좁히기)
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// typeof narrowing
|
|
37
|
+
function process(value: string | number) {
|
|
38
|
+
if (typeof value === 'string') return value.toUpperCase();
|
|
39
|
+
return value.toFixed(2);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// in narrowing
|
|
43
|
+
function move(animal: Fish | Bird) {
|
|
44
|
+
if ('swim' in animal) animal.swim();
|
|
45
|
+
else animal.fly();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Custom Type Guard
|
|
49
|
+
function isError(value: unknown): value is Error {
|
|
50
|
+
return value instanceof Error;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Assertion Function
|
|
54
|
+
function assertDefined<T>(value: T | null | undefined): asserts value is T {
|
|
55
|
+
if (value === null || value === undefined) throw new Error('Value is not defined');
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Branded Types (타입 브랜딩)
|
|
60
|
+
같은 원시 타입이지만 의미가 다른 값을 구분.
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
type UserId = string & { readonly __brand: 'UserId' };
|
|
64
|
+
type OrderId = string & { readonly __brand: 'OrderId' };
|
|
65
|
+
|
|
66
|
+
function createUserId(id: string): UserId {
|
|
67
|
+
if (!id.startsWith('user-')) throw new Error('Invalid user ID format');
|
|
68
|
+
return id as UserId;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function getUser(id: UserId): Promise<User> { ... }
|
|
72
|
+
function getOrder(id: OrderId): Promise<Order> { ... }
|
|
73
|
+
|
|
74
|
+
getUser(userId); // ✅ OK
|
|
75
|
+
getUser(orderId); // ❌ Type Error!
|
|
76
|
+
|
|
77
|
+
// 응용
|
|
78
|
+
type Money = number & { readonly __brand: 'Money' };
|
|
79
|
+
type Email = string & { readonly __brand: 'Email' };
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Template Literal Types
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
type ApiPath = `/api/${string}`;
|
|
86
|
+
fetchApi('/api/users'); // ✅
|
|
87
|
+
fetchApi('/users'); // ❌
|
|
88
|
+
|
|
89
|
+
type CSSUnit = `${number}${'px' | 'rem' | 'em' | '%'}`;
|
|
90
|
+
const width: CSSUnit = '100px'; // ✅
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Infer로 타입 추출
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
type Awaited<T> = T extends Promise<infer U> ? U : T;
|
|
97
|
+
type ArrayElement<T> = T extends (infer U)[] ? U : never;
|
|
98
|
+
type FirstArg<T> = T extends (first: infer F, ...args: any[]) => any ? F : never;
|
|
99
|
+
|
|
100
|
+
// API 응답에서 data 타입 추출
|
|
101
|
+
type ApiResponse<T> = { success: true; data: T } | { success: false; error: string };
|
|
102
|
+
type ExtractData<T> = T extends { success: true; data: infer D } ? D : never;
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Zod 런타임 검증
|
|
106
|
+
외부 입력은 타입만으로 부족, 런타임 검증 필요.
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { z } from 'zod';
|
|
110
|
+
|
|
111
|
+
const userSchema = z.object({
|
|
112
|
+
id: z.string().uuid(),
|
|
113
|
+
email: z.string().email(),
|
|
114
|
+
name: z.string().min(2).max(50),
|
|
115
|
+
role: z.enum(['admin', 'user', 'guest']),
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
type User = z.infer<typeof userSchema>;
|
|
119
|
+
|
|
120
|
+
// API 핸들러
|
|
121
|
+
async function createUser(req: Request) {
|
|
122
|
+
const result = userSchema.safeParse(req.body);
|
|
123
|
+
if (!result.success) return { error: result.error.format() };
|
|
124
|
+
const user = result.data;
|
|
125
|
+
await db.user.create({ data: user });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 환경변수 검증
|
|
129
|
+
const envSchema = z.object({
|
|
130
|
+
DATABASE_URL: z.string().url(),
|
|
131
|
+
JWT_SECRET: z.string().min(32),
|
|
132
|
+
PORT: z.coerce.number().default(3000),
|
|
133
|
+
});
|
|
134
|
+
export const env = envSchema.parse(process.env);
|
|
135
|
+
```
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TypeScript Utility Types & Advanced Patterns
|
|
3
|
+
impact: HIGH
|
|
4
|
+
tags: typescript, utility-types, advanced
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# TypeScript Utility Types & Advanced Patterns
|
|
8
|
+
|
|
9
|
+
## DTO 타입 조합
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
interface User {
|
|
13
|
+
id: string;
|
|
14
|
+
email: string;
|
|
15
|
+
name: string;
|
|
16
|
+
password: string;
|
|
17
|
+
createdAt: Date;
|
|
18
|
+
updatedAt: Date;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type CreateUserDto = Omit<User, 'id' | 'createdAt' | 'updatedAt'>;
|
|
22
|
+
type UpdateUserDto = Partial<Omit<User, 'id' | 'createdAt' | 'updatedAt'>>;
|
|
23
|
+
type UserResponseDto = Omit<User, 'password'>;
|
|
24
|
+
|
|
25
|
+
type UsersListDto = {
|
|
26
|
+
users: UserResponseDto[];
|
|
27
|
+
total: number;
|
|
28
|
+
page: number;
|
|
29
|
+
limit: number;
|
|
30
|
+
};
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## DeepPartial / DeepReadonly
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
type DeepPartial<T> = {
|
|
37
|
+
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
type DeepReadonly<T> = {
|
|
41
|
+
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
|
|
42
|
+
};
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 타입 안전한 API 클라이언트
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
type ApiEndpoint = {
|
|
49
|
+
'/users': {
|
|
50
|
+
GET: { response: User[]; query?: { page?: number; limit?: number } };
|
|
51
|
+
POST: { response: User; body: CreateUserDto };
|
|
52
|
+
};
|
|
53
|
+
'/users/:id': {
|
|
54
|
+
GET: { response: User; params: { id: string } };
|
|
55
|
+
PUT: { response: User; params: { id: string }; body: UpdateUserDto };
|
|
56
|
+
DELETE: { response: void; params: { id: string } };
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
async function api<
|
|
61
|
+
Path extends keyof ApiEndpoint,
|
|
62
|
+
Method extends keyof ApiEndpoint[Path]
|
|
63
|
+
>(
|
|
64
|
+
path: Path,
|
|
65
|
+
method: Method,
|
|
66
|
+
options?: ApiEndpoint[Path][Method] extends { body: infer B } ? { body: B } : never
|
|
67
|
+
): Promise<ApiEndpoint[Path][Method] extends { response: infer R } ? R : never> {
|
|
68
|
+
// 구현
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const users = await api('/users', 'GET'); // User[]
|
|
72
|
+
const user = await api('/users', 'POST', {
|
|
73
|
+
body: { email: 'a@b.com', name: 'Test', password: '...' }
|
|
74
|
+
}); // User
|
|
75
|
+
await api('/users', 'DELETE'); // ❌ DELETE는 /users에 없음
|
|
76
|
+
```
|