el-maker 0.0.0 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/.gitmodules +3 -0
  2. package/ElementMaker.js +95 -0
  3. package/Instructions.md +9 -0
  4. package/README.md +105 -1
  5. package/SuggestionForExtending.md +131 -0
  6. package/package.json +19 -3
  7. package/types/.kiro/specs/conversion-template/README.md +128 -0
  8. package/types/.kiro/specs/conversion-template/design.md +360 -0
  9. package/types/.kiro/specs/conversion-template/requirements.md +191 -0
  10. package/types/.kiro/specs/conversion-template/tasks.md +174 -0
  11. package/types/.kiro/steering/coding-standards.md +17 -0
  12. package/types/.kiro/steering/conversion-guide.md +103 -0
  13. package/types/.kiro/steering/declarative-configuration.md +108 -0
  14. package/types/.kiro/steering/emc-json-serializability.md +306 -0
  15. package/types/EnhancementConversionInstructions.md +1626 -0
  16. package/types/LICENSE +21 -0
  17. package/types/NewCustomElementFeature.md +683 -0
  18. package/types/NewEnhancementInstructions.md +395 -0
  19. package/types/README.md +2 -0
  20. package/types/agrace/types.d.ts +11 -0
  21. package/types/assign-gingerly/types.d.ts +476 -0
  22. package/types/be-a-beacon/types.d.ts +17 -0
  23. package/types/be-bound/types.d.ts +61 -0
  24. package/types/be-buttoned-up/types.d.ts +19 -0
  25. package/types/be-clonable/types.d.ts +36 -0
  26. package/types/be-committed/types.d.ts +22 -0
  27. package/types/be-decked-with/types.d.ts +26 -0
  28. package/types/be-delible/types.d.ts +25 -0
  29. package/types/be-reflective/types.d.ts +78 -0
  30. package/types/be-render-neutral/types.d.ts +29 -0
  31. package/types/be-typed/types.d.ts +31 -0
  32. package/types/do-inc/types.d.ts +56 -0
  33. package/types/do-invoke/types.d.ts +38 -0
  34. package/types/do-merge/types.d.ts +28 -0
  35. package/types/do-toggle/types.d.ts +31 -0
  36. package/types/face-up/types.d.ts +100 -0
  37. package/types/global.d.ts +29 -0
  38. package/types/id-generation/types.d.ts +26 -0
  39. package/types/inferencer/types.d.ts +46 -0
  40. package/types/mount-observer/types.d.ts +363 -0
  41. package/types/nested-regex-groups/types.d.ts +101 -0
  42. package/types/roundabout/types.d.ts +255 -0
  43. package/types/templ-maker/types.d.ts +43 -0
  44. package/types/time-ticker/types.d.ts +62 -0
  45. package/types/truth-sourcer/types.d.ts +44 -0
