assign-gingerly 0.0.53 → 0.0.55

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 (114) hide show
  1. package/README.md +847 -5
  2. package/assignFrom.js +229 -9
  3. package/assignFrom.ts +338 -9
  4. package/assignGingerly.js +34 -1
  5. package/assignGingerly.ts +54 -1
  6. package/beVigilant.js +73 -0
  7. package/beVigilant.ts +85 -0
  8. package/enhanceAll.js +106 -0
  9. package/enhanceAll.ts +138 -0
  10. package/handlers/join.js +74 -0
  11. package/handlers/join.ts +80 -0
  12. package/handlers/lazyLoad.js +212 -0
  13. package/handlers/lazyLoad.ts +307 -0
  14. package/handlers/lazyLoadSwitch.js +58 -0
  15. package/handlers/lazyLoadSwitch.ts +63 -0
  16. package/handlers/microDataJoin.js +184 -0
  17. package/handlers/microDataJoin.ts +270 -0
  18. package/inferencer/.gitmodules +3 -0
  19. package/inferencer/.vscode/settings.json +2 -0
  20. package/inferencer/InferencedPropagator.js +230 -0
  21. package/inferencer/InferencedPropagator.ts +269 -0
  22. package/inferencer/LICENSE +21 -0
  23. package/inferencer/README.md +524 -0
  24. package/inferencer/Requirements/SupportForPropagator.md +368 -0
  25. package/inferencer/imports.html +7 -0
  26. package/inferencer/inferencer.js +254 -0
  27. package/inferencer/inferencer.ts +292 -0
  28. package/inferencer/package-lock.json +129 -0
  29. package/inferencer/package.json +60 -0
  30. package/inferencer/playwright-report/data/507ad515125e13390ea07de92f22331c913fa068.md +55 -0
  31. package/inferencer/playwright-report/index.html +90 -0
  32. package/inferencer/playwright.config.ts +54 -0
  33. package/inferencer/test-results/.last-run.json +6 -0
  34. package/inferencer/test-results/inferencer-Inferencer-Enha-535bc-inferencer-tests-in-browser-chromium/error-context.md +55 -0
  35. package/inferencer/tests/inferencedPropagator.html +428 -0
  36. package/inferencer/tests/inferencedPropagator.spec.ts +18 -0
  37. package/inferencer/tests/inferencer.html +355 -0
  38. package/inferencer/tests/inferencer.spec.ts +19 -0
  39. package/inferencer/tsconfig.json +19 -0
  40. package/inferencer/types/.kiro/specs/conversion-template/README.md +128 -0
  41. package/inferencer/types/.kiro/specs/conversion-template/design.md +360 -0
  42. package/inferencer/types/.kiro/specs/conversion-template/requirements.md +191 -0
  43. package/inferencer/types/.kiro/specs/conversion-template/tasks.md +174 -0
  44. package/inferencer/types/.kiro/steering/coding-standards.md +53 -0
  45. package/inferencer/types/.kiro/steering/conversion-guide.md +108 -0
  46. package/inferencer/types/.kiro/steering/declarative-configuration.md +108 -0
  47. package/inferencer/types/.kiro/steering/emc-json-serializability.md +306 -0
  48. package/inferencer/types/EnhancementConversionInstructions.md +1854 -0
  49. package/inferencer/types/LICENSE +21 -0
  50. package/inferencer/types/NewCustomElement.md +388 -0
  51. package/inferencer/types/NewCustomElementFeature.md +683 -0
  52. package/inferencer/types/NewEnhancementInstructions.md +705 -0
  53. package/inferencer/types/README.md +2 -0
  54. package/inferencer/types/agrace/types.d.ts +11 -0
  55. package/inferencer/types/assign-gingerly/types.d.ts +572 -0
  56. package/inferencer/types/be-a-beacon/types.d.ts +17 -0
  57. package/inferencer/types/be-bound/types.d.ts +66 -0
  58. package/inferencer/types/be-buttoned-up/types.d.ts +19 -0
  59. package/inferencer/types/be-calculating/types.d.ts +54 -0
  60. package/inferencer/types/be-clonable/types.d.ts +38 -0
  61. package/inferencer/types/be-committed/types.d.ts +22 -0
  62. package/inferencer/types/be-consoling/types.d.ts +24 -0
  63. package/inferencer/types/be-decked-with/types.d.ts +26 -0
  64. package/inferencer/types/be-delible/types.d.ts +27 -0
  65. package/inferencer/types/be-dispatching/types.d.ts +34 -0
  66. package/inferencer/types/be-evanescent/types.d.ts +20 -0
  67. package/inferencer/types/be-flashy/types.d.ts +21 -0
  68. package/inferencer/types/be-gone/types.d.ts +25 -0
  69. package/inferencer/types/be-observing/types.d.ts +55 -0
  70. package/inferencer/types/be-reflective/types.d.ts +78 -0
  71. package/inferencer/types/be-reformable/types.d.ts +49 -0
  72. package/inferencer/types/be-render-neutral/types.d.ts +32 -0
  73. package/inferencer/types/be-switched/types.d.ts +146 -0
  74. package/inferencer/types/be-typed/types.d.ts +32 -0
  75. package/inferencer/types/be-valued/types.d.ts +22 -0
  76. package/inferencer/types/data-props/types.d.ts +34 -0
  77. package/inferencer/types/do-inc/types.d.ts +56 -0
  78. package/inferencer/types/do-invoke/types.d.ts +38 -0
  79. package/inferencer/types/do-merge/types.d.ts +28 -0
  80. package/inferencer/types/do-toggle/types.d.ts +31 -0
  81. package/inferencer/types/face-up/types.d.ts +100 -0
  82. package/inferencer/types/fetch-for/types.d.ts +36 -0
  83. package/inferencer/types/folder-picker/types.d.ts +21 -0
  84. package/inferencer/types/global.d.ts +29 -0
  85. package/inferencer/types/id-generation/types.d.ts +26 -0
  86. package/inferencer/types/inferencer/types.d.ts +46 -0
  87. package/inferencer/types/mount-observer/types.d.ts +363 -0
  88. package/inferencer/types/nested-regex-groups/types.d.ts +107 -0
  89. package/inferencer/types/pipe-in/types.d.ts +52 -0
  90. package/inferencer/types/roundabout/types.d.ts +268 -0
  91. package/inferencer/types/soak-up/types.d.ts +40 -0
  92. package/inferencer/types/templ-maker/types.d.ts +43 -0
  93. package/inferencer/types/time-ticker/types.d.ts +62 -0
  94. package/inferencer/types/truth-sourcer/types.d.ts +44 -0
  95. package/inferencer/upSearch.js +27 -0
  96. package/inferencer/upSearch.ts +26 -0
  97. package/inferencer/withScopePerimeter.js +27 -0
  98. package/inferencer/withScopePerimeter.ts +33 -0
  99. package/inferredAssignments.js +38 -0
  100. package/inferredAssignments.ts +65 -0
  101. package/isAllowedImportPath.js +42 -0
  102. package/isAllowedImportPath.ts +53 -0
  103. package/package.json +57 -3
  104. package/paths.js +231 -0
  105. package/paths.ts +413 -0
  106. package/processHandlerCommands.js +188 -0
  107. package/processHandlerCommands.ts +217 -0
  108. package/resolveIdRef.js +144 -0
  109. package/resolveIdRef.ts +170 -0
  110. package/resolveValues.js +41 -2
  111. package/resolveValues.ts +41 -1
  112. package/transitionHelper.js +109 -0
  113. package/transitionHelper.ts +132 -0
  114. package/types/assign-gingerly/types.d.ts +89 -0
