@levu/snap 0.1.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 (168) hide show
  1. package/.github/workflows/ci.yml +26 -0
  2. package/README.md +49 -0
  3. package/dist/cli/help-command.d.ts +1 -0
  4. package/dist/cli/help-command.js +1 -0
  5. package/dist/cli-entry.d.ts +1 -0
  6. package/dist/cli-entry.js +80 -0
  7. package/dist/core/contracts/action-contract.d.ts +25 -0
  8. package/dist/core/contracts/action-contract.js +1 -0
  9. package/dist/core/contracts/help-contract.d.ts +18 -0
  10. package/dist/core/contracts/help-contract.js +1 -0
  11. package/dist/core/contracts/module-contract.d.ts +6 -0
  12. package/dist/core/contracts/module-contract.js +1 -0
  13. package/dist/core/errors/framework-errors.d.ts +19 -0
  14. package/dist/core/errors/framework-errors.js +26 -0
  15. package/dist/core/registry/action-registry.d.ts +16 -0
  16. package/dist/core/registry/action-registry.js +52 -0
  17. package/dist/help/help-command.d.ts +8 -0
  18. package/dist/help/help-command.js +21 -0
  19. package/dist/help/help-model.d.ts +9 -0
  20. package/dist/help/help-model.js +1 -0
  21. package/dist/help/help-renderer.d.ts +2 -0
  22. package/dist/help/help-renderer.js +16 -0
  23. package/dist/help/hierarchy-resolver.d.ts +3 -0
  24. package/dist/help/hierarchy-resolver.js +43 -0
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.js +8 -0
  27. package/dist/modules/sample-content/module.d.ts +3 -0
  28. package/dist/modules/sample-content/module.js +61 -0
  29. package/dist/modules/sample-system/module.d.ts +3 -0
  30. package/dist/modules/sample-system/module.js +71 -0
  31. package/dist/runtime/dispatch.d.ts +11 -0
  32. package/dist/runtime/dispatch.js +47 -0
  33. package/dist/runtime/engine.d.ts +13 -0
  34. package/dist/runtime/engine.js +44 -0
  35. package/dist/runtime/mode-resolver.d.ts +8 -0
  36. package/dist/runtime/mode-resolver.js +8 -0
  37. package/dist/runtime/resume-store.d.ts +13 -0
  38. package/dist/runtime/resume-store.js +45 -0
  39. package/dist/runtime/runtime-context.d.ts +9 -0
  40. package/dist/runtime/runtime-context.js +1 -0
  41. package/dist/runtime/state-machine.d.ts +32 -0
  42. package/dist/runtime/state-machine.js +50 -0
  43. package/dist/src/cli/help-command.d.ts +1 -0
  44. package/dist/src/cli/help-command.js +1 -0
  45. package/dist/src/cli-entry.d.ts +1 -0
  46. package/dist/src/cli-entry.js +80 -0
  47. package/dist/src/core/contracts/action-contract.d.ts +25 -0
  48. package/dist/src/core/contracts/action-contract.js +1 -0
  49. package/dist/src/core/contracts/help-contract.d.ts +18 -0
  50. package/dist/src/core/contracts/help-contract.js +1 -0
  51. package/dist/src/core/contracts/module-contract.d.ts +6 -0
  52. package/dist/src/core/contracts/module-contract.js +1 -0
  53. package/dist/src/core/errors/framework-errors.d.ts +19 -0
  54. package/dist/src/core/errors/framework-errors.js +26 -0
  55. package/dist/src/core/registry/action-registry.d.ts +16 -0
  56. package/dist/src/core/registry/action-registry.js +52 -0
  57. package/dist/src/help/help-command.d.ts +8 -0
  58. package/dist/src/help/help-command.js +21 -0
  59. package/dist/src/help/help-model.d.ts +9 -0
  60. package/dist/src/help/help-model.js +1 -0
  61. package/dist/src/help/help-renderer.d.ts +2 -0
  62. package/dist/src/help/help-renderer.js +16 -0
  63. package/dist/src/help/hierarchy-resolver.d.ts +3 -0
  64. package/dist/src/help/hierarchy-resolver.js +43 -0
  65. package/dist/src/index.d.ts +3 -0
  66. package/dist/src/index.js +8 -0
  67. package/dist/src/modules/sample-content/module.d.ts +3 -0
  68. package/dist/src/modules/sample-content/module.js +61 -0
  69. package/dist/src/modules/sample-system/module.d.ts +3 -0
  70. package/dist/src/modules/sample-system/module.js +71 -0
  71. package/dist/src/runtime/dispatch.d.ts +11 -0
  72. package/dist/src/runtime/dispatch.js +47 -0
  73. package/dist/src/runtime/engine.d.ts +13 -0
  74. package/dist/src/runtime/engine.js +44 -0
  75. package/dist/src/runtime/mode-resolver.d.ts +8 -0
  76. package/dist/src/runtime/mode-resolver.js +8 -0
  77. package/dist/src/runtime/resume-store.d.ts +13 -0
  78. package/dist/src/runtime/resume-store.js +45 -0
  79. package/dist/src/runtime/runtime-context.d.ts +9 -0
  80. package/dist/src/runtime/runtime-context.js +1 -0
  81. package/dist/src/runtime/state-machine.d.ts +32 -0
  82. package/dist/src/runtime/state-machine.js +50 -0
  83. package/dist/src/tui/accessibility-footer.d.ts +7 -0
  84. package/dist/src/tui/accessibility-footer.js +4 -0
  85. package/dist/src/tui/component-adapters/confirm.d.ts +5 -0
  86. package/dist/src/tui/component-adapters/confirm.js +3 -0
  87. package/dist/src/tui/component-adapters/group.d.ts +5 -0
  88. package/dist/src/tui/component-adapters/group.js +7 -0
  89. package/dist/src/tui/component-adapters/multiselect.d.ts +10 -0
  90. package/dist/src/tui/component-adapters/multiselect.js +9 -0
  91. package/dist/src/tui/component-adapters/select.d.ts +10 -0
  92. package/dist/src/tui/component-adapters/select.js +7 -0
  93. package/dist/src/tui/component-adapters/text.d.ts +6 -0
  94. package/dist/src/tui/component-adapters/text.js +7 -0
  95. package/dist/src/tui/interrupt-handlers.d.ts +7 -0
  96. package/dist/src/tui/interrupt-handlers.js +7 -0
  97. package/dist/tests/e2e/cli-smoke.e2e.test.d.ts +1 -0
  98. package/dist/tests/e2e/cli-smoke.e2e.test.js +16 -0
  99. package/dist/tests/integration/runtime-dispatch.integration.test.d.ts +1 -0
  100. package/dist/tests/integration/runtime-dispatch.integration.test.js +20 -0
  101. package/dist/tests/transcript/help.transcript.test.d.ts +1 -0
  102. package/dist/tests/transcript/help.transcript.test.js +18 -0
  103. package/dist/tests/unit/state-machine.test.d.ts +1 -0
  104. package/dist/tests/unit/state-machine.test.js +20 -0
  105. package/dist/tui/accessibility-footer.d.ts +7 -0
  106. package/dist/tui/accessibility-footer.js +4 -0
  107. package/dist/tui/component-adapters/confirm.d.ts +5 -0
  108. package/dist/tui/component-adapters/confirm.js +3 -0
  109. package/dist/tui/component-adapters/group.d.ts +5 -0
  110. package/dist/tui/component-adapters/group.js +7 -0
  111. package/dist/tui/component-adapters/multiselect.d.ts +10 -0
  112. package/dist/tui/component-adapters/multiselect.js +9 -0
  113. package/dist/tui/component-adapters/select.d.ts +10 -0
  114. package/dist/tui/component-adapters/select.js +7 -0
  115. package/dist/tui/component-adapters/text.d.ts +6 -0
  116. package/dist/tui/component-adapters/text.js +7 -0
  117. package/dist/tui/interrupt-handlers.d.ts +7 -0
  118. package/dist/tui/interrupt-handlers.js +7 -0
  119. package/dist/vitest.config.d.ts +2 -0
  120. package/dist/vitest.config.js +7 -0
  121. package/docs/help-contract-spec.md +29 -0
  122. package/docs/module-authoring-guide.md +52 -0
  123. package/package.json +20 -0
  124. package/plans/260209-1547-hub-dual-runtime-framework/phase-01-foundation-and-contracts.md +71 -0
  125. package/plans/260209-1547-hub-dual-runtime-framework/phase-02-runtime-and-state-machine.md +76 -0
  126. package/plans/260209-1547-hub-dual-runtime-framework/phase-03-tui-components-and-policies.md +71 -0
  127. package/plans/260209-1547-hub-dual-runtime-framework/phase-04-help-system-and-ai-readability.md +69 -0
  128. package/plans/260209-1547-hub-dual-runtime-framework/phase-05-testing-and-quality-gates.md +79 -0
  129. package/plans/260209-1547-hub-dual-runtime-framework/phase-06-sample-modules-and-adoption.md +75 -0
  130. package/plans/260209-1547-hub-dual-runtime-framework/plan.md +105 -0
  131. package/plans/260209-1547-hub-dual-runtime-framework/reports/planner-report.md +27 -0
  132. package/plans/260209-1547-hub-dual-runtime-framework/research/researcher-01-report.md +166 -0
  133. package/plans/260209-1547-hub-dual-runtime-framework/research/researcher-02-report.md +87 -0
  134. package/plans/260209-1547-hub-dual-runtime-framework/scout/scout-01-report.md +24 -0
  135. package/src/cli/help-command.ts +1 -0
  136. package/src/cli-entry.ts +83 -0
  137. package/src/core/contracts/action-contract.ts +30 -0
  138. package/src/core/contracts/help-contract.ts +20 -0
  139. package/src/core/contracts/module-contract.ts +7 -0
  140. package/src/core/errors/framework-errors.ts +26 -0
  141. package/src/core/registry/action-registry.ts +94 -0
  142. package/src/help/help-command.ts +32 -0
  143. package/src/help/help-model.ts +10 -0
  144. package/src/help/help-renderer.ts +21 -0
  145. package/src/help/hierarchy-resolver.ts +54 -0
  146. package/src/index.ts +10 -0
  147. package/src/modules/sample-content/module.ts +66 -0
  148. package/src/modules/sample-system/module.ts +74 -0
  149. package/src/runtime/dispatch.ts +64 -0
  150. package/src/runtime/engine.ts +59 -0
  151. package/src/runtime/mode-resolver.ts +18 -0
  152. package/src/runtime/resume-store.ts +53 -0
  153. package/src/runtime/runtime-context.ts +10 -0
  154. package/src/runtime/state-machine.ts +77 -0
  155. package/src/tui/accessibility-footer.ts +11 -0
  156. package/src/tui/component-adapters/confirm.ts +8 -0
  157. package/src/tui/component-adapters/group.ts +12 -0
  158. package/src/tui/component-adapters/multiselect.ts +22 -0
  159. package/src/tui/component-adapters/select.ts +18 -0
  160. package/src/tui/component-adapters/text.ts +13 -0
  161. package/src/tui/interrupt-handlers.ts +15 -0
  162. package/tests/e2e/cli-smoke.e2e.test.ts +19 -0
  163. package/tests/integration/runtime-dispatch.integration.test.ts +23 -0
  164. package/tests/transcript/help.transcript.test.ts +20 -0
  165. package/tests/unit/state-machine.test.ts +22 -0
  166. package/tsconfig.build.json +9 -0
  167. package/tsconfig.json +17 -0
  168. package/vitest.config.ts +8 -0
