baldart 3.6.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 (230) hide show
  1. package/CHANGELOG.md +599 -0
  2. package/README.md +566 -0
  3. package/VERSION +1 -0
  4. package/bin/baldart.js +143 -0
  5. package/framework/.claude/agents/REGISTRY.md +169 -0
  6. package/framework/.claude/agents/api-perf-cost-auditor.md +291 -0
  7. package/framework/.claude/agents/code-reviewer.md +350 -0
  8. package/framework/.claude/agents/codebase-architect.md +391 -0
  9. package/framework/.claude/agents/coder.md +291 -0
  10. package/framework/.claude/agents/deep-human-insight.md +198 -0
  11. package/framework/.claude/agents/doc-reviewer.md +440 -0
  12. package/framework/.claude/agents/email-deliverability-architect.md +193 -0
  13. package/framework/.claude/agents/hybrid-ml-architect.md +285 -0
  14. package/framework/.claude/agents/hyper-gamification-designer.md +149 -0
  15. package/framework/.claude/agents/legal-counsel-gdpr.md +179 -0
  16. package/framework/.claude/agents/marketing-conversion-strategist.md +162 -0
  17. package/framework/.claude/agents/motion-expert.md +108 -0
  18. package/framework/.claude/agents/onboarding-architect-lead.md +230 -0
  19. package/framework/.claude/agents/plan-auditor.md +546 -0
  20. package/framework/.claude/agents/prd-card-writer.md +372 -0
  21. package/framework/.claude/agents/prd.md +744 -0
  22. package/framework/.claude/agents/qa-sentinel.md +305 -0
  23. package/framework/.claude/agents/remotion-animator-orchestrator.md +218 -0
  24. package/framework/.claude/agents/security-reviewer.md +276 -0
  25. package/framework/.claude/agents/senior-researcher.md +175 -0
  26. package/framework/.claude/agents/seo-analytics-strategist.md +156 -0
  27. package/framework/.claude/agents/skill-improver.md +61 -0
  28. package/framework/.claude/agents/ui-expert.md +191 -0
  29. package/framework/.claude/agents/visual-designer.md +190 -0
  30. package/framework/.claude/agents/website-orchestrator.md +118 -0
  31. package/framework/.claude/agents/wiki-curator.md +145 -0
  32. package/framework/.claude/commands/baldart-push.md +15 -0
  33. package/framework/.claude/commands/check.md +237 -0
  34. package/framework/.claude/commands/codexreview.md +203 -0
  35. package/framework/.claude/commands/design-review.md +11 -0
  36. package/framework/.claude/commands/issue-review.md +34 -0
  37. package/framework/.claude/commands/new.md +331 -0
  38. package/framework/.claude/commands/qa.md +257 -0
  39. package/framework/.claude/hooks/framework-edit-gate.js +208 -0
  40. package/framework/.claude/hooks/lint-before-commit.sh.template +66 -0
  41. package/framework/.claude/settings.local.json.example +32 -0
  42. package/framework/.claude/skills/api-design-principles/SKILL.md +567 -0
  43. package/framework/.claude/skills/api-design-principles/assets/api-design-checklist.md +155 -0
  44. package/framework/.claude/skills/api-design-principles/assets/rest-api-template.py +182 -0
  45. package/framework/.claude/skills/api-design-principles/references/graphql-schema-design.md +583 -0
  46. package/framework/.claude/skills/api-design-principles/references/rest-best-practices.md +408 -0
  47. package/framework/.claude/skills/baldart-push/SKILL.md +222 -0
  48. package/framework/.claude/skills/bug/SKILL.md +200 -0
  49. package/framework/.claude/skills/bug/references/logging-patterns.md +174 -0
  50. package/framework/.claude/skills/capture/SKILL.md +125 -0
  51. package/framework/.claude/skills/capture/references/synthesis-template.md +42 -0
  52. package/framework/.claude/skills/context-primer/SKILL.md +189 -0
  53. package/framework/.claude/skills/copywriting/SKILL.md +273 -0
  54. package/framework/.claude/skills/copywriting/references/copy-frameworks.md +338 -0
  55. package/framework/.claude/skills/copywriting/references/natural-transitions.md +252 -0
  56. package/framework/.claude/skills/doc-writing-for-rag/SKILL.md +119 -0
  57. package/framework/.claude/skills/doc-writing-for-rag/references/before-after-examples.md +291 -0
  58. package/framework/.claude/skills/doc-writing-for-rag/references/compact-templates.md +183 -0
  59. package/framework/.claude/skills/doc-writing-for-rag/references/frontmatter-minimal.md +112 -0
  60. package/framework/.claude/skills/doc-writing-for-rag/references/line-count-targets.md +110 -0
  61. package/framework/.claude/skills/doc-writing-for-rag/references/schemas-and-errors.md +129 -0
  62. package/framework/.claude/skills/find-skills/SKILL.md +133 -0
  63. package/framework/.claude/skills/frontend-design/LICENSE.txt +177 -0
  64. package/framework/.claude/skills/frontend-design/SKILL.md +84 -0
  65. package/framework/.claude/skills/gamification-design/SKILL.md +130 -0
  66. package/framework/.claude/skills/issue-review/SKILL.md +45 -0
  67. package/framework/.claude/skills/kie-ai/SKILL.md +262 -0
  68. package/framework/.claude/skills/kie-ai/references/models-catalog.md +272 -0
  69. package/framework/.claude/skills/kie-ai/scripts/kie_api.sh +209 -0
  70. package/framework/.claude/skills/kie-ai/scripts/remove_greenscreen.py +69 -0
  71. package/framework/.claude/skills/kie-ai/scripts/setup_api_key.sh +77 -0
  72. package/framework/.claude/skills/motion-design/LICENSE +21 -0
  73. package/framework/.claude/skills/motion-design/README.md +82 -0
  74. package/framework/.claude/skills/motion-design/SKILL.md +336 -0
  75. package/framework/.claude/skills/motion-design/director/choreography.md +93 -0
  76. package/framework/.claude/skills/motion-design/director/context-adaptation.md +83 -0
  77. package/framework/.claude/skills/motion-design/director/core-philosophy.md +53 -0
  78. package/framework/.claude/skills/motion-design/director/decision-framework.md +91 -0
  79. package/framework/.claude/skills/motion-design/director/disney-principles.md +102 -0
  80. package/framework/.claude/skills/motion-design/director/emotion-mapping.md +71 -0
  81. package/framework/.claude/skills/motion-design/director/motion-personality.md +89 -0
  82. package/framework/.claude/skills/motion-design/director/narrative-structure.md +62 -0
  83. package/framework/.claude/skills/motion-design/patterns/ambient-continuous.md +81 -0
  84. package/framework/.claude/skills/motion-design/patterns/entrance-exit.md +82 -0
  85. package/framework/.claude/skills/motion-design/patterns/multi-element.md +69 -0
  86. package/framework/.claude/skills/motion-design/patterns/state-feedback.md +96 -0
  87. package/framework/.claude/skills/motion-design/reference/property-selection.md +95 -0
  88. package/framework/.claude/skills/motion-design/reference/quality-checklist.md +67 -0
  89. package/framework/.claude/skills/motion-design/reference/timing-easing-tables.md +106 -0
  90. package/framework/.claude/skills/motion-design/reference/troubleshooting.md +73 -0
  91. package/framework/.claude/skills/new/SKILL.md +1687 -0
  92. package/framework/.claude/skills/playwright-skill/API_REFERENCE.md +652 -0
  93. package/framework/.claude/skills/playwright-skill/SKILL.md +157 -0
  94. package/framework/.claude/skills/playwright-skill/package.json +26 -0
  95. package/framework/.claude/skills/prd/SKILL.md +228 -0
  96. package/framework/.claude/skills/prd/assets/card-template.yml +232 -0
  97. package/framework/.claude/skills/prd/assets/epic-template.yml +190 -0
  98. package/framework/.claude/skills/prd/assets/prd-template.md +230 -0
  99. package/framework/.claude/skills/prd/assets/state-template.md +78 -0
  100. package/framework/.claude/skills/prd/references/api-perf-gate.md +152 -0
  101. package/framework/.claude/skills/prd/references/audit-phase.md +478 -0
  102. package/framework/.claude/skills/prd/references/backlog-phase.md +145 -0
  103. package/framework/.claude/skills/prd/references/discovery-phase.md +359 -0
  104. package/framework/.claude/skills/prd/references/impact-analysis.md +233 -0
  105. package/framework/.claude/skills/prd/references/prd-add-phase.md +214 -0
  106. package/framework/.claude/skills/prd/references/prd-writing-phase.md +145 -0
  107. package/framework/.claude/skills/prd/references/research-phase.md +216 -0
  108. package/framework/.claude/skills/prd/references/ui-design-phase.md +61 -0
  109. package/framework/.claude/skills/prd/references/validation-phase.md +72 -0
  110. package/framework/.claude/skills/prd-add/SKILL.md +222 -0
  111. package/framework/.claude/skills/prd-add/references/impact-analysis.md +233 -0
  112. package/framework/.claude/skills/remotion-best-practices/SKILL.md +48 -0
  113. package/framework/.claude/skills/remotion-best-practices/rules/3d.md +86 -0
  114. package/framework/.claude/skills/remotion-best-practices/rules/animations.md +29 -0
  115. package/framework/.claude/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
  116. package/framework/.claude/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
  117. package/framework/.claude/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
  118. package/framework/.claude/skills/remotion-best-practices/rules/assets.md +78 -0
  119. package/framework/.claude/skills/remotion-best-practices/rules/audio.md +169 -0
  120. package/framework/.claude/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
  121. package/framework/.claude/skills/remotion-best-practices/rules/can-decode.md +75 -0
  122. package/framework/.claude/skills/remotion-best-practices/rules/charts.md +58 -0
  123. package/framework/.claude/skills/remotion-best-practices/rules/compositions.md +141 -0
  124. package/framework/.claude/skills/remotion-best-practices/rules/display-captions.md +184 -0
  125. package/framework/.claude/skills/remotion-best-practices/rules/extract-frames.md +229 -0
  126. package/framework/.claude/skills/remotion-best-practices/rules/fonts.md +152 -0
  127. package/framework/.claude/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
  128. package/framework/.claude/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
  129. package/framework/.claude/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
  130. package/framework/.claude/skills/remotion-best-practices/rules/gifs.md +141 -0
  131. package/framework/.claude/skills/remotion-best-practices/rules/images.md +130 -0
  132. package/framework/.claude/skills/remotion-best-practices/rules/import-srt-captions.md +69 -0
  133. package/framework/.claude/skills/remotion-best-practices/rules/light-leaks.md +73 -0
  134. package/framework/.claude/skills/remotion-best-practices/rules/lottie.md +67 -0
  135. package/framework/.claude/skills/remotion-best-practices/rules/maps.md +401 -0
  136. package/framework/.claude/skills/remotion-best-practices/rules/measuring-dom-nodes.md +34 -0
  137. package/framework/.claude/skills/remotion-best-practices/rules/measuring-text.md +143 -0
  138. package/framework/.claude/skills/remotion-best-practices/rules/parameters.md +98 -0
  139. package/framework/.claude/skills/remotion-best-practices/rules/sequencing.md +118 -0
  140. package/framework/.claude/skills/remotion-best-practices/rules/subtitles.md +36 -0
  141. package/framework/.claude/skills/remotion-best-practices/rules/tailwind.md +11 -0
  142. package/framework/.claude/skills/remotion-best-practices/rules/text-animations.md +20 -0
  143. package/framework/.claude/skills/remotion-best-practices/rules/timing.md +179 -0
  144. package/framework/.claude/skills/remotion-best-practices/rules/transcribe-captions.md +70 -0
  145. package/framework/.claude/skills/remotion-best-practices/rules/transitions.md +197 -0
  146. package/framework/.claude/skills/remotion-best-practices/rules/transparent-videos.md +106 -0
  147. package/framework/.claude/skills/remotion-best-practices/rules/trimming.md +52 -0
  148. package/framework/.claude/skills/remotion-best-practices/rules/videos.md +171 -0
  149. package/framework/.claude/skills/seo-audit/SKILL.md +394 -0
  150. package/framework/.claude/skills/seo-audit/references/aeo-geo-patterns.md +279 -0
  151. package/framework/.claude/skills/seo-audit/references/ai-writing-detection.md +190 -0
  152. package/framework/.claude/skills/simplify/SKILL.md +137 -0
  153. package/framework/.claude/skills/skill-creator/LICENSE.txt +202 -0
  154. package/framework/.claude/skills/skill-creator/SKILL.md +356 -0
  155. package/framework/.claude/skills/skill-creator/references/output-patterns.md +82 -0
  156. package/framework/.claude/skills/skill-creator/references/workflows.md +28 -0
  157. package/framework/.claude/skills/skill-creator/scripts/init_skill.py +303 -0
  158. package/framework/.claude/skills/skill-creator/scripts/package_skill.py +110 -0
  159. package/framework/.claude/skills/skill-creator/scripts/quick_validate.py +95 -0
  160. package/framework/.claude/skills/ui-design/SKILL.md +199 -0
  161. package/framework/.claude/skills/ui-design/references/component-discovery.md +54 -0
  162. package/framework/.claude/skills/ui-design/references/evaluation.md +171 -0
  163. package/framework/.claude/skills/ui-design/references/generation.md +109 -0
  164. package/framework/.claude/skills/ui-design/references/inventory.md +59 -0
  165. package/framework/.claude/skills/webapp-testing/LICENSE.txt +202 -0
  166. package/framework/.claude/skills/webapp-testing/SKILL.md +123 -0
  167. package/framework/.claude/skills/webapp-testing/examples/console_logging.py +35 -0
  168. package/framework/.claude/skills/webapp-testing/examples/element_discovery.py +40 -0
  169. package/framework/.claude/skills/webapp-testing/examples/static_html_automation.py +33 -0
  170. package/framework/.claude/skills/webapp-testing/scripts/with_server.py +106 -0
  171. package/framework/.claude/skills/worktree-manager/SKILL.md +680 -0
  172. package/framework/AGENTS.md +240 -0
  173. package/framework/agents/api-contracts.md +137 -0
  174. package/framework/agents/architecture.md +145 -0
  175. package/framework/agents/coding-standards.md +148 -0
  176. package/framework/agents/data-model.md +110 -0
  177. package/framework/agents/deployment-protocol.md +232 -0
  178. package/framework/agents/design-review.md +172 -0
  179. package/framework/agents/env-reference.md +171 -0
  180. package/framework/agents/github-issue-subagent.md +252 -0
  181. package/framework/agents/index.md +261 -0
  182. package/framework/agents/llm-wiki-methodology.md +216 -0
  183. package/framework/agents/maintenance-protocol.md +305 -0
  184. package/framework/agents/observability.md +162 -0
  185. package/framework/agents/performance.md +155 -0
  186. package/framework/agents/project-context.md +145 -0
  187. package/framework/agents/runbook.md +208 -0
  188. package/framework/agents/security.md +168 -0
  189. package/framework/agents/skills-mapping.md +286 -0
  190. package/framework/agents/testing.md +111 -0
  191. package/framework/agents/workflows.md +215 -0
  192. package/framework/docs/PROJECT-CONFIGURATION.md +336 -0
  193. package/framework/docs/references/brand-guidelines.md +170 -0
  194. package/framework/docs/references/ui-guidelines.template.md +182 -0
  195. package/framework/routines/code-review.routine.yml +46 -0
  196. package/framework/routines/doc-review.routine.yml +45 -0
  197. package/framework/routines/ds-drift.routine.yml +52 -0
  198. package/framework/routines/full-sweep.routine.yml +51 -0
  199. package/framework/routines/index.yml +70 -0
  200. package/framework/routines/skill-improve.routine.yml +50 -0
  201. package/framework/routines/wiki-review.routine.yml +45 -0
  202. package/framework/templates/baldart.config.template.yml +113 -0
  203. package/framework/templates/breaking-change-checklist.md +484 -0
  204. package/framework/templates/feature-card.template.yml +125 -0
  205. package/framework/templates/overlays/README.md +44 -0
  206. package/framework/templates/overlays/copywriting.fidelity-example.md +62 -0
  207. package/framework/templates/overlays/ui-design.fidelity-example.md +75 -0
  208. package/framework/templates/skill-project-context.snippet.md +19 -0
  209. package/framework/templates/spec.template.md +208 -0
  210. package/package.json +51 -0
  211. package/src/commands/add.js +229 -0
  212. package/src/commands/configure.js +385 -0
  213. package/src/commands/doctor.js +486 -0
  214. package/src/commands/migrate.js +185 -0
  215. package/src/commands/push.js +0 -0
  216. package/src/commands/routines.js +269 -0
  217. package/src/commands/status.js +130 -0
  218. package/src/commands/update.js +419 -0
  219. package/src/commands/version.js +88 -0
  220. package/src/utils/contamination.js +400 -0
  221. package/src/utils/git.js +181 -0
  222. package/src/utils/hooks.js +152 -0
  223. package/src/utils/routine-adapters/claude-code-cloud.js +78 -0
  224. package/src/utils/routine-adapters/cron.js +138 -0
  225. package/src/utils/routine-adapters/github-actions.js +141 -0
  226. package/src/utils/routine-adapters/index.js +21 -0
  227. package/src/utils/routines.js +166 -0
  228. package/src/utils/state.js +143 -0
  229. package/src/utils/symlinks.js +425 -0
  230. package/src/utils/ui.js +133 -0