package/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "types"]
2
+ path = types
3
+ url = https://github.com/bahrus/types.git
@@ -0,0 +1,95 @@
1
+ // @ts-check
2
+ /** @import {SupportedFeaturesMap} from './types/assign-gingerly/types' */
3
+
4
+
5
+ /**
6
+ * ElementMaker — Abstract base custom element class that declares support
7
+ * for a catalog of composable features via `static supportedFeatures`.
8
+ *
9
+ * Concrete elements are defined declaratively (via `defineWithFeatures` or
10
+ * cede scripts) by selecting which features to activate and providing
11
+ * per-element configuration — without writing any JavaScript class code.
12
+ *
13
+ * Features are lazily instantiated on first property access. Async fallback
14
+ * spawns ensure implementations are only loaded when a derived element
15
+ * actually uses them.
16
+ *
17
+ * @abstract
18
+ */
19
+ export class ElementMaker extends HTMLElement {
20
+ /** @type {EventTarget} */
21
+ propagator = new EventTarget();
22
+
23
+ /** @type {ElementInternals} */
24
+ #internals;
25
+
26
+ /** @type {SupportedFeaturesMap} */
27
+ static supportedFeatures = {
28
+ roundabout: {
29
+ fallbackSpawn: () => import('roundabout-lib/roundaboutFeature.js')
30
+ .then(m => m.RoundaboutFeature),
31
+ callbackForwarding: ['connectedCallback'],
32
+ /** @param {ElementMaker} instance */
33
+ getSharedContext(instance) {
34
+ return {
35
+ internals: instance.#internals,
36
+ hostPropagator: instance.propagator,
37
+ };
38
+ },
39
+ },
40
+ truthSourcer: {
41
+ fallbackSpawn: () => import('truth-sourcer/TruthSourcer.js')
42
+ .then(m => m.TruthSourcer),
43
+ callbackForwarding: ['connectedCallback', 'attributeChangedCallback'],
44
+ /** @param {ElementMaker} instance */
45
+ getSharedContext(instance) {
46
+ return {
47
+ hostPropagator: instance.propagator,
48
+ };
49
+ },
50
+ },
51
+ faceUp: {
52
+ fallbackSpawn: () => import('face-up/FaceUp.js')
53
+ .then(m => m.FaceUp),
54
+ callbackForwarding: [
55
+ 'connectedCallback',
56
+ 'disconnectedCallback',
57
+ 'formDisabledCallback',
58
+ 'formResetCallback',
59
+ 'formStateRestoreCallback',
60
+ ],
61
+ /** @param {ElementMaker} instance */
62
+ getSharedContext(instance) {
63
+ return {
64
+ internals: instance.#internals,
65
+ };
66
+ },
67
+ },
68
+ reflector: {
69
+ fallbackSpawn: () => import('be-reflective/ReflectorLazy.js')
70
+ .then(m => m.ReflectorLazy),
71
+ callbackForwarding: ['connectedCallback', 'disconnectedCallback'],
72
+ /** @param {ElementMaker} instance */
73
+ getSharedContext(instance) {
74
+ return {
75
+ internals: instance.#internals,
76
+ hostPropagator: instance.propagator,
77
+ };
78
+ },
79
+ },
80
+ templateMaker: {
81
+ fallbackSpawn: () => import('templ-maker/TemplateMaker.js')
82
+ .then(m => m.TemplateMaker),
83
+ callbackForwarding: ['connectedCallback'],
84
+ },
85
+ };
86
+
87
+ static featuresConfig = {
88
+ lifecycleKeys: true,
89
+ };
90
+
91
+ constructor() {
92
+ super();
93
+ this.#internals = this.attachInternals();
94
+ }
95
+ }
@@ -0,0 +1,9 @@
1
+ # Instructions
2
+
3
+ ## Human ask
4
+
5
+ Please become familiar with the documentation in types/NewCustomElementFeature.md (tangentially relevant) and deeply familiar with https://raw.githubusercontent.com/bahrus/assign-gingerly/refs/heads/baseline/docs/defineWithFeatures.md.
6
+
7
+ Then take a look at the README.md.
8
+
9
+ If you then have the confidence to proceed implementing the ElementMaker.js abstract custom element class, please proceed. Otherwise, post questions below.
package/README.md CHANGED
@@ -1 +1,105 @@
1
- # element-maker
1
+ # element-maker
2
+
3
+ An abstract custom element base class (`ElementMaker`) that bundles a catalog of composable features behind async lazy-loading. Concrete elements are defined declaratively — picking which features to activate and providing per-element configuration — without writing any JavaScript class code.
4
+
5
+ ## How It Works
6
+
7
+ `ElementMaker` extends `HTMLElement` and declares `static supportedFeatures` with async `fallbackSpawn` functions for each feature. Feature implementations are only imported when a derived element actually uses them, so unused features add zero overhead.
8
+
9
+ Concrete elements are created via [`defineWithFeatures`](https://github.com/bahrus/assign-gingerly/blob/baseline/docs/defineWithFeatures.md), which:
10
+
11
+ 1. Waits for the base class to be defined
12
+ 2. Resolves async fallback spawns in parallel (cached per base class)
13
+ 3. Creates a subclass dynamically
14
+ 4. Calls `assignFeatures` with the resolved spawns + JSON config
15
+ 5. Registers the element
16
+
17
+ This enables fully declarative element definition from JSON — including from [mount-observer cede scripts](https://github.com/bahrus/mount-observer#custom-element-definition-cede-scripts) embedded in HTML.
18
+
19
+ ## Usage
20
+
21
+ ### From JavaScript
22
+
23
+ ```js
24
+ import { defineWithFeatures } from 'assign-gingerly/defineWithFeatures.js';
25
+
26
+ await defineWithFeatures('time-ticker', 'el-maker', {
27
+ assignFeatures: {
28
+ roundabout: {
29
+ customData: { raConfig: { actions: {...}, compacts: {...} } },
30
+ withAttrs: { base: 'tt', duration: '${base}-duration', _duration: { instanceOf: 'Number' } },
31
+ callbackForwarding: ['connectedCallback']
32
+ },
33
+ truthSourcer: {
34
+ callbackForwarding: ['connectedCallback', 'attributeChangedCallback']
35
+ },
36
+ faceUp: {
37
+ customData: { integrateWithRoundabout: true },
38
+ callbackForwarding: ['connectedCallback', 'formDisabledCallback', 'formResetCallback', 'formStateRestoreCallback']
39
+ }
40
+ }
41
+ });
42
+ ```
43
+
44
+ ### From a cede script in HTML
45
+
46
+ ```html
47
+ <time-ticker>
48
+ <script type="cede" data-extends="el-maker">{
49
+ "assignFeatures": {
50
+ "roundabout": {
51
+ "customData": { "raConfig": { ... } },
52
+ "withAttrs": { "base": "tt", "duration": "${base}-duration" },
53
+ "callbackForwarding": ["connectedCallback"]
54
+ },
55
+ "truthSourcer": {
56
+ "callbackForwarding": ["connectedCallback", "attributeChangedCallback"]
57
+ }
58
+ }
59
+ }</script>
60
+ </time-ticker>
61
+ ```
62
+
63
+ ## What the Base Class Provides
64
+
65
+ `ElementMaker` sets up shared infrastructure that features depend on:
66
+
67
+ | Resource | Purpose |
68
+ |----------|---------|
69
+ | `propagator` (EventTarget) | Property change event bus — used by truthSourcer and reflector to observe value changes |
70
+ | `#internals` (ElementInternals) | Shared via `getSharedContext` with faceUp (form control), reflector (custom states), and roundabout |
71
+ | `static featuresConfig` | Installs `whenFeatureReady()` for awaiting async feature resolution |
72
+
73
+ Because all spawns are async, defining 10 elements that extend `el-maker` only imports each feature module once — results are cached per base class.
74
+
75
+ ## Feature Catalog
76
+
77
+ | Package | Description | Source |
78
+ |---------|-------------|--------|
79
+ | [truth-sourcer](https://www.npmjs.com/package/truth-sourcer) | Attribute/property binding and truth-sourcing for custom elements | [GitHub](https://github.com/bahrus/truth-sourcer) |
80
+ | [be-reflective](https://www.npmjs.com/package/be-reflective) | CSS custom state reflection from computed styles | [GitHub](https://github.com/bahrus/be-reflective) |
81
+ | [face-up](https://www.npmjs.com/package/face-up) | Form Associated Custom Element behavior via ElementInternals | [GitHub](https://github.com/bahrus/face-up) |
82
+ | [roundabout-lib](https://www.npmjs.com/package/roundabout-lib) | Reactive view-model binding with template rendering and computed property orchestration | [GitHub](https://github.com/bahrus/roundabout-lib) |
83
+ | [templ-maker](https://www.npmjs.com/package/templ-maker) | Extracts a DOM fragment into a reusable template and clones it per instance (works with cede scripts) | [GitHub](https://github.com/bahrus/templ-maker) |
84
+
85
+ ### Example: time-ticker
86
+
87
+ [time-ticker](https://github.com/bahrus/time-ticker) demonstrates a fully feature-based component with no code in the element class itself — all behavior comes from the `roundabout` and `timeTicker` features wired via `assignFeatures`.
88
+
89
+ ## Viewing Demos Locally
90
+
91
+ 1. Install git
92
+ 2. Fork/clone this repo
93
+ 3. Install node.js
94
+ 4. Open command window to folder where you cloned this repo
95
+ 5. > git submodule add https://github.com/bahrus/types.git types
96
+ 6. > git submodule update --init --recursive
97
+ 7. > npm install
98
+ 8. > npm run serve
99
+ 9. Open http://localhost:8000/demo/ in a modern browser
100
+
101
+ ## Running Tests
102
+
103
+ ```
104
+ > npm run test
105
+ ```
@@ -0,0 +1,131 @@
1
+ # Suggestion for Extending
2
+
3
+ I like how you made a good call to treat the time-ticker feature as one that probably doesn't belong in an "abstract" class called ElementMaker that serves as general a purpose as element-maker does. But the explanation provided for separating it out was a bit fuzzy, I think.
4
+
5
+ The time-ticker package does in fact include both a [custom element feature](https://raw.githubusercontent.com/bahrus/time-ticker/refs/heads/baseline/TimeTicker.js) as well as a [custom element](https://raw.githubusercontent.com/bahrus/time-ticker/refs/heads/baseline/time-ticker-element.js).
6
+
7
+ I would like to go back to that package, and make the custom element extend ElementMaker from this package so that the static features get "inherited" somehow, and add on the time-ticker package. I guess there could be a separate file that could be referenced as an old-fashioned module that registers the custom element name, similar to [def.js](https://raw.githubusercontent.com/bahrus/time-ticker/refs/heads/baseline/def.js)
8
+
9
+ After studying these links carefully, can you spell out what to do below, and I will then copy this file into that project and ask kiro to make the necessary adjustments.
10
+
11
+ ---
12
+
13
+ ## Instructions for Converting time-ticker to Extend ElementMaker
14
+
15
+ ### Overview
16
+
17
+ Currently `time-ticker-element.js` is a standalone `HTMLElement` subclass that manually redeclares `propagator`, `#internals`, `attachInternals()`, and `static supportedFeatures` entries for `truthSourcer`, `faceUp`, and `roundabout`. All of that is already provided by `ElementMaker`. The goal is to:
18
+
19
+ 1. Extend `ElementMaker` instead of `HTMLElement`
20
+ 2. Inherit all of ElementMaker's features automatically
21
+ 3. Only declare the *additional* feature (`timeTicker`) that is specific to this package
22
+ 4. Simplify `wireFeatures.js` to only inject what's unique to this element
23
+ 5. Keep `def.js` as the side-effect module that registers the tag name
24
+
25
+ ### Step 1: Add `el-maker` as a dependency
26
+
27
+ In `package.json`, add:
28
+
29
+ ```json
30
+ "dependencies": {
31
+ "el-maker": "0.0.0"
32
+ }
33
+ ```
34
+
35
+ Also add it to `imports.html`:
36
+
37
+ ```html
38
+ "el-maker/": "/node_modules/el-maker/"
39
+ ```
40
+
41
+ ### Step 2: Rewrite `time-ticker-element.js`
42
+
43
+ Replace the entire file with:
44
+
45
+ ```js
46
+ import { ElementMaker } from 'el-maker/ElementMaker.js';
47
+
48
+ export class TimeTickerElement extends ElementMaker {
49
+ static supportedFeatures = {
50
+ ...ElementMaker.supportedFeatures,
51
+ timeTicker: {},
52
+ };
53
+ }
54
+ ```
55
+
56
+ Key points:
57
+ - Extends `ElementMaker` instead of `HTMLElement`
58
+ - No need to redeclare `propagator`, `#internals`, or `constructor` — inherited from `ElementMaker`
59
+ - No need to redeclare `truthSourcer`, `faceUp`, `roundabout`, or `reflector` — inherited via the spread of `ElementMaker.supportedFeatures`
60
+ - Only adds the `timeTicker` slot, which is specific to this package
61
+ - `static formAssociated = true` is no longer needed here — `FaceUp.onAssigned` sets it automatically when `faceUp` is wired via `assignFeatures`
62
+
63
+ ### Step 3: Simplify `wireFeatures.js`
64
+
65
+ The current `wireFeatures.js` eagerly imports all feature classes (RoundaboutFeature, TruthSourcer, FaceUp) and passes them as explicit `spawn` values. Since `ElementMaker` already declares async `fallbackSpawn` for all of those, you only need to provide:
66
+
67
+ - The `timeTicker` spawn (unique to this package)
68
+ - The `roundabout` config (`customData`, `withAttrs`) that comes from the cef.json
69
+ - Any `callbackForwarding` or `customData` overrides specific to this element
70
+
71
+ ```js
72
+ import { TimeTicker } from './TimeTicker.js';
73
+ import 'assign-gingerly/assignFeatures.js';
74
+
75
+ export async function wireFeatures(ElementClass, cfg) {
76
+ const { roundabout } = cfg.features;
77
+ const { customData, withAttrs } = roundabout;
78
+
79
+ await customElements.assignFeatures(ElementClass, {
80
+ timeTicker: { spawn: TimeTicker },
81
+ truthSourcer: {
82
+ callbackForwarding: ['connectedCallback', 'attributeChangedCallback'],
83
+ },
84
+ faceUp: {
85
+ customData: { integrateWithRoundabout: true },
86
+ callbackForwarding: [
87
+ 'connectedCallback', 'disconnectedCallback',
88
+ 'formDisabledCallback', 'formResetCallback', 'formStateRestoreCallback',
89
+ ],
90
+ },
91
+ roundabout: {
92
+ customData,
93
+ withAttrs,
94
+ callbackForwarding: ['connectedCallback'],
95
+ },
96
+ });
97
+ }
98
+ ```
99
+
100
+ Key changes:
101
+ - Removed all explicit `spawn` entries for `truthSourcer`, `faceUp`, and `roundabout` — the async `fallbackSpawn` from `ElementMaker.supportedFeatures` will be used instead
102
+ - Removed the eager imports of `RoundaboutFeature`, `TruthSourcer`, and `FaceUp` — they'll be lazy-loaded on first access
103
+ - Still pass `callbackForwarding` and `customData` since those are per-element configuration (the consumer additions get unioned with the author defaults from `supportedFeatures`)
104
+
105
+ ### Step 4: `def.js` stays the same
106
+
107
+ ```js
108
+ import { TimeTickerElement } from './time-ticker-element.js';
109
+ import { wireFeatures } from './wireFeatures.js';
110
+ import defRef from './defRef.json' with { type: 'json' };
111
+
112
+ await wireFeatures(TimeTickerElement, defRef);
113
+ customElements.define('time-ticker', TimeTickerElement);
114
+ ```
115
+
116
+ No changes needed.
117
+
118
+ ### Step 5: Remove redundant dependencies
119
+
120
+ Since `ElementMaker` brings in `truth-sourcer`, `face-up`, `be-reflective`, and `roundabout-lib` as its own dependencies, you can remove them from time-ticker's `package.json` dependencies (they'll be available transitively). Keep only:
121
+
122
+ - `el-maker` (brings everything)
123
+ - `assign-gingerly` (needed for `assignFeatures.js` import)
124
+ - Any test/dev dependencies
125
+
126
+ ### Benefits
127
+
128
+ 1. **Less boilerplate** — no manual `propagator`, `#internals`, `attachInternals()`, or `getSharedContext` declarations per element
129
+ 2. **Lazy loading** — feature implementations are only imported when actually accessed, not eagerly at module load time
130
+ 3. **Consistency** — all elements extending `ElementMaker` get the same shared context wiring, reducing bugs from copy-paste divergence
131
+ 4. **Extensibility** — if a new feature is added to `ElementMaker` later, all extending elements inherit it automatically
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "el-maker",
3
- "version": "0.0.0",
3
+ "version": "0.0.1",
4
4
  "description": "",
5
5
  "homepage": "https://github.com/bahrus/element-maker#readme",
6
6
  "bugs": {
@@ -13,8 +13,24 @@
13
13
  "license": "MIT",
14
14
  "author": "Bruce B. Anderson <anderson.bruce.b@gmail.com>",
15
15
  "type": "module",
16
- "main": "index.js",
16
+ "main": "ElementMaker.js",
17
17
  "scripts": {
18
- "test": "playwright test"
18
+ "build": "node emc.mjs > emc.json && node ⏻.mjs > ⏻.json",
19
+ "serve": "node ./node_modules/spa-ssi/serve.js",
20
+ "test": "playwright test",
21
+ "safari": "npx playwright wk http://localhost:8000",
22
+ "update": "ncu -u && npm install"
23
+ },
24
+ "dependencies": {
25
+ "be-reflective": "0.0.3",
26
+ "face-up": "0.0.4",
27
+ "roundabout-lib": "0.0.20",
28
+ "templ-maker": "0.0.1",
29
+ "truth-sourcer": "0.0.3",
30
+ "time-ticker": "0.0.31"
31
+ },
32
+ "devDependencies": {
33
+ "spa-ssi": "0.0.27",
34
+ "@playwright/test": "1.60.0"
19
35
  }
20
36
  }
@@ -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.