@@ -0,0 +1,79 @@
1
+ # Phase 05 — Testing and quality gates
2
+
3
+ ## Context links
4
+ - Runtime/help phases: `./phase-02-runtime-and-state-machine.md`, `./phase-04-help-system-and-ai-readability.md`
5
+ - Research: `./research/researcher-02-report.md`
6
+ - Overview: `./plan.md`
7
+
8
+ ## Overview
9
+ - Priority: P1
10
+ - Status: complete
11
+ - Description: define deterministic tests and CI gates for contract correctness, runtime behavior, help stability, and security guardrails.
12
+
13
+ ## Key Insights
14
+ - Need 4-layer testing: unit, integration, transcript snapshot, e2e smoke.
15
+ - Deterministic env controls are mandatory for terminal tests.
16
+ - Security tests must cover injection, redaction, and escape sanitization.
17
+
18
+ ## Requirements
19
+ <!-- Updated: Validation Session 1 - require 3-OS CI matrix for MVP -->
20
+ - Functional:
21
+ - Add tests for contract triad enforcement.
22
+ - Add runtime mode-selection tests (default TUI vs auto non-interactive).
23
+ - Add help output contract/snapshot tests.
24
+ - Add cancel/timeout/exit code tests.
25
+ - Non-functional:
26
+ - CI matrix includes Linux + macOS + Windows and target Node versions.
27
+ - Flake policy documented and enforced.
28
+
29
+ ## Architecture
30
+ - Test layers:
31
+ - unit: validators, resolver, state transitions.
32
+ - integration: runtime + adapters + registry.
33
+ - transcript: deterministic output frames.
34
+ - e2e-smoke: critical user paths with real process.
35
+ - Quality gates:
36
+ - lint + typecheck + tests + security assertions.
37
+
38
+ ## Related code files
39
+ - Modify: none (greenfield)
40
+ - Create:
41
+ - `vitest.config.ts`
42
+ - `tests/unit/*.test.ts`
43
+ - `tests/integration/*.test.ts`
44
+ - `tests/transcript/*.test.ts`
45
+ - `tests/e2e/*.test.ts`
46
+ - `.github/workflows/ci.yml`
47
+ - Delete: none
48
+
49
+ ## Implementation Steps
50
+ 1. Configure test tooling and deterministic env defaults.
51
+ 2. Implement unit and integration suites for core/runtime/help.
52
+ 3. Add transcript snapshots with stable formatter policy.
53
+ 4. Add e2e smoke for top workflows.
54
+ 5. Configure CI gates and failure policy.
55
+
56
+ ## Todo list
57
+ - [x] Test tooling configured
58
+ - [x] Unit/integration suites implemented
59
+ - [x] Transcript snapshots implemented
60
+ - [x] E2E smoke implemented
61
+ - [x] CI gates and matrix configured
62
+
63
+ ## Success Criteria
64
+ - All quality gates pass on target matrix.
65
+ - Runtime/help regressions caught before merge.
66
+ - Security-sensitive behaviors covered by tests.
67
+
68
+ ## Risk Assessment
69
+ - Risk: flaky terminal tests.
70
+ - Mitigation: deterministic env + focused e2e scope.
71
+ - Risk: long CI runtime.
72
+ - Mitigation: split jobs, run smoke in PR and full nightly optional.
73
+
74
+ ## Security Considerations
75
+ - Test command injection defenses and unsafe shell wrapping.
76
+ - Test secret redaction and terminal escape sanitization paths.
77
+
78
+ ## Next steps
79
+ - Deliver sample modules and adoption assets in Phase 06.
@@ -0,0 +1,75 @@
1
+ # Phase 06 — Sample modules and adoption
2
+
3
+ ## Context links
4
+ - Plan: `./plan.md`
5
+ - Prior phases: `./phase-01-foundation-and-contracts.md` to `./phase-05-testing-and-quality-gates.md`
6
+ - Planner report: `./reports/planner-report.md`
7
+
8
+ ## Overview
9
+ - Priority: P2
10
+ - Status: complete
11
+ - Description: add reference modules and adoption docs proving framework contract and runtime behavior for real teams.
12
+
13
+ ## Key Insights
14
+ - Adoption fails if first module feels heavy.
15
+ - Sample should cover both interactive and non-interactive execution.
16
+ - Keep examples realistic but small.
17
+
18
+ ## Requirements
19
+ - Functional:
20
+ - Provide 2 sample modules with at least 2 actions each.
21
+ - Each sample action includes TUI flow, commandline args/options, and complete help output.
22
+ - Include quickstart for module authors.
23
+ - Non-functional:
24
+ - Minimal boilerplate.
25
+ - Consistent naming and folder conventions.
26
+
27
+ ## Architecture
28
+ - Module shape:
29
+ - `module/index` exports action contracts.
30
+ - Action contracts registered via public API bootstrap.
31
+ - Adoption assets:
32
+ - quickstart doc + “build first action in 10 minutes” path.
33
+
34
+ ## Related code files
35
+ - Modify:
36
+ - `README.md` (create if absent)
37
+ - `src/cli-entry.ts`
38
+ - Create:
39
+ - `src/modules/sample-system/module.ts`
40
+ - `src/modules/sample-content/module.ts`
41
+ - `docs/module-authoring-guide.md`
42
+ - `docs/help-contract-spec.md`
43
+ - Delete: none
44
+
45
+ ## Implementation Steps
46
+ 1. Create two sample modules with distinct action types.
47
+ 2. Register modules into bootstrap entry.
48
+ 3. Validate each action triad and help coverage.
49
+ 4. Write concise adoption docs and migration notes.
50
+ 5. Run final quality gate suite.
51
+
52
+ ## Todo list
53
+ - [x] Sample modules implemented
54
+ - [x] Bootstrap wiring complete
55
+ - [x] Authoring guide drafted
56
+ - [x] Help contract spec drafted
57
+ - [x] Final tests and smoke run complete
58
+
59
+ ## Success Criteria
60
+ - New developer can add one action using docs without reading core internals.
61
+ - Sample actions run in TUI default and auto non-interactive mode.
62
+ - Help outputs satisfy strict contract for all sample actions.
63
+
64
+ ## Risk Assessment
65
+ - Risk: samples diverge from real architecture.
66
+ - Mitigation: enforce same contract checks as production modules.
67
+ - Risk: docs stale quickly.
68
+ - Mitigation: docs tied to tested examples in CI.
69
+
70
+ ## Security Considerations
71
+ - Samples avoid unsafe command execution patterns.
72
+ - Docs include explicit secret-handling and logging redaction notes.
73
+
74
+ ## Next steps
75
+ - Hand off to implementation agent with phase-by-phase checklist execution.
@@ -0,0 +1,105 @@
1
+ ---
2
+ title: "Hub Dual-Runtime Framework Plan"
3
+ description: "Implementation plan for a contract-first TypeScript framework that unifies TUI-default and auto headless CLI execution with strict AI-readable help."
4
+ status: completed
5
+ priority: P2
6
+ effort: 6 phases / ~8-10d
7
+ branch: no-git
8
+ tags: [framework, cli, tui, clack, bombsh-args, ai-readable-help, state-machine]
9
+ created: 2026-02-09
10
+ ---
11
+
12
+ # Plan Overview
13
+
14
+ Goal: build `hub` framework for human + AI terminal usage with one action contract enforcing `tui + commandline + help`.
15
+
16
+ ## Inputs
17
+ - Scout: `./scout/scout-01-report.md`
18
+ - Research: `./research/researcher-01-report.md`, `./research/researcher-02-report.md`
19
+ - Summary: `./reports/planner-report.md`
20
+
21
+ ## Locked decisions
22
+ - Default runtime mode = TUI.
23
+ - Auto non-interactive run when required CLI args are sufficient.
24
+ - Use clack prompts/core broadly.
25
+ - In-process module loading only.
26
+ - Text-first strict help sections for AI/human readability.
27
+ - Workflow model = state machine.
28
+
29
+ ## Phases
30
+ 1. **Phase 01** (complete, 100%)
31
+ - Foundation contracts and triad enforcement
32
+ - `./phase-01-foundation-and-contracts.md`
33
+ 2. **Phase 02** (complete, 100%)
34
+ - Runtime resolver and shared state-machine engine
35
+ - `./phase-02-runtime-and-state-machine.md`
36
+ 3. **Phase 03** (complete, 100%)
37
+ - TUI component adapters and policy handling
38
+ - `./phase-03-tui-components-and-policies.md`
39
+ 4. **Phase 04** (complete, 100%)
40
+ - Hierarchical help system and AI-readable format
41
+ - `./phase-04-help-system-and-ai-readability.md`
42
+ 5. **Phase 05** (complete, 100%)
43
+ - Testing pyramid and quality/security gates
44
+ - `./phase-05-testing-and-quality-gates.md`
45
+ 6. **Phase 06** (complete, 100%)
46
+ - Sample modules and adoption assets
47
+ - `./phase-06-sample-modules-and-adoption.md`
48
+
49
+ ## Dependency chain
50
+ `01 -> 02 -> 03 -> 04 -> 05 -> 06`
51
+
52
+ ## Delivery gates
53
+ - Triad enforcement active at registration.
54
+ - Runtime mode resolver deterministic in TTY/non-TTY.
55
+ - Help output deterministic across all hierarchy levels.
56
+ - Test matrix green on target OS/Node set.
57
+
58
+ ## Open items to confirm
59
+ - Package layout preference (single package vs monorepo).
60
+ - CI provider and mandatory OS/Node support for MVP.
61
+
62
+ ## Validation Log
63
+
64
+ ### Session 1 — 2026-02-09
65
+ **Trigger:** Initial plan creation validation interview.
66
+ **Questions asked:** 4
67
+
68
+ #### Questions & Answers
69
+
70
+ 1. **[Architecture]** Which package layout should we lock for MVP implementation?
71
+ - Options: Single package (Recommended) | Monorepo now | Hybrid scaffold
72
+ - **Answer:** Single package (Recommended)
73
+ - **Rationale:** Reduces setup complexity, keeps velocity high for greenfield MVP.
74
+
75
+ 2. **[Risk]** What OS matrix do you want as required quality gate for MVP?
76
+ - Options: Linux + macOS + Windows (Recommended) | Linux only | Linux + macOS
77
+ - **Answer:** Linux + macOS + Windows (Recommended)
78
+ - **Rationale:** Terminal behavior differs by OS; cross-platform gate is required for framework trust.
79
+
80
+ 3. **[Scope]** How should we finalize the help output contract for MVP?
81
+ - Options: Text-only strict sections (Recommended) | Text + optional JSON | Text + required JSON
82
+ - **Answer:** Text-only strict sections (Recommended)
83
+ - **Rationale:** Aligns product goal and keeps MVP focused on deterministic text contract.
84
+
85
+ 4. **[Tradeoffs]** How much state-machine complexity should we include in MVP?
86
+ - Options: No resume/jump in MVP (Recommended) | Add jump only | Add jump + resume
87
+ - **Answer:** Add jump + resume
88
+ - **Rationale:** Stronger workflow UX requirement accepted despite extra implementation cost.
89
+
90
+ #### Confirmed Decisions
91
+ - Package layout: single package — optimize MVP speed.
92
+ - CI OS gate: Linux + macOS + Windows — enforce terminal compatibility.
93
+ - Help contract: text-only strict sections — deterministic AI/human read path.
94
+ - State-machine scope: include jump + resume — richer workflow support in MVP.
95
+
96
+ #### Action Items
97
+ - [ ] Update phase-02 with jump + resume architecture and tasks.
98
+ - [ ] Update phase-05 with mandatory 3-OS CI matrix requirement.
99
+ - [ ] Mark package layout and text-help contract as locked in phase docs.
100
+
101
+ #### Impact on Phases
102
+ - Phase 01: record single-package architecture decision.
103
+ - Phase 02: add persisted resume + node jump support requirements/architecture/tests.
104
+ - Phase 04: lock text-only strict help contract in requirements.
105
+ - Phase 05: mandate Linux+macOS+Windows CI matrix for MVP.
@@ -0,0 +1,27 @@
1
+ # Planner Report
2
+
3
+ ## Summary
4
+ Created full implementation plan for hub dual-runtime framework in active plan dir. Plan is contract-first, state-machine-driven, and enforces per-action triad: `tui + commandline + help`. Sequence is 6 phases from foundation to adoption, with strict quality gates.
5
+
6
+ ## Rationale
7
+ - YAGNI: skip dynamic plugin loading, marketplace, resumable sessions in v1.
8
+ - KISS: one execution engine, two adapters, one help contract.
9
+ - DRY: single action contract generates runtime behavior and help surface.
10
+ - User-lock alignment: default TUI, auto non-interactive run on sufficient args, clack-heavy interaction model, in-process loading, text-only machine-readable help.
11
+
12
+ ## Key trade-offs
13
+ - Chosen: rigid text help contract over flexible prose.
14
+ - Pro: deterministic for AI/tools.
15
+ - Con: less expressive docs style.
16
+ - Chosen: in-process module loading only.
17
+ - Pro: simpler security/runtime model.
18
+ - Con: no external plugin discovery in v1.
19
+ - Chosen: state-machine orchestration for both runtime paths.
20
+ - Pro: predictable edge handling.
21
+ - Con: upfront modeling cost.
22
+
23
+ ## Unresolved questions
24
+ 1. Repo/package layout preference: single package vs monorepo from day 1?
25
+ 2. Canonical `@bomb.sh/args` reference/API location to lock exact parser contract?
26
+ 3. CI provider preference and mandatory OS coverage at MVP gate?
27
+ 4. Should machine-readable help include optional JSON mode later, while still keeping text contract primary?
@@ -0,0 +1,166 @@
1
+ # Researcher 01 Report
2
+
3
+ - Conducted: 2026-02-09 (Asia/Saigon)
4
+ - Scope: greenfield TypeScript Node.js framework unifying TUI + CLI for human + AI operators
5
+ - Bias: YAGNI/KISS/DRY, minimal moving parts, deterministic output
6
+
7
+ ## Executive takeaways
8
+
9
+ 1. Use **single-source action contracts** as core artifact; generate CLI, TUI, and help from same schema.
10
+ 2. Treat TUI as a **state machine wrapper** over the same command executor used by CLI.
11
+ 3. For AI compatibility, make help output **strict text sections** + stable keys (no ANSI, no prose drift).
12
+ 4. `@clack/prompts` is strong for interactive UX, but cancellation/interrupt handling must be centralized and explicit.
13
+ 5. `@bomb.sh/args` is suitable for typed parsing + discoverability; pair it with contract-driven metadata for rich help.
14
+
15
+ ---
16
+
17
+ ## 1) Architecture patterns: single-source contracts for TUI + CLI + docs
18
+
19
+ ### Recommended pattern: Action Contract Registry
20
+ Define every action once:
21
+
22
+ ```ts
23
+ type ActionContract = {
24
+ id: "module.action.useCase";
25
+ summary: string;
26
+ args: ArgSpec[];
27
+ options: OptionSpec[];
28
+ interactive: PromptPlan[]; // optional
29
+ execute: (ctx: RunContext) => Promise<Result>;
30
+ examples: string[];
31
+ aiNotes?: string[];
32
+ };
33
+ ```
34
+
35
+ Build layers:
36
+
37
+ - **Contract layer**: pure metadata + validator + executor binding.
38
+ - **Execution layer**: shared runtime, idempotent, no UI logic.
39
+ - **Interface adapters**:
40
+ - CLI adapter (`@bomb.sh/args`) maps argv -> ctx
41
+ - TUI adapter (`@clack/prompts`) maps prompts -> same ctx
42
+ - Help adapter renders strict docs from contract
43
+
44
+ Why this wins:
45
+ - DRY: one action definition.
46
+ - KISS: no duplicated business logic between TUI/CLI.
47
+ - YAGNI: only add prompt plans for actions that need interactivity.
48
+
49
+ ### Contract-driven generation targets
50
+ - Command tree (`module action [use-case]`)
51
+ - Flags and defaults
52
+ - Validation rules and coercion
53
+ - Example snippets
54
+ - Help docs (human + AI mode)
55
+
56
+ ---
57
+
58
+ ## 2) Clack capabilities/constraints relevant here
59
+
60
+ Observed/known patterns from official package/docs:
61
+
62
+ - Prompt primitives: `select`, `multiselect`, `confirm`, text-like inputs.
63
+ - Flow control: `isCancel(value)` + `cancel()` pattern after each prompt.
64
+ - Interrupt model: ESC/Ctrl+C should map to unified cancel path (do not continue execution).
65
+ - Async tasks/logging: spinner/task progress style pattern (`intro/outro`, task wrappers) for long-running steps.
66
+ - Grouped flows: compose multiple prompts sequentially, capture object payload, short-circuit on cancel.
67
+
68
+ Practical constraints:
69
+ - Terminal UX can break under non-TTY; detect and auto-fallback to CLI flags.
70
+ - Avoid deep nested prompt flows; keep <=3 levels to reduce abandonment.
71
+ - Cancellation must be treated as first-class result (`status: "cancelled"`) not exception spam.
72
+
73
+ ---
74
+
75
+ ## 3) `@bomb.sh/args` usage patterns for robust parsing/discoverability
76
+
77
+ Recommended usage model:
78
+
79
+ - Keep top-level parser thin; load command modules lazily.
80
+ - Explicit command metadata in contract:
81
+ - `name`, `aliases`, `summary`, `examples`, `deprecated`, `hidden`
82
+ - Use parser for:
83
+ - strict unknown-flag errors
84
+ - typed coercion
85
+ - defaulting
86
+ - per-command help
87
+ - Discoverability:
88
+ - support `--help`, `help <module>`, `help <module> <action>`
89
+ - add “related commands” list from same registry
90
+ - always print next-step hints after errors
91
+
92
+ Rule: parser does parsing; **contract executor does business logic**.
93
+
94
+ ---
95
+
96
+ ## 4) Help system design (hierarchical, AI-optimized text-only)
97
+
98
+ ### Output contract (strict sections, stable ordering)
99
+
100
+ For every help response, always print:
101
+
102
+ 1. `PATH` (module/action/use-case)
103
+ 2. `PURPOSE`
104
+ 3. `USAGE`
105
+ 4. `ARGS`
106
+ 5. `OPTIONS`
107
+ 6. `EXAMPLES`
108
+ 7. `EXIT_CODES`
109
+ 8. `RELATED`
110
+ 9. `MACHINE_READABLE_SCHEMA` (compact JSON)
111
+
112
+ Design notes:
113
+ - No ANSI colors in AI mode.
114
+ - No variable phrasing; keep section headers exact.
115
+ - Keep line lengths predictable; avoid tables if parser stability matters.
116
+ - Add `--format ai|human|json`; default human for TTY, ai for non-interactive agents.
117
+
118
+ ---
119
+
120
+ ## 5) Edge-case navigation policies for state-machine terminal UX
121
+
122
+ Use finite states:
123
+
124
+ `Idle -> CollectingInput -> Validating -> Confirming -> Executing -> Completed | Cancelled | Failed`
125
+
126
+ Mandatory policies:
127
+ - Invalid input: inline error + retry count (max 3), then suggest `--help`.
128
+ - Cancel (ESC/Ctrl+C): immediate transition to `Cancelled`, print resumable hint.
129
+ - Go back: support one-step back in prompt flows (`Back` option in selects).
130
+ - Jump: allow “jump to section” only in long forms; otherwise YAGNI.
131
+ - Exit: always available, same semantics as cancel.
132
+ - Recoverability: if execution not started, lossless exit; if started, print rollback/retry guidance.
133
+
134
+ Error taxonomy:
135
+ - `E_INPUT_INVALID`
136
+ - `E_USER_CANCELLED`
137
+ - `E_RUNTIME_FAILURE`
138
+ - `E_DEPENDENCY_UNAVAILABLE`
139
+
140
+ Use same codes in CLI/TUI/help docs for deterministic automation.
141
+
142
+ ---
143
+
144
+ ## Suggested baseline stack (minimal)
145
+
146
+ - Node.js LTS + TypeScript strict mode
147
+ - `@bomb.sh/args` for argv parsing
148
+ - `@clack/prompts` for interactive flows
149
+ - `zod` (or equivalent) for contract validation
150
+ - one shared `ActionRegistry` package inside monorepo/app
151
+
152
+ ---
153
+
154
+ ## Source URLs
155
+
156
+ - https://www.npmjs.com/package/@clack/prompts
157
+ - https://github.com/bombshell-dev/clack
158
+ - https://bomb.sh
159
+ - https://www.npmjs.com/search?q=%40bomb.sh%2Fargs
160
+ - https://github.com/search?q=%40bomb.sh%2Fargs&type=repositories
161
+
162
+ ## Unresolved questions
163
+
164
+ - Exact latest API surface of `@bomb.sh/args` (official reference pages were not directly retrievable in-session).
165
+ - Preferred canonical doc URL for Bomb.sh args module (site path ambiguity).
166
+ - Whether framework should support resumable prompt sessions (persisted checkpoints) in v1 or defer (YAGNI).
@@ -0,0 +1,87 @@
1
+ # Researcher 02 Report
2
+
3
+ _Date: 2026-02-09 (Asia/Saigon)_
4
+ _Target: TypeScript Node.js framework for unified CLI/TUI (human + AI)_
5
+
6
+ ## Executive Summary
7
+ - Use a 4-layer test strategy: unit, integration, transcript snapshot, e2e.
8
+ - Use `tsup` for build outputs and `tsx` for dev ergonomics.
9
+ - Keep plugin/module loading in-process and explicit.
10
+ - Guardrails needed for command injection, secret leakage, and terminal escape issues.
11
+
12
+ ## 1) Testing Strategy for Terminal Frameworks
13
+ Test pyramid:
14
+ 1. Unit (majority): parser, validation, flow transitions
15
+ 2. Integration: command execution and IO behavior
16
+ 3. Transcript snapshot: deterministic terminal output frames/events
17
+ 4. E2E: smoke critical flows via real process/PTY
18
+
19
+ Flake controls:
20
+ - deterministic env (TZ, locale, seeded randomness)
21
+ - retries only for e2e/transcript where justified
22
+ - quarantine policy for unstable tests
23
+
24
+ CI matrix (minimal):
25
+ - OS: ubuntu, macos, windows
26
+ - Node: active LTS + current
27
+ - job split: lint/typecheck/unit, integration, transcript, e2e-smoke
28
+
29
+ ## 2) TypeScript Packaging/Build
30
+ Baseline strategy:
31
+ - Build with `tsup` (ESM/CJS + d.ts)
32
+ - Dev run with `tsx`
33
+ - Published CLI uses compiled `bin` entry
34
+ - `exports` map for framework API surface
35
+
36
+ Suggested shape:
37
+ - `src/core/*`
38
+ - `src/cli-entry.ts`
39
+ - `src/public-api.ts`
40
+ - outputs in `dist/`
41
+
42
+ ## 3) Developer Bootstrap API Patterns
43
+ Recommended fluent bootstrap style:
44
+ - `createHub().use(...).command(...).start()`
45
+ - capability plugins with explicit setup/dispose hooks
46
+ - command objects with metadata + run(ctx,args)
47
+ - typed context injection and lifecycle hooks
48
+
49
+ Avoid:
50
+ - hidden globals
51
+ - excessive DI abstraction in v1
52
+ - implicit runtime auto-discovery magic
53
+
54
+ ## 4) Security + Reliability Guardrails
55
+ Security:
56
+ - never shell-execute unsanitized input
57
+ - redact secrets from logs/transcripts
58
+ - sanitize untrusted terminal output
59
+ - plugin compatibility checks + trust policy
60
+
61
+ Reliability:
62
+ - timeouts and cancellation via AbortController
63
+ - stable exit code taxonomy
64
+ - crash-safe top-level handlers
65
+ - atomic writes for config/session artifacts
66
+
67
+ Ship gate checklist:
68
+ - shell wrapper audit
69
+ - secret redaction tests
70
+ - transcript sanitization
71
+ - plugin version checks
72
+ - cross-platform path/encoding tests
73
+
74
+ ## Sources
75
+ - https://nodejs.org/api/packages.html
76
+ - https://github.com/egoist/tsup
77
+ - https://github.com/privatenumber/tsx
78
+ - https://vitest.dev/guide/
79
+ - https://playwright.dev/docs/test-cli
80
+ - https://owasp.org/www-community/attacks/Command_Injection
81
+ - https://owasp.org/www-project-top-ten/
82
+ - https://oclif.io/
83
+
84
+ ## Unresolved questions
85
+ 1. Keep plugin runtime local-only in v1 or support dynamic package loading?
86
+ 2. Preferred transcript golden format: ANSI snapshot vs structured events vs both?
87
+ 3. Need compliance constraints (e.g., FIPS) now or later?
@@ -0,0 +1,24 @@
1
+ # Scout Report
2
+
3
+ ## Relevant Files
4
+ - `/Users/khang/Documents/repo/snap/` - project root exists, minimal content.
5
+ - `/Users/khang/Documents/repo/snap/plans/` - created for planning artifacts.
6
+ - `/Users/khang/Documents/repo/snap/plans/260209-1547-hub-dual-runtime-framework/` - active plan directory.
7
+ - `/Users/khang/Documents/repo/snap/plans/260209-1547-hub-dual-runtime-framework/research/` - research reports location.
8
+ - `/Users/khang/Documents/repo/snap/plans/260209-1547-hub-dual-runtime-framework/reports/` - planning reports location.
9
+ - `/Users/khang/Documents/repo/snap/plans/260209-1547-hub-dual-runtime-framework/scout/` - scout reports location.
10
+
11
+ ## Findings
12
+ - Repository currently has no discovered source code files.
13
+ - `README.md` does not exist in project root.
14
+ - `docs/` directory does not exist.
15
+ - Planning must assume greenfield bootstrap with no existing architecture constraints.
16
+
17
+ ## Implications for Plan
18
+ - Include bootstrap phases for project scaffold, coding standards baseline, test harness, and sample modules.
19
+ - Include docs bootstrap inside plan scope where needed for framework adoption.
20
+
21
+ ## Unresolved Questions
22
+ 1. Should initial implementation be single package or monorepo layout?
23
+ 2. Should framework include built-in templates/generator in v1?
24
+ 3. Any required CI provider preference (GitHub Actions vs other)?
@@ -0,0 +1 @@
1
+ export { runHelpCommand, type HelpCommandInput } from '../help/help-command.js';
@@ -0,0 +1,83 @@
1
+ import { fileURLToPath } from 'node:url';
2
+ import { createRegistry } from './index.js';
3
+ import sampleContentModule from './modules/sample-content/module.js';
4
+ import sampleSystemModule from './modules/sample-system/module.js';
5
+ import { dispatchAction } from './runtime/dispatch.js';
6
+ import { runHelpCommand } from './cli/help-command.js';
7
+
8
+ const parseCliArgs = (argv: string[]): { moduleId?: string; actionId?: string; args: Record<string, string | boolean> } => {
9
+ const args: Record<string, string | boolean> = {};
10
+ const positional: string[] = [];
11
+
12
+ for (const token of argv) {
13
+ if (token.startsWith('--')) {
14
+ const body = token.slice(2);
15
+ const separatorIndex = body.indexOf('=');
16
+ if (separatorIndex === -1) {
17
+ if (body.length > 0) args[body] = true;
18
+ } else {
19
+ const key = body.slice(0, separatorIndex);
20
+ const value = body.slice(separatorIndex + 1);
21
+ if (key.length > 0) args[key] = value;
22
+ }
23
+ continue;
24
+ }
25
+ positional.push(token);
26
+ }
27
+
28
+ return {
29
+ moduleId: positional[0],
30
+ actionId: positional[1],
31
+ args
32
+ };
33
+ };
34
+
35
+ const registry = createRegistry([sampleContentModule, sampleSystemModule]);
36
+
37
+ export const runCli = async (argv: string[], isTTY = Boolean(process.stdout.isTTY)): Promise<number> => {
38
+ const wantsHelp = argv.includes('-h') || argv.includes('--help');
39
+ const filtered = argv.filter((item) => item !== '-h' && item !== '--help');
40
+ const parsed = parseCliArgs(filtered);
41
+
42
+ if (wantsHelp || !parsed.moduleId) {
43
+ const helpResult = runHelpCommand({
44
+ registry,
45
+ moduleId: parsed.moduleId,
46
+ actionId: parsed.actionId
47
+ });
48
+
49
+ if (helpResult.data) process.stdout.write(`${helpResult.data}\n`);
50
+ if (helpResult.errorMessage) process.stderr.write(`${helpResult.errorMessage}\n`);
51
+ return helpResult.exitCode;
52
+ }
53
+
54
+ if (!parsed.actionId) {
55
+ const helpResult = runHelpCommand({ registry, moduleId: parsed.moduleId });
56
+ if (helpResult.data) process.stdout.write(`${helpResult.data}\n`);
57
+ return helpResult.exitCode;
58
+ }
59
+
60
+ const result = await dispatchAction({
61
+ registry,
62
+ moduleId: parsed.moduleId,
63
+ actionId: parsed.actionId,
64
+ args: parsed.args,
65
+ isTTY
66
+ });
67
+
68
+ if (result.data !== undefined) process.stdout.write(`${String(result.data)}\n`);
69
+ if (result.errorMessage) process.stderr.write(`${result.errorMessage}\n`);
70
+ return result.exitCode;
71
+ };
72
+
73
+ const isMain = process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1];
74
+ if (isMain) {
75
+ runCli(process.argv.slice(2))
76
+ .then((code) => {
77
+ process.exitCode = code;
78
+ })
79
+ .catch((error: unknown) => {
80
+ process.stderr.write(`${error instanceof Error ? error.message : 'Unknown CLI error'}\n`);
81
+ process.exitCode = 1;
82
+ });
83
+ }
@@ -0,0 +1,30 @@
1
+ import type { HelpContract } from './help-contract.js';
2
+ import type { RuntimeContext } from '../../runtime/runtime-context.js';
3
+
4
+ export type RuntimeMode = 'tui' | 'commandline';
5
+
6
+ export interface CommandlineContract {
7
+ requiredArgs: string[];
8
+ optionalArgs?: string[];
9
+ }
10
+
11
+ export interface TuiContract {
12
+ steps: string[];
13
+ }
14
+
15
+ export interface ActionResultEnvelope<T = unknown> {
16
+ ok: boolean;
17
+ mode: RuntimeMode;
18
+ exitCode: number;
19
+ data?: T;
20
+ errorMessage?: string;
21
+ }
22
+
23
+ export interface ActionContract {
24
+ actionId: string;
25
+ description: string;
26
+ tui: TuiContract;
27
+ commandline: CommandlineContract;
28
+ help: HelpContract;
29
+ run: (context: RuntimeContext) => Promise<ActionResultEnvelope>;
30
+ }