its-magic 0.1.2-9 → 0.1.3-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.
Files changed (237) hide show
  1. package/README.md +1602 -755
  2. package/bin/its-magic.js +121 -11
  3. package/bin/postinstall.js +93 -0
  4. package/installer.ps1 +759 -0
  5. package/installer.py +1036 -0
  6. package/installer.sh +649 -0
  7. package/package.json +18 -14
  8. package/scripts/check_intake_template_parity.py +312 -0
  9. package/scripts/doc_profile_lib.py +415 -0
  10. package/scripts/guard_installer_publish.py +88 -0
  11. package/scripts/intake_bug_routing_guard.py +67 -0
  12. package/scripts/intake_evidence_lib.py +802 -0
  13. package/scripts/intake_evidence_validate.py +73 -0
  14. package/scripts/materialize_codebase_map.py +184 -0
  15. package/scripts/remote_config_summary.py +243 -0
  16. package/template/.cursor/agents/curator.mdc +35 -0
  17. package/template/.cursor/agents/dev.mdc +29 -0
  18. package/template/.cursor/agents/po.mdc +141 -0
  19. package/template/.cursor/agents/qa.mdc +28 -0
  20. package/template/.cursor/agents/release.mdc +28 -0
  21. package/template/.cursor/agents/security.mdc +98 -0
  22. package/template/.cursor/agents/tech-lead.mdc +57 -0
  23. package/template/.cursor/commands/architecture.md +127 -0
  24. package/template/.cursor/commands/ask.md +55 -0
  25. package/template/.cursor/commands/auto.md +533 -0
  26. package/template/.cursor/commands/discovery.md +47 -0
  27. package/template/.cursor/commands/execute.md +343 -0
  28. package/template/.cursor/commands/intake.md +323 -0
  29. package/template/.cursor/commands/map-codebase.md +46 -0
  30. package/template/.cursor/commands/memory-audit.md +175 -0
  31. package/template/.cursor/commands/milestone-complete.md +51 -0
  32. package/template/.cursor/commands/milestone-start.md +59 -0
  33. package/template/.cursor/commands/pause.md +64 -0
  34. package/{.cursor/commands/gsd-phase-context.md → template/.cursor/commands/phase-context.md} +6 -2
  35. package/template/.cursor/commands/plan-verify.md +34 -0
  36. package/template/.cursor/commands/qa.md +226 -0
  37. package/template/.cursor/commands/quick.md +41 -0
  38. package/template/.cursor/commands/refresh-context.md +82 -0
  39. package/template/.cursor/commands/release.md +523 -0
  40. package/template/.cursor/commands/research.md +49 -0
  41. package/template/.cursor/commands/resume.md +67 -0
  42. package/template/.cursor/commands/security-review.md +81 -0
  43. package/template/.cursor/commands/sprint-plan.md +103 -0
  44. package/template/.cursor/commands/status-reconcile.md +95 -0
  45. package/template/.cursor/commands/verify-work.md +152 -0
  46. package/template/.cursor/dev-environment.json.example +22 -0
  47. package/{.cursor → template/.cursor}/hooks/README.md +3 -2
  48. package/{.cursor/hooks/gsd-hook.py → template/.cursor/hooks/hook.py} +15 -6
  49. package/template/.cursor/hooks.json +26 -0
  50. package/template/.cursor/remote.json +31 -0
  51. package/template/.cursor/rules/caveman.mdc +184 -0
  52. package/template/.cursor/rules/coding-standards.mdc +39 -0
  53. package/template/.cursor/rules/core.mdc +111 -0
  54. package/template/.cursor/rules/handoffs.mdc +27 -0
  55. package/template/.cursor/rules/quality.mdc +49 -0
  56. package/template/.cursor/scratchpad.local.example.md +323 -0
  57. package/template/.cursor/scratchpad.md +324 -0
  58. package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/SKILL.md +2 -2
  59. package/template/.cursorignore +6 -0
  60. package/template/.env.example +28 -0
  61. package/template/.github/workflows/ci.yml +194 -0
  62. package/{.github → template/.github}/workflows/deploy.yml +5 -2
  63. package/template/.its-magic-version +1 -0
  64. package/template/CHANGELOG.md +11 -0
  65. package/template/README.md +1602 -0
  66. package/template/decisions/DEC-0001.md +11 -0
  67. package/template/decisions/DEC-0002.md +11 -0
  68. package/template/docs/developer/README.md +44 -0
  69. package/template/docs/engineering/architecture.md +9 -0
  70. package/template/docs/engineering/artifact-ordering-policy.md +48 -0
  71. package/template/docs/engineering/artifact-ownership-policy.md +57 -0
  72. package/template/docs/engineering/auto-orchestration-reference.md +1211 -0
  73. package/{docs → template/docs}/engineering/codebase-map.md +0 -5
  74. package/template/docs/engineering/compatibility-report.md +20 -0
  75. package/template/docs/engineering/compatibility-signals.md +7 -0
  76. package/template/docs/engineering/component-scope-report.md +16 -0
  77. package/template/docs/engineering/component-scope.md +19 -0
  78. package/template/docs/engineering/context/installer-owned-paths.manifest +96 -0
  79. package/template/docs/engineering/context/readme-section-affinity.json +30 -0
  80. package/template/docs/engineering/decisions.md +16 -0
  81. package/template/docs/engineering/legacy-drift-audit.md +21 -0
  82. package/template/docs/engineering/manifests/components/api-gateway.manifest.yaml +12 -0
  83. package/template/docs/engineering/manifests/registry.manifest.yaml +20 -0
  84. package/template/docs/engineering/manifests/repo.manifest.yaml +11 -0
  85. package/template/docs/engineering/phase-context.md +16 -0
  86. package/template/docs/engineering/release-targets.json +123 -0
  87. package/template/docs/engineering/research.md +29 -0
  88. package/template/docs/engineering/runbook.md +2391 -0
  89. package/template/docs/engineering/runtime-connectivity.md +81 -0
  90. package/template/docs/engineering/security-review.md +33 -0
  91. package/template/docs/engineering/spec-pack/README.md +20 -0
  92. package/template/docs/engineering/state-archive/README.md +15 -0
  93. package/template/docs/engineering/state.md +20 -0
  94. package/template/docs/engineering/status-normalization-report.md +19 -0
  95. package/template/docs/engineering/token-cost-parity-manifest.md +16 -0
  96. package/template/docs/engineering/us-0084-remote-e2e.md +44 -0
  97. package/template/docs/product/acceptance.md +1 -0
  98. package/template/docs/product/backlog.md +5 -0
  99. package/template/docs/product/vision.md +11 -0
  100. package/template/docs/user-guides/README.md +40 -0
  101. package/{handoffs → template/handoffs}/dev_to_qa.md +0 -3
  102. package/{handoffs → template/handoffs}/po_to_tl.md +0 -3
  103. package/{handoffs → template/handoffs}/qa_to_dev.md +1 -2
  104. package/template/handoffs/release_notes.md +51 -0
  105. package/template/handoffs/release_queue.md +47 -0
  106. package/template/handoffs/release_to_dev.md +31 -0
  107. package/template/handoffs/releases/Sxxxx-release-notes.md +62 -0
  108. package/template/handoffs/releases/vX.Y.Z-release-notes.md.example +21 -0
  109. package/template/handoffs/resume_brief.md +14 -0
  110. package/{handoffs → template/handoffs}/tl_to_dev.md +0 -2
  111. package/template/handoffs/token_cost_runs/README.md +26 -0
  112. package/template/its_magic/.its-magic-version +1 -0
  113. package/template/its_magic/README.md +9 -0
  114. package/template/scripts/auto_outer_driver.py +521 -0
  115. package/template/scripts/caveman_compress_input.py +903 -0
  116. package/template/scripts/check_downstream_ci_guard.py +67 -0
  117. package/template/scripts/check_intake_template_parity.py +312 -0
  118. package/template/scripts/check_token_cost_parity.py +69 -0
  119. package/template/scripts/dev_environment_lib.py +601 -0
  120. package/template/scripts/doc_profile_lib.py +415 -0
  121. package/template/scripts/downstream_ci_guard_lib.py +222 -0
  122. package/template/scripts/enforce-triad-hot-surface.py +753 -0
  123. package/template/scripts/guard_installer_publish.py +88 -0
  124. package/template/scripts/intake_bug_resume_brief_refresh.py +303 -0
  125. package/template/scripts/intake_bug_routing_guard.py +67 -0
  126. package/template/scripts/intake_evidence_lib.py +802 -0
  127. package/template/scripts/intake_evidence_validate.py +73 -0
  128. package/template/scripts/materialize_codebase_map.py +184 -0
  129. package/template/scripts/pack_json_validate.py +130 -0
  130. package/template/scripts/project_readme_coverage_lib.py +417 -0
  131. package/template/scripts/readme_feature_coverage_lib.py +608 -0
  132. package/{scripts → template/scripts}/release-all.sh +27 -4
  133. package/template/scripts/release_changelog_backfill.py +153 -0
  134. package/template/scripts/release_changelog_lib.py +544 -0
  135. package/template/scripts/release_changelog_validate.py +134 -0
  136. package/template/scripts/remote_config_summary.py +243 -0
  137. package/template/scripts/sync_push_gates.py +198 -0
  138. package/template/scripts/token_cost_compare.py +40 -0
  139. package/template/scripts/token_cost_lib.py +108 -0
  140. package/template/scripts/uat_probe_lib.py +868 -0
  141. package/template/scripts/validate-and-push.ps1 +280 -0
  142. package/template/scripts/validate-and-push.sh +243 -0
  143. package/template/scripts/validate_doc_profile.py +103 -0
  144. package/template/scripts/validate_project_readme_coverage.py +151 -0
  145. package/template/scripts/validate_readme_feature_coverage.py +140 -0
  146. package/template/sprints/S0001/progress.md +1 -0
  147. package/template/sprints/S0001/qa-findings.md +9 -0
  148. package/template/sprints/S0001/release-findings.md +24 -0
  149. package/template/sprints/S0001/sprint.md +9 -0
  150. package/template/sprints/S0001/summary.md +7 -0
  151. package/template/sprints/S0001/tasks.md +1 -0
  152. package/template/sprints/S0001/uat.json +6 -0
  153. package/template/sprints/S0001/uat.md +5 -0
  154. package/template/sprints/quick/Q0001/summary.md +1 -0
  155. package/{sprints → template/sprints}/quick/Q0001/task.json +0 -1
  156. package/.cursor/agents/curator.mdc +0 -21
  157. package/.cursor/agents/dev.mdc +0 -20
  158. package/.cursor/agents/po.mdc +0 -19
  159. package/.cursor/agents/qa.mdc +0 -19
  160. package/.cursor/agents/release.mdc +0 -19
  161. package/.cursor/agents/tech-lead.mdc +0 -21
  162. package/.cursor/commands/gsd-architecture.md +0 -29
  163. package/.cursor/commands/gsd-auto.md +0 -27
  164. package/.cursor/commands/gsd-discovery.md +0 -27
  165. package/.cursor/commands/gsd-execute.md +0 -32
  166. package/.cursor/commands/gsd-intake.md +0 -28
  167. package/.cursor/commands/gsd-map-codebase.md +0 -25
  168. package/.cursor/commands/gsd-milestone-complete.md +0 -24
  169. package/.cursor/commands/gsd-milestone-start.md +0 -26
  170. package/.cursor/commands/gsd-pause.md +0 -25
  171. package/.cursor/commands/gsd-plan-verify.md +0 -26
  172. package/.cursor/commands/gsd-qa.md +0 -28
  173. package/.cursor/commands/gsd-quick.md +0 -24
  174. package/.cursor/commands/gsd-refresh-context.md +0 -26
  175. package/.cursor/commands/gsd-release.md +0 -29
  176. package/.cursor/commands/gsd-research.md +0 -28
  177. package/.cursor/commands/gsd-resume.md +0 -26
  178. package/.cursor/commands/gsd-sprint-plan.md +0 -30
  179. package/.cursor/commands/gsd-verify-work.md +0 -25
  180. package/.cursor/hooks.json +0 -26
  181. package/.cursor/plans/cursor-gsd-team-kit_8cfee9b8.plan.md +0 -57
  182. package/.cursor/remote.json +0 -18
  183. package/.cursor/rules/gsd-core.mdc +0 -18
  184. package/.cursor/rules/gsd-handoffs.mdc +0 -10
  185. package/.cursor/rules/gsd-quality.mdc +0 -15
  186. package/.cursor/scratchpad.md +0 -34
  187. package/.github/workflows/ci.yml +0 -47
  188. package/decisions/DEC-0001.md +0 -21
  189. package/decisions/DEC-0002.md +0 -21
  190. package/docs/engineering/architecture.md +0 -354
  191. package/docs/engineering/decisions.md +0 -6
  192. package/docs/engineering/research.md +0 -11
  193. package/docs/engineering/runbook.md +0 -32
  194. package/docs/engineering/state.md +0 -33
  195. package/docs/product/acceptance.md +0 -6
  196. package/docs/product/backlog.md +0 -7
  197. package/docs/product/vision.md +0 -46
  198. package/gsd-installer.ps1 +0 -189
  199. package/gsd-installer.py +0 -195
  200. package/gsd-installer.sh +0 -201
  201. package/handoffs/release_notes.md +0 -14
  202. package/handoffs/resume_brief.md +0 -8
  203. package/milestones/M0001/milestone.json +0 -7
  204. package/milestones/M0001/phases.json +0 -9
  205. package/milestones/M0001/progress.md +0 -3
  206. package/milestones/M0001/summary.md +0 -3
  207. package/scripts/generate-release-notes.ps1 +0 -74
  208. package/scripts/generate-release-notes.sh +0 -63
  209. package/scripts/release-all.ps1 +0 -423
  210. package/sprints/S0001/progress.md +0 -4
  211. package/sprints/S0001/qa-findings.md +0 -113
  212. package/sprints/S0001/sprint.md +0 -70
  213. package/sprints/S0001/summary.md +0 -46
  214. package/sprints/S0001/tasks.md +0 -35
  215. package/sprints/S0001/uat.json +0 -8
  216. package/sprints/S0001/uat.md +0 -8
  217. package/sprints/quick/Q0001/summary.md +0 -3
  218. /package/{.cursor/rules/gsd-escalation.mdc → template/.cursor/rules/escalation.mdc} +0 -0
  219. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/acceptance.json +0 -0
  220. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/acceptance.md +0 -0
  221. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/architecture.json +0 -0
  222. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/architecture.md +0 -0
  223. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/decision.json +0 -0
  224. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/decision.md +0 -0
  225. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/handoff.json +0 -0
  226. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/handoff.md +0 -0
  227. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/milestone.json +0 -0
  228. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/phase-context.json +0 -0
  229. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/plan-verify.json +0 -0
  230. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/sprint.json +0 -0
  231. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/sprint.md +0 -0
  232. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/story.json +0 -0
  233. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/story.md +0 -0
  234. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/uat.json +0 -0
  235. /package/{docs → template/docs}/engineering/context/phase-template.json +0 -0
  236. /package/{docs → template/docs}/engineering/dependencies.json +0 -0
  237. /package/{sprints → template/sprints}/S0001/plan-verify.json +0 -0
