specweave 0.22.14 → 0.23.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 (150) hide show
  1. package/CLAUDE.md +178 -1
  2. package/dist/src/cli/commands/import-external.d.ts +22 -0
  3. package/dist/src/cli/commands/import-external.d.ts.map +1 -0
  4. package/dist/src/cli/commands/import-external.js +282 -0
  5. package/dist/src/cli/commands/import-external.js.map +1 -0
  6. package/dist/src/cli/commands/init.d.ts.map +1 -1
  7. package/dist/src/cli/commands/init.js +46 -0
  8. package/dist/src/cli/commands/init.js.map +1 -1
  9. package/dist/src/cli/helpers/github-repo-selector.d.ts +59 -0
  10. package/dist/src/cli/helpers/github-repo-selector.d.ts.map +1 -0
  11. package/dist/src/cli/helpers/github-repo-selector.js +265 -0
  12. package/dist/src/cli/helpers/github-repo-selector.js.map +1 -0
  13. package/dist/src/config/types.d.ts +16 -16
  14. package/dist/src/core/increment/ac-status-manager.d.ts.map +1 -1
  15. package/dist/src/core/increment/ac-status-manager.js +4 -2
  16. package/dist/src/core/increment/ac-status-manager.js.map +1 -1
  17. package/dist/src/core/increment/completion-validator.d.ts +30 -1
  18. package/dist/src/core/increment/completion-validator.d.ts.map +1 -1
  19. package/dist/src/core/increment/completion-validator.js +151 -3
  20. package/dist/src/core/increment/completion-validator.js.map +1 -1
  21. package/dist/src/core/increment/increment-archiver.d.ts +25 -0
  22. package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
  23. package/dist/src/core/increment/increment-archiver.js +130 -3
  24. package/dist/src/core/increment/increment-archiver.js.map +1 -1
  25. package/dist/src/core/living-docs/feature-archiver.d.ts +37 -0
  26. package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
  27. package/dist/src/core/living-docs/feature-archiver.js +262 -18
  28. package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
  29. package/dist/src/core/living-docs/feature-id-manager.d.ts +17 -0
  30. package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -1
  31. package/dist/src/core/living-docs/feature-id-manager.js +25 -0
  32. package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
  33. package/dist/src/core/living-docs/living-docs-sync.d.ts +14 -0
  34. package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
  35. package/dist/src/core/living-docs/living-docs-sync.js +46 -0
  36. package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
  37. package/dist/src/core/sync/sync-event-logger.d.ts +15 -1
  38. package/dist/src/core/sync/sync-event-logger.d.ts.map +1 -1
  39. package/dist/src/core/sync/sync-event-logger.js +39 -1
  40. package/dist/src/core/sync/sync-event-logger.js.map +1 -1
  41. package/dist/src/core/types/sync-config-validator.d.ts +57 -0
  42. package/dist/src/core/types/sync-config-validator.d.ts.map +1 -0
  43. package/dist/src/core/types/sync-config-validator.js +116 -0
  44. package/dist/src/core/types/sync-config-validator.js.map +1 -0
  45. package/dist/src/importers/duplicate-detector.d.ts +107 -0
  46. package/dist/src/importers/duplicate-detector.d.ts.map +1 -0
  47. package/dist/src/importers/duplicate-detector.js +189 -0
  48. package/dist/src/importers/duplicate-detector.js.map +1 -0
  49. package/dist/src/importers/import-coordinator.d.ts +15 -0
  50. package/dist/src/importers/import-coordinator.d.ts.map +1 -1
  51. package/dist/src/importers/import-coordinator.js +43 -1
  52. package/dist/src/importers/import-coordinator.js.map +1 -1
  53. package/dist/src/importers/item-converter.d.ts +5 -0
  54. package/dist/src/importers/item-converter.d.ts.map +1 -1
  55. package/dist/src/importers/item-converter.js +27 -2
  56. package/dist/src/importers/item-converter.js.map +1 -1
  57. package/dist/src/importers/rate-limiter.d.ts +128 -0
  58. package/dist/src/importers/rate-limiter.d.ts.map +1 -0
  59. package/dist/src/importers/rate-limiter.js +200 -0
  60. package/dist/src/importers/rate-limiter.js.map +1 -0
  61. package/dist/src/init/compliance/types.d.ts +2 -2
  62. package/dist/src/integrations/ado/ado-client.d.ts +6 -0
  63. package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
  64. package/dist/src/integrations/ado/ado-client.js +23 -0
  65. package/dist/src/integrations/ado/ado-client.js.map +1 -1
  66. package/dist/src/integrations/jira/jira-client.d.ts +6 -0
  67. package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
  68. package/dist/src/integrations/jira/jira-client.js +38 -0
  69. package/dist/src/integrations/jira/jira-client.js.map +1 -1
  70. package/dist/src/sync/external-item-sync-service.d.ts +150 -0
  71. package/dist/src/sync/external-item-sync-service.d.ts.map +1 -0
  72. package/dist/src/sync/external-item-sync-service.js +241 -0
  73. package/dist/src/sync/external-item-sync-service.js.map +1 -0
  74. package/dist/src/sync/format-preservation-sync.d.ts +90 -0
  75. package/dist/src/sync/format-preservation-sync.d.ts.map +1 -0
  76. package/dist/src/sync/format-preservation-sync.js +173 -0
  77. package/dist/src/sync/format-preservation-sync.js.map +1 -0
  78. package/dist/src/sync/index.d.ts +8 -0
  79. package/dist/src/sync/index.d.ts.map +1 -0
  80. package/dist/src/sync/index.js +6 -0
  81. package/dist/src/sync/index.js.map +1 -0
  82. package/dist/src/sync/sync-coordinator.d.ts +49 -0
  83. package/dist/src/sync/sync-coordinator.d.ts.map +1 -0
  84. package/dist/src/sync/sync-coordinator.js +248 -0
  85. package/dist/src/sync/sync-coordinator.js.map +1 -0
  86. package/dist/src/sync/sync-metadata.d.ts +75 -0
  87. package/dist/src/sync/sync-metadata.d.ts.map +1 -0
  88. package/dist/src/sync/sync-metadata.js +100 -0
  89. package/dist/src/sync/sync-metadata.js.map +1 -0
  90. package/dist/src/types/living-docs-us-file.d.ts +63 -0
  91. package/dist/src/types/living-docs-us-file.d.ts.map +1 -0
  92. package/dist/src/types/living-docs-us-file.js +27 -0
  93. package/dist/src/types/living-docs-us-file.js.map +1 -0
  94. package/dist/src/validators/format-preservation-validator.d.ts +127 -0
  95. package/dist/src/validators/format-preservation-validator.d.ts.map +1 -0
  96. package/dist/src/validators/format-preservation-validator.js +187 -0
  97. package/dist/src/validators/format-preservation-validator.js.map +1 -0
  98. package/package.json +3 -2
  99. package/plugins/specweave/.claude-plugin/plugin.json +20 -0
  100. package/plugins/specweave/commands/specweave-archive-features.md +11 -1
  101. package/plugins/specweave/commands/specweave-import-docs.md +88 -278
  102. package/plugins/specweave/commands/specweave-import-external.md +407 -0
  103. package/plugins/specweave/hooks/post-edit-spec.sh +41 -0
  104. package/plugins/specweave/hooks/post-increment-completion.sh +0 -0
  105. package/plugins/specweave/hooks/post-spec-update.sh +0 -0
  106. package/plugins/specweave/hooks/post-task-completion.sh +13 -3
  107. package/plugins/specweave/hooks/post-write-spec.sh +37 -0
  108. package/plugins/specweave/lib/hooks/auto-transition.js +1 -1
  109. package/plugins/specweave/lib/hooks/auto-transition.ts +1 -1
  110. package/plugins/specweave/lib/hooks/invoke-translator-skill.js +1 -1
  111. package/plugins/specweave/lib/hooks/invoke-translator-skill.ts +1 -1
  112. package/plugins/specweave/lib/hooks/sync-living-docs.js +35 -1
  113. package/plugins/specweave/lib/hooks/sync-us-tasks.js +179 -3
  114. package/plugins/specweave/lib/hooks/translate-file.js +1 -1
  115. package/plugins/specweave/lib/hooks/translate-file.ts +1 -1
  116. package/plugins/specweave/lib/hooks/update-ac-status.js +1 -1
  117. package/plugins/specweave/lib/hooks/update-ac-status.ts +1 -1
  118. package/plugins/specweave/lib/vendor/core/increment/ac-status-manager.d.ts +115 -0
  119. package/plugins/specweave/lib/vendor/core/increment/ac-status-manager.js +345 -0
  120. package/plugins/specweave/lib/vendor/core/increment/ac-status-manager.js.map +1 -0
  121. package/plugins/specweave/lib/vendor/core/increment/active-increment-manager.d.ts +106 -0
  122. package/plugins/specweave/lib/vendor/core/increment/active-increment-manager.js +220 -0
  123. package/plugins/specweave/lib/vendor/core/increment/active-increment-manager.js.map +1 -0
  124. package/plugins/specweave/lib/vendor/core/increment/auto-transition-manager.d.ts +60 -0
  125. package/plugins/specweave/lib/vendor/core/increment/auto-transition-manager.js +192 -0
  126. package/plugins/specweave/lib/vendor/core/increment/auto-transition-manager.js.map +1 -0
  127. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.d.ts +52 -0
  128. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js +276 -0
  129. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js.map +1 -0
  130. package/plugins/specweave/lib/vendor/core/increment/metadata-manager.d.ts +163 -0
  131. package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js +541 -0
  132. package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js.map +1 -0
  133. package/plugins/specweave/lib/vendor/core/types/increment-metadata.d.ts +157 -0
  134. package/plugins/specweave/lib/vendor/core/types/increment-metadata.js +191 -0
  135. package/plugins/specweave/lib/vendor/core/types/increment-metadata.js.map +1 -0
  136. package/plugins/specweave/lib/vendor/generators/spec/task-parser.d.ts +95 -0
  137. package/plugins/specweave/lib/vendor/generators/spec/task-parser.js +301 -0
  138. package/plugins/specweave/lib/vendor/generators/spec/task-parser.js.map +1 -0
  139. package/plugins/specweave/lib/vendor/utils/logger.d.ts +48 -0
  140. package/plugins/specweave/lib/vendor/utils/logger.js +53 -0
  141. package/plugins/specweave/lib/vendor/utils/logger.js.map +1 -0
  142. package/plugins/specweave/lib/vendor/utils/translation.d.ts +187 -0
  143. package/plugins/specweave/lib/vendor/utils/translation.js +414 -0
  144. package/plugins/specweave/lib/vendor/utils/translation.js.map +1 -0
  145. package/plugins/specweave-ado/lib/ado-multi-project-sync.js +0 -1
  146. package/plugins/specweave-github/commands/specweave-github-update-user-story.md +1 -1
  147. package/plugins/specweave-github/skills/github-issue-standard/SKILL.md +1 -1
  148. package/plugins/specweave-jira/lib/enhanced-jira-sync.js +3 -3
  149. package/plugins/specweave-ado/lib/enhanced-ado-sync.js +0 -170
  150. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +0 -5694