@@ -0,0 +1,355 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Inferencer Enhancement Tests</title>
7
+ <!-- #include virtual="/imports.html" -->
8
+ </head>
9
+ <body>
10
+ <h1>Inferencer Enhancement Tests</h1>
11
+ <div id="results"></div>
12
+
13
+ <script type="module">
14
+ import { value, display, registryItem, inferEventType } from '../inferencer.js';
15
+ import 'assign-gingerly/object-extension.js';
16
+
17
+ const results = [];
18
+ let testCount = 0;
19
+ let passCount = 0;
20
+
21
+ function test(name, fn) {
22
+ testCount++;
23
+ try {
24
+ fn();
25
+ passCount++;
26
+ results.push(`✓ ${name}`);
27
+ console.log(`✓ ${name}`);
28
+ } catch (error) {
29
+ results.push(`✗ ${name}: ${error.message}`);
30
+ console.error(`✗ ${name}:`, error);
31
+ }
32
+ }
33
+
34
+ // Register the enhancement
35
+ customElements.enhancementRegistry.push(registryItem);
36
+
37
+ // Test 1: Input text element
38
+ test('should set value on text input', () => {
39
+ const input = document.createElement('input');
40
+ input.type = 'text';
41
+ input.set[value] = 'hello';
42
+
43
+ if (input.value !== 'hello') {
44
+ throw new Error(`Expected 'hello', got '${input.value}'`);
45
+ }
46
+ });
47
+
48
+ // Test 2: Checkbox element
49
+ test('should set checked on checkbox', () => {
50
+ const checkbox = document.createElement('input');
51
+ checkbox.type = 'checkbox';
52
+ checkbox.set[value] = true;
53
+
54
+ if (!checkbox.checked) {
55
+ throw new Error('Expected checkbox to be checked');
56
+ }
57
+ });
58
+
59
+ // Test 3: Radio button
60
+ test('should set checked on radio button', () => {
61
+ const radio = document.createElement('input');
62
+ radio.type = 'radio';
63
+ radio.set[value] = true;
64
+
65
+ if (!radio.checked) {
66
+ throw new Error('Expected radio to be checked');
67
+ }
68
+ });
69
+
70
+ // Test 4: Textarea element
71
+ test('should set value on textarea', () => {
72
+ const textarea = document.createElement('textarea');
73
+ textarea.set[value] = 'multiline text';
74
+
75
+ if (textarea.value !== 'multiline text') {
76
+ throw new Error(`Expected 'multiline text', got '${textarea.value}'`);
77
+ }
78
+ });
79
+
80
+ // Test 5: Select element
81
+ test('should set value on select', () => {
82
+ const select = document.createElement('select');
83
+ const option = document.createElement('option');
84
+ option.value = 'option1';
85
+ select.appendChild(option);
86
+ select.set[value] = 'option1';
87
+
88
+ if (select.value !== 'option1') {
89
+ throw new Error(`Expected 'option1', got '${select.value}'`);
90
+ }
91
+ });
92
+
93
+ // Test 6: Div element (textContent)
94
+ test('should set textContent on div', () => {
95
+ const div = document.createElement('div');
96
+ div.set[value] = 'content';
97
+
98
+ if (div.textContent !== 'content') {
99
+ throw new Error(`Expected 'content', got '${div.textContent}'`);
100
+ }
101
+ });
102
+
103
+ // Test 7: Time element
104
+ test('should set dateTime on time element', () => {
105
+ const time = document.createElement('time');
106
+ time.set[value] = '2024-01-01T00:00:00Z';
107
+
108
+ if (time.dateTime !== '2024-01-01T00:00:00Z') {
109
+ throw new Error(`Expected '2024-01-01T00:00:00Z', got '${time.dateTime}'`);
110
+ }
111
+ });
112
+
113
+ // Test 8: Data element
114
+ test('should set value on data element', () => {
115
+ const data = document.createElement('data');
116
+ data.set[value] = '12345';
117
+
118
+ if (data.value !== '12345') {
119
+ throw new Error(`Expected '12345', got '${data.value}'`);
120
+ }
121
+ });
122
+
123
+ // Test 9: Progress element
124
+ test('should set value on progress element', () => {
125
+ const progress = document.createElement('progress');
126
+ progress.max = 100;
127
+ progress.set[value] = 50;
128
+
129
+ if (progress.value !== 50) {
130
+ throw new Error(`Expected 50, got ${progress.value}`);
131
+ }
132
+ });
133
+
134
+ // Test 10: Meter element
135
+ test('should set value on meter element', () => {
136
+ const meter = document.createElement('meter');
137
+ meter.min = 0;
138
+ meter.max = 100;
139
+ meter.set[value] = 75;
140
+
141
+ if (meter.value !== 75) {
142
+ throw new Error(`Expected 75, got ${meter.value}`);
143
+ }
144
+ });
145
+
146
+ // Test 11: Output element
147
+ test('should set value on output element', () => {
148
+ const output = document.createElement('output');
149
+ output.set[value] = 'result';
150
+
151
+ if (output.value !== 'result') {
152
+ throw new Error(`Expected 'result', got '${output.value}'`);
153
+ }
154
+ });
155
+
156
+ // Test 12: Element with itemprop
157
+ test('should use itemprop as property name', () => {
158
+ const span = document.createElement('span');
159
+ span.setAttribute('itemprop', 'title');
160
+ span.set[value] = 'My Title';
161
+
162
+ if (span.title !== 'My Title') {
163
+ throw new Error(`Expected 'My Title', got '${span.title}'`);
164
+ }
165
+ });
166
+
167
+ // Test 13: Display property on div
168
+ test('should set display (textContent) on div', () => {
169
+ const div = document.createElement('div');
170
+ div.set[display] = 'displayed content';
171
+
172
+ if (div.textContent !== 'displayed content') {
173
+ throw new Error(`Expected 'displayed content', got '${div.textContent}'`);
174
+ }
175
+ });
176
+
177
+ // Test 14: Display property on time element
178
+ test('should set display (textContent) on time element', () => {
179
+ const time = document.createElement('time');
180
+ time.set[display] = 'Just now';
181
+
182
+ if (time.textContent !== 'Just now') {
183
+ throw new Error(`Expected 'Just now', got '${time.textContent}'`);
184
+ }
185
+ });
186
+
187
+ // Test 15: Display property on meter element
188
+ test('should set display (ariaValueText) on meter element', () => {
189
+ const meter = document.createElement('meter');
190
+ meter.set[display] = '75 percent';
191
+
192
+ if (meter.ariaValueText !== '75 percent') {
193
+ throw new Error(`Expected '75 percent', got '${meter.ariaValueText}'`);
194
+ }
195
+ });
196
+
197
+ // Test 16: Access via enh.infer
198
+ test('should be accessible via enh.infer', () => {
199
+ const input = document.createElement('input');
200
+ input.set[value] = 'test';
201
+
202
+ if (!input.enh || !input.enh.infer) {
203
+ throw new Error('Enhancement not accessible via enh.infer');
204
+ }
205
+
206
+ if (input.enh.infer.value !== 'test') {
207
+ throw new Error(`Expected cached value 'test', got '${input.enh.infer.value}'`);
208
+ }
209
+ });
210
+
211
+ // Test 17: Multiple assignments
212
+ test('should handle multiple value assignments', () => {
213
+ const input = document.createElement('input');
214
+ input.set[value] = 'first';
215
+ input.set[value] = 'second';
216
+ input.set[value] = 'third';
217
+
218
+ if (input.value !== 'third') {
219
+ throw new Error(`Expected 'third', got '${input.value}'`);
220
+ }
221
+ });
222
+
223
+ // Test 18: Both value and display
224
+ test('should handle both value and display assignments', () => {
225
+ const time = document.createElement('time');
226
+ time.set[value] = '2024-01-01T00:00:00Z';
227
+ time.set[display] = 'January 1, 2024';
228
+
229
+ if (time.dateTime !== '2024-01-01T00:00:00Z') {
230
+ throw new Error(`Expected dateTime '2024-01-01T00:00:00Z', got '${time.dateTime}'`);
231
+ }
232
+ if (time.textContent !== 'January 1, 2024') {
233
+ throw new Error(`Expected textContent 'January 1, 2024', got '${time.textContent}'`);
234
+ }
235
+ });
236
+
237
+ // Test 19: inferEventType for input element
238
+ test('should infer "input" event for input element', () => {
239
+ const input = document.createElement('input');
240
+ const eventType = inferEventType(input);
241
+
242
+ if (eventType !== 'input') {
243
+ throw new Error(`Expected 'input', got '${eventType}'`);
244
+ }
245
+ });
246
+
247
+ // Test 20: inferEventType for textarea element
248
+ test('should infer "input" event for textarea element', () => {
249
+ const textarea = document.createElement('textarea');
250
+ const eventType = inferEventType(textarea);
251
+
252
+ if (eventType !== 'input') {
253
+ throw new Error(`Expected 'input', got '${eventType}'`);
254
+ }
255
+ });
256
+
257
+ // Test 21: inferEventType for select element
258
+ test('should infer "input" event for select element', () => {
259
+ const select = document.createElement('select');
260
+ const eventType = inferEventType(select);
261
+
262
+ if (eventType !== 'input') {
263
+ throw new Error(`Expected 'input', got '${eventType}'`);
264
+ }
265
+ });
266
+
267
+ // Test 22: inferEventType for form element
268
+ test('should infer "submit" event for form element', () => {
269
+ const form = document.createElement('form');
270
+ const eventType = inferEventType(form);
271
+
272
+ if (eventType !== 'submit') {
273
+ throw new Error(`Expected 'submit', got '${eventType}'`);
274
+ }
275
+ });
276
+
277
+ // Test 23: inferEventType for details element
278
+ test('should infer "toggle" event for details element', () => {
279
+ const details = document.createElement('details');
280
+ const eventType = inferEventType(details);
281
+
282
+ if (eventType !== 'toggle') {
283
+ throw new Error(`Expected 'toggle', got '${eventType}'`);
284
+ }
285
+ });
286
+
287
+ // Test 24: inferEventType for dialog element
288
+ test('should infer "close" event for dialog element', () => {
289
+ const dialog = document.createElement('dialog');
290
+ const eventType = inferEventType(dialog);
291
+
292
+ if (eventType !== 'close') {
293
+ throw new Error(`Expected 'close', got '${eventType}'`);
294
+ }
295
+ });
296
+
297
+ // Test 25: inferEventType for button element (default to click)
298
+ test('should infer "click" event for button element', () => {
299
+ const button = document.createElement('button');
300
+ const eventType = inferEventType(button);
301
+
302
+ if (eventType !== 'click') {
303
+ throw new Error(`Expected 'click', got '${eventType}'`);
304
+ }
305
+ });
306
+
307
+ // Test 26: inferEventType for div element (default to click)
308
+ test('should infer "click" event for div element', () => {
309
+ const div = document.createElement('div');
310
+ const eventType = inferEventType(div);
311
+
312
+ if (eventType !== 'click') {
313
+ throw new Error(`Expected 'click', got '${eventType}'`);
314
+ }
315
+ });
316
+
317
+ // Test 27: eventType getter via enh.infer
318
+ test('should access eventType via enh.infer.eventType', () => {
319
+ const input = document.createElement('input');
320
+ input.set[value] = 'test';
321
+
322
+ if (input.enh.infer.eventType !== 'input') {
323
+ throw new Error(`Expected 'input', got '${input.enh.infer.eventType}'`);
324
+ }
325
+ });
326
+
327
+ // Test 28: eventType getter for different element types
328
+ test('should return correct eventType for different elements via getter', () => {
329
+ const form = document.createElement('form');
330
+ form.set[value] = 'test';
331
+
332
+ if (form.enh.infer.eventType !== 'submit') {
333
+ throw new Error(`Expected 'submit', got '${form.enh.infer.eventType}'`);
334
+ }
335
+
336
+ const button = document.createElement('button');
337
+ button.set[value] = 'test';
338
+
339
+ if (button.enh.infer.eventType !== 'click') {
340
+ throw new Error(`Expected 'click', got '${button.enh.infer.eventType}'`);
341
+ }
342
+ });
343
+
344
+ // Display results
345
+ const resultsDiv = document.getElementById('results');
346
+ resultsDiv.innerHTML = `
347
+ <h2>Results: ${passCount}/${testCount} tests passed</h2>
348
+ <pre>${results.join('\n')}</pre>
349
+ `;
350
+
351
+ // Report to parent (for Playwright)
352
+ window.testResults = { passed: passCount, total: testCount, results };
353
+ </script>
354
+ </body>
355
+ </html>
@@ -0,0 +1,19 @@
1
+ import { test, expect } from '@playwright/test';
2
+
3
+ test('Inferencer Enhancement › should run all inferencer tests in browser', async ({ page }) => {
4
+ // Start local server and navigate
5
+ await page.goto('http://localhost:8000/tests/inferencer.html');
6
+
7
+ // Wait for tests to complete
8
+ await page.waitForFunction(() => window.testResults !== undefined, { timeout: 5000 });
9
+
10
+ // Get test results
11
+ const results = await page.evaluate(() => window.testResults);
12
+
13
+ // Log results
14
+ console.log(`Inferencer tests: ${results.passed}/${results.total} passed`);
15
+ results.results.forEach((result: string) => console.log(result));
16
+
17
+ // Assert all tests passed
18
+ expect(results.passed).toBe(results.total);
19
+ });
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module":"ESNext",
5
+ "sourceMap": false,
6
+ "experimentalDecorators": false,
7
+ "newLine": "LF",
8
+ "strict": true,
9
+ "skipLibCheck": true
10
+ },
11
+ "include": [
12
+ "inferencer.ts",
13
+ "InferencedPropagator.ts",
14
+ "upSearch.ts"
15
+ ],
16
+ "exclude":[
17
+ "node_modules/*"
18
+ ]
19
+ }
@@ -0,0 +1,128 @@
1
+ # Conversion Template
2
+
3
+ This spec template provides a structured approach to converting legacy be-* enhancement projects to the modern architecture.
4
+
5
+ ## When to Use This Template
6
+
7
+ Use this template when:
8
+ - You want to track conversion progress step-by-step
9
+ - You're converting a be-* project for the first time
10
+ - You want to review each step before proceeding
11
+ - Multiple people are involved in the conversion
12
+ - You want a record of the conversion process
13
+
14
+ ## How to Use This Template
15
+
16
+ ### Option 1: Copy to Project (Recommended)
17
+
18
+ 1. Copy this entire folder to your project's `.kiro/specs/` directory:
19
+ ```bash
20
+ cp -r types/.kiro/specs/conversion-template .kiro/specs/conversion-[project-name]
21
+ ```
22
+
23
+ 2. Update placeholders in all files:
24
+ - Replace `[PROJECT_NAME]` with your project name (e.g., "be-clonable")
25
+ - Replace `[project-name]` with kebab-case name (e.g., "be-clonable")
26
+ - Replace `[ClassName]` with PascalCase name (e.g., "BeClonable")
27
+ - Replace `[emoji]` with actual emoji if applicable (e.g., "⿻")
28
+
29
+ 3. Work through the tasks in `tasks.md` sequentially
30
+
31
+ 4. Use Kiro to execute tasks: "execute task 1", "execute task 2", etc.
32
+
33
+ ### Option 2: Use as Reference
34
+
35
+ Simply reference this template while doing a manual conversion:
36
+ - Follow the requirements in `requirements.md`
37
+ - Understand the architecture from `design.md`
38
+ - Use `tasks.md` as a checklist
39
+
40
+ ## Template Structure
41
+
42
+ ### requirements.md
43
+ - User stories for each conversion step
44
+ - Correctness properties to verify
45
+ - Success criteria
46
+ - Non-functional requirements
47
+
48
+ ### design.md
49
+ - Architecture overview with diagrams
50
+ - Component design for each file type
51
+ - Data flow explanations
52
+ - Design decisions and rationale
53
+ - Alternatives considered
54
+
55
+ ### tasks.md
56
+ - Detailed task breakdown (11 major tasks, 60+ subtasks)
57
+ - Task dependencies
58
+ - Execution notes for each step
59
+ - Reference to ConversionInstructions.md
60
+
61
+ ## Key Features
62
+
63
+ ### Comprehensive Coverage
64
+ All 10 conversion steps from ConversionInstructions.md are covered with detailed subtasks
65
+
66
+ ### Verification Built-in
67
+ Task 11 provides comprehensive verification steps to ensure conversion success
68
+
69
+ ### Reference Integration
70
+ All files reference ConversionInstructions.md for detailed step-by-step instructions
71
+
72
+ ### Kiro-Optimized
73
+ - Uses file references: `#[[file:../../ConversionInstructions.md]]`
74
+ - Task format compatible with Kiro's task execution
75
+ - Structured for spec-driven development workflow
76
+
77
+ ## Example Usage with Kiro
78
+
79
+ ```
80
+ User: "I want to convert be-clonable to the modern architecture"
81
+
82
+ Kiro: "I can help you with that. Would you like to:
83
+ 1. Create a tracked conversion spec (recommended for first-time conversions)
84
+ 2. Do a direct conversion (faster, for experienced users)
85
+
86
+ User: "Create a spec"
87
+
88
+ Kiro: [Creates spec from template, updates placeholders]
89
+ "I've created a conversion spec at .kiro/specs/conversion-be-clonable/
90
+ Let's start with Task 1: Migrate Type Definitions. Ready to begin?"
91
+
92
+ User: "Yes"
93
+
94
+ Kiro: [Executes Task 1, marks subtasks complete]
95
+ "Task 1 complete. Type definitions migrated to types/be-clonable/.
96
+ Ready for Task 2: Archive Legacy Implementation?"
97
+ ```
98
+
99
+ ## Success Criteria
100
+
101
+ A successful conversion using this template should result in:
102
+ - ✅ All tasks marked complete
103
+ - ✅ `npm run build` succeeds
104
+ - ✅ `npm test` passes
105
+ - ✅ No TypeScript errors
106
+ - ✅ Legacy code preserved in legacy/ folder
107
+ - ✅ Modern architecture verified
108
+
109
+ ## Related Files
110
+
111
+ - `../../ConversionInstructions.md` - Detailed step-by-step instructions
112
+ - `../../.kiro/steering/conversion-guide.md` - Kiro steering guidance
113
+ - Reference implementations:
114
+ - [be-a-beacon](https://github.com/bahrus/be-a-beacon)
115
+ - [be-committed](https://github.com/bahrus/be-committed)
116
+ - [be-decked-with](https://github.com/bahrus/be-decked-with)
117
+
118
+ ## Customization
119
+
120
+ Feel free to customize this template for your specific needs:
121
+ - Add project-specific tasks
122
+ - Modify verification steps
123
+ - Add additional correctness properties
124
+ - Extend design documentation
125
+
126
+ ## Feedback
127
+
128
+ If you find issues with this template or have suggestions for improvement, please update the template in the types repository so all projects benefit.