@sushanglewis/lincoln 1.5.0 → 1.5.2

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 (305) hide show
  1. package/dist/main.d.ts +3 -0
  2. package/dist/main.js +1286 -916
  3. package/dist/main.js.map +1 -1
  4. package/dist/postinstall.d.ts +3 -0
  5. package/dist/postinstall.js +18 -0
  6. package/dist/postinstall.js.map +1 -0
  7. package/framework/.claude/agents/_contract.md +79 -0
  8. package/framework/.claude/agents/architect.md +31 -0
  9. package/framework/.claude/agents/default.md +151 -0
  10. package/framework/.claude/agents/designer.md +33 -0
  11. package/framework/.claude/agents/engineer.md +42 -0
  12. package/framework/.claude/agents/external/NOTICES.md +12 -0
  13. package/framework/.claude/agents/external/everything-claude-code.manifest.yaml +23 -0
  14. package/framework/.claude/agents/external/oh-my-claudecode.manifest.yaml +26 -0
  15. package/framework/.claude/agents/external/wshobson-agents.manifest.yaml +23 -0
  16. package/framework/.claude/agents/frontend-engineer.md +32 -0
  17. package/framework/.claude/agents/knowledge-curator.md +28 -0
  18. package/framework/.claude/agents/pm.md +38 -0
  19. package/framework/.claude/agents/qa.md +28 -0
  20. package/framework/.claude/agents/release-coordinator.md +25 -0
  21. package/framework/.claude/agents/researcher.md +41 -0
  22. package/framework/.claude/harnesses/claude-code.yaml +15 -0
  23. package/framework/.claude/harnesses/codex.yaml +40 -0
  24. package/framework/.claude/harnesses/command-map.yaml +255 -0
  25. package/framework/.claude/harnesses/opencode.yaml +32 -0
  26. package/framework/.claude/harnesses/scenarios.yaml +45 -0
  27. package/framework/.claude/hooks/on-pr-event.sh +69 -0
  28. package/framework/.claude/hooks/on-session-start.sh +427 -0
  29. package/framework/.claude/hooks/on-stop.sh +104 -0
  30. package/framework/.claude/hooks/post-tool-use.sh +161 -0
  31. package/framework/.claude/hooks/pre-tool-use.sh +246 -0
  32. package/framework/.claude/schemas/agent-definition.schema.json +35 -0
  33. package/framework/.claude/schemas/benchmark-report.schema.json +148 -0
  34. package/framework/.claude/schemas/pm-to-ux-handoff.schema.yaml +128 -0
  35. package/framework/.claude/schemas/stage-definition.schema.json +233 -0
  36. package/framework/.claude/schemas/workflow-stage.schema.json +86 -0
  37. package/framework/.claude/schemas/workflow-template.schema.json +88 -0
  38. package/framework/.claude/settings.json +14 -0
  39. package/framework/.claude/skills/build-product-prototype/SKILL.md +35 -0
  40. package/framework/.claude/skills/build-product-prototype/prompts/main.md +78 -0
  41. package/framework/.claude/skills/clarify-requirements/SKILL.md +32 -0
  42. package/framework/.claude/skills/clarify-requirements/prompts/main.md +81 -0
  43. package/framework/.claude/skills/dependencies.yaml +139 -0
  44. package/framework/.claude/skills/draft-product-design/SKILL.md +40 -0
  45. package/framework/.claude/skills/draft-product-design/prompts/main.md +47 -0
  46. package/framework/.claude/skills/lc-analyze-frameworks/SKILL.md +43 -0
  47. package/framework/.claude/skills/lc-analyze-frameworks/prompts/main.md +95 -0
  48. package/framework/.claude/skills/lc-benchmark/SKILL.md +61 -0
  49. package/framework/.claude/skills/lc-build-codebase-knowledge/SKILL.md +38 -0
  50. package/framework/.claude/skills/lc-build-codebase-knowledge/prompts/build-codebase-knowledge.md +61 -0
  51. package/framework/.claude/skills/lc-collect-intelligence/SKILL.md +43 -0
  52. package/framework/.claude/skills/lc-collect-intelligence/prompts/main.md +72 -0
  53. package/framework/.claude/skills/lc-competitive-analysis/SKILL.md +43 -0
  54. package/framework/.claude/skills/lc-competitive-analysis/prompts/main.md +70 -0
  55. package/framework/.claude/skills/lc-explore-opensource/SKILL.md +36 -0
  56. package/framework/.claude/skills/lc-explore-opensource/prompts/explore-opensource.md +77 -0
  57. package/framework/.claude/skills/lc-first-principles/SKILL.md +43 -0
  58. package/framework/.claude/skills/lc-first-principles/prompts/main.md +73 -0
  59. package/framework/.claude/skills/lc-handoff/SKILL.md +34 -0
  60. package/framework/.claude/skills/lc-init-branch/SKILL.md +52 -0
  61. package/framework/.claude/skills/lc-market-research/SKILL.md +43 -0
  62. package/framework/.claude/skills/lc-market-research/prompts/main.md +79 -0
  63. package/framework/.claude/skills/lc-product-research/SKILL.md +43 -0
  64. package/framework/.claude/skills/lc-product-research/prompts/main.md +80 -0
  65. package/framework/.claude/skills/lc-research-report/SKILL.md +43 -0
  66. package/framework/.claude/skills/lc-research-report/prompts/main.md +90 -0
  67. package/framework/.claude/skills/lc-research-scope/SKILL.md +43 -0
  68. package/framework/.claude/skills/lc-research-scope/prompts/main.md +82 -0
  69. package/framework/.claude/skills/lc-setup/SKILL.md +68 -0
  70. package/framework/.claude/skills/lc-setup/prompts/main.md +88 -0
  71. package/framework/.claude/skills/lc-stage/SKILL.md +45 -0
  72. package/framework/.claude/skills/lc-stakeholder-research/SKILL.md +43 -0
  73. package/framework/.claude/skills/lc-stakeholder-research/prompts/main.md +65 -0
  74. package/framework/.claude/skills/lc-status/SKILL.md +25 -0
  75. package/framework/.claude/skills/lc-storytelling/SKILL.md +43 -0
  76. package/framework/.claude/skills/lc-storytelling/prompts/main.md +77 -0
  77. package/framework/.claude/skills/lc-wf/SKILL.md +54 -0
  78. package/framework/.claude/skills/lc-workflow/SKILL.md +48 -0
  79. package/framework/.claude/skills/lc-workflow/validators/validate.py +755 -0
  80. package/framework/.claude/skills/lc-workflow-router/SKILL.md +41 -0
  81. package/framework/.claude/skills/lc-workflow-router/prompts/intake-prompt.md +91 -0
  82. package/framework/.claude/skills/lc-workflow-router/prompts/router-prompt.md +44 -0
  83. package/framework/.claude/skills/plan-tdd-development/SKILL.md +31 -0
  84. package/framework/.claude/skills/plan-tdd-development/prompts/main.md +44 -0
  85. package/framework/.claude/skills/process-interview/SKILL.md +32 -0
  86. package/framework/.claude/skills/process-interview/prompts/main.md +47 -0
  87. package/framework/.claude/skills/propose-with-openspec/SKILL.md +37 -0
  88. package/framework/.claude/skills/propose-with-openspec/prompts/main.md +53 -0
  89. package/framework/.claude/skills/split-to-github/SKILL.md +32 -0
  90. package/framework/.claude/skills/split-to-github/prompts/main.md +42 -0
  91. package/framework/.claude/skills/sync-to-knowledge/SKILL.md +35 -0
  92. package/framework/.claude/skills/sync-to-knowledge/prompts/main.md +54 -0
  93. package/framework/.claude/skills/workflow-continue/SKILL.md +24 -0
  94. package/framework/.claude/skills/workflow-continue/prompts/main.md +25 -0
  95. package/framework/.claude/stages/build-codebase-knowledge.yaml +42 -0
  96. package/framework/.claude/stages/clarify.yaml +59 -0
  97. package/framework/.claude/stages/explore-opensource.yaml +40 -0
  98. package/framework/.claude/stages/implement.yaml +60 -0
  99. package/framework/.claude/stages/ingest.yaml +40 -0
  100. package/framework/.claude/stages/lc-analyze-frameworks.yaml +37 -0
  101. package/framework/.claude/stages/lc-collect-intelligence.yaml +37 -0
  102. package/framework/.claude/stages/lc-competitive-analysis.yaml +37 -0
  103. package/framework/.claude/stages/lc-first-principles.yaml +37 -0
  104. package/framework/.claude/stages/lc-market-research.yaml +37 -0
  105. package/framework/.claude/stages/lc-product-research.yaml +37 -0
  106. package/framework/.claude/stages/lc-research-report.yaml +38 -0
  107. package/framework/.claude/stages/lc-research-scope.yaml +38 -0
  108. package/framework/.claude/stages/lc-stakeholder-research.yaml +37 -0
  109. package/framework/.claude/stages/lc-storytelling.yaml +37 -0
  110. package/framework/.claude/stages/product-design-docs.yaml +66 -0
  111. package/framework/.claude/stages/product-prototype.yaml +53 -0
  112. package/framework/.claude/stages/propose.yaml +45 -0
  113. package/framework/.claude/stages/split.yaml +41 -0
  114. package/framework/.claude/stages/sync-knowledge.yaml +49 -0
  115. package/framework/.claude/stages/tdd-development-plan.yaml +43 -0
  116. package/framework/.claude/stages/workflow-router.yaml +45 -0
  117. package/framework/.claude/templates/solo-workflow-context.yaml +23 -0
  118. package/framework/.claude/workflows/README.md +93 -0
  119. package/framework/.claude/workflows/bug-fix.yaml +81 -0
  120. package/framework/.claude/workflows/design-spike.yaml +55 -0
  121. package/framework/.claude/workflows/existing-project-iteration.yaml +106 -0
  122. package/framework/.claude/workflows/interview-to-knowledge.yaml +189 -0
  123. package/framework/.claude/workflows/oss-first-design.yaml +100 -0
  124. package/framework/.claude/workflows/pm-research.yaml +115 -0
  125. package/framework/.claude-plugin/hooks.json +6 -0
  126. package/framework/.claude-plugin/marketplace.json +32 -0
  127. package/framework/.claude-plugin/plugin.json +57 -0
  128. package/framework/.version-bump.json +43 -0
  129. package/framework/CLAUDE.md +140 -0
  130. package/framework/CONTRIBUTING.md +219 -0
  131. package/framework/LICENSE +21 -0
  132. package/framework/README.en.md +139 -0
  133. package/framework/README.md +139 -0
  134. package/framework/RELEASE.md +334 -0
  135. package/framework/SKILL.md +24 -0
  136. package/framework/USAGE.md +356 -0
  137. package/framework/manifest.json +1214 -0
  138. package/framework/requirements.txt +4 -0
  139. package/framework/scripts/__init__.py +0 -0
  140. package/framework/scripts/build_codebase_knowledge.py +76 -0
  141. package/framework/scripts/bump_version.py +181 -0
  142. package/framework/scripts/check-dependency-drift.py +69 -0
  143. package/framework/scripts/check-harness-drift.sh +57 -0
  144. package/framework/scripts/check-main-merge-hygiene.py +128 -0
  145. package/framework/scripts/check-skill-dependencies.sh +124 -0
  146. package/framework/scripts/init-lincoln-branch.sh +300 -0
  147. package/framework/scripts/init-project.sh +184 -0
  148. package/framework/scripts/lc-benchmark-cli.py +66 -0
  149. package/framework/scripts/lincoln-audit.py +288 -0
  150. package/framework/scripts/lincoln-setup.py +651 -0
  151. package/framework/scripts/lincoln-status.py +448 -0
  152. package/framework/scripts/lincoln_benchmark.py +224 -0
  153. package/framework/scripts/lincoln_benchmark_eval.py +104 -0
  154. package/framework/scripts/lincoln_benchmark_metrics.py +818 -0
  155. package/framework/scripts/lincoln_benchmark_report.py +141 -0
  156. package/framework/scripts/lincoln_command_map.py +289 -0
  157. package/framework/scripts/lincoln_dependency_manager.py +335 -0
  158. package/framework/scripts/lincoln_documents.py +175 -0
  159. package/framework/scripts/lincoln_harness_adapter.py +319 -0
  160. package/framework/scripts/lincoln_index.py +255 -0
  161. package/framework/scripts/lincoln_paths.py +198 -0
  162. package/framework/scripts/lincoln_prd.py +227 -0
  163. package/framework/scripts/lincoln_role.py +46 -0
  164. package/framework/scripts/lincoln_scenario.py +59 -0
  165. package/framework/scripts/lincoln_session_start_metrics.py +71 -0
  166. package/framework/scripts/lincoln_skill_prompt.py +48 -0
  167. package/framework/scripts/lincoln_trace.py +335 -0
  168. package/framework/scripts/lincoln_workflow.py +199 -0
  169. package/framework/scripts/list-active-lincoln-branches.sh +87 -0
  170. package/framework/scripts/package-lincoln-plugin.py +340 -0
  171. package/framework/scripts/run-infrastructure-tests.py +84 -0
  172. package/framework/scripts/stage_loader.py +1071 -0
  173. package/framework/scripts/static-check.sh +356 -0
  174. package/framework/scripts/sync-external-agents.sh +210 -0
  175. package/framework/scripts/sync-framework-package.mjs +218 -0
  176. package/framework/scripts/task_tool_guard.py +213 -0
  177. package/framework/scripts/track-artifacts.py +140 -0
  178. package/framework/scripts/validate_stage.py +350 -0
  179. package/{README.md → framework/tools/lincoln/README.md} +4 -4
  180. package/framework/tools/lincoln/package-lock.json +3349 -0
  181. package/framework/tools/lincoln/package.json +48 -0
  182. package/framework/tools/lincoln/src/cli.tsx +60 -0
  183. package/framework/tools/lincoln/src/components/AudioMeter.tsx +34 -0
  184. package/framework/tools/lincoln/src/components/CancelledScreen.tsx +11 -0
  185. package/framework/tools/lincoln/src/components/DevicesMenu.tsx +79 -0
  186. package/framework/tools/lincoln/src/components/HintBar.tsx +25 -0
  187. package/framework/tools/lincoln/src/components/LogView.tsx +36 -0
  188. package/framework/tools/lincoln/src/components/ModelMenu.tsx +122 -0
  189. package/framework/tools/lincoln/src/components/ReadyScreen.tsx +54 -0
  190. package/framework/tools/lincoln/src/components/RecordingApp.tsx +211 -0
  191. package/framework/tools/lincoln/src/components/RecordingScreen.tsx +41 -0
  192. package/framework/tools/lincoln/src/components/SelectMenu.tsx +53 -0
  193. package/framework/tools/lincoln/src/components/StatusPanel.tsx +52 -0
  194. package/framework/tools/lincoln/src/components/StopConfirmation.tsx +32 -0
  195. package/framework/tools/lincoln/src/config/args.ts +35 -0
  196. package/framework/tools/lincoln/src/config/loadConfig.ts +81 -0
  197. package/framework/tools/lincoln/src/config/resolveConfig.ts +85 -0
  198. package/framework/tools/lincoln/src/devices/listDevices.ts +11 -0
  199. package/framework/tools/lincoln/src/devices/parseDevices.ts +25 -0
  200. package/framework/tools/lincoln/src/hooks/useKeyHandler.ts +63 -0
  201. package/framework/tools/lincoln/src/main.tsx +4 -0
  202. package/framework/tools/lincoln/src/models/models.ts +34 -0
  203. package/framework/tools/lincoln/src/models/runWarmup.ts +46 -0
  204. package/framework/tools/lincoln/src/models/warmupProgress.ts +30 -0
  205. package/framework/tools/lincoln/src/recording/spawnRecorder.ts +127 -0
  206. package/framework/tools/lincoln/src/recording/useRecorder.ts +146 -0
  207. package/framework/tools/lincoln/src/utils/amplitudeToMeter.ts +4 -0
  208. package/framework/tools/lincoln/src/utils/formatDuration.ts +6 -0
  209. package/framework/tools/lincoln/src/utils/sessionId.ts +25 -0
  210. package/framework/tools/lincoln/tests/cli.test.tsx +52 -0
  211. package/framework/tools/lincoln/tests/components/AudioMeter.test.tsx +31 -0
  212. package/framework/tools/lincoln/tests/components/CancelledScreen.test.tsx +12 -0
  213. package/framework/tools/lincoln/tests/components/ReadyScreen.test.tsx +68 -0
  214. package/framework/tools/lincoln/tests/components/RecordingApp.menus.test.tsx +158 -0
  215. package/framework/tools/lincoln/tests/components/RecordingApp.test.tsx +248 -0
  216. package/framework/tools/lincoln/tests/components/RecordingScreen.test.tsx +37 -0
  217. package/framework/tools/lincoln/tests/components/SelectMenu.test.tsx +59 -0
  218. package/framework/tools/lincoln/tests/components/StopConfirmation.test.tsx +38 -0
  219. package/framework/tools/lincoln/tests/config/args.test.ts +49 -0
  220. package/framework/tools/lincoln/tests/config/loadConfig.test.ts +59 -0
  221. package/framework/tools/lincoln/tests/config/resolveConfig.test.ts +72 -0
  222. package/framework/tools/lincoln/tests/devices/parseDevices.test.ts +21 -0
  223. package/framework/tools/lincoln/tests/hooks/useKeyHandler.enabled.test.tsx +44 -0
  224. package/framework/tools/lincoln/tests/hooks/useKeyHandler.test.tsx +130 -0
  225. package/framework/tools/lincoln/tests/models/models.test.ts +27 -0
  226. package/framework/tools/lincoln/tests/models/warmupProgress.test.ts +25 -0
  227. package/framework/tools/lincoln/tests/recording/spawnRecorder.test.ts +85 -0
  228. package/framework/tools/lincoln/tests/recording/useRecorder.test.tsx +172 -0
  229. package/framework/tools/lincoln/tests/utils/amplitudeToMeter.test.ts +22 -0
  230. package/framework/tools/lincoln/tests/utils/formatDuration.test.ts +11 -0
  231. package/framework/tools/lincoln/tests/utils/sessionId.test.ts +30 -0
  232. package/framework/tools/lincoln/tsconfig.json +22 -0
  233. package/framework/tools/lincoln/tsconfig.tests.json +10 -0
  234. package/framework/tools/lincoln/tsup.config.ts +17 -0
  235. package/framework/tools/lincoln/vitest.config.ts +20 -0
  236. package/framework/tools/lincoln-installer/package-lock.json +3611 -0
  237. package/framework/tools/lincoln-installer/package.json +53 -0
  238. package/framework/tools/lincoln-installer/src/cli.tsx +63 -0
  239. package/framework/tools/lincoln-installer/src/components/HarnessSelectScreen.tsx +43 -0
  240. package/framework/tools/lincoln-installer/src/components/InstallerApp.tsx +98 -0
  241. package/framework/tools/lincoln-installer/src/components/OptionsScreen.tsx +56 -0
  242. package/framework/tools/lincoln-installer/src/components/ProgressScreen.tsx +25 -0
  243. package/framework/tools/lincoln-installer/src/components/ResultScreen.tsx +40 -0
  244. package/framework/tools/lincoln-installer/src/components/SelectMenu.tsx +73 -0
  245. package/framework/tools/lincoln-installer/src/components/SummaryScreen.tsx +49 -0
  246. package/framework/tools/lincoln-installer/src/components/UpdateApp.tsx +135 -0
  247. package/framework/tools/lincoln-installer/src/components/WelcomeScreen.tsx +22 -0
  248. package/framework/tools/lincoln-installer/src/config/args.ts +76 -0
  249. package/framework/tools/lincoln-installer/src/config/resolveConfig.ts +33 -0
  250. package/framework/tools/lincoln-installer/src/config/updateArgs.ts +67 -0
  251. package/framework/tools/lincoln-installer/src/hooks/useSetup.ts +149 -0
  252. package/framework/tools/lincoln-installer/src/main.tsx +11 -0
  253. package/framework/tools/lincoln-installer/src/types.ts +19 -0
  254. package/framework/tools/lincoln-installer/src/update-main.tsx +11 -0
  255. package/framework/tools/lincoln-installer/src/update.tsx +90 -0
  256. package/framework/tools/lincoln-installer/src/utils/detectHarness.ts +51 -0
  257. package/framework/tools/lincoln-installer/src/utils/runSetup.ts +62 -0
  258. package/framework/tools/lincoln-installer/src/utils/updateRelease.ts +454 -0
  259. package/framework/tools/lincoln-installer/tests/components/InstallerApp.test.tsx +88 -0
  260. package/framework/tools/lincoln-installer/tests/components/SelectMenu.test.tsx +26 -0
  261. package/framework/tools/lincoln-installer/tests/components/UpdateApp.test.tsx +170 -0
  262. package/framework/tools/lincoln-installer/tests/components/screens.test.tsx +310 -0
  263. package/framework/tools/lincoln-installer/tests/config/args.test.ts +66 -0
  264. package/framework/tools/lincoln-installer/tests/config/resolveConfig.test.ts +75 -0
  265. package/framework/tools/lincoln-installer/tests/config/updateArgs.test.ts +52 -0
  266. package/framework/tools/lincoln-installer/tests/hooks/useSetup.test.tsx +213 -0
  267. package/framework/tools/lincoln-installer/tests/update.test.tsx +108 -0
  268. package/framework/tools/lincoln-installer/tests/utils/detectHarness.test.ts +40 -0
  269. package/framework/tools/lincoln-installer/tests/utils/runSetup.test.ts +45 -0
  270. package/framework/tools/lincoln-installer/tests/utils/updateRelease.test.ts +559 -0
  271. package/framework/tools/lincoln-installer/tsconfig.json +22 -0
  272. package/framework/tools/lincoln-installer/tsconfig.tests.json +8 -0
  273. package/framework/tools/lincoln-installer/tsup.config.ts +17 -0
  274. package/framework/tools/lincoln-installer/vitest.config.ts +20 -0
  275. package/framework/tools/lincoln-record/Cargo.lock +1896 -0
  276. package/framework/tools/lincoln-record/Cargo.toml +24 -0
  277. package/framework/tools/lincoln-record/diarize/diarize.py +117 -0
  278. package/framework/tools/lincoln-record/diarize/merge.py +55 -0
  279. package/framework/tools/lincoln-record/src/audio/capture/microphone.rs +194 -0
  280. package/framework/tools/lincoln-record/src/audio/capture/mod.rs +1 -0
  281. package/framework/tools/lincoln-record/src/audio/devices.rs +20 -0
  282. package/framework/tools/lincoln-record/src/audio/mod.rs +5 -0
  283. package/framework/tools/lincoln-record/src/audio/resampler.rs +44 -0
  284. package/framework/tools/lincoln-record/src/audio/saver.rs +87 -0
  285. package/framework/tools/lincoln-record/src/audio/source.rs +104 -0
  286. package/framework/tools/lincoln-record/src/cli.rs +96 -0
  287. package/framework/tools/lincoln-record/src/config.rs +135 -0
  288. package/framework/tools/lincoln-record/src/lib.rs +6 -0
  289. package/framework/tools/lincoln-record/src/main.rs +242 -0
  290. package/framework/tools/lincoln-record/src/model/mod.rs +248 -0
  291. package/framework/tools/lincoln-record/src/output/metadata.rs +30 -0
  292. package/framework/tools/lincoln-record/src/output/mod.rs +2 -0
  293. package/framework/tools/lincoln-record/src/output/transcript.rs +42 -0
  294. package/framework/tools/lincoln-record/src/transcription/diarization.rs +64 -0
  295. package/framework/tools/lincoln-record/src/transcription/mod.rs +3 -0
  296. package/framework/tools/lincoln-record/src/transcription/provider.rs +43 -0
  297. package/framework/tools/lincoln-record/src/transcription/whisper.rs +176 -0
  298. package/framework/tools/lincoln-record/tests/cli_args.rs +103 -0
  299. package/framework/tools/lincoln-record/tests/config_test.rs +70 -0
  300. package/framework/tools/lincoln-record/tests/devices_test.rs +23 -0
  301. package/framework/tools/lincoln-record/tests/diarization_tests.rs +101 -0
  302. package/framework/tools/lincoln-record/tests/integration_tests.rs +44 -0
  303. package/framework/tools/lincoln-record/tests/model_test.rs +68 -0
  304. package/framework/tools/lincoln-record/tests/transcription_tests.rs +73 -0
  305. package/package.json +19 -13
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "lincoln-install",
3
+ "version": "1.5.2",
4
+ "description": "Terminal TUI installer for the Lincoln AI-Native R&D workflow system",
5
+ "type": "module",
6
+ "main": "dist/main.js",
7
+ "module": "dist/main.js",
8
+ "types": "dist/main.d.ts",
9
+ "bin": {
10
+ "lincoln-install": "dist/main.js",
11
+ "lincoln-update": "dist/update-main.js"
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsup",
18
+ "dev": "tsup --watch",
19
+ "test": "vitest run --coverage",
20
+ "test:watch": "vitest",
21
+ "typecheck": "tsc --noEmit",
22
+ "typecheck:tests": "tsc -p tsconfig.tests.json",
23
+ "lint": "echo 'lint not configured'"
24
+ },
25
+ "dependencies": {
26
+ "ink": "^5.2.0",
27
+ "js-yaml": "^4.1.0",
28
+ "react": "^18.3.1",
29
+ "tar": "^7.4.3"
30
+ },
31
+ "devDependencies": {
32
+ "@types/js-yaml": "^4.0.9",
33
+ "@types/node": "^22.15.0",
34
+ "@types/react": "^18.3.12",
35
+ "@types/tar": "^6.1.13",
36
+ "@vitest/coverage-v8": "^4.1.10",
37
+ "ink-testing-library": "^4.0.0",
38
+ "tsup": "^8.5.0",
39
+ "typescript": "^5.8.3",
40
+ "vitest": "^4.1.9"
41
+ },
42
+ "engines": {
43
+ "node": ">=20.0.0"
44
+ },
45
+ "keywords": [
46
+ "lincoln",
47
+ "installer",
48
+ "tui",
49
+ "claude-code",
50
+ "ai-workflow"
51
+ ],
52
+ "license": "MIT"
53
+ }
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ import { Box, Text } from 'ink'
3
+ import React from 'react'
4
+
5
+ import { parseArgs } from './config/args'
6
+ import { resolveConfig } from './config/resolveConfig'
7
+ import { InstallerApp } from './components/InstallerApp'
8
+
9
+ export interface AppProps {
10
+ args: ReturnType<typeof parseArgs>
11
+ config: ReturnType<typeof resolveConfig>
12
+ }
13
+
14
+ export function App({ args, config }: AppProps) {
15
+ if (args.help) {
16
+ return (
17
+ <Box flexDirection="column" padding={1}>
18
+ <Text bold>lincoln-install</Text>
19
+ <Text>Terminal TUI installer for Lincoln.</Text>
20
+ <Text />
21
+ <Text bold>Usage:</Text>
22
+ <Text> npx lincoln-install [options]</Text>
23
+ <Text />
24
+ <Text bold>Options:</Text>
25
+ <Text> --root Project root directory (default: current dir)</Text>
26
+ <Text> --harness Target harness to generate (repeatable)</Text>
27
+ <Text> --yes Auto-confirm all prompts</Text>
28
+ <Text> --dry-run Show what would be done without executing</Text>
29
+ <Text> --no-tui Print resolved config as JSON and exit</Text>
30
+ <Text> --format Output format: human|json (default: human)</Text>
31
+ <Text> --help, -h Show this help message</Text>
32
+ </Box>
33
+ )
34
+ }
35
+
36
+ return <InstallerApp config={config} />
37
+ }
38
+
39
+ export async function main(argv: string[] = process.argv.slice(2)): Promise<void> {
40
+ try {
41
+ const args = parseArgs(argv)
42
+
43
+ if (args.help) {
44
+ const { render } = await import('ink')
45
+ render(<App args={args} config={{ root: process.cwd(), harnesses: [], yes: false, dryRun: false, format: args.format }} />)
46
+ return
47
+ }
48
+
49
+ const config = resolveConfig(args)
50
+
51
+ if (args.noTui) {
52
+ console.log(JSON.stringify(config, null, 2))
53
+ return
54
+ }
55
+
56
+ const { render } = await import('ink')
57
+ render(<App args={args} config={config} />)
58
+ } catch (err) {
59
+ const message = err instanceof Error ? err.message : String(err)
60
+ console.error(`Error: ${message}`)
61
+ process.exitCode = 1
62
+ }
63
+ }
@@ -0,0 +1,43 @@
1
+ import { Box, Text } from 'ink'
2
+ import React, { useState } from 'react'
3
+
4
+ import type { HarnessInfo } from '../types'
5
+ import { SelectMenu } from './SelectMenu'
6
+
7
+ export interface HarnessSelectScreenProps {
8
+ harnesses: HarnessInfo[]
9
+ selected: string[]
10
+ onConfirm: (selected: string[]) => void
11
+ }
12
+
13
+ export function HarnessSelectScreen({
14
+ harnesses,
15
+ selected: initialSelected,
16
+ onConfirm,
17
+ }: HarnessSelectScreenProps) {
18
+ const [selected, setSelected] = useState(initialSelected)
19
+ const items = harnesses.map((h) => ({
20
+ label: `${h.name} ${h.installed ? '(detected)' : ''} - ${h.description}`,
21
+ value: h.id,
22
+ }))
23
+
24
+ const handleSelect = (value: string) => {
25
+ setSelected((prev) =>
26
+ prev.includes(value) ? prev.filter((v) => v !== value) : [...prev, value]
27
+ )
28
+ }
29
+
30
+ return (
31
+ <Box flexDirection="column" padding={1}>
32
+ <Text bold>Select agent harnesses</Text>
33
+ <Text dimColor>Choose one or more targets for Lincoln.</Text>
34
+ <SelectMenu
35
+ items={items}
36
+ selected={selected}
37
+ multiple
38
+ onSelect={handleSelect}
39
+ onConfirm={() => onConfirm(selected)}
40
+ />
41
+ </Box>
42
+ )
43
+ }
@@ -0,0 +1,98 @@
1
+ import { Box, Text } from 'ink'
2
+ import React, { useState, useEffect } from 'react'
3
+
4
+ import type { InstallerConfig } from '../config/resolveConfig'
5
+ import type { HarnessInfo } from '../types'
6
+ import { detectHarnesses } from '../utils/detectHarness'
7
+ import { useSetup, type SetupPhase } from '../hooks/useSetup'
8
+ import { HarnessSelectScreen } from './HarnessSelectScreen'
9
+ import { OptionsScreen, type InstallerOptions } from './OptionsScreen'
10
+ import { ProgressScreen } from './ProgressScreen'
11
+ import { ResultScreen } from './ResultScreen'
12
+ import { SummaryScreen } from './SummaryScreen'
13
+ import { WelcomeScreen } from './WelcomeScreen'
14
+
15
+ export interface InstallerAppProps {
16
+ config: InstallerConfig
17
+ }
18
+
19
+ export function InstallerApp({ config }: InstallerAppProps) {
20
+ const [phase, setPhase] = useState<SetupPhase>('welcome')
21
+ const [harnesses, setHarnesses] = useState<HarnessInfo[]>([])
22
+ const [selectedHarnesses, setSelectedHarnesses] = useState<string[]>([])
23
+ const [options, setOptions] = useState<InstallerOptions>({
24
+ installRecordingDeps: false,
25
+ runBenchmark: false,
26
+ })
27
+
28
+ const { isRunning, results, currentStep, error, startSetup } = useSetup()
29
+
30
+ useEffect(() => {
31
+ const detected = detectHarnesses(config.root)
32
+ setHarnesses(detected)
33
+ setSelectedHarnesses(detected.filter((h) => h.installed).map((h) => h.id))
34
+ }, [config.root])
35
+
36
+ useEffect(() => {
37
+ if (!isRunning && phase === 'running') {
38
+ setPhase('result')
39
+ }
40
+ }, [isRunning, phase])
41
+
42
+ const handleHarnessConfirm = (selected: string[]) => {
43
+ setSelectedHarnesses(selected)
44
+ setPhase('options')
45
+ }
46
+
47
+ const handleOptionsConfirm = (opts: InstallerOptions) => {
48
+ setOptions(opts)
49
+ setPhase('summary')
50
+ }
51
+
52
+ const handleSummaryConfirm = () => {
53
+ startSetup({
54
+ root: config.root,
55
+ harnesses: selectedHarnesses,
56
+ yes: config.yes,
57
+ dryRun: config.dryRun,
58
+ })
59
+ setPhase('running')
60
+ }
61
+
62
+ const handleCancel = () => {
63
+ process.exit(0)
64
+ }
65
+
66
+ switch (phase) {
67
+ case 'welcome':
68
+ return <WelcomeScreen onStart={() => setPhase('harness')} />
69
+ case 'harness':
70
+ return (
71
+ <HarnessSelectScreen
72
+ harnesses={harnesses}
73
+ selected={selectedHarnesses}
74
+ onConfirm={handleHarnessConfirm}
75
+ />
76
+ )
77
+ case 'options':
78
+ return <OptionsScreen options={options} onConfirm={handleOptionsConfirm} />
79
+ case 'summary':
80
+ return (
81
+ <SummaryScreen
82
+ root={config.root}
83
+ selectedHarnesses={selectedHarnesses}
84
+ harnesses={harnesses}
85
+ options={options}
86
+ dryRun={config.dryRun}
87
+ onConfirm={handleSummaryConfirm}
88
+ onCancel={handleCancel}
89
+ />
90
+ )
91
+ case 'running':
92
+ return <ProgressScreen currentStep={currentStep} results={results} />
93
+ case 'result':
94
+ return <ResultScreen results={results} error={error} onFinish={() => process.exit(0)} />
95
+ default:
96
+ return <Text>Unknown phase</Text>
97
+ }
98
+ }
@@ -0,0 +1,56 @@
1
+ import { Box, Text, useInput } from 'ink'
2
+ import React, { useState } from 'react'
3
+
4
+ export interface InstallerOptions {
5
+ installRecordingDeps: boolean
6
+ runBenchmark: boolean
7
+ }
8
+
9
+ export interface OptionsScreenProps {
10
+ options: InstallerOptions
11
+ onConfirm: (options: InstallerOptions) => void
12
+ }
13
+
14
+ const OPTIONS: { key: keyof InstallerOptions; label: string }[] = [
15
+ {
16
+ key: 'installRecordingDeps',
17
+ label: 'Install optional recording dependencies (ffmpeg, faster-whisper)',
18
+ },
19
+ { key: 'runBenchmark', label: 'Enable benchmark tooling' },
20
+ ]
21
+
22
+ export function OptionsScreen({ options: initialOptions, onConfirm }: OptionsScreenProps) {
23
+ const [cursor, setCursor] = useState(0)
24
+ const [options, setOptions] = useState(initialOptions)
25
+
26
+ useInput((input, key) => {
27
+ if (key.upArrow) {
28
+ setCursor((c) => (c > 0 ? c - 1 : OPTIONS.length - 1))
29
+ } else if (key.downArrow) {
30
+ setCursor((c) => (c < OPTIONS.length - 1 ? c + 1 : 0))
31
+ } else if (input === ' ') {
32
+ const key = OPTIONS[cursor].key
33
+ setOptions((o) => ({ ...o, [key]: !o[key] }))
34
+ } else if (key.return) {
35
+ onConfirm(options)
36
+ }
37
+ })
38
+
39
+ return (
40
+ <Box flexDirection="column" padding={1}>
41
+ <Text bold>Options</Text>
42
+ {OPTIONS.map((option, index) => {
43
+ const isCursor = index === cursor
44
+ const enabled = options[option.key]
45
+ return (
46
+ <Text key={option.key} color={isCursor ? 'cyan' : undefined}>
47
+ {isCursor ? '> ' : ' '}
48
+ [{enabled ? 'x' : ' '}] {option.label}
49
+ </Text>
50
+ )
51
+ })}
52
+ <Text dimColor></Text>
53
+ <Text dimColor>Space to toggle, Enter to confirm</Text>
54
+ </Box>
55
+ )
56
+ }
@@ -0,0 +1,25 @@
1
+ import { Box, Text } from 'ink'
2
+ import React from 'react'
3
+
4
+ import type { StepResult } from '../hooks/useSetup'
5
+
6
+ export interface ProgressScreenProps {
7
+ currentStep: string
8
+ results: StepResult[]
9
+ }
10
+
11
+ export function ProgressScreen({ currentStep, results }: ProgressScreenProps) {
12
+ return (
13
+ <Box flexDirection="column" padding={1}>
14
+ <Text bold>Installing Lincoln...</Text>
15
+ {results.map((result) => (
16
+ <Text key={result.step}>
17
+ {result.success ? '✅' : '❌'} {result.step}
18
+ </Text>
19
+ ))}
20
+ {currentStep && !results.some((r) => r.step === currentStep && r.success) && (
21
+ <Text color="cyan">⏳ {currentStep}...</Text>
22
+ )}
23
+ </Box>
24
+ )
25
+ }
@@ -0,0 +1,40 @@
1
+ import { Box, Text, useInput } from 'ink'
2
+ import React from 'react'
3
+
4
+ import type { StepResult } from '../hooks/useSetup'
5
+
6
+ export interface ResultScreenProps {
7
+ results: StepResult[]
8
+ error?: string
9
+ onFinish: () => void
10
+ }
11
+
12
+ export function ResultScreen({ results, error, onFinish }: ResultScreenProps) {
13
+ useInput((_, key) => {
14
+ if (key.return || key.escape) {
15
+ onFinish()
16
+ }
17
+ })
18
+
19
+ const allSuccess = results.length > 0 && results.every((r) => r.success)
20
+
21
+ return (
22
+ <Box flexDirection="column" padding={1}>
23
+ {allSuccess ? (
24
+ <Text bold color="green">✅ Lincoln installation complete!</Text>
25
+ ) : (
26
+ <Text bold color="red">❌ Installation incomplete</Text>
27
+ )}
28
+ {error && <Text color="red">{error}</Text>}
29
+ {results.map((result) => (
30
+ <Box key={result.step} flexDirection="column" marginBottom={1}>
31
+ <Text>
32
+ {result.success ? '✅' : '❌'} {result.step}
33
+ </Text>
34
+ {result.error && <Text color="red"> {result.error}</Text>}
35
+ </Box>
36
+ ))}
37
+ <Text dimColor>Press Enter or Esc to exit.</Text>
38
+ </Box>
39
+ )
40
+ }
@@ -0,0 +1,73 @@
1
+ import { Box, Text, useInput } from 'ink'
2
+ import React, { useState } from 'react'
3
+
4
+ export interface SelectMenuItem {
5
+ label: string
6
+ value: string
7
+ }
8
+
9
+ export interface SelectMenuProps {
10
+ title?: string
11
+ items: SelectMenuItem[]
12
+ selected: string[]
13
+ multiple?: boolean
14
+ onSelect: (value: string) => void
15
+ onConfirm: (value?: string) => void
16
+ onCancel?: () => void
17
+ }
18
+
19
+ export function SelectMenu({
20
+ title,
21
+ items,
22
+ selected,
23
+ multiple = false,
24
+ onSelect,
25
+ onConfirm,
26
+ onCancel,
27
+ }: SelectMenuProps) {
28
+ const [cursor, setCursor] = useState(0)
29
+
30
+ useInput((input, key) => {
31
+ if (key.upArrow) {
32
+ setCursor((c) => (c > 0 ? c - 1 : items.length - 1))
33
+ } else if (key.downArrow) {
34
+ setCursor((c) => (c < items.length - 1 ? c + 1 : 0))
35
+ } else if (key.return) {
36
+ if (multiple) {
37
+ onConfirm()
38
+ } else {
39
+ const value = items[cursor]?.value
40
+ if (value) {
41
+ onSelect(value)
42
+ onConfirm(value)
43
+ }
44
+ }
45
+ } else if (key.escape) {
46
+ onCancel?.()
47
+ } else if (input === ' ') {
48
+ const value = items[cursor]?.value
49
+ if (value) {
50
+ onSelect(value)
51
+ }
52
+ }
53
+ })
54
+
55
+ return (
56
+ <Box flexDirection="column">
57
+ {title ? <Text bold>{title}</Text> : null}
58
+ {items.map((item, index) => {
59
+ const isCursor = index === cursor
60
+ const isSelected = selected.includes(item.value)
61
+ const marker = multiple ? (isSelected ? '[x]' : '[ ]') : isSelected ? '●' : '○'
62
+ return (
63
+ <Text key={item.value} color={isCursor ? 'cyan' : undefined}>
64
+ {isCursor ? '> ' : ' '}
65
+ {marker} {item.label}
66
+ </Text>
67
+ )
68
+ })}
69
+ <Text dimColor></Text>
70
+ <Text dimColor>{multiple ? 'Space to select, Enter to confirm' : '↑↓ to navigate, Enter to select'}</Text>
71
+ </Box>
72
+ )
73
+ }
@@ -0,0 +1,49 @@
1
+ import { Box, Text, useInput } from 'ink'
2
+ import React from 'react'
3
+
4
+ import type { HarnessInfo } from '../types'
5
+
6
+ export interface SummaryScreenProps {
7
+ root: string
8
+ selectedHarnesses: string[]
9
+ harnesses: HarnessInfo[]
10
+ options: { installRecordingDeps: boolean; runBenchmark: boolean }
11
+ dryRun: boolean
12
+ onConfirm: () => void
13
+ onCancel: () => void
14
+ }
15
+
16
+ export function SummaryScreen({
17
+ root,
18
+ selectedHarnesses,
19
+ harnesses,
20
+ options,
21
+ dryRun,
22
+ onConfirm,
23
+ onCancel,
24
+ }: SummaryScreenProps) {
25
+ useInput((_, key) => {
26
+ if (key.return) {
27
+ onConfirm()
28
+ } else if (key.escape) {
29
+ onCancel()
30
+ }
31
+ })
32
+
33
+ const harnessNames = selectedHarnesses
34
+ .map((id) => harnesses.find((h) => h.id === id)?.name || id)
35
+ .join(', ')
36
+
37
+ return (
38
+ <Box flexDirection="column" padding={1}>
39
+ <Text bold>Summary</Text>
40
+ <Text>Project root: {root}</Text>
41
+ <Text>Harnesses: {harnessNames}</Text>
42
+ <Text>Recording deps: {options.installRecordingDeps ? 'yes' : 'no'}</Text>
43
+ <Text>Benchmark: {options.runBenchmark ? 'yes' : 'no'}</Text>
44
+ {dryRun && <Text color="yellow">Dry-run mode: no changes will be made.</Text>}
45
+ <Text dimColor></Text>
46
+ <Text>Press Enter to proceed or Esc to cancel.</Text>
47
+ </Box>
48
+ )
49
+ }
@@ -0,0 +1,135 @@
1
+ import { Box, Text, useInput, useApp } from 'ink'
2
+ import React, { useEffect, useState } from 'react'
3
+
4
+ import { updateRelease, type UpdateResult } from '../utils/updateRelease'
5
+
6
+ export interface UpdateAppProps {
7
+ root: string
8
+ repo: string
9
+ dryRun: boolean
10
+ }
11
+
12
+ type UpdatePhase = 'welcome' | 'confirm' | 'running' | 'result'
13
+
14
+ export function UpdateApp({ root, repo, dryRun }: UpdateAppProps) {
15
+ const { exit } = useApp()
16
+ const [phase, setPhase] = useState<UpdatePhase>('welcome')
17
+ const [result, setResult] = useState<UpdateResult | undefined>(undefined)
18
+
19
+ useEffect(() => {
20
+ async function check(): Promise<void> {
21
+ const checkResult = await updateRelease({ root, repo, dryRun: true })
22
+ setResult(checkResult)
23
+ if (!checkResult.success) {
24
+ setPhase('result')
25
+ return
26
+ }
27
+ if (checkResult.fromVersion === checkResult.toVersion) {
28
+ setPhase('result')
29
+ } else {
30
+ setPhase(dryRun ? 'result' : 'confirm')
31
+ }
32
+ }
33
+ check()
34
+ }, [root, repo, dryRun])
35
+
36
+ useInput((input, key) => {
37
+ if (phase === 'confirm' && key.return) {
38
+ setPhase('running')
39
+ updateRelease({ root, repo, dryRun })
40
+ .then((applyResult) => {
41
+ setResult(applyResult)
42
+ setPhase('result')
43
+ })
44
+ .catch((err) => {
45
+ setResult({
46
+ success: false,
47
+ updated: [],
48
+ preserved: [],
49
+ error: err instanceof Error ? err.message : String(err),
50
+ })
51
+ setPhase('result')
52
+ })
53
+ }
54
+
55
+ if (phase === 'result' && key.return) {
56
+ exit()
57
+ }
58
+ })
59
+
60
+ if (phase === 'welcome') {
61
+ return (
62
+ <Box flexDirection="column" padding={1}>
63
+ <Text bold>Lincoln Update</Text>
64
+ <Text dimColor>Checking for the latest release...</Text>
65
+ </Box>
66
+ )
67
+ }
68
+
69
+ if (phase === 'confirm' && result?.success) {
70
+ return (
71
+ <Box flexDirection="column" padding={1}>
72
+ <Text bold>Update available</Text>
73
+ <Text>
74
+ Current: {result.fromVersion} → Latest: {result.toVersion}
75
+ </Text>
76
+ <Text>Press Enter to apply the update, or Ctrl+C to cancel.</Text>
77
+ </Box>
78
+ )
79
+ }
80
+
81
+ if (phase === 'running') {
82
+ return (
83
+ <Box flexDirection="column" padding={1}>
84
+ <Text bold>Updating Lincoln...</Text>
85
+ <Text dimColor>Downloading and applying the latest release.</Text>
86
+ </Box>
87
+ )
88
+ }
89
+
90
+ if (!result) {
91
+ return null
92
+ }
93
+
94
+ return (
95
+ <Box flexDirection="column" padding={1}>
96
+ {result.success && result.fromVersion === result.toVersion ? (
97
+ <Text color="green">✓ Lincoln is up to date ({result.fromVersion}).</Text>
98
+ ) : result.success && dryRun ? (
99
+ <>
100
+ <Text color="cyan">◌ Dry run: {result.fromVersion} → {result.toVersion} available.</Text>
101
+ <Text>Re-run without --dry-run to apply the update.</Text>
102
+ </>
103
+ ) : result.success ? (
104
+ <>
105
+ <Text color="green">✓ Update complete: {result.fromVersion} → {result.toVersion}.</Text>
106
+ {result.updated.length > 0 && (
107
+ <Box flexDirection="column" marginTop={1}>
108
+ <Text bold>Updated files:</Text>
109
+ {result.updated.slice(0, 10).map((file) => (
110
+ <Text key={file}> {file}</Text>
111
+ ))}
112
+ {result.updated.length > 10 && <Text dimColor> ...and {result.updated.length - 10} more.</Text>}
113
+ </Box>
114
+ )}
115
+ {result.preserved.length > 0 && (
116
+ <Box flexDirection="column" marginTop={1}>
117
+ <Text bold>Preserved user data:</Text>
118
+ {result.preserved.map((path) => (
119
+ <Text key={path}> {path}</Text>
120
+ ))}
121
+ </Box>
122
+ )}
123
+ </>
124
+ ) : (
125
+ <>
126
+ <Text color="red">✗ Update failed.</Text>
127
+ {result.error && <Text>{result.error}</Text>}
128
+ </>
129
+ )}
130
+ <Box marginTop={1}>
131
+ <Text dimColor>Press Enter to exit.</Text>
132
+ </Box>
133
+ </Box>
134
+ )
135
+ }
@@ -0,0 +1,22 @@
1
+ import { Box, Text, useInput } from 'ink'
2
+ import React from 'react'
3
+
4
+ export interface WelcomeScreenProps {
5
+ onStart: () => void
6
+ }
7
+
8
+ export function WelcomeScreen({ onStart }: WelcomeScreenProps) {
9
+ useInput((_, key) => {
10
+ if (key.return) {
11
+ onStart()
12
+ }
13
+ })
14
+
15
+ return (
16
+ <Box flexDirection="column" padding={1}>
17
+ <Text bold color="cyan">Welcome to Lincoln</Text>
18
+ <Text>This installer will set up Lincoln in your project.</Text>
19
+ <Text dimColor>Press Enter to start.</Text>
20
+ </Box>
21
+ )
22
+ }