@@ -0,0 +1,407 @@
1
+ ---
2
+ name: specweave:import-external
3
+ description: Manually pull external work items from GitHub, JIRA, or Azure DevOps into living docs. Supports time range filtering, platform selection, and dry-run mode for ongoing imports after initial setup.
4
+ ---
5
+
6
+ # Import External Work Items
7
+
8
+ Import work items from GitHub (issues/milestones), JIRA (epics/stories), or Azure DevOps (work items) into SpecWeave living docs.
9
+
10
+ ## What This Does
11
+
12
+ 1. **Detects configured external tools** (GitHub, JIRA, ADO) from environment/config
13
+ 2. **Fetches work items** based on time range filter (since last import by default)
14
+ 3. **Assigns IDs** with E suffix (US-001E, T-001E) to indicate external origin
15
+ 4. **Creates living docs files** in `.specweave/docs/internal/specs/FS-XXXE/`
16
+ 5. **Updates sync metadata** (`.specweave/sync-metadata.json`) with import timestamp
17
+ 6. **Skips duplicates** automatically (checks existing external IDs)
18
+ 7. **Shows progress** indicator and summary report
19
+
20
+ ## Usage
21
+
22
+ ```bash
23
+ /specweave:import-external [options]
24
+ ```
25
+
26
+ ### Options
27
+
28
+ - `--since=<range>` - Time range filter (default: since last import)
29
+ - `last` - Since last import (uses sync metadata)
30
+ - `1m`, `3m`, `6m` - Last 1/3/6 months
31
+ - `all` - All items (no time filter)
32
+ - Custom: `2025-01-01` - Since specific date (ISO format)
33
+ - `--github-only` - Import from GitHub only
34
+ - `--jira-only` - Import from JIRA only
35
+ - `--ado-only` - Import from Azure DevOps only
36
+ - `--dry-run` - Preview what would be imported without creating files
37
+
38
+ ## Examples
39
+
40
+ ### Example 1: Import New Items (Default)
41
+
42
+ ```bash
43
+ /specweave:import-external
44
+
45
+ # Uses default behavior:
46
+ # - Imports from ALL configured platforms (GitHub, JIRA, ADO)
47
+ # - Since last import timestamp (from .specweave/sync-metadata.json)
48
+ # - Creates living docs files
49
+ # - Updates sync metadata
50
+
51
+ # Result:
52
+ # šŸ”„ Importing from GitHub... [30/30] āœ“
53
+ # šŸ”„ Importing from JIRA... [12/12] āœ“
54
+ # šŸ“Š Import Summary:
55
+ # Total imported: 42 items
56
+ # - GitHub: 30 items (US-201E to US-230E)
57
+ # - JIRA: 12 items (US-231E to US-242E)
58
+ # Duplicates skipped: 5 items
59
+ # āœ… Import complete!
60
+ ```
61
+
62
+ ### Example 2: GitHub Only (Last 3 Months)
63
+
64
+ ```bash
65
+ /specweave:import-external --github-only --since=3m
66
+
67
+ # Imports only from GitHub
68
+ # Items created in last 3 months
69
+ ```
70
+
71
+ ### Example 3: Dry Run (Preview)
72
+
73
+ ```bash
74
+ /specweave:import-external --dry-run --since=1m
75
+
76
+ # Shows what would be imported without creating files
77
+ # Useful for checking item counts before actual import
78
+
79
+ # Result:
80
+ # šŸ” Dry run - no files will be created
81
+ # šŸ“Š Preview:
82
+ # GitHub: 25 items (5 duplicates skipped)
83
+ # JIRA: 10 items (2 duplicates skipped)
84
+ # Total: 35 new items, 7 existing
85
+ # āš ļø Remove --dry-run to perform actual import
86
+ ```
87
+
88
+ ### Example 4: JIRA Only (All Items)
89
+
90
+ ```bash
91
+ /specweave:import-external --jira-only --since=all
92
+
93
+ # Imports all JIRA items (no time filter)
94
+ # āš ļø Warning shown if > 100 items detected
95
+ ```
96
+
97
+ ## Time Range Filters
98
+
99
+ ### Since Last Import (Default)
100
+
101
+ ```bash
102
+ /specweave:import-external
103
+
104
+ # Reads last import timestamp from:
105
+ # .specweave/sync-metadata.json
106
+ # {
107
+ # "github": { "lastImport": "2025-11-15T10:30:00Z" },
108
+ # "jira": { "lastImport": "2025-11-10T14:20:00Z" }
109
+ # }
110
+ #
111
+ # GitHub: imports items created after 2025-11-15T10:30:00Z
112
+ # JIRA: imports items created after 2025-11-10T14:20:00Z
113
+ ```
114
+
115
+ ### Relative Time Ranges
116
+
117
+ ```bash
118
+ --since=1m # Last 1 month
119
+ --since=3m # Last 3 months
120
+ --since=6m # Last 6 months
121
+ ```
122
+
123
+ ### Absolute Date
124
+
125
+ ```bash
126
+ --since=2025-01-01 # Since January 1, 2025 (ISO format: YYYY-MM-DD)
127
+ ```
128
+
129
+ ### All Items
130
+
131
+ ```bash
132
+ --since=all # Import all items (no time filter)
133
+ # āš ļø Warning: May import hundreds of items
134
+ ```
135
+
136
+ ## Configured Platforms
137
+
138
+ The command auto-detects configured platforms from:
139
+
140
+ ### GitHub
141
+ - **Detection**: `.git/config` remote URL
142
+ - **Auth**: `GITHUB_TOKEN` environment variable
143
+ - **Format**: `github.com/{owner}/{repo}`
144
+
145
+ ### JIRA
146
+ - **Detection**: `JIRA_HOST` environment variable
147
+ - **Auth**: `JIRA_EMAIL` + `JIRA_API_TOKEN`
148
+ - **Format**: `https://{company}.atlassian.net`
149
+
150
+ ### Azure DevOps
151
+ - **Detection**: `ADO_ORG_URL` environment variable
152
+ - **Auth**: `ADO_PAT` (Personal Access Token)
153
+ - **Format**: `https://dev.azure.com/{org}` + `ADO_PROJECT`
154
+
155
+ ## Progress Indicator
156
+
157
+ During import, you'll see real-time progress:
158
+
159
+ ```
160
+ šŸ”„ Importing from GitHub... [25/150] ā ‹
161
+ āš ļø GitHub rate limit low: 42/5000 remaining. Resets at 10:45 AM (in 300s).
162
+ šŸ”„ Importing from GitHub... [150/150] āœ“
163
+
164
+ šŸ”„ Importing from JIRA... [12/12] āœ“
165
+ ```
166
+
167
+ - **Spinner**: Shows active import
168
+ - **Counter**: `[current/total]` items processed
169
+ - **Rate limit warnings**: Shown if remaining requests drop below threshold
170
+ - **Checkmark**: `āœ“` when platform import completes
171
+
172
+ ## Summary Report
173
+
174
+ After import, a detailed summary is shown:
175
+
176
+ ```
177
+ šŸ“Š Import Summary:
178
+ Total imported: 162 items
179
+ - GitHub: 150 items (US-201E to US-350E)
180
+ - JIRA: 12 items (US-351E to US-362E)
181
+
182
+ Duplicates skipped: 8 items
183
+ - GitHub: 5 items (already imported)
184
+ - JIRA: 3 items (already imported)
185
+
186
+ Rate limit status:
187
+ - GitHub: 3842/5000 remaining (resets at 11:00 AM)
188
+ - JIRA: Estimated 950/1000 remaining
189
+
190
+ āœ… Import complete!
191
+ Living docs updated: .specweave/docs/internal/specs/
192
+ Sync metadata updated: .specweave/sync-metadata.json
193
+ ```
194
+
195
+ ## Duplicate Detection
196
+
197
+ The command automatically skips items that have already been imported:
198
+
199
+ - Scans all `us-*.md` files in living docs
200
+ - Checks `external_id` frontmatter field
201
+ - Skips if external ID already exists (e.g., `GH-#638`, `JIRA-PROJ-123`)
202
+ - Reports skipped count in summary
203
+
204
+ ## Rate Limiting
205
+
206
+ The command monitors API rate limits and handles them gracefully:
207
+
208
+ ### Warning Threshold (100 requests remaining)
209
+
210
+ ```
211
+ āš ļø GitHub rate limit low: 42/5000 remaining. Resets at 10:45 AM (in 300s).
212
+ ```
213
+
214
+ - Import continues normally
215
+ - Warning shown to user
216
+
217
+ ### Pause Threshold (10 requests remaining)
218
+
219
+ ```
220
+ āš ļø GitHub rate limit critically low. Waiting 60s before continuing...
221
+ ```
222
+
223
+ - Import pauses automatically
224
+ - Resumes after wait period
225
+ - No user action required
226
+
227
+ ### Retry Suggestions (Rate limit exceeded)
228
+
229
+ ```
230
+ āŒ GitHub rate limit exceeded.
231
+ Remaining: 0/5000
232
+ Resets at: 10:45 AM (in 300 seconds)
233
+
234
+ šŸ’” Suggestions:
235
+ - Wait 5 minutes and retry
236
+ - Use --github-only next time to avoid hitting limit
237
+ - Increase time range to reduce item count (--since=1m instead of --since=all)
238
+ ```
239
+
240
+ ## Large Import Confirmation
241
+
242
+ If import detects > 100 items, you'll be prompted:
243
+
244
+ ```
245
+ āš ļø Found 250 items to import:
246
+ - GitHub: 200 items
247
+ - JIRA: 50 items
248
+
249
+ This may take 5-10 minutes and use significant API quota.
250
+
251
+ Continue? (Y/n) _
252
+ ```
253
+
254
+ - Press `Y` or `Enter` to proceed
255
+ - Press `n` to cancel
256
+ - Use `--since=1m` to reduce item count
257
+
258
+ ## Sync Metadata
259
+
260
+ After successful import, sync metadata is updated:
261
+
262
+ **File**: `.specweave/sync-metadata.json`
263
+
264
+ ```json
265
+ {
266
+ "github": {
267
+ "lastImport": "2025-11-19T10:30:00Z",
268
+ "lastImportCount": 150,
269
+ "lastSkippedCount": 5,
270
+ "lastSyncResult": "success"
271
+ },
272
+ "jira": {
273
+ "lastImport": "2025-11-19T10:32:00Z",
274
+ "lastImportCount": 12,
275
+ "lastSkippedCount": 3,
276
+ "lastSyncResult": "success"
277
+ }
278
+ }
279
+ ```
280
+
281
+ - `lastImport`: Timestamp of most recent successful import
282
+ - `lastImportCount`: Number of items imported in last sync
283
+ - `lastSkippedCount`: Number of duplicates skipped
284
+ - `lastSyncResult`: `success`, `partial`, or `failed`
285
+
286
+ ## Living Docs Structure
287
+
288
+ Imported items create living docs files with E suffix:
289
+
290
+ ```
291
+ .specweave/docs/internal/specs/
292
+ ā”œā”€ā”€ FS-042E/ ← Feature (external)
293
+ │ ā”œā”€ā”€ README.md ← Feature metadata
294
+ │ ā”œā”€ā”€ us-001e-login.md ← User Story (external)
295
+ │ └── us-002e-signup.md ← User Story (external)
296
+ └── FS-043E/ ← Feature (external)
297
+ └── us-001e-api-auth.md ← User Story (external)
298
+ ```
299
+
300
+ ### User Story File Format
301
+
302
+ ```markdown
303
+ ---
304
+ us_id: US-001E
305
+ title: "User Login"
306
+ feature_id: FS-042E
307
+ origin: external
308
+ external_platform: github
309
+ external_id: GH-#638
310
+ external_url: https://github.com/owner/repo/issues/638
311
+ imported_at: 2025-11-19T10:30:00Z
312
+ status: open
313
+ ---
314
+
315
+ # US-001E: User Login
316
+
317
+ **Origin**: šŸ”— GitHub (GH-#638)
318
+
319
+ ## Description
320
+
321
+ [Original GitHub issue description]
322
+
323
+ ## Acceptance Criteria
324
+
325
+ [Parsed from GitHub issue body or comments]
326
+
327
+ ## Tasks
328
+
329
+ No tasks defined.
330
+
331
+ ## Implementation Notes
332
+
333
+ [Original labels, comments, metadata from GitHub]
334
+ ```
335
+
336
+ ## When to Use
337
+
338
+ - **After initial setup**: Import new external items created after `specweave init`
339
+ - **Periodic sync**: Weekly/monthly imports to stay in sync with external tools
340
+ - **Brownfield onboarding**: Import historical items missed during initialization
341
+ - **Cross-team collaboration**: Pull work items from other teams' external tools
342
+
343
+ ## Limitations
344
+
345
+ - **NO automatic increment creation**: Imported items live in living docs ONLY
346
+ - User must manually create increment when ready to work on external item
347
+ - **Read-only snapshot**: External items are imported as static snapshots
348
+ - No bidirectional sync (external tool → SpecWeave only)
349
+ - **Pagination**: Large imports (500+ items) may take several minutes
350
+ - **API quota**: Uses GitHub/JIRA/ADO API quota
351
+ - GitHub: 5000 requests/hour (authenticated)
352
+ - JIRA: ~1000 requests/hour (Cloud estimate)
353
+ - ADO: 200 requests/minute
354
+
355
+ ## Differences from `specweave init`
356
+
357
+ | Feature | `specweave init` | `/specweave:import-external` |
358
+ |---------|------------------|------------------------------|
359
+ | When to use | First-time setup | Ongoing imports after init |
360
+ | User prompts | Interactive setup | Minimal prompts (confirmation only) |
361
+ | Time range | Configurable (default: 1 month) | Since last import (default) |
362
+ | Config update | Creates `.specweave/config.json` | Uses existing config |
363
+ | Primary use case | Brownfield onboarding | Stay in sync with external tools |
364
+
365
+ ## Troubleshooting
366
+
367
+ ### Error: "No platforms configured"
368
+
369
+ ```
370
+ āŒ No external platforms configured.
371
+
372
+ šŸ’” Ensure one of these is set:
373
+ - GitHub: GITHUB_TOKEN + .git/config remote
374
+ - JIRA: JIRA_HOST + JIRA_EMAIL + JIRA_API_TOKEN
375
+ - Azure DevOps: ADO_ORG_URL + ADO_PROJECT + ADO_PAT
376
+ ```
377
+
378
+ **Solution**: Set environment variables for at least one platform
379
+
380
+ ### Error: "Rate limit exceeded"
381
+
382
+ ```
383
+ āŒ GitHub rate limit exceeded (0/5000 remaining).
384
+ Resets at: 10:45 AM (in 300 seconds)
385
+ ```
386
+
387
+ **Solution**: Wait for rate limit reset, or use platform filter (`--jira-only`) to avoid GitHub
388
+
389
+ ### Warning: "Found 0 items to import"
390
+
391
+ ```
392
+ āš ļø No new items found since last import (2025-11-19T10:30:00Z).
393
+ ```
394
+
395
+ **Solution**: This is expected if no new work items created since last import. Use `--since=all` to re-import all items (will skip duplicates).
396
+
397
+ ## See Also
398
+
399
+ - `specweave init` - Initial project setup with external tool import
400
+ - [External Import Guide](https://docs.spec-weave.com/guides/external-import)
401
+ - [GitHub Integration](https://docs.spec-weave.com/integrations/github)
402
+ - [JIRA Integration](https://docs.spec-weave.com/integrations/jira)
403
+ - [Azure DevOps Integration](https://docs.spec-weave.com/integrations/ado)
404
+
405
+ ---
406
+
407
+ **Implementation**: `src/cli/commands/import-external.ts`
@@ -0,0 +1,41 @@
1
+ #!/bin/bash
2
+ #
3
+ # Post-Edit Hook: Update Status Line After spec.md or tasks.md Edits
4
+ #
5
+ # Triggers: After Edit tool modifies spec.md (AC updates) or tasks.md (task completion)
6
+ # Action: Updates status line cache to reflect latest AC/task progress
7
+ #
8
+ # This ensures status line stays in sync when ACs are marked complete via Edit tool
9
+ # (not just TodoWrite, which only tracks internal todo lists)
10
+
11
+ set -e
12
+
13
+ # Find project root
14
+ find_project_root() {
15
+ local dir="$PWD"
16
+ while [[ "$dir" != "/" ]]; do
17
+ if [[ -d "$dir/.specweave" ]]; then
18
+ echo "$dir"
19
+ return 0
20
+ fi
21
+ dir=$(dirname "$dir")
22
+ done
23
+ echo "$PWD"
24
+ }
25
+
26
+ PROJECT_ROOT=$(find_project_root)
27
+
28
+ # Get the file that was edited from TOOL_USE_CONTENT environment variable
29
+ # Claude Code provides this in the hook context
30
+ EDITED_FILE="${TOOL_USE_CONTENT:-}"
31
+
32
+ # Only update status line if spec.md or tasks.md was edited
33
+ if [[ "$EDITED_FILE" == *"/spec.md"* ]] || [[ "$EDITED_FILE" == *"/tasks.md"* ]]; then
34
+ # Check if the edit is in an increment folder
35
+ if [[ "$EDITED_FILE" == *"/.specweave/increments/"* ]]; then
36
+ # Run status line update
37
+ "$PROJECT_ROOT/plugins/specweave/hooks/lib/update-status-line.sh" &>/dev/null || true
38
+ fi
39
+ fi
40
+
41
+ exit 0
File without changes
@@ -200,11 +200,20 @@ fi
200
200
 
201
201
  if command -v node &> /dev/null; then
202
202
  if [ -n "$CURRENT_INCREMENT" ]; then
203
- echo "[$(date)] šŸ“š Checking living docs sync for $CURRENT_INCREMENT" >> "$DEBUG_LOG" 2>/dev/null || true
204
-
205
203
  # ========================================================================
206
- # EXTRACT FEATURE ID (NEW in v0.23.0 - Increment 0047: US-Task Linkage)
204
+ # SKIP ARCHIVED INCREMENTS (CRITICAL - prevents folder recreation)
207
205
  # ========================================================================
206
+ # If increment is archived, skip living docs sync entirely
207
+ # This prevents recreating archived feature folders in active location
208
+ # See: ULTRATHINK-ARCHIVE-REORGANIZATION-BUG.md for full analysis
209
+ if [ -d ".specweave/increments/_archive/$CURRENT_INCREMENT" ]; then
210
+ echo "[$(date)] ā­ļø Skipping living docs sync for archived increment $CURRENT_INCREMENT" >> "$DEBUG_LOG" 2>/dev/null || true
211
+ else
212
+ echo "[$(date)] šŸ“š Checking living docs sync for $CURRENT_INCREMENT" >> "$DEBUG_LOG" 2>/dev/null || true
213
+
214
+ # ========================================================================
215
+ # EXTRACT FEATURE ID (NEW in v0.23.0 - Increment 0047: US-Task Linkage)
216
+ # ========================================================================
208
217
  # Extract epic field from spec.md frontmatter (e.g., epic: FS-047)
209
218
  # This ensures sync uses the explicitly defined feature ID rather than
210
219
  # auto-generating one, maintaining traceability with living docs structure.
@@ -290,6 +299,7 @@ if command -v node &> /dev/null; then
290
299
  else
291
300
  echo "[$(date)] āš ļø sync-living-docs.js not found in any location" >> "$DEBUG_LOG" 2>/dev/null || true
292
301
  fi
302
+ fi # Close the archive check 'else' block
293
303
  fi
294
304
  fi
295
305
 
@@ -0,0 +1,37 @@
1
+ #!/bin/bash
2
+ #
3
+ # Post-Write Hook: Update Status Line After spec.md or tasks.md Writes
4
+ #
5
+ # Triggers: After Write tool creates/replaces spec.md or tasks.md
6
+ # Action: Updates status line cache to reflect latest AC/task progress
7
+
8
+ set -e
9
+
10
+ # Find project root
11
+ find_project_root() {
12
+ local dir="$PWD"
13
+ while [[ "$dir" != "/" ]]; do
14
+ if [[ -d "$dir/.specweave" ]]; then
15
+ echo "$dir"
16
+ return 0
17
+ fi
18
+ dir=$(dirname "$dir")
19
+ done
20
+ echo "$PWD"
21
+ }
22
+
23
+ PROJECT_ROOT=$(find_project_root)
24
+
25
+ # Get the file that was written from TOOL_USE_CONTENT environment variable
26
+ WRITTEN_FILE="${TOOL_USE_CONTENT:-}"
27
+
28
+ # Only update status line if spec.md or tasks.md was written
29
+ if [[ "$WRITTEN_FILE" == *"/spec.md"* ]] || [[ "$WRITTEN_FILE" == *"/tasks.md"* ]]; then
30
+ # Check if the write is in an increment folder
31
+ if [[ "$WRITTEN_FILE" == *"/.specweave/increments/"* ]]; then
32
+ # Run status line update
33
+ "$PROJECT_ROOT/plugins/specweave/hooks/lib/update-status-line.sh" &>/dev/null || true
34
+ fi
35
+ fi
36
+
37
+ exit 0
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { AutoTransitionManager } from "../../../../dist/src/core/increment/auto-transition-manager.js";
2
+ import { AutoTransitionManager } from "../vendor/core/increment/auto-transition-manager.js";
3
3
  async function main() {
4
4
  const event = process.argv[2];
5
5
  const incrementId = process.argv[3];
@@ -19,7 +19,7 @@
19
19
  * node auto-transition.ts auto-correct 0039-ultra-smart-next-command
20
20
  */
21
21
 
22
- import { AutoTransitionManager } from '../../../../dist/src/core/increment/auto-transition-manager.js';
22
+ import { AutoTransitionManager } from '../vendor/core/increment/auto-transition-manager.js';
23
23
 
24
24
  async function main() {
25
25
  const event = process.argv[2];
@@ -4,7 +4,7 @@ import {
4
4
  prepareTranslation,
5
5
  postProcessTranslation,
6
6
  getLanguageName
7
- } from "../../../../dist/src/utils/translation.js";
7
+ } from "../vendor/utils/translation.js";
8
8
  async function invokeTranslatorSkill(content, sourceLang, targetLang = "en") {
9
9
  try {
10
10
  const prepared = prepareTranslation(content, sourceLang, targetLang);
@@ -16,7 +16,7 @@ import {
16
16
  postProcessTranslation,
17
17
  getLanguageName,
18
18
  type SupportedLanguage,
19
- } from '../../../../dist/src/utils/translation.js';
19
+ } from '../vendor/utils/translation.js';
20
20
 
21
21
  /**
22
22
  * Translation result
@@ -54,7 +54,9 @@ async function syncLivingDocs(incrementId) {
54
54
  return;
55
55
  }
56
56
 
57
- await syncToGitHub(incrementId, changedDocs);
57
+ // T-034E: Use FormatPreservationSyncService for origin-aware sync
58
+ await syncWithFormatPreservation(incrementId);
59
+
58
60
  console.log("\u2705 Living docs sync complete\n");
59
61
  } catch (error) {
60
62
  console.error("\u274C Error syncing living docs:", error);
@@ -334,6 +336,38 @@ if (isMainModule) {
334
336
  console.error("\u274C Fatal error:", error);
335
337
  });
336
338
  }
339
+
340
+ /**
341
+ * Sync with format preservation (T-034E)
342
+ * Routes sync based on origin metadata (external vs internal)
343
+ */
344
+ async function syncWithFormatPreservation(incrementId) {
345
+ try {
346
+ console.log("\nšŸ”„ Using format-preserving sync...");
347
+
348
+ const { SyncCoordinator } = await import("../../../../dist/src/sync/sync-coordinator.js");
349
+
350
+ const coordinator = new SyncCoordinator({
351
+ projectRoot: process.cwd(),
352
+ incrementId
353
+ });
354
+
355
+ const result = await coordinator.syncIncrementCompletion();
356
+
357
+ if (result.success) {
358
+ console.log(`āœ… Format-preserving sync complete (${result.syncMode} mode)`);
359
+ console.log(` ${result.userStoriesSynced} user story/stories synced`);
360
+ } else {
361
+ console.log(`āš ļø Sync completed with ${result.errors.length} error(s)`);
362
+ result.errors.forEach(err => console.error(` - ${err}`));
363
+ }
364
+ } catch (error) {
365
+ console.error("āš ļø Format-preserving sync error:", error);
366
+ console.log(" Falling back to legacy sync...");
367
+ // Don't fail - just log and continue
368
+ }
369
+ }
370
+
337
371
  export {
338
372
  syncLivingDocs
339
373
  };