timsquad 3.6.0 → 3.7.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.
Files changed (433) hide show
  1. package/README.ko.md +103 -113
  2. package/README.md +100 -110
  3. package/dist/commands/init.js +4 -8
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/commands/{upgrade.d.ts → update.d.ts} +3 -3
  6. package/dist/commands/update.d.ts.map +1 -0
  7. package/dist/commands/{upgrade.js → update.js} +12 -17
  8. package/dist/commands/update.js.map +1 -0
  9. package/dist/daemon/event-queue.d.ts +3 -11
  10. package/dist/daemon/event-queue.d.ts.map +1 -1
  11. package/dist/daemon/event-queue.js +62 -203
  12. package/dist/daemon/event-queue.js.map +1 -1
  13. package/dist/daemon/index.d.ts +1 -1
  14. package/dist/daemon/index.d.ts.map +1 -1
  15. package/dist/daemon/index.js +15 -14
  16. package/dist/daemon/index.js.map +1 -1
  17. package/dist/index.js +3 -43
  18. package/dist/index.js.map +1 -1
  19. package/dist/lib/agent-generator.d.ts.map +1 -1
  20. package/dist/lib/agent-generator.js +10 -10
  21. package/dist/lib/agent-generator.js.map +1 -1
  22. package/dist/lib/compile-rules.d.ts.map +1 -1
  23. package/dist/lib/compile-rules.js +37 -4
  24. package/dist/lib/compile-rules.js.map +1 -1
  25. package/dist/lib/compiler.d.ts +1 -0
  26. package/dist/lib/compiler.d.ts.map +1 -1
  27. package/dist/lib/compiler.js +67 -11
  28. package/dist/lib/compiler.js.map +1 -1
  29. package/dist/{commands/log.d.ts → lib/log-utils.d.ts} +7 -15
  30. package/dist/lib/log-utils.d.ts.map +1 -0
  31. package/dist/lib/log-utils.js +347 -0
  32. package/dist/lib/log-utils.js.map +1 -0
  33. package/dist/lib/skill-generator.d.ts.map +1 -1
  34. package/dist/lib/skill-generator.js +4 -44
  35. package/dist/lib/skill-generator.js.map +1 -1
  36. package/dist/lib/ssot-map.d.ts.map +1 -1
  37. package/dist/lib/ssot-map.js +3 -0
  38. package/dist/lib/ssot-map.js.map +1 -1
  39. package/dist/lib/template.d.ts +10 -3
  40. package/dist/lib/template.d.ts.map +1 -1
  41. package/dist/lib/template.js +142 -22
  42. package/dist/lib/template.js.map +1 -1
  43. package/dist/lib/upgrade-backup.js +1 -1
  44. package/dist/lib/upgrade-backup.js.map +1 -1
  45. package/dist/types/config.d.ts.map +1 -1
  46. package/dist/types/config.js +37 -34
  47. package/dist/types/config.js.map +1 -1
  48. package/dist/types/feedback.d.ts +1 -54
  49. package/dist/types/feedback.d.ts.map +1 -1
  50. package/dist/types/feedback.js +1 -22
  51. package/dist/types/feedback.js.map +1 -1
  52. package/dist/types/project.d.ts +5 -0
  53. package/dist/types/project.d.ts.map +1 -1
  54. package/dist/types/project.js +15 -0
  55. package/dist/types/project.js.map +1 -1
  56. package/dist/types/ssot-map.d.ts +2 -0
  57. package/dist/types/ssot-map.d.ts.map +1 -1
  58. package/package.json +1 -1
  59. package/templates/base/agents/base/tsq-architect.md +1 -1
  60. package/templates/base/agents/base/tsq-dba.md +3 -1
  61. package/templates/base/agents/base/tsq-designer.md +3 -1
  62. package/templates/base/agents/base/tsq-developer.md +3 -1
  63. package/templates/base/agents/base/tsq-librarian.md +1 -1
  64. package/templates/base/agents/base/tsq-qa.md +3 -1
  65. package/templates/base/agents/base/tsq-security.md +3 -1
  66. package/templates/base/agents/overlays/platform/claude-code.md +2 -2
  67. package/templates/base/config.template.yaml +17 -28
  68. package/templates/base/knowledge/templates/task-result.md +5 -10
  69. package/templates/base/skills/_template/SKILL.md +1 -3
  70. package/templates/base/skills/{architecture → tsq-architecture}/SKILL.md +2 -2
  71. package/templates/base/skills/tsq-audit/SKILL.md +74 -0
  72. package/templates/base/skills/{methodology/bdd → tsq-bdd}/SKILL.md +14 -9
  73. package/templates/base/skills/{coding → tsq-coding}/SKILL.md +2 -4
  74. package/templates/base/skills/tsq-controller/SKILL.md +81 -0
  75. package/templates/base/skills/{mobile/dart → tsq-dart}/SKILL.md +5 -3
  76. package/templates/base/skills/{database → tsq-database}/SKILL.md +5 -2
  77. package/templates/base/skills/{methodology/ddd → tsq-ddd}/SKILL.md +15 -10
  78. package/templates/base/skills/{methodology/debugging → tsq-debugging}/SKILL.md +2 -2
  79. package/templates/base/skills/tsq-decompose/SKILL.md +117 -0
  80. package/templates/base/skills/tsq-delete/SKILL.md +72 -0
  81. package/templates/base/skills/{mobile/flutter → tsq-flutter}/SKILL.md +6 -3
  82. package/templates/base/skills/tsq-full/SKILL.md +67 -0
  83. package/templates/base/skills/tsq-grill/SKILL.md +86 -0
  84. package/templates/base/skills/{backend/node → tsq-hono}/SKILL.md +6 -4
  85. package/templates/base/skills/tsq-librarian/SKILL.md +78 -0
  86. package/templates/base/skills/tsq-log/SKILL.md +30 -0
  87. package/templates/base/skills/{frontend/nextjs → tsq-nextjs}/SKILL.md +14 -9
  88. package/templates/base/skills/{planning → tsq-planning}/SKILL.md +2 -2
  89. package/templates/base/skills/{database/prisma → tsq-prisma}/SKILL.md +15 -9
  90. package/templates/base/skills/{product-audit → tsq-product-audit}/SKILL.md +2 -4
  91. package/templates/base/skills/{prompt-engineering → tsq-prompt}/SKILL.md +6 -4
  92. package/templates/base/skills/tsq-protocol/SKILL.md +85 -33
  93. package/templates/base/skills/tsq-quick/SKILL.md +58 -0
  94. package/templates/base/skills/{frontend/react → tsq-react}/SKILL.md +6 -3
  95. package/templates/base/skills/tsq-retro/SKILL.md +86 -0
  96. package/templates/base/skills/tsq-retro/references/feedback-guide.md +58 -0
  97. package/templates/base/skills/tsq-retro/references/improve-protocol.md +87 -0
  98. package/templates/base/skills/{security → tsq-security}/SKILL.md +2 -4
  99. package/templates/base/skills/{spec → tsq-spec}/SKILL.md +4 -6
  100. package/templates/base/skills/{stability-verification → tsq-stability}/SKILL.md +3 -3
  101. package/templates/base/skills/tsq-start/SKILL.md +90 -0
  102. package/templates/base/skills/tsq-start/references/onboarding-questions.md +177 -0
  103. package/templates/base/skills/tsq-status/SKILL.md +32 -0
  104. package/templates/base/skills/{methodology/tdd → tsq-tdd}/SKILL.md +6 -3
  105. package/templates/base/skills/{testing → tsq-testing}/SKILL.md +5 -7
  106. package/templates/base/skills/{typescript → tsq-typescript}/SKILL.md +2 -2
  107. package/templates/base/skills/{ui-design → tsq-ui}/SKILL.md +2 -2
  108. package/templates/base/skills/tsq-update/SKILL.md +48 -0
  109. package/templates/base/timsquad/constraints/competency-framework.xml +2 -2
  110. package/templates/base/timsquad/constraints/ssot-schema.xml +2 -2
  111. package/templates/base/timsquad/process/phase-checklist.yaml +1 -1
  112. package/templates/base/timsquad/process/state-machine.xml +2 -2
  113. package/templates/base/timsquad/process/validation-rules.xml +8 -8
  114. package/templates/base/timsquad/process/workflow-base.xml +8 -8
  115. package/templates/base/timsquad/retrospective/cycle-report.template.md +2 -2
  116. package/templates/base/timsquad/retrospective/patterns/failure-patterns.md +1 -1
  117. package/templates/base/timsquad/retrospective/patterns/success-patterns.md +2 -2
  118. package/templates/base/timsquad/retrospective/retrospective-state.xml +2 -2
  119. package/templates/base/timsquad/ssot/audit-trail-spec.template.md +155 -0
  120. package/templates/base/timsquad/ssot/compliance-matrix.template.md +105 -0
  121. package/templates/base/timsquad/ssot/component-map.template.md +181 -0
  122. package/templates/base/timsquad/ssot/data-design.template.md +4 -4
  123. package/templates/base/timsquad/ssot/deployment-spec.template.md +29 -22
  124. package/templates/base/timsquad/ssot/env-config.template.md +4 -2
  125. package/templates/base/timsquad/ssot/error-codes.template.md +3 -3
  126. package/templates/base/timsquad/ssot/functional-spec.template.md +40 -3
  127. package/templates/base/timsquad/ssot/glossary.template.md +2 -2
  128. package/templates/base/timsquad/ssot/infra-topology.template.md +191 -0
  129. package/templates/base/timsquad/ssot/integration-spec.template.md +2 -2
  130. package/templates/base/timsquad/ssot/monitoring-spec.template.md +185 -0
  131. package/templates/base/timsquad/ssot/navigation-map.template.md +154 -0
  132. package/templates/base/timsquad/ssot/performance-budget.template.md +132 -0
  133. package/templates/base/timsquad/ssot/planning.template.md +3 -3
  134. package/templates/base/timsquad/ssot/prd/_template.md +73 -0
  135. package/templates/base/timsquad/ssot/prd.template.md +10 -21
  136. package/templates/base/timsquad/ssot/requirements.template.md +3 -3
  137. package/templates/base/timsquad/ssot/sdk-spec.template.md +223 -0
  138. package/templates/base/timsquad/ssot/service-spec.template.md +3 -3
  139. package/templates/base/timsquad/ssot/state-machine.template.md +127 -0
  140. package/templates/base/timsquad/ssot/ui-ux-spec.template.md +43 -3
  141. package/templates/base/timsquad/ssot-map.template.yaml +28 -0
  142. package/templates/base/timsquad/state/workspace.xml +11 -11
  143. package/templates/platforms/claude-code/rules/adr-rules.md +1 -1
  144. package/templates/platforms/claude-code/rules/build-gate.md +1 -1
  145. package/templates/platforms/claude-code/rules/completion-verification.md +0 -2
  146. package/templates/platforms/claude-code/rules/context-monitor.md +1 -1
  147. package/templates/platforms/claude-code/rules/feedback-routing.md +2 -2
  148. package/templates/platforms/claude-code/rules/phase-management.md +2 -2
  149. package/templates/platforms/claude-code/rules/plan-review.md +2 -2
  150. package/templates/platforms/claude-code/rules/quality-guards.md +0 -2
  151. package/templates/platforms/claude-code/rules/sequence-management.md +15 -15
  152. package/templates/platforms/claude-code/rules/session-notes.md +1 -1
  153. package/templates/platforms/claude-code/rules/workspace-sync.md +1 -1
  154. package/templates/platforms/claude-code/scripts/build-gate.sh +6 -1
  155. package/templates/platforms/claude-code/scripts/change-scope-guard.sh +1 -4
  156. package/templates/platforms/claude-code/scripts/check-capability.sh +68 -0
  157. package/templates/platforms/claude-code/scripts/completion-guard.sh +62 -4
  158. package/templates/platforms/claude-code/scripts/context-restore.sh +33 -6
  159. package/templates/platforms/claude-code/scripts/phase-guard.sh +2 -5
  160. package/templates/platforms/claude-code/scripts/pre-compact.sh +3 -3
  161. package/templates/platforms/claude-code/scripts/safe-guard.sh +2 -5
  162. package/templates/platforms/claude-code/scripts/subagent-start.sh +11 -0
  163. package/templates/platforms/claude-code/scripts/subagent-stop.sh +11 -0
  164. package/templates/platforms/claude-code/settings.json +20 -74
  165. package/templates/project-types/api-backend/config.yaml +9 -5
  166. package/templates/project-types/api-backend/process/workflow.xml +2 -2
  167. package/templates/project-types/fintech/config.yaml +13 -19
  168. package/templates/project-types/fintech/ssot/audit-trail-spec.template.md +207 -0
  169. package/templates/project-types/fintech/ssot/compliance-matrix.template.md +187 -0
  170. package/templates/project-types/infra/config.yaml +7 -4
  171. package/templates/project-types/infra/process/workflow.xml +3 -3
  172. package/templates/project-types/mobile-app/config.yaml +8 -14
  173. package/templates/project-types/mobile-app/process/workflow.xml +4 -4
  174. package/templates/project-types/platform/config.yaml +8 -5
  175. package/templates/project-types/platform/process/workflow.xml +3 -3
  176. package/templates/project-types/web-app/config.yaml +9 -15
  177. package/templates/project-types/web-app/process/workflow.xml +6 -6
  178. package/templates/project-types/web-service/config.yaml +10 -19
  179. package/templates/project-types/web-service/process/workflow.xml +6 -6
  180. package/dist/commands/audit.d.ts +0 -22
  181. package/dist/commands/audit.d.ts.map +0 -1
  182. package/dist/commands/audit.js +0 -233
  183. package/dist/commands/audit.js.map +0 -1
  184. package/dist/commands/compile.d.ts +0 -3
  185. package/dist/commands/compile.d.ts.map +0 -1
  186. package/dist/commands/compile.js +0 -251
  187. package/dist/commands/compile.js.map +0 -1
  188. package/dist/commands/feedback.d.ts +0 -12
  189. package/dist/commands/feedback.d.ts.map +0 -1
  190. package/dist/commands/feedback.js +0 -382
  191. package/dist/commands/feedback.js.map +0 -1
  192. package/dist/commands/full.d.ts +0 -3
  193. package/dist/commands/full.d.ts.map +0 -1
  194. package/dist/commands/full.js +0 -88
  195. package/dist/commands/full.js.map +0 -1
  196. package/dist/commands/git/commit.d.ts +0 -3
  197. package/dist/commands/git/commit.d.ts.map +0 -1
  198. package/dist/commands/git/commit.js +0 -85
  199. package/dist/commands/git/commit.js.map +0 -1
  200. package/dist/commands/git/index.d.ts +0 -5
  201. package/dist/commands/git/index.d.ts.map +0 -1
  202. package/dist/commands/git/index.js +0 -5
  203. package/dist/commands/git/index.js.map +0 -1
  204. package/dist/commands/git/pr.d.ts +0 -3
  205. package/dist/commands/git/pr.d.ts.map +0 -1
  206. package/dist/commands/git/pr.js +0 -139
  207. package/dist/commands/git/pr.js.map +0 -1
  208. package/dist/commands/git/release.d.ts +0 -3
  209. package/dist/commands/git/release.d.ts.map +0 -1
  210. package/dist/commands/git/release.js +0 -153
  211. package/dist/commands/git/release.js.map +0 -1
  212. package/dist/commands/git/sync.d.ts +0 -3
  213. package/dist/commands/git/sync.d.ts.map +0 -1
  214. package/dist/commands/git/sync.js +0 -132
  215. package/dist/commands/git/sync.js.map +0 -1
  216. package/dist/commands/improve.d.ts +0 -3
  217. package/dist/commands/improve.d.ts.map +0 -1
  218. package/dist/commands/improve.js +0 -286
  219. package/dist/commands/improve.js.map +0 -1
  220. package/dist/commands/knowledge.d.ts +0 -3
  221. package/dist/commands/knowledge.d.ts.map +0 -1
  222. package/dist/commands/knowledge.js +0 -316
  223. package/dist/commands/knowledge.js.map +0 -1
  224. package/dist/commands/log.d.ts.map +0 -1
  225. package/dist/commands/log.js +0 -1468
  226. package/dist/commands/log.js.map +0 -1
  227. package/dist/commands/meta-index.d.ts +0 -3
  228. package/dist/commands/meta-index.d.ts.map +0 -1
  229. package/dist/commands/meta-index.js +0 -431
  230. package/dist/commands/meta-index.js.map +0 -1
  231. package/dist/commands/metrics.d.ts +0 -3
  232. package/dist/commands/metrics.d.ts.map +0 -1
  233. package/dist/commands/metrics.js +0 -843
  234. package/dist/commands/metrics.js.map +0 -1
  235. package/dist/commands/quick.d.ts +0 -3
  236. package/dist/commands/quick.d.ts.map +0 -1
  237. package/dist/commands/quick.js +0 -136
  238. package/dist/commands/quick.js.map +0 -1
  239. package/dist/commands/retro.d.ts +0 -3
  240. package/dist/commands/retro.d.ts.map +0 -1
  241. package/dist/commands/retro.js +0 -885
  242. package/dist/commands/retro.js.map +0 -1
  243. package/dist/commands/session.d.ts +0 -3
  244. package/dist/commands/session.d.ts.map +0 -1
  245. package/dist/commands/session.js +0 -346
  246. package/dist/commands/session.js.map +0 -1
  247. package/dist/commands/skills.d.ts +0 -12
  248. package/dist/commands/skills.d.ts.map +0 -1
  249. package/dist/commands/skills.js +0 -228
  250. package/dist/commands/skills.js.map +0 -1
  251. package/dist/commands/status.d.ts +0 -3
  252. package/dist/commands/status.d.ts.map +0 -1
  253. package/dist/commands/status.js +0 -127
  254. package/dist/commands/status.js.map +0 -1
  255. package/dist/commands/upgrade.d.ts.map +0 -1
  256. package/dist/commands/upgrade.js.map +0 -1
  257. package/dist/commands/watch.d.ts +0 -3
  258. package/dist/commands/watch.d.ts.map +0 -1
  259. package/dist/commands/watch.js +0 -213
  260. package/dist/commands/watch.js.map +0 -1
  261. package/dist/commands/workflow.d.ts +0 -5
  262. package/dist/commands/workflow.d.ts.map +0 -1
  263. package/dist/commands/workflow.js +0 -781
  264. package/dist/commands/workflow.js.map +0 -1
  265. package/templates/base/skills/audit/SKILL.md +0 -66
  266. package/templates/base/skills/controller/SKILL.md +0 -77
  267. package/templates/base/skills/controller/delegation/developer.md +0 -25
  268. package/templates/base/skills/controller/delegation/librarian.md +0 -33
  269. package/templates/base/skills/controller/delegation/reviewer.md +0 -19
  270. package/templates/base/skills/controller/triggers/phase-complete.md +0 -25
  271. package/templates/base/skills/controller/triggers/sequence-complete.md +0 -15
  272. package/templates/base/skills/controller/triggers/ssot-changed.md +0 -14
  273. package/templates/base/skills/controller/triggers/task-complete.md +0 -14
  274. package/templates/base/skills/librarian/SKILL.md +0 -53
  275. package/templates/base/skills/main-session-constraints/SKILL.md +0 -62
  276. package/templates/base/skills/retrospective/SKILL.md +0 -77
  277. package/templates/base/skills/review/SKILL.md +0 -72
  278. package/templates/base/skills/tsq-cli/SKILL.md +0 -73
  279. package/templates/base/skills/tsq-cli/references/cli-reference.md +0 -92
  280. package/templates/base/timsquad/feedback/feedback-router.sh +0 -341
  281. package/templates/base/timsquad/feedback/routing-rules.yaml +0 -352
  282. package/templates/platforms/claude-code/CLAUDE.md.template +0 -89
  283. package/templates/platforms/claude-code/rules/skill-suggest.md +0 -27
  284. package/templates/platforms/claude-code/scripts/skill-inject.sh +0 -216
  285. package/templates/platforms/claude-code/scripts/skill-rules.json +0 -95
  286. package/templates/platforms/claude-code/scripts/skill-suggest.sh +0 -105
  287. package/templates/platforms/claude-code/scripts/subagent-inject.sh +0 -53
  288. /package/templates/base/skills/{architecture → tsq-architecture}/references/adr-template.md +0 -0
  289. /package/templates/base/skills/{architecture → tsq-architecture}/references/api-design.md +0 -0
  290. /package/templates/base/skills/{methodology/bdd → tsq-bdd}/rules/gherkin-patterns.md +0 -0
  291. /package/templates/base/skills/{coding → tsq-coding}/rules/async-patterns.md +0 -0
  292. /package/templates/base/skills/{coding → tsq-coding}/rules/code-organization.md +0 -0
  293. /package/templates/base/skills/{coding → tsq-coding}/rules/error-handling.md +0 -0
  294. /package/templates/base/skills/{coding → tsq-coding}/rules/patterns.md +0 -0
  295. /package/templates/base/skills/{coding → tsq-coding}/rules/type-safety.md +0 -0
  296. /package/templates/base/skills/{controller → tsq-controller}/memory/.gitkeep +0 -0
  297. /package/templates/base/skills/{controller → tsq-controller}/references/README.md +0 -0
  298. /package/templates/base/skills/{controller → tsq-controller}/rules/README.md +0 -0
  299. /package/templates/base/skills/{mobile/dart → tsq-dart}/rules/async-patterns.md +0 -0
  300. /package/templates/base/skills/{mobile/dart → tsq-dart}/rules/code-style.md +0 -0
  301. /package/templates/base/skills/{mobile/dart → tsq-dart}/rules/null-safety.md +0 -0
  302. /package/templates/base/skills/{mobile/dart → tsq-dart}/rules/type-system.md +0 -0
  303. /package/templates/base/skills/{database → tsq-database}/rules/query-optimization.md +0 -0
  304. /package/templates/base/skills/{database → tsq-database}/rules/supabase-patterns.md +0 -0
  305. /package/templates/base/skills/{methodology/ddd → tsq-ddd}/rules/strategic-patterns.md +0 -0
  306. /package/templates/base/skills/{methodology/debugging → tsq-debugging}/references/root-cause-tracing.md +0 -0
  307. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/ci-cd/SKILL.md +0 -0
  308. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/ci-cd/references/ci-cd-pipeline.md +0 -0
  309. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/ci-cd/rules/code-signing.md +0 -0
  310. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/ci-cd/rules/codemagic-setup.md +0 -0
  311. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/ci-cd/rules/fastlane-setup.md +0 -0
  312. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/ci-cd/rules/github-actions.md +0 -0
  313. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/ci-cd/rules/store-deployment.md +0 -0
  314. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/ci-cd/rules/versioning.md +0 -0
  315. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/i18n/SKILL.md +0 -0
  316. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/i18n/references/i18n-architecture.md +0 -0
  317. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/i18n/rules/arb-files.md +0 -0
  318. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/i18n/rules/locale-switching.md +0 -0
  319. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/i18n/rules/localization-setup.md +0 -0
  320. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/i18n/rules/plural-gender.md +0 -0
  321. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/i18n/rules/text-direction.md +0 -0
  322. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/monitoring/SKILL.md +0 -0
  323. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/monitoring/references/monitoring-architecture.md +0 -0
  324. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/monitoring/rules/analytics.md +0 -0
  325. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/monitoring/rules/crashlytics-setup.md +0 -0
  326. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/monitoring/rules/logging.md +0 -0
  327. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/monitoring/rules/performance-monitoring.md +0 -0
  328. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/monitoring/rules/sentry-integration.md +0 -0
  329. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/networking/SKILL.md +0 -0
  330. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/networking/references/api-client-architecture.md +0 -0
  331. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/networking/rules/caching.md +0 -0
  332. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/networking/rules/connectivity.md +0 -0
  333. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/networking/rules/dio-setup.md +0 -0
  334. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/networking/rules/error-handling.md +0 -0
  335. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/networking/rules/interceptors.md +0 -0
  336. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/networking/rules/retrofit-patterns.md +0 -0
  337. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/push-notifications/SKILL.md +0 -0
  338. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/push-notifications/references/notification-architecture.md +0 -0
  339. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/push-notifications/references/platform-setup.md +0 -0
  340. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/push-notifications/rules/background-processing.md +0 -0
  341. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/push-notifications/rules/deep-linking.md +0 -0
  342. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/push-notifications/rules/fcm-setup.md +0 -0
  343. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/push-notifications/rules/local-notifications.md +0 -0
  344. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/push-notifications/rules/notification-handling.md +0 -0
  345. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/push-notifications/rules/notification-permissions.md +0 -0
  346. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/push-notifications/rules/rich-notifications.md +0 -0
  347. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/references/freezed-patterns.md +0 -0
  348. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/references/project-structure.md +0 -0
  349. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/rules/animations.md +0 -0
  350. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/rules/architecture.md +0 -0
  351. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/rules/navigation-routing.md +0 -0
  352. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/rules/performance.md +0 -0
  353. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/rules/platform-adaptive.md +0 -0
  354. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/rules/state-management.md +0 -0
  355. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/rules/testing.md +0 -0
  356. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/rules/widget-conventions.md +0 -0
  357. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/security/SKILL.md +0 -0
  358. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/security/references/mobile-security-checklist.md +0 -0
  359. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/security/rules/api-key-protection.md +0 -0
  360. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/security/rules/authentication.md +0 -0
  361. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/security/rules/data-protection.md +0 -0
  362. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/security/rules/obfuscation.md +0 -0
  363. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/security/rules/secure-storage.md +0 -0
  364. /package/templates/base/skills/{mobile/flutter → tsq-flutter}/security/rules/ssl-pinning.md +0 -0
  365. /package/templates/base/skills/{backend/node → tsq-hono}/rules/async-patterns.md +0 -0
  366. /package/templates/base/skills/{backend/node → tsq-hono}/rules/deployment.md +0 -0
  367. /package/templates/base/skills/{backend/node → tsq-hono}/rules/env-config.md +0 -0
  368. /package/templates/base/skills/{backend/node → tsq-hono}/rules/error-handling.md +0 -0
  369. /package/templates/base/skills/{backend/node → tsq-hono}/rules/hono-app-setup.md +0 -0
  370. /package/templates/base/skills/{backend/node → tsq-hono}/rules/jwt-auth.md +0 -0
  371. /package/templates/base/skills/{backend/node → tsq-hono}/rules/middleware.md +0 -0
  372. /package/templates/base/skills/{backend/node → tsq-hono}/rules/testing.md +0 -0
  373. /package/templates/base/skills/{frontend/nextjs → tsq-nextjs}/rules/app-router.md +0 -0
  374. /package/templates/base/skills/{planning → tsq-planning}/references/prd-guide.md +0 -0
  375. /package/templates/base/skills/{planning → tsq-planning}/references/requirements-guide.md +0 -0
  376. /package/templates/base/skills/{database/prisma → tsq-prisma}/rules/queries.md +0 -0
  377. /package/templates/base/skills/{database/prisma → tsq-prisma}/rules/schema-design.md +0 -0
  378. /package/templates/base/skills/{product-audit → tsq-product-audit}/checklists/01-security.md +0 -0
  379. /package/templates/base/skills/{product-audit → tsq-product-audit}/checklists/02-performance.md +0 -0
  380. /package/templates/base/skills/{product-audit → tsq-product-audit}/checklists/03-seo.md +0 -0
  381. /package/templates/base/skills/{product-audit → tsq-product-audit}/checklists/04-accessibility.md +0 -0
  382. /package/templates/base/skills/{product-audit → tsq-product-audit}/checklists/05-ui-ux.md +0 -0
  383. /package/templates/base/skills/{product-audit → tsq-product-audit}/checklists/06-architecture.md +0 -0
  384. /package/templates/base/skills/{product-audit → tsq-product-audit}/checklists/07-functional-requirements.md +0 -0
  385. /package/templates/base/skills/{product-audit → tsq-product-audit}/rules/audit-protocol.md +0 -0
  386. /package/templates/base/skills/{product-audit → tsq-product-audit}/rules/false-positive-guard.md +0 -0
  387. /package/templates/base/skills/{product-audit → tsq-product-audit}/rules/scoring-criteria.md +0 -0
  388. /package/templates/base/skills/{product-audit → tsq-product-audit}/templates/improvement-plan-template.md +0 -0
  389. /package/templates/base/skills/{product-audit → tsq-product-audit}/templates/report-template.md +0 -0
  390. /package/templates/base/skills/{frontend/react → tsq-react}/rules/_sections.md +0 -0
  391. /package/templates/base/skills/{frontend/react → tsq-react}/rules/anti-patterns.md +0 -0
  392. /package/templates/base/skills/{frontend/react → tsq-react}/rules/async-api-routes.md +0 -0
  393. /package/templates/base/skills/{frontend/react → tsq-react}/rules/async-defer-await.md +0 -0
  394. /package/templates/base/skills/{frontend/react → tsq-react}/rules/async-dependencies.md +0 -0
  395. /package/templates/base/skills/{frontend/react → tsq-react}/rules/async-parallel.md +0 -0
  396. /package/templates/base/skills/{frontend/react → tsq-react}/rules/async-suspense-boundaries.md +0 -0
  397. /package/templates/base/skills/{frontend/react → tsq-react}/rules/bundle-barrel-imports.md +0 -0
  398. /package/templates/base/skills/{frontend/react → tsq-react}/rules/bundle-defer-third-party.md +0 -0
  399. /package/templates/base/skills/{frontend/react → tsq-react}/rules/bundle-dynamic-imports.md +0 -0
  400. /package/templates/base/skills/{frontend/react → tsq-react}/rules/component-conventions.md +0 -0
  401. /package/templates/base/skills/{frontend/react → tsq-react}/rules/js-combine-iterations.md +0 -0
  402. /package/templates/base/skills/{frontend/react → tsq-react}/rules/js-early-exit.md +0 -0
  403. /package/templates/base/skills/{frontend/react → tsq-react}/rules/js-index-maps.md +0 -0
  404. /package/templates/base/skills/{frontend/react → tsq-react}/rules/js-set-map-lookups.md +0 -0
  405. /package/templates/base/skills/{frontend/react → tsq-react}/rules/rendering-conditional-render.md +0 -0
  406. /package/templates/base/skills/{frontend/react → tsq-react}/rules/rendering-content-visibility.md +0 -0
  407. /package/templates/base/skills/{frontend/react → tsq-react}/rules/rendering-hoist-jsx.md +0 -0
  408. /package/templates/base/skills/{frontend/react → tsq-react}/rules/rerender-defer-reads.md +0 -0
  409. /package/templates/base/skills/{frontend/react → tsq-react}/rules/rerender-derived-state.md +0 -0
  410. /package/templates/base/skills/{frontend/react → tsq-react}/rules/rerender-memo.md +0 -0
  411. /package/templates/base/skills/{frontend/react → tsq-react}/rules/rerender-transitions.md +0 -0
  412. /package/templates/base/skills/{frontend/react → tsq-react}/rules/server-after-nonblocking.md +0 -0
  413. /package/templates/base/skills/{frontend/react → tsq-react}/rules/server-cache-react.md +0 -0
  414. /package/templates/base/skills/{frontend/react → tsq-react}/rules/server-parallel-fetching.md +0 -0
  415. /package/templates/base/skills/{frontend/react → tsq-react}/rules/state-location.md +0 -0
  416. /package/templates/base/skills/{retrospective → tsq-retro}/references/improvement-template.md +0 -0
  417. /package/templates/base/skills/{security → tsq-security}/rules/auth-patterns.md +0 -0
  418. /package/templates/base/skills/{security → tsq-security}/rules/dependency-security.md +0 -0
  419. /package/templates/base/skills/{security → tsq-security}/rules/input-validation.md +0 -0
  420. /package/templates/base/skills/{security → tsq-security}/rules/owasp-examples.md +0 -0
  421. /package/templates/base/skills/{security → tsq-security}/rules/secrets-management.md +0 -0
  422. /package/templates/base/skills/{security → tsq-security}/scripts/check-secrets.sh +0 -0
  423. /package/templates/base/skills/{stability-verification → tsq-stability}/references/release-checklist.md +0 -0
  424. /package/templates/base/skills/{stability-verification → tsq-stability}/references/security-fix-patterns.md +0 -0
  425. /package/templates/base/skills/{stability-verification → tsq-stability}/rules/verification-layers.md +0 -0
  426. /package/templates/base/skills/{stability-verification → tsq-stability}/rules/verification-workflow.md +0 -0
  427. /package/templates/base/skills/{stability-verification → tsq-stability}/scripts/verify.sh +0 -0
  428. /package/templates/base/skills/{methodology/tdd → tsq-tdd}/rules/real-world-example.md +0 -0
  429. /package/templates/base/skills/{methodology/tdd → tsq-tdd}/rules/techniques.md +0 -0
  430. /package/templates/base/skills/{testing → tsq-testing}/references/e2e-stability.md +0 -0
  431. /package/templates/base/skills/{testing → tsq-testing}/references/testing-patterns.md +0 -0
  432. /package/templates/base/skills/{typescript → tsq-typescript}/rules/type-patterns.md +0 -0
  433. /package/templates/base/skills/{typescript → tsq-typescript}/rules/utility-types.md +0 -0