@@ -1,354 +0,0 @@
1
- # Architecture
2
-
3
- ## Overview
4
-
5
- The application follows a **frontend + backend split** with a clear API boundary. Both layers use TypeScript to enable shared type definitions and validation schemas across the stack.
6
-
7
- ```
8
- ┌──────────────────────────────────────────────────┐
9
- │ Frontend (SPA) │
10
- │ React 18 · TypeScript · Vite · TanStack Query │
11
- │ │
12
- │ ┌────────────┐ ┌──────────┐ ┌──────────────┐ │
13
- │ │ Filter Bar │ │ List View│ │ Detail Panel │ │
14
- │ └─────┬──────┘ └────┬─────┘ └──────┬───────┘ │
15
- │ └───────────────┴───────────────┘ │
16
- │ │ HTTP/JSON │
17
- └────────────────────────┼─────────────────────────┘
18
-
19
- ┌───────────────┴───────────────┐
20
- │ API Gateway │
21
- │ Express · TypeScript · Zod │
22
- ├───────────────────────────────┤
23
- │ Routes → Validators → Svc │
24
- └───────────────┬───────────────┘
25
-
26
- ┌──────────┴──────────┐
27
- │ Data Layer │
28
- │ SQLite (dev/test) │
29
- │ PostgreSQL (prod) │
30
- └─────────────────────┘
31
- ```
32
-
33
- ## Components
34
-
35
- ### Frontend (`/frontend`)
36
-
37
- | Concern | Choice | Rationale |
38
- |---------|--------|-----------|
39
- | Framework | React 18 | Component model fits filter bar, list, and panel UX |
40
- | Build | Vite | Fast HMR, native TS support |
41
- | State / data fetching | TanStack Query | Cache-first fetching, optimistic updates for detail panel (US-0003) |
42
- | Routing | React Router v6 | Filter state persisted in URL search params (answers PO open question) |
43
- | Styling | Tailwind CSS | Utility-first, fast iteration on chip/filter UI |
44
-
45
- Key modules:
46
-
47
- - `components/FilterBar.tsx` — chip-based multi-select filters (US-0002)
48
- - `components/ItemList.tsx` — virtualized list with keyboard nav
49
- - `components/DetailPanel.tsx` — slide-over panel, arrow-key traversal (US-0003)
50
- - `components/EmptyState.tsx` — friendly empty state with reset action (US-0004)
51
- - `hooks/useFilters.ts` — reads/writes filter state to URL search params
52
- - `api/client.ts` — typed API client generated from shared schema
53
-
54
- ### Backend (`/backend`)
55
-
56
- | Concern | Choice | Rationale |
57
- |---------|--------|-----------|
58
- | Runtime | Node.js 20 LTS | Matches frontend language (TypeScript) |
59
- | Framework | Express 5 | Minimal, well-understood, large middleware ecosystem |
60
- | Validation | Zod 3 | Shared schemas with frontend; generates OpenAPI |
61
- | ORM | Drizzle ORM | Lightweight, type-safe, supports SQLite + PostgreSQL |
62
- | API spec | OpenAPI 3.1 (auto-generated from Zod via `zod-to-openapi`) | Single source of truth |
63
-
64
- Key modules:
65
-
66
- - `routes/items.ts` — CRUD + filtered list endpoint
67
- - `middleware/validate.ts` — generic Zod validation middleware
68
- - `services/item.service.ts` — business logic
69
- - `db/schema.ts` — Drizzle table definitions
70
-
71
- ### Shared (`/shared`)
72
-
73
- A small package consumed by both frontend and backend (via TypeScript path aliases or a workspace package):
74
-
75
- - `schemas/item.schema.ts` — Zod schemas for Item create/update/filter
76
- - `schemas/filter.schema.ts` — Zod schema for filter query params
77
- - `types/` — inferred TypeScript types (`z.infer<typeof ...>`)
78
-
79
- ## API Schema
80
-
81
- ### Base URL
82
-
83
- `/api/v1`
84
-
85
- ### Endpoints
86
-
87
- #### `GET /items`
88
-
89
- Returns a filtered, paginated list of items.
90
-
91
- **Query parameters** (all optional):
92
-
93
- | Param | Type | Description |
94
- |-------|------|-------------|
95
- | `status` | `string[]` | Filter by status (comma-separated) |
96
- | `category` | `string[]` | Filter by category (comma-separated) |
97
- | `dateFrom` | `ISO 8601 string` | Items created on or after |
98
- | `dateTo` | `ISO 8601 string` | Items created on or before |
99
- | `search` | `string` | Free-text search |
100
- | `page` | `integer ≥ 1` | Page number (default 1) |
101
- | `pageSize` | `integer 1–100` | Items per page (default 25) |
102
- | `sort` | `string` | Sort field (e.g. `createdAt`, `title`) |
103
- | `order` | `asc \| desc` | Sort direction (default `desc`) |
104
-
105
- **Response `200`:**
106
-
107
- ```json
108
- {
109
- "data": [
110
- {
111
- "id": "uuid",
112
- "title": "string",
113
- "status": "open | in_progress | done",
114
- "category": "string",
115
- "description": "string",
116
- "createdAt": "ISO 8601",
117
- "updatedAt": "ISO 8601"
118
- }
119
- ],
120
- "meta": {
121
- "page": 1,
122
- "pageSize": 25,
123
- "totalItems": 142,
124
- "totalPages": 6,
125
- "activeFilters": 2
126
- }
127
- }
128
- ```
129
-
130
- #### `GET /items/:id`
131
-
132
- Returns a single item with full details (used by the detail panel).
133
-
134
- **Response `200`:**
135
-
136
- ```json
137
- {
138
- "data": {
139
- "id": "uuid",
140
- "title": "string",
141
- "status": "open | in_progress | done",
142
- "category": "string",
143
- "description": "string",
144
- "metadata": {},
145
- "createdAt": "ISO 8601",
146
- "updatedAt": "ISO 8601"
147
- }
148
- }
149
- ```
150
-
151
- **Response `404`:** `{ "error": { "code": "NOT_FOUND", "message": "Item not found" } }`
152
-
153
- #### `POST /items`
154
-
155
- Creates a new item.
156
-
157
- **Request body:**
158
-
159
- ```json
160
- {
161
- "title": "string (1–200 chars, required)",
162
- "status": "open | in_progress | done (default: open)",
163
- "category": "string (1–100 chars, required)",
164
- "description": "string (max 5000 chars, optional)"
165
- }
166
- ```
167
-
168
- **Response `201`:** Full item object.
169
-
170
- #### `PATCH /items/:id`
171
-
172
- Partial update. Same fields as POST, all optional. Returns updated item.
173
-
174
- #### `DELETE /items/:id`
175
-
176
- Soft-delete. Returns `204 No Content`.
177
-
178
- ### Error envelope
179
-
180
- All errors follow a consistent shape:
181
-
182
- ```json
183
- {
184
- "error": {
185
- "code": "VALIDATION_ERROR | NOT_FOUND | INTERNAL_ERROR",
186
- "message": "Human-readable message",
187
- "details": []
188
- }
189
- }
190
- ```
191
-
192
- For validation errors, `details` contains per-field issues:
193
-
194
- ```json
195
- {
196
- "error": {
197
- "code": "VALIDATION_ERROR",
198
- "message": "Request validation failed",
199
- "details": [
200
- { "field": "title", "message": "Required" },
201
- { "field": "pageSize", "message": "Must be between 1 and 100" }
202
- ]
203
- }
204
- }
205
- ```
206
-
207
- ## Validation Strategy
208
-
209
- ### Principle: Single schema, both sides
210
-
211
- Zod schemas defined in `/shared` are the **single source of truth** for validation. They are consumed in three places:
212
-
213
- 1. **Backend middleware** — `validate.ts` parses `req.query`, `req.body`, and `req.params` before the handler runs. Invalid requests receive a `400` with structured error details.
214
- 2. **Frontend forms** — The same Zod schemas integrate with React Hook Form via `@hookform/resolvers/zod` for inline field validation.
215
- 3. **API client** — Response data is parsed through Zod schemas on the frontend to catch contract drift at runtime.
216
-
217
- ### Schema example (shared)
218
-
219
- ```typescript
220
- // shared/schemas/item.schema.ts
221
- import { z } from "zod";
222
-
223
- export const ItemStatus = z.enum(["open", "in_progress", "done"]);
224
-
225
- export const CreateItemSchema = z.object({
226
- title: z.string().min(1).max(200),
227
- status: ItemStatus.default("open"),
228
- category: z.string().min(1).max(100),
229
- description: z.string().max(5000).optional(),
230
- });
231
-
232
- export const UpdateItemSchema = CreateItemSchema.partial();
233
-
234
- export const ItemFilterSchema = z.object({
235
- status: z.array(ItemStatus).optional(),
236
- category: z.array(z.string()).optional(),
237
- dateFrom: z.string().datetime().optional(),
238
- dateTo: z.string().datetime().optional(),
239
- search: z.string().max(200).optional(),
240
- page: z.coerce.number().int().min(1).default(1),
241
- pageSize: z.coerce.number().int().min(1).max(100).default(25),
242
- sort: z.enum(["createdAt", "updatedAt", "title"]).default("createdAt"),
243
- order: z.enum(["asc", "desc"]).default("desc"),
244
- });
245
-
246
- export type CreateItem = z.infer<typeof CreateItemSchema>;
247
- export type UpdateItem = z.infer<typeof UpdateItemSchema>;
248
- export type ItemFilter = z.infer<typeof ItemFilterSchema>;
249
- ```
250
-
251
- ### Backend validation middleware
252
-
253
- ```typescript
254
- // backend/middleware/validate.ts
255
- import { ZodSchema } from "zod";
256
- import { Request, Response, NextFunction } from "express";
257
-
258
- export function validate(target: "body" | "query" | "params", schema: ZodSchema) {
259
- return (req: Request, res: Response, next: NextFunction) => {
260
- const result = schema.safeParse(req[target]);
261
- if (!result.success) {
262
- return res.status(400).json({
263
- error: {
264
- code: "VALIDATION_ERROR",
265
- message: "Request validation failed",
266
- details: result.error.issues.map((i) => ({
267
- field: i.path.join("."),
268
- message: i.message,
269
- })),
270
- },
271
- });
272
- }
273
- req[target] = result.data; // Replace with parsed/coerced values
274
- next();
275
- };
276
- }
277
- ```
278
-
279
- ### Frontend form integration
280
-
281
- ```typescript
282
- // frontend/components/CreateItemForm.tsx (sketch)
283
- import { useForm } from "react-hook-form";
284
- import { zodResolver } from "@hookform/resolvers/zod";
285
- import { CreateItemSchema, CreateItem } from "@shared/schemas/item.schema";
286
-
287
- function CreateItemForm() {
288
- const { register, handleSubmit, formState: { errors } } = useForm<CreateItem>({
289
- resolver: zodResolver(CreateItemSchema),
290
- });
291
- // ...
292
- }
293
- ```
294
-
295
- ### OpenAPI generation
296
-
297
- ```typescript
298
- // backend/openapi.ts
299
- import { OpenAPIRegistry } from "@asteasolutions/zod-to-openapi";
300
- import { CreateItemSchema, ItemFilterSchema } from "@shared/schemas/item.schema";
301
-
302
- const registry = new OpenAPIRegistry();
303
- registry.registerPath({
304
- method: "get",
305
- path: "/api/v1/items",
306
- request: { query: ItemFilterSchema },
307
- // ...
308
- });
309
- // Export as JSON/YAML for docs or client codegen.
310
- ```
311
-
312
- ## Folder Structure
313
-
314
- ```
315
- /
316
- ├── frontend/ # React SPA
317
- │ ├── src/
318
- │ │ ├── api/ # Typed API client
319
- │ │ ├── components/ # UI components
320
- │ │ ├── hooks/ # Custom hooks (useFilters, etc.)
321
- │ │ ├── pages/ # Route-level components
322
- │ │ └── main.tsx
323
- │ ├── index.html
324
- │ ├── vite.config.ts
325
- │ └── package.json
326
- ├── backend/ # Express API
327
- │ ├── src/
328
- │ │ ├── routes/ # Route handlers
329
- │ │ ├── middleware/ # validate, auth, error handler
330
- │ │ ├── services/ # Business logic
331
- │ │ ├── db/ # Drizzle schema + migrations
332
- │ │ └── server.ts
333
- │ └── package.json
334
- ├── shared/ # Shared Zod schemas + types
335
- │ ├── schemas/
336
- │ ├── types/
337
- │ └── package.json
338
- ├── package.json # Workspace root (npm workspaces)
339
- └── tsconfig.base.json # Shared TS config
340
- ```
341
-
342
- ## Risks
343
-
344
- | Risk | Likelihood | Impact | Mitigation |
345
- |------|-----------|--------|------------|
346
- | Shared schema drift (FE/BE versions diverge) | Medium | High | Single `/shared` workspace package; CI verifies both build against same version |
347
- | SQLite → PostgreSQL migration pain | Low | Medium | Drizzle abstracts dialect; integration tests run against both |
348
- | Filter query params exceed URL length limit | Low | Low | Compress with base64 encoding if >2k chars; add POST-based filter endpoint as fallback |
349
- | Optimistic update conflicts in detail panel | Medium | Medium | TanStack Query mutation with rollback; backend returns updated `updatedAt` for conflict detection |
350
-
351
- ## Decisions
352
-
353
- - [DEC-0001](../../decisions/DEC-0001.md) — Frontend/backend technology split
354
- - [DEC-0002](../../decisions/DEC-0002.md) — Validation strategy: shared Zod schemas
@@ -1,6 +0,0 @@
1
- # Decisions
2
-
3
- - DEC-0001: Pending
4
- - DEC-0002: Pending
5
-
6
- Full records: `decisions/DEC-0001.md`, `decisions/DEC-0002.md`
@@ -1,11 +0,0 @@
1
- # Research
2
-
3
- ## Summary
4
- - ...
5
-
6
- ## Findings
7
- - ...
8
-
9
- ## Risks
10
- - ...
11
-
@@ -1,32 +0,0 @@
1
- # Runbook
2
-
3
- ## Commands
4
-
5
- TEST_COMMAND: powershell -ExecutionPolicy Bypass -File tests/run-tests.ps1
6
- LINT_COMMAND:
7
- TYPECHECK_COMMAND:
8
- DEPLOY_STAGING_COMMAND:
9
- DEPLOY_PROD_COMMAND:
10
-
11
- ## Notes
12
- - Leave a command blank to skip that step.
13
- - Use explicit commands, not placeholders.
14
-
15
- ## Project run steps (fill in per project)
16
-
17
- ### Prerequisites
18
-
19
- - ...
20
-
21
- ### Local run
22
-
23
- ```bash
24
- ...
25
- ```
26
-
27
- ### Tests
28
-
29
- ```bash
30
- ...
31
- ```
32
-
@@ -1,33 +0,0 @@
1
- # Engineering State (compacted 2026-02-06)
2
-
3
- ## Session status
4
- - **PAUSED** — checkpoint 2026-02-06
5
-
6
- ## Progress snapshot
7
- - **Sprint S0001** — v1.0.0 released; all 22 tasks delivered; all phases complete (arch → plan → dev → QA → release)
8
- - **QA:** 20 PASS / 2 FAIL / 1 WARN — 0 critical/blocking
9
- - **Artifact:** reference app in `examples/webview-app/` (Express + SPA)
10
-
11
- ## Known issues (carry-forward)
12
-
13
- | ID | Severity | Summary |
14
- |-------|----------|--------------------------------------------------------------|
15
- | F-001 | Medium | Silent failure on item detail fetch — needs visible feedback |
16
- | F-002 | Medium | Non-JSON error responses crash `apiFetch` — needs try/catch |
17
- | F-003 | Low | No loading/spinner state during API calls |
18
- | F-004 | Low | Category filter values not validated on backend |
19
- | F-005 | Low | Soft-delete confirmation implies restore but no restore UI |
20
-
21
- ## Key risks
22
- - `/shared` must build before FE/BE in CI (schema drift)
23
- - CORS misconfiguration between SPA origin and API origin
24
- - SQLite → PostgreSQL dialect gaps at migration time
25
-
26
- ## Git (at checkpoint)
27
- - HEAD `8ddc68a` on `main`; 20 modified + 7 untracked; remote in sync at HEAD
28
-
29
- ## Next actions
30
- 1. Fix F-001, F-002 (medium) in S0002
31
- 2. Groom F-003–F-005 into backlog
32
- 3. Plan S0002 sprint scope
33
- 4. Commit working tree changes when ready
@@ -1,6 +0,0 @@
1
- # Acceptance
2
-
3
- ## US-0001
4
- - [ ] Criterion 1
5
- - [ ] Criterion 2
6
-
@@ -1,7 +0,0 @@
1
- # Backlog
2
-
3
- ## US-0001
4
- - Title:
5
- - Summary:
6
- - Priority:
7
-
@@ -1,46 +0,0 @@
1
- # Vision
2
-
3
- ## Problem
4
- - ...
5
-
6
- ## Audience
7
- - ...
8
-
9
- ## Value
10
- - ...
11
-
12
- ## Look and Feel
13
- - ...
14
-
15
- ## UX References
16
-
17
- ### 1. Airbnb — Filter Bar + Instant Results
18
- - **Source:** airbnb.com search experience
19
- - **Pattern:** Horizontal filter chips (price, type, amenities) sit above results. Selecting a filter instantly refines the list without a full page reload. Active filters are visually highlighted as filled chips with an "×" to remove.
20
- - **Takeaway:** Filters should feel lightweight and reversible. Users see the effect immediately, encouraging exploration rather than committing to a search upfront.
21
-
22
- ### 2. Linear — Side-Panel Detail View
23
- - **Source:** linear.app issue tracker
24
- - **Pattern:** Clicking an item in the list opens a slide-over detail panel on the right while the list remains visible and scrollable on the left. The detail panel contains all metadata, comments, and actions. Pressing Escape or clicking outside closes the panel and returns focus to the list.
25
- - **Takeaway:** A non-navigating detail view preserves list context and supports rapid scanning. Users can review multiple items without losing their place.
26
-
27
- ### 3. Notion Database — Multi-Select Faceted Filters
28
- - **Source:** notion.so database views
29
- - **Pattern:** A "Filter" button opens a dropdown builder where users add conditions (e.g., Status is "In Progress", Tag contains "UX"). Multiple conditions stack with AND/OR logic. A small badge on the Filter button shows the active filter count.
30
- - **Takeaway:** For power users, composable filter rules offer precision. The badge count provides at-a-glance awareness that results are filtered, reducing surprise.
31
-
32
- ## Intended Interaction Flow — Filters & Details
33
-
34
- ### Filter Flow
35
- 1. **Default state:** All items are visible; no filters are active. The filter bar shows available dimensions (e.g., status, category, date range) as collapsed chips or buttons.
36
- 2. **Activate filter:** User clicks a filter chip -> a small popover/dropdown appears with selectable options (checkboxes for multi-select, radio for single-select). Selecting an option immediately updates the result list.
37
- 3. **Stack filters:** Multiple filters can be active simultaneously (AND logic). Each active filter shows as a filled chip with an "×" dismiss control. A "Clear all" link appears when 2+ filters are active.
38
- 4. **Empty state:** If the active filters produce zero results, show a friendly empty state with a suggestion to relax filters or a one-click "Reset filters" button.
39
-
40
- ### Detail Flow
41
- 1. **Trigger:** User clicks a list item (row or card).
42
- 2. **Panel opens:** A detail panel slides in from the right (or expands inline on narrow viewports). The list remains visible but dims or narrows to accommodate the panel.
43
- 3. **Content:** The panel displays full metadata, descriptions, related items, and action buttons (edit, delete, status change).
44
- 4. **Navigation:** Arrow keys or swipe gestures allow moving to the next/previous item without closing the panel.
45
- 5. **Close:** Pressing Escape, clicking the "×" button, or clicking the dimmed list area closes the panel and restores the full list view.
46
-
package/gsd-installer.ps1 DELETED
@@ -1,189 +0,0 @@
1
- Param(
2
- [string]$Target,
3
- [ValidateSet("missing","overwrite","interactive")]
4
- [string]$Mode,
5
- [switch]$Backup,
6
- [switch]$Create
7
- )
8
-
9
- $ErrorActionPreference = "Stop"
10
-
11
- function Normalize-PathSafe($Path) {
12
- return [System.IO.Path]::GetFullPath($Path)
13
- }
14
-
15
- function Ensure-Parent($Path) {
16
- $parent = Split-Path -Parent $Path
17
- if ($parent -and -not (Test-Path $parent)) {
18
- New-Item -ItemType Directory -Path $parent -Force | Out-Null
19
- }
20
- }
21
-
22
- function List-SourceFiles($SourceRoot, $IncludePaths) {
23
- $files = New-Object System.Collections.Generic.List[string]
24
- foreach ($rel in $IncludePaths) {
25
- $src = Join-Path $SourceRoot $rel
26
- if (Test-Path $src -PathType Leaf) {
27
- $files.Add($rel)
28
- } elseif (Test-Path $src -PathType Container) {
29
- Get-ChildItem -Path $src -Recurse -File | ForEach-Object {
30
- $relPath = $_.FullName.Substring($SourceRoot.Length).TrimStart("\","/")
31
- $files.Add($relPath)
32
- }
33
- }
34
- }
35
- return $files | Select-Object -Unique | Sort-Object
36
- }
37
-
38
- function Backup-Files($TargetRoot, $RelPaths) {
39
- $timestamp = (Get-Date).ToUniversalTime().ToString("yyyyMMdd-HHmmssZ")
40
- $backupRoot = Join-Path $TargetRoot ("gsd-backups\" + $timestamp)
41
- foreach ($rel in $RelPaths) {
42
- $src = Join-Path $TargetRoot $rel
43
- if (Test-Path $src -PathType Leaf) {
44
- $dst = Join-Path $backupRoot $rel
45
- Ensure-Parent $dst
46
- Copy-Item -Path $src -Destination $dst -Force
47
- }
48
- }
49
- return $backupRoot
50
- }
51
-
52
- function Choose-Mode {
53
- Write-Host "Select install mode:"
54
- Write-Host "1) missing-only (copy only files that do not exist)"
55
- Write-Host "2) overwrite-all (replace existing files)"
56
- Write-Host "3) interactive (prompt per file)"
57
- $choice = Read-Host "Enter 1, 2, or 3"
58
- switch ($choice) {
59
- "1" { return "missing" }
60
- "2" { return "overwrite" }
61
- Default { return "interactive" }
62
- }
63
- }
64
-
65
- function Prompt-YesNo($Label, $Default = $false) {
66
- $suffix = if ($Default) { "Y/n" } else { "y/N" }
67
- $value = (Read-Host "$Label [$suffix]").ToLowerInvariant()
68
- if ([string]::IsNullOrWhiteSpace($value)) { return $Default }
69
- return @("y","yes") -contains $value
70
- }
71
-
72
- $sourceRoot = Normalize-PathSafe (Split-Path -Parent $MyInvocation.MyCommand.Path)
73
- if (-not $Target) {
74
- $Target = Read-Host "Target repository path"
75
- }
76
- $targetRoot = Normalize-PathSafe $Target
77
-
78
- if (-not (Test-Path $targetRoot -PathType Container)) {
79
- if ($Create -or (Prompt-YesNo "Target missing. Create?" $false)) {
80
- New-Item -ItemType Directory -Path $targetRoot -Force | Out-Null
81
- } else {
82
- Write-Host "Target directory does not exist."
83
- exit 1
84
- }
85
- }
86
-
87
- $mode = if ($Mode) { $Mode } else { Choose-Mode }
88
- $backupEnabled = $Backup.IsPresent
89
- if (($mode -eq "overwrite" -or $mode -eq "interactive") -and -not $backupEnabled) {
90
- $backupEnabled = Prompt-YesNo "Backup existing files before overwrite?" $false
91
- }
92
-
93
- $includePaths = @(
94
- ".cursor/commands",
95
- ".cursor/rules",
96
- ".cursor/skills",
97
- ".cursor/agents",
98
- ".cursor/hooks",
99
- ".cursor/hooks.json",
100
- ".cursor/scratchpad.md",
101
- "docs",
102
- "sprints",
103
- "handoffs",
104
- "decisions",
105
- ".github/workflows",
106
- "README.md",
107
- "gsd-installer.py",
108
- "gsd-installer.ps1",
109
- "gsd-installer.sh"
110
- )
111
-
112
- $files = List-SourceFiles $sourceRoot $includePaths
113
- if ($files.Count -eq 0) {
114
- Write-Host "No source files found to install."
115
- exit 1
116
- }
117
-
118
- if ($backupEnabled -and $mode -eq "overwrite") {
119
- $overwriteCandidates = @()
120
- foreach ($rel in $files) {
121
- $dst = Join-Path $targetRoot $rel
122
- if (Test-Path $dst -PathType Leaf) { $overwriteCandidates += $rel }
123
- }
124
- if ($overwriteCandidates.Count -gt 0) {
125
- $backupRoot = Backup-Files $targetRoot $overwriteCandidates
126
- Write-Host "Backup created at: $backupRoot"
127
- }
128
- }
129
-
130
- foreach ($rel in $files) {
131
- $src = Join-Path $sourceRoot $rel
132
- $dst = Join-Path $targetRoot $rel
133
- $exists = Test-Path $dst -PathType Leaf
134
-
135
- if ($mode -eq "missing") {
136
- if ($exists) { continue }
137
- Ensure-Parent $dst
138
- Copy-Item -Path $src -Destination $dst -Force
139
- continue
140
- }
141
-
142
- if ($mode -eq "overwrite") {
143
- Ensure-Parent $dst
144
- Copy-Item -Path $src -Destination $dst -Force
145
- continue
146
- }
147
-
148
- if ($mode -eq "interactive") {
149
- if (-not $exists) {
150
- Ensure-Parent $dst
151
- Copy-Item -Path $src -Destination $dst -Force
152
- continue
153
- }
154
- $answer = (Read-Host "File exists: $rel | [o]verwrite [s]kip [q]uit").ToLowerInvariant()
155
- if ($answer -eq "q") {
156
- Write-Host "Aborted."
157
- exit 1
158
- }
159
- if ($answer -eq "o") {
160
- if ($backupEnabled) {
161
- $backupRoot = Backup-Files $targetRoot @($rel)
162
- Write-Host "Backed up: $rel -> $backupRoot"
163
- }
164
- Ensure-Parent $dst
165
- Copy-Item -Path $src -Destination $dst -Force
166
- }
167
- }
168
- }
169
-
170
- function Show-ItsMagicBanner {
171
- $prev = [Console]::OutputEncoding
172
- [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
173
- Write-Host ""
174
- Write-Host " ██╗████████╗███████╗ ███╗ ███╗ █████╗ ██████╗ ██╗ ██████╗" -ForegroundColor Magenta
175
- Write-Host " ██║╚══██╔══╝██╔════╝ ████╗ ████║██╔══██╗██╔════╝ ██║██╔════╝" -ForegroundColor Magenta
176
- Write-Host " ██║ ██║ ███████╗█████╗██╔████╔██║███████║██║ ███╗██║██║ " -ForegroundColor Magenta
177
- Write-Host " ██║ ██║ ╚════██║╚════╝██║╚██╔╝██║██╔══██║██║ ██║██║██║ " -ForegroundColor Cyan
178
- Write-Host " ██║ ██║ ███████║ ██║ ╚═╝ ██║██║ ██║╚██████╔╝██║╚██████╗" -ForegroundColor Cyan
179
- Write-Host " ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝" -ForegroundColor Cyan
180
- Write-Host ""
181
- Write-Host " AI dev team" -ForegroundColor Yellow
182
- Write-Host " Installation complete!" -ForegroundColor Green
183
- Write-Host ""
184
- [Console]::OutputEncoding = $prev
185
- }
186
-
187
- Show-ItsMagicBanner
188
- exit 0
189
-