@@ -0,0 +1,269 @@
1
+ const chalk = require('chalk');
2
+ const UI = require('../utils/ui');
3
+ const Routines = require('../utils/routines');
4
+ const { listAdapters, getAdapter } = require('../utils/routine-adapters');
5
+
6
+ const STATUS_BADGE = {
7
+ installed: chalk.green('● installed'),
8
+ available: chalk.cyan('○ available'),
9
+ skipped: chalk.gray('— skipped'),
10
+ disabled: chalk.gray('× disabled'),
11
+ blocked: chalk.yellow('! blocked'),
12
+ unavailable: chalk.gray('— unavailable'),
13
+ error: chalk.red('✗ error')
14
+ };
15
+
16
+ async function list() {
17
+ UI.header('BALDART Routines');
18
+
19
+ const routines = new Routines();
20
+ const rows = routines.computeStatus();
21
+
22
+ if (rows.length === 0) {
23
+ UI.warning('No routines catalog found. Run `npx baldart update` first.');
24
+ return;
25
+ }
26
+
27
+ UI.info(`Catalog: ${rows.length} routines defined.`);
28
+ UI.newline();
29
+
30
+ rows.forEach(r => {
31
+ const badge = STATUS_BADGE[r.status] || r.status;
32
+ const cadence = r.spec.schedule && r.spec.schedule.cadence_label
33
+ ? chalk.gray(`[${r.spec.schedule.cadence_label}]`)
34
+ : '';
35
+ console.log(` ${badge} ${chalk.bold(r.spec.name)} ${cadence}`);
36
+ console.log(` ${chalk.gray(r.spec.description || '')}`);
37
+ if (r.lockEntry && r.lockEntry.backend) {
38
+ console.log(` ${chalk.gray('backend:')} ${r.lockEntry.backend}`);
39
+ }
40
+ if (r.status === 'blocked' && r.requiredArtifacts.missing.length > 0) {
41
+ console.log(` ${chalk.yellow('missing artifacts:')} ${r.requiredArtifacts.missing.map(m => m.path).join(', ')}`);
42
+ }
43
+ if (r.status === 'error') {
44
+ console.log(` ${chalk.red('error:')} ${r.error}`);
45
+ }
46
+ UI.newline();
47
+ });
48
+
49
+ UI.section('Legend');
50
+ console.log(` ${STATUS_BADGE.installed} active in the selected backend (see lock file)`);
51
+ console.log(` ${STATUS_BADGE.available} ready to install (\`npx baldart routines install <name>\`)`);
52
+ console.log(` ${STATUS_BADGE.blocked} required artifacts missing — install the relevant feature first`);
53
+ console.log(` ${STATUS_BADGE.skipped} user opted out (re-prompt with \`routines install <name>\`)`);
54
+ console.log(` ${STATUS_BADGE.disabled} previously installed, now disabled`);
55
+ UI.newline();
56
+ }
57
+
58
+ async function install(name) {
59
+ UI.header(`Install routine: ${name}`);
60
+
61
+ const routines = new Routines();
62
+ let spec;
63
+ try {
64
+ spec = routines.readSpec(name);
65
+ } catch (err) {
66
+ UI.error(err.message);
67
+ process.exit(1);
68
+ }
69
+
70
+ // Show summary
71
+ UI.box(`Routine: ${spec.name}`, [
72
+ spec.description,
73
+ '',
74
+ `Schedule: ${spec.schedule.cron} (${spec.schedule.cadence_label || 'scheduled'}, ${spec.schedule.timezone || 'UTC'})`,
75
+ `Agent: ${spec.agent}`,
76
+ `Output: ${(spec.output && spec.output.path) || '(none)'}`,
77
+ `Commit: ${spec.output && spec.output.commit && spec.output.commit.enabled ? 'yes (' + spec.output.commit.prefix + ')' : 'no'}`
78
+ ]);
79
+
80
+ // Check artifacts
81
+ const status = routines.computeStatus().find(r => r.spec.name === name);
82
+ if (status && status.requiredArtifacts.missing.length > 0) {
83
+ if (spec.optional) {
84
+ UI.warning(`Optional routine — required artifacts missing: ${status.requiredArtifacts.missing.map(m => m.path).join(', ')}`);
85
+ const proceed = await UI.confirm('Install anyway?', false);
86
+ if (!proceed) {
87
+ UI.info('Aborted.');
88
+ return;
89
+ }
90
+ } else {
91
+ UI.error(`Required artifacts missing — cannot install:`);
92
+ status.requiredArtifacts.missing.forEach(m => console.log(' • ' + m.path));
93
+ process.exit(1);
94
+ }
95
+ }
96
+
97
+ // Pick adapter
98
+ const choices = listAdapters().map(n => {
99
+ const adapter = getAdapter(n);
100
+ return { name: `${adapter.label} — ${adapter.description}`, value: n };
101
+ });
102
+ choices.push({ name: 'Cancel (do nothing)', value: '__cancel' });
103
+
104
+ const backend = await UI.select('Which scheduling backend?', choices);
105
+ if (backend === '__cancel') {
106
+ UI.info('Aborted.');
107
+ return;
108
+ }
109
+
110
+ // Install
111
+ const adapter = getAdapter(backend);
112
+ const result = adapter.install(spec);
113
+
114
+ routines.setLockEntry(name, {
115
+ status: 'installed',
116
+ backend: backend,
117
+ since_version: spec.since_version || null,
118
+ artifacts: result.artifacts || []
119
+ });
120
+
121
+ UI.success(`Routine "${name}" installed via ${adapter.label}.`);
122
+ if (result.artifacts && result.artifacts.length > 0) {
123
+ UI.section('Generated artifacts');
124
+ result.artifacts.forEach(a => console.log(' • ' + a));
125
+ }
126
+ if (result.followup && result.followup.length > 0) {
127
+ UI.section('Follow-up steps');
128
+ result.followup.forEach(l => console.log(' ' + l));
129
+ }
130
+ UI.newline();
131
+ }
132
+
133
+ async function disable(name) {
134
+ UI.header(`Disable routine: ${name}`);
135
+
136
+ const routines = new Routines();
137
+ const lock = routines.readLock();
138
+ const entry = (lock.routines || {})[name];
139
+
140
+ if (!entry || entry.status !== 'installed') {
141
+ UI.warning(`Routine "${name}" is not currently installed.`);
142
+ return;
143
+ }
144
+
145
+ let adapter;
146
+ try { adapter = getAdapter(entry.backend); }
147
+ catch (err) { UI.warning(`Unknown backend in lock: ${entry.backend}. Removing lock entry only.`); }
148
+
149
+ if (adapter) {
150
+ const result = adapter.uninstall(name);
151
+ if (result.followup && result.followup.length > 0) {
152
+ UI.section('Manual cleanup steps');
153
+ result.followup.forEach(l => console.log(' ' + l));
154
+ }
155
+ }
156
+
157
+ routines.setLockEntry(name, { status: 'disabled' });
158
+ UI.success(`Routine "${name}" disabled.`);
159
+ }
160
+
161
+ async function doctor() {
162
+ UI.header('Routines health check');
163
+
164
+ const routines = new Routines();
165
+ const rows = routines.computeStatus();
166
+ let problems = 0;
167
+
168
+ rows.forEach(r => {
169
+ if (r.status === 'installed' && r.lockEntry) {
170
+ let adapter;
171
+ try { adapter = getAdapter(r.lockEntry.backend); }
172
+ catch (err) {
173
+ UI.error(`${r.spec.name}: unknown backend in lock — ${r.lockEntry.backend}`);
174
+ problems++;
175
+ return;
176
+ }
177
+ const present = adapter.detect(r.spec.name);
178
+ if (!present) {
179
+ UI.error(`${r.spec.name}: lock says installed via ${r.lockEntry.backend} but artifact is missing.`);
180
+ problems++;
181
+ } else {
182
+ UI.success(`${r.spec.name}: OK (${r.lockEntry.backend})`);
183
+ }
184
+ } else if (r.status === 'blocked') {
185
+ UI.warning(`${r.spec.name}: blocked — missing ${r.requiredArtifacts.missing.map(m => m.path).join(', ')}`);
186
+ problems++;
187
+ } else if (r.status === 'error') {
188
+ UI.error(`${r.spec.name}: spec error — ${r.error}`);
189
+ problems++;
190
+ }
191
+ });
192
+
193
+ UI.newline();
194
+ if (problems === 0) {
195
+ UI.success('All routines healthy.');
196
+ } else {
197
+ UI.warning(`Found ${problems} problem(s). Run \`npx baldart routines install <name>\` to re-install or \`disable <name>\` to clean up.`);
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Wizard meant to be called after `add` / `update` succeeds.
203
+ * Surfaces routines the user has never been prompted about and offers to
204
+ * install them. Non-interactive when stdin is not a TTY (silently exits).
205
+ */
206
+ async function postUpdateWizard() {
207
+ if (!process.stdin.isTTY) return;
208
+
209
+ const routines = new Routines();
210
+ const newOnes = routines.newRoutines();
211
+
212
+ if (newOnes.length === 0) return;
213
+
214
+ UI.newline();
215
+ UI.section('New routines available');
216
+ UI.info(`BALDART ships ${newOnes.length} scheduled routine(s) you haven't reviewed yet.`);
217
+ UI.info('These are the schedules that make the framework\'s auto-learning / drift loops actually run.');
218
+ UI.newline();
219
+
220
+ newOnes.forEach(r => {
221
+ const cadence = r.spec.schedule && r.spec.schedule.cadence_label
222
+ ? `[${r.spec.schedule.cadence_label} — ${r.spec.schedule.cron}]`
223
+ : '';
224
+ console.log(` • ${chalk.bold(r.spec.name)} ${chalk.gray(cadence)}`);
225
+ console.log(` ${chalk.gray(r.spec.description)}`);
226
+ });
227
+ UI.newline();
228
+
229
+ const proceed = await UI.confirm('Configure these routines now?', true);
230
+ if (!proceed) {
231
+ // Mark them all as skipped so we don't ask again on the next update.
232
+ newOnes.forEach(r => routines.setLockEntry(r.spec.name, { status: 'skipped' }));
233
+ UI.info('Skipped. Run `npx baldart routines list` to revisit.');
234
+ return;
235
+ }
236
+
237
+ for (const r of newOnes) {
238
+ const choice = await UI.select(`Routine "${r.spec.name}" — what now?`, [
239
+ { name: 'Install with Claude Code Cloud (RemoteTrigger)', value: 'claude-code-cloud' },
240
+ { name: 'Install with GitHub Actions', value: 'github-actions' },
241
+ { name: 'Install with local cron', value: 'cron' },
242
+ { name: 'Skip (don\'t ask again unless I run `routines install`)', value: '__skip' },
243
+ { name: 'Decide later (ask me again next update)', value: '__later' }
244
+ ]);
245
+
246
+ if (choice === '__later') continue;
247
+ if (choice === '__skip') {
248
+ routines.setLockEntry(r.spec.name, { status: 'skipped' });
249
+ continue;
250
+ }
251
+
252
+ const adapter = getAdapter(choice);
253
+ const result = adapter.install(r.spec);
254
+ routines.setLockEntry(r.spec.name, {
255
+ status: 'installed',
256
+ backend: choice,
257
+ since_version: r.spec.since_version || null,
258
+ artifacts: result.artifacts || []
259
+ });
260
+ UI.success(`Installed ${r.spec.name} via ${adapter.label}.`);
261
+ if (result.followup && result.followup.length > 0) {
262
+ UI.section('Follow-up');
263
+ result.followup.forEach(l => console.log(' ' + l));
264
+ }
265
+ UI.newline();
266
+ }
267
+ }
268
+
269
+ module.exports = { list, install, disable, doctor, postUpdateWizard };
@@ -0,0 +1,130 @@
1
+ const GitUtils = require('../utils/git');
2
+ const SymlinkUtils = require('../utils/symlinks');
3
+ const UI = require('../utils/ui');
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+
7
+ async function status() {
8
+ const git = new GitUtils();
9
+ const symlinks = new SymlinkUtils();
10
+
11
+ try {
12
+ UI.header('BALDART STATUS');
13
+
14
+ // Check installation
15
+ const exists = await git.frameworkExists();
16
+
17
+ if (!exists) {
18
+ UI.warning('Framework not installed');
19
+ UI.info('Install with: npx baldart add');
20
+ process.exit(0);
21
+ }
22
+
23
+ // Get version
24
+ const version = await git.getFrameworkVersion();
25
+ UI.success(`Framework installed: v${version}`);
26
+
27
+ // Check symlinks
28
+ UI.newline();
29
+ UI.section('Symlinks Status');
30
+ const symlinkValid = symlinks.verifySymlinks();
31
+
32
+ if (!symlinkValid) {
33
+ UI.newline();
34
+ UI.warning('Some symlinks are broken. Run: baldart add (to reinstall)');
35
+ }
36
+
37
+ // Check customizable files
38
+ UI.newline();
39
+ UI.section('Customizable Files');
40
+
41
+ const customFiles = [
42
+ '.claude/hooks/lint-before-commit.sh.template',
43
+ '.claude/hooks/lint-before-commit.sh',
44
+ 'docs/references/ui-guidelines.template.md',
45
+ 'docs/references/brand-guidelines.md',
46
+ 'templates/feature-card.template.yml',
47
+ 'baldart.config.yml',
48
+ ];
49
+
50
+ customFiles.forEach(file => {
51
+ const fullPath = path.join(process.cwd(), file);
52
+ if (fs.existsSync(fullPath)) {
53
+ UI.success(`Found: ${file}`);
54
+ } else {
55
+ UI.warning(`Missing: ${file}`);
56
+ }
57
+ });
58
+
59
+ // Project context (v3.0.0+): list any authored skill overlays
60
+ UI.newline();
61
+ UI.section('Skill Overlays (.baldart/overlays/)');
62
+
63
+ const overlaysDir = path.join(process.cwd(), '.baldart', 'overlays');
64
+ if (!fs.existsSync(overlaysDir)) {
65
+ UI.warning('Missing: .baldart/overlays/ — run `npx baldart configure` to create it.');
66
+ } else {
67
+ const overlays = fs.readdirSync(overlaysDir).filter((f) => f.endsWith('.md'));
68
+ if (overlays.length === 0) {
69
+ UI.info('No overlays authored. Examples in: .framework/templates/overlays/');
70
+ } else {
71
+ // Best-effort version-drift check
72
+ const yaml = require('js-yaml');
73
+ const fwVersion = version;
74
+ overlays.forEach((file) => {
75
+ const full = path.join(overlaysDir, file);
76
+ let line = `Overlay: ${file}`;
77
+ try {
78
+ const txt = fs.readFileSync(full, 'utf8');
79
+ const fmMatch = txt.match(/^---\n([\s\S]*?)\n---/);
80
+ if (fmMatch) {
81
+ const fm = yaml.load(fmMatch[1]) || {};
82
+ if (fm.base_skill_version && fwVersion && fm.base_skill_version !== fwVersion) {
83
+ line += ` (targets v${fm.base_skill_version}, installed v${fwVersion} — review for drift)`;
84
+ UI.warning(line);
85
+ return;
86
+ }
87
+ if (fm.base_skill_version) line += ` (v${fm.base_skill_version})`;
88
+ }
89
+ UI.success(line);
90
+ } catch (_) {
91
+ UI.warning(`${line} — could not parse frontmatter`);
92
+ }
93
+ });
94
+ }
95
+ }
96
+
97
+ // Check for pending updates
98
+ UI.newline();
99
+ UI.section('Update Status');
100
+
101
+ try {
102
+ await git.fetch('antbald/BALDART');
103
+ UI.info('Checking for updates...');
104
+ // Simplified - would need more sophisticated version comparison
105
+ UI.success('Up to date (check with: baldart update)');
106
+ } catch (error) {
107
+ UI.warning('Cannot check for updates (offline?)');
108
+ }
109
+
110
+ // Summary
111
+ UI.newline();
112
+ UI.box('SUMMARY', [
113
+ `Version: ${version}`,
114
+ `Installation: ${symlinkValid ? 'Valid' : 'Issues detected'}`,
115
+ '',
116
+ 'Commands available:',
117
+ ' • baldart update - Update framework',
118
+ ' • baldart push - Contribute changes',
119
+ ' • baldart version - Show version'
120
+ ]);
121
+
122
+ UI.newline();
123
+
124
+ } catch (error) {
125
+ UI.error(`Status check failed: ${error.message}`);
126
+ process.exit(1);
127
+ }
128
+ }
129
+
130
+ module.exports = status;