@@ -1,781 +0,0 @@
1
- import path from 'path';
2
- import fs from 'fs-extra';
3
- import { colors, printHeader, printError, printSuccess, printKeyValue } from '../utils/colors.js';
4
- import { findProjectRoot } from '../lib/project.js';
5
- import { getTimestamp } from '../utils/date.js';
6
- import { loadWorkflowState, saveWorkflowState, isSequenceComplete, findSequenceForAgent, } from '../lib/workflow-state.js';
7
- import { getSequencesDir, getPhasesDir, buildSequenceLogData, buildPhaseGateData, loadSequenceTaskLogs, hasSemantic, } from './log.js';
8
- import { queryDaemon } from '../daemon/meta-cache.js';
9
- import { writeContext } from '../daemon/context-writer.js';
10
- import { parseAgentPrerequisites, checkStale, loadManifest } from '../lib/compiler.js';
11
- const LOG_SCHEMA_VERSION = '1.0.0';
12
- export function registerWorkflowCommand(program) {
13
- const wfCmd = program
14
- .command('workflow')
15
- .alias('wf')
16
- .description('Manage automated workflow (sequences, phases, automation toggles)');
17
- // tsq workflow set-phase <phase-id>
18
- wfCmd
19
- .command('set-phase <phase-id>')
20
- .description('Set the current active phase')
21
- .option('--force', 'Force phase transition even if gate conditions are not met')
22
- .action(async (phaseId, options) => {
23
- try {
24
- await setPhase(phaseId, options.force);
25
- }
26
- catch (error) {
27
- printError(error.message);
28
- process.exit(1);
29
- }
30
- });
31
- // tsq workflow add-sequence <seq-id>
32
- wfCmd
33
- .command('add-sequence <seq-id>')
34
- .description('Register a sequence for workflow tracking')
35
- .requiredOption('--agents <list>', 'Comma-separated expected agent types (e.g. developer,dba)')
36
- .option('--phase <id>', 'Phase ID (defaults to current phase)')
37
- .action(async (seqId, options) => {
38
- try {
39
- await addSequence(seqId, options);
40
- }
41
- catch (error) {
42
- printError(error.message);
43
- process.exit(1);
44
- }
45
- });
46
- // tsq workflow remove-sequence <seq-id>
47
- wfCmd
48
- .command('remove-sequence <seq-id>')
49
- .description('Remove a sequence from tracking')
50
- .action(async (seqId) => {
51
- try {
52
- await removeSequence(seqId);
53
- }
54
- catch (error) {
55
- printError(error.message);
56
- process.exit(1);
57
- }
58
- });
59
- // tsq workflow status
60
- wfCmd
61
- .command('status')
62
- .description('Show workflow state and automation status')
63
- .action(async () => {
64
- try {
65
- await showStatus();
66
- }
67
- catch (error) {
68
- printError(error.message);
69
- process.exit(1);
70
- }
71
- });
72
- // tsq workflow config <key> <value>
73
- wfCmd
74
- .command('config <key> <value>')
75
- .description('Toggle automation settings (e.g. sequence_log on/off)')
76
- .action(async (key, value) => {
77
- try {
78
- await setConfig(key, value);
79
- }
80
- catch (error) {
81
- printError(error.message);
82
- process.exit(1);
83
- }
84
- });
85
- // tsq task start --agent <agent> --scope <paths>
86
- wfCmd
87
- .command('task-start')
88
- .description('Prepare task context for a sub-agent (creates task-context.json)')
89
- .requiredOption('--agent <type>', 'Agent type (developer, qa, dba, etc.)')
90
- .option('--scope <paths>', 'Comma-separated scope paths (e.g. "src/auth,src/models")')
91
- .action(async (options) => {
92
- try {
93
- await taskStart(options);
94
- }
95
- catch (error) {
96
- printError(error.message);
97
- process.exit(1);
98
- }
99
- });
100
- // tsq workflow track-task <agent> <task-log-path> (internal — called by hook)
101
- wfCmd
102
- .command('track-task <agent> <task-log-path>')
103
- .description('(internal) Track a completed task in workflow state')
104
- .action(async (agent, taskLogPath) => {
105
- try {
106
- await trackTask(agent, taskLogPath);
107
- }
108
- catch {
109
- // Silent fail for hook usage — don't break the hook chain
110
- process.exit(0);
111
- }
112
- });
113
- // tsq workflow check (internal — called by hook on SessionEnd)
114
- wfCmd
115
- .command('check')
116
- .description('(internal) Check workflow state and auto-create L2/L3/gate/retro')
117
- .action(async () => {
118
- try {
119
- await checkAndAutomate();
120
- }
121
- catch {
122
- // Silent fail for hook usage
123
- process.exit(0);
124
- }
125
- });
126
- }
127
- // ============================================================
128
- // Commands
129
- // ============================================================
130
- async function setPhase(phaseId, force) {
131
- const projectRoot = await findProjectRoot();
132
- if (!projectRoot)
133
- throw new Error('Not a TimSquad project');
134
- const state = await loadWorkflowState(projectRoot);
135
- // Phase Gate enforcement: check current phase before transitioning
136
- if (state.current_phase && state.current_phase.id !== phaseId && state.automation.phase_gate) {
137
- const gateResult = await buildPhaseGateData(projectRoot, state.current_phase.id);
138
- if (!gateResult.can_transition) {
139
- if (force) {
140
- console.log(colors.warning(`\n ⚠ Phase gate BLOCKED for "${state.current_phase.id}" — forced override`));
141
- for (const condition of gateResult.blocking_conditions) {
142
- console.log(colors.dim(` - ${condition}`));
143
- }
144
- for (const report of gateResult.missing_reports) {
145
- console.log(colors.dim(` - Missing report: ${report}`));
146
- }
147
- console.log('');
148
- }
149
- else {
150
- const lines = [
151
- `Phase gate BLOCKED for "${state.current_phase.id}". Cannot transition to "${phaseId}".`,
152
- ];
153
- if (gateResult.blocking_conditions.length > 0) {
154
- lines.push('Blocking conditions:');
155
- for (const c of gateResult.blocking_conditions) {
156
- lines.push(` - ${c}`);
157
- }
158
- }
159
- if (gateResult.missing_reports.length > 0) {
160
- lines.push('Missing reports:');
161
- for (const r of gateResult.missing_reports) {
162
- lines.push(` - ${r}`);
163
- }
164
- }
165
- lines.push('', 'Use --force to override.');
166
- throw new Error(lines.join('\n'));
167
- }
168
- }
169
- }
170
- // Archive current phase if exists
171
- if (state.current_phase && state.current_phase.id !== phaseId) {
172
- state.completed_phases.push(state.current_phase.id);
173
- }
174
- state.current_phase = {
175
- id: phaseId,
176
- started_at: getTimestamp(),
177
- sequences: [],
178
- };
179
- // Atomic sync: update workflow.json and current-phase.json together
180
- await syncPhaseFiles(projectRoot, state);
181
- printSuccess(`Phase set: ${phaseId}`);
182
- printKeyValue('Automation', formatAutomation(state.automation));
183
- }
184
- /**
185
- * Atomically sync workflow.json and current-phase.json
186
- * Uses write-to-temp + rename pattern to prevent desync on failure
187
- */
188
- async function syncPhaseFiles(projectRoot, state) {
189
- const stateDir = path.join(projectRoot, '.timsquad', 'state');
190
- await fs.ensureDir(stateDir);
191
- const workflowPath = path.join(stateDir, 'workflow.json');
192
- const phasePath = path.join(stateDir, 'current-phase.json');
193
- const workflowTmp = workflowPath + '.tmp';
194
- const phaseTmp = phasePath + '.tmp';
195
- const phaseData = state.current_phase
196
- ? { current: state.current_phase.id, startedAt: state.current_phase.started_at, progress: 0 }
197
- : { current: 'planning', startedAt: getTimestamp(), progress: 0 };
198
- try {
199
- // 1. Write both temp files
200
- await fs.writeJson(workflowTmp, state, { spaces: 2 });
201
- await fs.writeJson(phaseTmp, phaseData, { spaces: 2 });
202
- // 2. Rename atomically (rename is atomic on POSIX filesystems)
203
- await fs.rename(workflowTmp, workflowPath);
204
- await fs.rename(phaseTmp, phasePath);
205
- }
206
- catch (err) {
207
- // Cleanup temp files on failure
208
- await fs.remove(workflowTmp).catch(() => { });
209
- await fs.remove(phaseTmp).catch(() => { });
210
- throw new Error(`Phase sync failed: ${err.message}`);
211
- }
212
- }
213
- async function addSequence(seqId, options) {
214
- const projectRoot = await findProjectRoot();
215
- if (!projectRoot)
216
- throw new Error('Not a TimSquad project');
217
- const state = await loadWorkflowState(projectRoot);
218
- const phaseId = options.phase || state.current_phase?.id;
219
- if (!phaseId) {
220
- throw new Error('No active phase. Run `tsq workflow set-phase <phase-id>` first.');
221
- }
222
- if (state.sequences[seqId]) {
223
- throw new Error(`Sequence ${seqId} already exists. Remove it first to re-add.`);
224
- }
225
- const agents = options.agents.split(',').map(a => a.trim());
226
- state.sequences[seqId] = {
227
- status: 'pending',
228
- phase: phaseId,
229
- expected_agents: agents,
230
- completed_tasks: [],
231
- report_path: null,
232
- l2_created: false,
233
- };
234
- // Add to current phase's sequence list
235
- if (state.current_phase && !state.current_phase.sequences.includes(seqId)) {
236
- state.current_phase.sequences.push(seqId);
237
- }
238
- await saveWorkflowState(projectRoot, state);
239
- printSuccess(`Sequence added: ${seqId}`);
240
- printKeyValue('Phase', phaseId);
241
- printKeyValue('Expected agents', agents.join(', '));
242
- }
243
- async function removeSequence(seqId) {
244
- const projectRoot = await findProjectRoot();
245
- if (!projectRoot)
246
- throw new Error('Not a TimSquad project');
247
- const state = await loadWorkflowState(projectRoot);
248
- if (!state.sequences[seqId]) {
249
- throw new Error(`Sequence ${seqId} not found`);
250
- }
251
- delete state.sequences[seqId];
252
- if (state.current_phase) {
253
- state.current_phase.sequences = state.current_phase.sequences.filter(s => s !== seqId);
254
- }
255
- await saveWorkflowState(projectRoot, state);
256
- printSuccess(`Sequence removed: ${seqId}`);
257
- }
258
- async function showStatus() {
259
- const projectRoot = await findProjectRoot();
260
- if (!projectRoot)
261
- throw new Error('Not a TimSquad project');
262
- const state = await loadWorkflowState(projectRoot);
263
- printHeader('Workflow Status');
264
- // Automation toggles
265
- console.log(colors.subheader(' Automation'));
266
- for (const [key, val] of Object.entries(state.automation)) {
267
- const icon = val ? colors.success('ON') : colors.dim('OFF');
268
- console.log(` ${key.padEnd(16)} ${icon}`);
269
- }
270
- // Current phase
271
- console.log(colors.subheader('\n Phase'));
272
- if (state.current_phase) {
273
- printKeyValue(' Current', state.current_phase.id);
274
- printKeyValue(' Started', state.current_phase.started_at);
275
- printKeyValue(' Sequences', state.current_phase.sequences.join(', ') || '(none)');
276
- }
277
- else {
278
- console.log(colors.dim(' No active phase. Run `tsq wf set-phase <id>`'));
279
- }
280
- // Sequences
281
- const seqEntries = Object.entries(state.sequences);
282
- if (seqEntries.length > 0) {
283
- console.log(colors.subheader('\n Sequences'));
284
- for (const [seqId, seq] of seqEntries) {
285
- const statusIcon = seq.status === 'completed'
286
- ? colors.success('✓')
287
- : seq.status === 'in_progress'
288
- ? colors.warning('▸')
289
- : seq.status === 'blocked'
290
- ? colors.error('✗')
291
- : colors.dim('○');
292
- const l2Icon = seq.l2_created ? colors.success('[L2]') : colors.dim('[--]');
293
- const completedAgents = seq.completed_tasks.map(t => t.agent);
294
- const remaining = seq.expected_agents.filter(a => !completedAgents.includes(a));
295
- console.log(` ${statusIcon} ${colors.agent(seqId)} ${l2Icon} ${colors.dim(`[${seq.phase}]`)}`);
296
- console.log(` agents: ${seq.expected_agents.map(a => completedAgents.includes(a) ? colors.success(a) : colors.dim(a)).join(', ')}`);
297
- if (remaining.length > 0 && seq.status !== 'completed') {
298
- console.log(` ${colors.dim(`waiting: ${remaining.join(', ')}`)}`);
299
- }
300
- }
301
- }
302
- // Completed phases
303
- if (state.completed_phases.length > 0) {
304
- console.log(colors.subheader('\n Completed Phases'));
305
- console.log(` ${state.completed_phases.join(', ')}`);
306
- }
307
- }
308
- async function setConfig(key, value) {
309
- const projectRoot = await findProjectRoot();
310
- if (!projectRoot)
311
- throw new Error('Not a TimSquad project');
312
- const state = await loadWorkflowState(projectRoot);
313
- const validKeys = Object.keys(state.automation);
314
- if (!validKeys.includes(key)) {
315
- throw new Error(`Invalid key: ${key}. Valid: ${validKeys.join(', ')}`);
316
- }
317
- const boolVal = value === 'on' || value === 'true' || value === '1';
318
- state.automation[key] = boolVal;
319
- await saveWorkflowState(projectRoot, state);
320
- printSuccess(`${key} = ${boolVal ? 'ON' : 'OFF'}`);
321
- }
322
- // ============================================================
323
- // Internal: Called by hooks
324
- // ============================================================
325
- /**
326
- * Prepare task context for a sub-agent.
327
- * Queries daemon IPC (or disk fallback) for scope data and writes task-context.json.
328
- */
329
- async function taskStart(options) {
330
- const projectRoot = await findProjectRoot();
331
- if (!projectRoot)
332
- throw new Error('Not a TimSquad project');
333
- const scopePaths = options.scope?.split(',').map(s => s.trim()) || [];
334
- if (scopePaths.length === 0) {
335
- printSuccess(`Task started for ${options.agent} (no scope filter)`);
336
- return;
337
- }
338
- // SCR (Single Change Rule) enforcement: detect compound tasks (11-B)
339
- const scrResult = analyzeScopeComplexity(scopePaths);
340
- if (scrResult.compound) {
341
- console.log(colors.warning(`\n ⚠ SCR Warning: ${scrResult.reason}`));
342
- if (scrResult.groups.length > 1) {
343
- console.log(colors.dim(' Suggested splits:'));
344
- scrResult.groups.forEach((g, i) => {
345
- console.log(colors.dim(` ${i + 1}. [${g.module}] ${g.paths.join(', ')}`));
346
- });
347
- }
348
- console.log(colors.dim(' Consider splitting into sequential single-scope tasks.\n'));
349
- }
350
- // Prerequisite auto-validation (11-A): check agent prerequisites against compiled specs
351
- await validateAgentPrerequisites(projectRoot, options.agent);
352
- // 데몬 IPC로 scope 쿼리
353
- let scopedData = null;
354
- try {
355
- const response = await queryDaemon(projectRoot, 'scope', { paths: scopePaths });
356
- scopedData = response.context;
357
- }
358
- catch {
359
- // 데몬 미실행 — fallback으로 MetaCache 사용
360
- const { MetaCache } = await import('../daemon/meta-cache.js');
361
- const cache = new MetaCache(projectRoot);
362
- await cache.load();
363
- scopedData = cache.filterByScope(scopePaths);
364
- }
365
- if (scopedData && Object.keys(scopedData.files).length > 0) {
366
- const ctxPath = await writeContext(projectRoot, options.agent, scopedData);
367
- printSuccess(`Task context created for ${options.agent}`);
368
- printKeyValue(' Context', ctxPath);
369
- printKeyValue(' Files', String(Object.keys(scopedData.files).length));
370
- }
371
- else {
372
- console.log(colors.dim(` No files matched scope: ${scopePaths.join(', ')}`));
373
- }
374
- }
375
- /**
376
- * Track a completed task in workflow state.
377
- * Called by SubagentStop hook: tsq workflow track-task <agent> <task-log-path>
378
- * Creates L2 sequence log inline when sequence is completed (no daemon dependency).
379
- */
380
- async function trackTask(agent, taskLogPath) {
381
- const projectRoot = await findProjectRoot();
382
- if (!projectRoot)
383
- return;
384
- const state = await loadWorkflowState(projectRoot);
385
- // Find matching sequence
386
- const seqId = findSequenceForAgent(state, agent);
387
- if (!seqId)
388
- return; // No match or ambiguous — skip silently
389
- const seq = state.sequences[seqId];
390
- seq.completed_tasks.push({
391
- agent,
392
- task_log: taskLogPath,
393
- completed_at: getTimestamp(),
394
- });
395
- // Update status
396
- if (seq.status === 'pending') {
397
- seq.status = 'in_progress';
398
- }
399
- if (isSequenceComplete(seq)) {
400
- seq.status = 'completed';
401
- // Inline L2 creation — don't wait for daemon or SessionEnd
402
- if (state.automation.sequence_log && !seq.l2_created) {
403
- try {
404
- const entry = await buildSequenceLogData(projectRoot, seqId, {
405
- phase: seq.phase,
406
- report: seq.report_path || '(auto) no report',
407
- verdict: 'proceed',
408
- });
409
- const seqDir = getSequencesDir(projectRoot);
410
- await fs.ensureDir(seqDir);
411
- await fs.writeJson(path.join(seqDir, `${seqId}.json`), entry, { spaces: 2 });
412
- seq.l2_created = true;
413
- await appendWorkflowLog(projectRoot, `[AUTO] L2 sequence log created: ${seqId}`);
414
- }
415
- catch { /* L2 creation failure — checkAndAutomate fallback will retry */ }
416
- }
417
- }
418
- await saveWorkflowState(projectRoot, state);
419
- }
420
- /**
421
- * Check workflow state and auto-create L2/L3/gate/retro.
422
- * Called by SessionEnd hook: tsq workflow check
423
- */
424
- async function checkAndAutomate() {
425
- const projectRoot = await findProjectRoot();
426
- if (!projectRoot)
427
- return;
428
- const state = await loadWorkflowState(projectRoot);
429
- let stateChanged = false;
430
- // 1. Auto-create L2 for completed sequences
431
- if (state.automation.sequence_log) {
432
- for (const [seqId, seq] of Object.entries(state.sequences)) {
433
- if (seq.status === 'completed' && !seq.l2_created) {
434
- try {
435
- const entry = await buildSequenceLogData(projectRoot, seqId, {
436
- phase: seq.phase,
437
- report: seq.report_path || `(auto) no report`,
438
- verdict: 'proceed',
439
- });
440
- const seqDir = getSequencesDir(projectRoot);
441
- await fs.ensureDir(seqDir);
442
- await fs.writeJson(path.join(seqDir, `${seqId}.json`), entry, { spaces: 2 });
443
- seq.l2_created = true;
444
- stateChanged = true;
445
- // Log the automation
446
- await appendWorkflowLog(projectRoot, `[AUTO] L2 sequence log created: ${seqId}`);
447
- }
448
- catch { /* skip on error */ }
449
- }
450
- }
451
- }
452
- // 2. Check if all sequences in current phase are completed
453
- if (state.current_phase && (state.automation.phase_log || state.automation.phase_gate)) {
454
- const phaseSeqs = state.current_phase.sequences;
455
- const allCompleted = phaseSeqs.length > 0 && phaseSeqs.every(id => {
456
- const seq = state.sequences[id];
457
- return seq && seq.status === 'completed' && seq.l2_created;
458
- });
459
- if (allCompleted) {
460
- const phaseId = state.current_phase.id;
461
- // 2a. Auto phase gate
462
- if (state.automation.phase_gate) {
463
- try {
464
- const gateResult = await buildPhaseGateData(projectRoot, phaseId);
465
- await appendWorkflowLog(projectRoot, `[AUTO] Phase gate ${phaseId}: ${gateResult.can_transition ? 'PASSED' : 'BLOCKED'}`);
466
- }
467
- catch { /* skip */ }
468
- }
469
- // 2b. Auto create L3 phase log
470
- if (state.automation.phase_log) {
471
- const phaseDir = getPhasesDir(projectRoot);
472
- const phaseLogPath = path.join(phaseDir, `${phaseId}.json`);
473
- if (!await fs.pathExists(phaseLogPath)) {
474
- try {
475
- const phaseLog = await buildPhaseLogData(projectRoot, phaseId, phaseSeqs);
476
- await fs.ensureDir(phaseDir);
477
- await fs.writeJson(phaseLogPath, phaseLog, { spaces: 2 });
478
- await appendWorkflowLog(projectRoot, `[AUTO] L3 phase log created: ${phaseId}`);
479
- stateChanged = true;
480
- }
481
- catch { /* skip */ }
482
- }
483
- }
484
- // 2c. Auto retro (basic KPT collection)
485
- if (state.automation.retro) {
486
- try {
487
- await autoRetro(projectRoot, phaseId, phaseSeqs, state);
488
- await appendWorkflowLog(projectRoot, `[AUTO] Retro generated: ${phaseId}`);
489
- }
490
- catch { /* skip */ }
491
- }
492
- }
493
- }
494
- // 3. Auto metrics (already handled by auto-metrics.sh, but log)
495
- if (state.automation.metrics) {
496
- // auto-metrics.sh handles this — no-op here
497
- }
498
- // 4. Pending feedback cleanup
499
- if (state.automation.feedback) {
500
- const feedbackDir = path.join(projectRoot, '.timsquad', 'feedback');
501
- const cleanedPending = [];
502
- for (const fbId of state.pending_feedback || []) {
503
- const fbPath = path.join(feedbackDir, `${fbId}.json`);
504
- if (await fs.pathExists(fbPath)) {
505
- try {
506
- const fb = await fs.readJson(fbPath);
507
- if (fb.status === 'open' || fb.status === 'in_review') {
508
- cleanedPending.push(fbId);
509
- }
510
- }
511
- catch { /* skip */ }
512
- }
513
- }
514
- if (cleanedPending.length !== (state.pending_feedback || []).length) {
515
- state.pending_feedback = cleanedPending;
516
- stateChanged = true;
517
- }
518
- if (cleanedPending.length > 0) {
519
- await appendWorkflowLog(projectRoot, `[AUTO] ${cleanedPending.length} pending feedback(s) blocking phase gate`);
520
- }
521
- }
522
- if (stateChanged) {
523
- await saveWorkflowState(projectRoot, state);
524
- }
525
- }
526
- // ============================================================
527
- // Internal helpers
528
- // ============================================================
529
- export async function buildPhaseLogData(projectRoot, phaseId, seqIds) {
530
- const seqDir = getSequencesDir(projectRoot);
531
- const now = getTimestamp();
532
- const seqLogs = [];
533
- let completed = 0, blocked = 0;
534
- for (const id of seqIds) {
535
- const seqPath = path.join(seqDir, `${id}.json`);
536
- if (await fs.pathExists(seqPath)) {
537
- const data = await fs.readJson(seqPath);
538
- seqLogs.push(data);
539
- if (data.execution.status === 'completed')
540
- completed++;
541
- else
542
- blocked++;
543
- }
544
- else {
545
- blocked++;
546
- }
547
- }
548
- let totalTasks = 0, totalSuccess = 0, totalRework = 0, totalFiles = 0;
549
- let totalIssues1 = 0, totalIssues2 = 0, totalIssues3 = 0;
550
- const durations = [];
551
- for (const seq of seqLogs) {
552
- totalTasks += seq.tasks.total;
553
- totalSuccess += seq.tasks.success;
554
- totalRework += seq.tasks.rework;
555
- durations.push(seq.execution.duration_ms);
556
- for (const axis of Object.values(seq.analysis)) {
557
- const r = axis;
558
- for (const issue of r.issues || []) {
559
- if (issue.level === 1)
560
- totalIssues1++;
561
- else if (issue.level === 2)
562
- totalIssues2++;
563
- else
564
- totalIssues3++;
565
- }
566
- }
567
- }
568
- for (const seqId of seqIds) {
569
- const taskLogs = await loadSequenceTaskLogs(projectRoot, seqId);
570
- for (const { data } of taskLogs) {
571
- totalFiles += data.mechanical?.files?.length || 0;
572
- }
573
- }
574
- const timestamps = seqLogs
575
- .map(s => [new Date(s.execution.started_at).getTime(), new Date(s.execution.completed_at).getTime()])
576
- .flat()
577
- .filter(t => t > 0);
578
- const leadTime = timestamps.length >= 2 ? Math.max(...timestamps) - Math.min(...timestamps) : 0;
579
- return {
580
- schema_version: LOG_SCHEMA_VERSION,
581
- trace: { phase_id: phaseId },
582
- execution: {
583
- status: blocked > 0 ? 'aborted' : 'completed',
584
- started_at: seqLogs[0]?.execution.started_at || now,
585
- completed_at: now,
586
- duration_ms: leadTime,
587
- sessions_count: seqLogs.length,
588
- },
589
- sequences: { total: seqIds.length, completed, blocked, ids: seqIds },
590
- aggregate_metrics: {
591
- total_tasks: totalTasks,
592
- task_success_rate: totalTasks > 0 ? totalSuccess / totalTasks : 0,
593
- task_rework_rate: totalTasks > 0 ? totalRework / totalTasks : 0,
594
- total_files_changed: totalFiles,
595
- total_issues: { level_1: totalIssues1, level_2: totalIssues2, level_3: totalIssues3 },
596
- ssot_conformance_rate: 0,
597
- mean_sequence_duration_ms: durations.length > 0 ? durations.reduce((a, b) => a + b, 0) / durations.length : 0,
598
- },
599
- dora_derived: {
600
- lead_time_ms: leadTime,
601
- change_failure_rate: totalTasks > 0 ? (totalTasks - totalSuccess) / totalTasks : 0,
602
- mean_recovery_time_ms: null,
603
- },
604
- planning: {
605
- original_sequences: seqIds,
606
- added_sequences: [],
607
- removed_sequences: [],
608
- scope_changes: [],
609
- plan_adherence_rate: 1,
610
- },
611
- retrospective: { keep: [], problem: [], try: [] },
612
- knowledge_extracted: [],
613
- };
614
- }
615
- /**
616
- * Auto-generate a basic retrospective from task/sequence data
617
- */
618
- async function autoRetro(projectRoot, phaseId, seqIds, state) {
619
- const retroDir = path.join(projectRoot, '.timsquad', 'retrospective', 'cycles');
620
- await fs.ensureDir(retroDir);
621
- const retroPath = path.join(retroDir, `${phaseId}-auto.md`);
622
- if (await fs.pathExists(retroPath))
623
- return; // Already exists
624
- const keep = [];
625
- const problem = [];
626
- const tryItems = [];
627
- // Analyze task logs for patterns
628
- let totalTasks = 0, tasksWithSemantic = 0, totalRework = 0;
629
- for (const seqId of seqIds) {
630
- const taskLogs = await loadSequenceTaskLogs(projectRoot, seqId);
631
- for (const { data } of taskLogs) {
632
- totalTasks++;
633
- if (hasSemantic(data.semantic))
634
- tasksWithSemantic++;
635
- if (data.semantic?.issues?.length) {
636
- for (const issue of data.semantic.issues) {
637
- if (issue.level >= 2) {
638
- problem.push(`[${seqId}] ${issue.description}`);
639
- }
640
- }
641
- }
642
- }
643
- const seq = state.sequences[seqId];
644
- if (seq) {
645
- const reworkCount = seq.completed_tasks.length - seq.expected_agents.length;
646
- if (reworkCount > 0)
647
- totalRework += reworkCount;
648
- }
649
- }
650
- // Generate observations
651
- const semanticCoverage = totalTasks > 0 ? Math.round((tasksWithSemantic / totalTasks) * 100) : 0;
652
- if (semanticCoverage >= 80) {
653
- keep.push(`Semantic coverage ${semanticCoverage}% — good documentation discipline`);
654
- }
655
- else if (semanticCoverage < 50) {
656
- problem.push(`Semantic coverage ${semanticCoverage}% — agents not consistently enriching logs`);
657
- tryItems.push('Enforce tsq log enrich in agent protocols');
658
- }
659
- if (totalRework === 0) {
660
- keep.push('No rework detected — first-pass quality was high');
661
- }
662
- else {
663
- problem.push(`${totalRework} rework tasks detected`);
664
- tryItems.push('Review SSOT alignment before implementation starts');
665
- }
666
- if (seqIds.length > 0) {
667
- keep.push(`${seqIds.length} sequences completed in phase ${phaseId}`);
668
- }
669
- // Write retro markdown
670
- const content = `# Retrospective: ${phaseId} (Auto-generated)
671
-
672
- > Generated at ${getTimestamp()} by tsq workflow check
673
-
674
- ## Keep
675
- ${keep.map(k => `- ${k}`).join('\n') || '- (none detected)'}
676
-
677
- ## Problem
678
- ${problem.map(p => `- ${p}`).join('\n') || '- (none detected)'}
679
-
680
- ## Try
681
- ${tryItems.map(t => `- ${t}`).join('\n') || '- (no suggestions)'}
682
-
683
- ---
684
-
685
- ## Metrics
686
- - Total tasks: ${totalTasks}
687
- - Semantic coverage: ${semanticCoverage}%
688
- - Rework tasks: ${totalRework}
689
- - Sequences: ${seqIds.join(', ')}
690
- `;
691
- await fs.writeFile(retroPath, content, 'utf-8');
692
- }
693
- /**
694
- * Append to workflow automation log (for debugging/auditing)
695
- */
696
- async function appendWorkflowLog(projectRoot, message) {
697
- const logDir = path.join(projectRoot, '.timsquad', 'logs');
698
- const logFile = path.join(logDir, 'workflow-automation.log');
699
- await fs.ensureDir(logDir);
700
- const line = `${getTimestamp()} ${message}\n`;
701
- await fs.appendFile(logFile, line, 'utf-8');
702
- }
703
- function analyzeScopeComplexity(scopePaths) {
704
- // Group by logical module (2nd-level dir or top-level for shallow paths)
705
- const moduleMap = new Map();
706
- for (const p of scopePaths) {
707
- const parts = p.split('/').filter(Boolean);
708
- // Use first 2 segments as module key (e.g. "src/commands", "src/lib", "tests/unit")
709
- const moduleKey = parts.length >= 2 ? `${parts[0]}/${parts[1]}` : parts[0] || p;
710
- if (!moduleMap.has(moduleKey))
711
- moduleMap.set(moduleKey, []);
712
- moduleMap.get(moduleKey).push(p);
713
- }
714
- const groups = [...moduleMap.entries()].map(([module, paths]) => ({ module, paths }));
715
- // Exclude test-related modules from independent module count
716
- const nonTestModules = groups.filter(g => !g.module.startsWith('tests/') && !g.module.startsWith('__tests__/'));
717
- const topLevelDirs = new Set(scopePaths.map(p => p.split('/')[0]));
718
- if (nonTestModules.length > 2) {
719
- return {
720
- compound: true,
721
- reason: `Scope spans ${nonTestModules.length} independent modules (${nonTestModules.map(g => g.module).join(', ')})`,
722
- groups,
723
- };
724
- }
725
- if (topLevelDirs.size > 2) {
726
- return {
727
- compound: true,
728
- reason: `Scope spans ${topLevelDirs.size} top-level directories (${[...topLevelDirs].join(', ')})`,
729
- groups,
730
- };
731
- }
732
- return { compound: false, reason: '', groups };
733
- }
734
- /**
735
- * Validate agent prerequisites against compiled specs (11-A).
736
- * Checks: agent file exists, prerequisites resolved, specs not stale.
737
- */
738
- async function validateAgentPrerequisites(projectRoot, agent) {
739
- const agentPath = path.join(projectRoot, '.claude', 'agents', `${agent}.md`);
740
- if (!await fs.pathExists(agentPath))
741
- return; // No agent file — skip validation
742
- const agentContent = await fs.readFile(agentPath, 'utf-8');
743
- const prereqs = parseAgentPrerequisites(agentContent);
744
- if (prereqs.length === 0)
745
- return; // No prerequisites declared
746
- const controllerDir = path.join(projectRoot, '.claude', 'skills', 'controller');
747
- const manifest = await loadManifest(controllerDir);
748
- if (!manifest) {
749
- console.log(colors.warning('\n ⚠ Prerequisite Warning: No compile manifest found'));
750
- console.log(colors.dim(' Run `tsq compile` before delegating tasks.\n'));
751
- return;
752
- }
753
- // Check missing prerequisites
754
- const compiledSources = new Set(manifest.entries.map(e => e.source.replace('ssot/', '').replace('.md', '')));
755
- const missing = prereqs.filter(p => !compiledSources.has(p));
756
- if (missing.length > 0) {
757
- console.log(colors.warning(`\n ⚠ Missing prerequisites for agent "${agent}":`));
758
- for (const m of missing) {
759
- console.log(colors.dim(` - ${m} (not compiled)`));
760
- }
761
- console.log(colors.dim(' Run `tsq compile` to resolve.\n'));
762
- }
763
- // Check stale specs
764
- const staleItems = await checkStale(projectRoot, controllerDir);
765
- const relevantStale = staleItems.filter(s => {
766
- const source = s.source.replace('ssot/', '').replace('.md', '');
767
- return prereqs.includes(source) || s.source === '*';
768
- });
769
- if (relevantStale.length > 0) {
770
- console.log(colors.warning(`\n ⚠ Stale specs detected for agent "${agent}":`));
771
- for (const s of relevantStale) {
772
- console.log(colors.dim(` - ${s.source}: ${s.reason}`));
773
- }
774
- console.log(colors.dim(' Run `tsq compile` to refresh.\n'));
775
- }
776
- }
777
- function formatAutomation(auto) {
778
- const enabled = Object.entries(auto).filter(([, v]) => v).map(([k]) => k);
779
- return enabled.length > 0 ? enabled.join(', ') : 'all OFF';
780
- }
781
- //# sourceMappingURL=workflow.js.map