mova-claude-import 0.1.1 → 0.1.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 (188) hide show
  1. package/README.md +68 -4
  2. package/control_surface_exclusions_v0.json +8 -0
  3. package/dist/anthropic_profile_v0.d.ts +1 -1
  4. package/dist/anthropic_profile_v0.js +1 -0
  5. package/dist/cli.js +206 -23
  6. package/dist/control_apply_v0.d.ts +5 -1
  7. package/dist/control_apply_v0.js +125 -8
  8. package/dist/control_check_v0.d.ts +1 -0
  9. package/dist/control_check_v0.js +194 -23
  10. package/dist/control_prefill_v0.js +128 -9
  11. package/dist/control_surface_coverage_v0.d.ts +22 -0
  12. package/dist/control_surface_coverage_v0.js +128 -0
  13. package/dist/control_v0.d.ts +149 -0
  14. package/dist/control_v0.js +360 -0
  15. package/dist/control_v0_schema.d.ts +6 -0
  16. package/dist/control_v0_schema.js +19 -0
  17. package/dist/init_v0.d.ts +6 -1
  18. package/dist/init_v0.js +41 -1
  19. package/dist/observability_writer_v0.d.ts +1 -0
  20. package/dist/observability_writer_v0.js +157 -0
  21. package/dist/observe_v0.d.ts +8 -0
  22. package/dist/observe_v0.js +57 -0
  23. package/dist/presets_v0.d.ts +11 -0
  24. package/dist/presets_v0.js +49 -0
  25. package/dist/redaction.js +5 -1
  26. package/dist/run_import.js +111 -26
  27. package/docs/CLAUDE_CONTROL_SURFACE_MAP_v0.md +78 -0
  28. package/docs/OPERATOR_GUIDE_v0.md +11 -0
  29. package/fixtures/pos/basic/mova/control_v0.json +93 -0
  30. package/fixtures/pos/claude_code_demo_full/.claude/agents/code-reviewer.md +13 -0
  31. package/fixtures/pos/claude_code_demo_full/.claude/agents/github-workflow.md +10 -0
  32. package/fixtures/pos/claude_code_demo_full/.claude/commands/code-quality.md +8 -0
  33. package/fixtures/pos/claude_code_demo_full/.claude/commands/docs-sync.md +8 -0
  34. package/fixtures/pos/claude_code_demo_full/.claude/commands/onboard.md +8 -0
  35. package/fixtures/pos/claude_code_demo_full/.claude/commands/pr-review.md +10 -0
  36. package/fixtures/pos/claude_code_demo_full/.claude/commands/pr-summary.md +8 -0
  37. package/fixtures/pos/claude_code_demo_full/.claude/commands/ticket.md +10 -0
  38. package/fixtures/pos/claude_code_demo_full/.claude/hooks/skill-eval.js +13 -0
  39. package/fixtures/pos/claude_code_demo_full/.claude/hooks/skill-eval.sh +15 -0
  40. package/fixtures/pos/claude_code_demo_full/.claude/hooks/skill-rules.json +21 -0
  41. package/fixtures/pos/claude_code_demo_full/.claude/hooks/skill-rules.schema.json +24 -0
  42. package/fixtures/pos/claude_code_demo_full/.claude/rules/code-style.md +5 -0
  43. package/fixtures/pos/claude_code_demo_full/.claude/rules/security.md +5 -0
  44. package/fixtures/pos/claude_code_demo_full/.claude/settings.json +102 -0
  45. package/fixtures/pos/claude_code_demo_full/.claude/settings.md +6 -0
  46. package/fixtures/pos/claude_code_demo_full/.claude/skills/core-components/SKILL.md +9 -0
  47. package/fixtures/pos/claude_code_demo_full/.claude/skills/formik-patterns/SKILL.md +9 -0
  48. package/fixtures/pos/claude_code_demo_full/.claude/skills/graphql-schema/SKILL.md +10 -0
  49. package/fixtures/pos/claude_code_demo_full/.claude/skills/react-ui-patterns/SKILL.md +10 -0
  50. package/fixtures/pos/claude_code_demo_full/.claude/skills/systematic-debugging/SKILL.md +9 -0
  51. package/fixtures/pos/claude_code_demo_full/.claude/skills/testing-patterns/SKILL.md +10 -0
  52. package/fixtures/pos/claude_code_demo_full/.github/workflows/pr-claude-code-review.yml +14 -0
  53. package/fixtures/pos/claude_code_demo_full/.github/workflows/scheduled-claude-code-dependency-audit.yml +14 -0
  54. package/fixtures/pos/claude_code_demo_full/.github/workflows/scheduled-claude-code-docs-sync.yml +14 -0
  55. package/fixtures/pos/claude_code_demo_full/.github/workflows/scheduled-claude-code-quality.yml +14 -0
  56. package/fixtures/pos/claude_code_demo_full/.mcp.json +44 -0
  57. package/fixtures/pos/claude_code_demo_full/CLAUDE.md +28 -0
  58. package/fixtures/pos/control_basic_project/mova/control_v0.json +93 -0
  59. package/fixtures/pos/observability_basic/CLAUDE.md +3 -0
  60. package/{.tmp_test_zip/out1 → fixtures/pos/preset_safe_observable_v0}/.mcp.json +3 -3
  61. package/fixtures/pos/preset_safe_observable_v0/CLAUDE.md +3 -0
  62. package/package.json +2 -1
  63. package/presets/safe_observable_v0/assets/.claude/agents/code-reviewer.md +9 -0
  64. package/presets/safe_observable_v0/assets/.claude/commands/finish.md +9 -0
  65. package/presets/safe_observable_v0/assets/.claude/commands/start.md +9 -0
  66. package/presets/safe_observable_v0/assets/.claude/hooks/skill-eval.js +15 -0
  67. package/presets/safe_observable_v0/assets/.claude/hooks/skill-eval.sh +17 -0
  68. package/presets/safe_observable_v0/assets/.claude/hooks/skill-rules.json +26 -0
  69. package/presets/safe_observable_v0/assets/.claude/rules/code-style.md +6 -0
  70. package/presets/safe_observable_v0/assets/.claude/rules/security.md +6 -0
  71. package/presets/safe_observable_v0/assets/.claude/skills/git-workflow/SKILL.md +9 -0
  72. package/presets/safe_observable_v0/assets/.claude/skills/security-basics/SKILL.md +9 -0
  73. package/presets/safe_observable_v0/assets/.claude/skills/systematic-debugging/SKILL.md +9 -0
  74. package/presets/safe_observable_v0/assets/.claude/skills/testing-patterns/SKILL.md +9 -0
  75. package/presets/safe_observable_v0/control_v0.json +214 -0
  76. package/schemas/mova.control_v0.schema.json +252 -0
  77. package/src/anthropic_profile_v0.ts +1 -0
  78. package/src/cli.ts +194 -23
  79. package/src/control_apply_v0.ts +131 -8
  80. package/src/control_check_v0.ts +203 -23
  81. package/src/control_prefill_v0.ts +136 -8
  82. package/src/control_surface_coverage_v0.ts +164 -0
  83. package/src/control_v0.ts +808 -0
  84. package/src/control_v0_schema.ts +26 -0
  85. package/src/init_v0.ts +48 -1
  86. package/src/observability_writer_v0.ts +157 -0
  87. package/src/observe_v0.ts +64 -0
  88. package/src/presets_v0.ts +55 -0
  89. package/src/redaction.ts +6 -1
  90. package/src/run_import.ts +132 -26
  91. package/test/control_demo_full_roundtrip.test.js +92 -0
  92. package/test/control_surface_coverage_v0.test.js +36 -0
  93. package/test/control_v0_schema_validation.test.js +69 -0
  94. package/test/init_v0.test.js +9 -0
  95. package/test/observability_writer_v0.test.js +59 -0
  96. package/test/preset_safe_observable_v0.test.js +55 -0
  97. package/test/profile_v0_output.test.js +1 -0
  98. package/test/scaffold_v0_output.test.js +1 -0
  99. package/tools/control_surface_coverage_v0.mjs +27 -0
  100. package/tools/smoke_v0.mjs +33 -0
  101. package/.tmp_test_control_apply/proj/.claude/agents/example_agent.md +0 -3
  102. package/.tmp_test_control_apply/proj/.claude/commands/example_command.md +0 -3
  103. package/.tmp_test_control_apply/proj/.claude/hooks/example_hook.sh +0 -2
  104. package/.tmp_test_control_apply/proj/.claude/output-styles/example_style.md +0 -3
  105. package/.tmp_test_control_apply/proj/.claude/settings.json +0 -30
  106. package/.tmp_test_control_apply/proj/.claude/settings.local.example.json +0 -3
  107. package/.tmp_test_control_apply/proj/.mcp.json +0 -3
  108. package/.tmp_test_control_apply/proj/CLAUDE.md +0 -13
  109. package/.tmp_test_control_apply/proj/MOVA.md +0 -3
  110. package/.tmp_test_control_check/proj/.mcp.json +0 -1
  111. package/.tmp_test_control_check/proj/CLAUDE.md +0 -1
  112. package/.tmp_test_control_prefill/out1/claude_control_profile_v0.json +0 -114
  113. package/.tmp_test_control_prefill/out1/prefill_report_v0.json +0 -13
  114. package/.tmp_test_control_prefill/out2/claude_control_profile_v0.json +0 -114
  115. package/.tmp_test_control_prefill/out2/prefill_report_v0.json +0 -13
  116. package/.tmp_test_overlay/proj/.claude/skills/a.md +0 -1
  117. package/.tmp_test_overlay/proj/.mcp.json +0 -1
  118. package/.tmp_test_overlay/proj/CLAUDE.md +0 -1
  119. package/.tmp_test_profile/proj/.claude/skills/a.md +0 -1
  120. package/.tmp_test_profile/proj/.mcp.json +0 -1
  121. package/.tmp_test_profile/proj/CLAUDE.md +0 -1
  122. package/.tmp_test_scaffold_apply/proj/.claude/agents/example_agent.md +0 -3
  123. package/.tmp_test_scaffold_apply/proj/.claude/commands/example_command.md +0 -3
  124. package/.tmp_test_scaffold_apply/proj/.claude/hooks/example_hook.sh +0 -2
  125. package/.tmp_test_scaffold_apply/proj/.claude/output-styles/example_style.md +0 -3
  126. package/.tmp_test_scaffold_apply/proj/.claude/settings.json +0 -30
  127. package/.tmp_test_scaffold_apply/proj/.claude/settings.local.example.json +0 -3
  128. package/.tmp_test_scaffold_apply/proj/.mcp.json +0 -3
  129. package/.tmp_test_scaffold_apply/proj/CLAUDE.md +0 -13
  130. package/.tmp_test_scaffold_apply/proj/MOVA.md +0 -3
  131. package/.tmp_test_strict/mova/claude_import/v0/VERSION.json +0 -10
  132. package/.tmp_test_strict/mova/claude_import/v0/episode_import_run.json +0 -20
  133. package/.tmp_test_strict/mova/claude_import/v0/import_manifest.json +0 -20
  134. package/.tmp_test_strict/mova/claude_import/v0/input_policy_report_v0.json +0 -32
  135. package/.tmp_test_zip/out1/.claude/agents/example_agent.md +0 -3
  136. package/.tmp_test_zip/out1/.claude/commands/example_command.md +0 -3
  137. package/.tmp_test_zip/out1/.claude/commands/mova_context.md +0 -4
  138. package/.tmp_test_zip/out1/.claude/commands/mova_lint.md +0 -4
  139. package/.tmp_test_zip/out1/.claude/commands/mova_proof.md +0 -6
  140. package/.tmp_test_zip/out1/.claude/hooks/example_hook.sh +0 -2
  141. package/.tmp_test_zip/out1/.claude/output-styles/example_style.md +0 -3
  142. package/.tmp_test_zip/out1/.claude/settings.json +0 -30
  143. package/.tmp_test_zip/out1/.claude/settings.local.example.json +0 -3
  144. package/.tmp_test_zip/out1/.claude/skills/a/SKILL.md +0 -1
  145. package/.tmp_test_zip/out1/.claude/skills/mova-control-v0/SKILL.md +0 -11
  146. package/.tmp_test_zip/out1/.claude/skills/mova-layer-v0/SKILL.md +0 -8
  147. package/.tmp_test_zip/out1/CLAUDE.md +0 -4
  148. package/.tmp_test_zip/out1/MOVA.md +0 -10
  149. package/.tmp_test_zip/out1/export.zip +0 -0
  150. package/.tmp_test_zip/out1/mova/claude_import/v0/VERSION.json +0 -10
  151. package/.tmp_test_zip/out1/mova/claude_import/v0/contracts/instruction_profile_v0.json +0 -8
  152. package/.tmp_test_zip/out1/mova/claude_import/v0/contracts/mcp_servers_v0.json +0 -4
  153. package/.tmp_test_zip/out1/mova/claude_import/v0/contracts/skills_catalog_v0.json +0 -11
  154. package/.tmp_test_zip/out1/mova/claude_import/v0/episode_import_run.json +0 -80
  155. package/.tmp_test_zip/out1/mova/claude_import/v0/export_manifest_v0.json +0 -32
  156. package/.tmp_test_zip/out1/mova/claude_import/v0/import_manifest.json +0 -33
  157. package/.tmp_test_zip/out1/mova/claude_import/v0/input_policy_report_v0.json +0 -38
  158. package/.tmp_test_zip/out1/mova/claude_import/v0/lint_report_v0.json +0 -6
  159. package/.tmp_test_zip/out1/mova/claude_import/v0/redaction_report.json +0 -4
  160. package/.tmp_test_zip/out2/.claude/agents/example_agent.md +0 -3
  161. package/.tmp_test_zip/out2/.claude/commands/example_command.md +0 -3
  162. package/.tmp_test_zip/out2/.claude/commands/mova_context.md +0 -4
  163. package/.tmp_test_zip/out2/.claude/commands/mova_lint.md +0 -4
  164. package/.tmp_test_zip/out2/.claude/commands/mova_proof.md +0 -6
  165. package/.tmp_test_zip/out2/.claude/hooks/example_hook.sh +0 -2
  166. package/.tmp_test_zip/out2/.claude/output-styles/example_style.md +0 -3
  167. package/.tmp_test_zip/out2/.claude/settings.json +0 -30
  168. package/.tmp_test_zip/out2/.claude/settings.local.example.json +0 -3
  169. package/.tmp_test_zip/out2/.claude/skills/a/SKILL.md +0 -1
  170. package/.tmp_test_zip/out2/.claude/skills/mova-control-v0/SKILL.md +0 -11
  171. package/.tmp_test_zip/out2/.claude/skills/mova-layer-v0/SKILL.md +0 -8
  172. package/.tmp_test_zip/out2/.mcp.json +0 -3
  173. package/.tmp_test_zip/out2/CLAUDE.md +0 -4
  174. package/.tmp_test_zip/out2/MOVA.md +0 -10
  175. package/.tmp_test_zip/out2/export.zip +0 -0
  176. package/.tmp_test_zip/out2/mova/claude_import/v0/VERSION.json +0 -10
  177. package/.tmp_test_zip/out2/mova/claude_import/v0/contracts/instruction_profile_v0.json +0 -8
  178. package/.tmp_test_zip/out2/mova/claude_import/v0/contracts/mcp_servers_v0.json +0 -4
  179. package/.tmp_test_zip/out2/mova/claude_import/v0/contracts/skills_catalog_v0.json +0 -11
  180. package/.tmp_test_zip/out2/mova/claude_import/v0/episode_import_run.json +0 -80
  181. package/.tmp_test_zip/out2/mova/claude_import/v0/export_manifest_v0.json +0 -32
  182. package/.tmp_test_zip/out2/mova/claude_import/v0/import_manifest.json +0 -33
  183. package/.tmp_test_zip/out2/mova/claude_import/v0/input_policy_report_v0.json +0 -38
  184. package/.tmp_test_zip/out2/mova/claude_import/v0/lint_report_v0.json +0 -6
  185. package/.tmp_test_zip/out2/mova/claude_import/v0/redaction_report.json +0 -4
  186. package/.tmp_test_zip/proj/.claude/skills/a.md +0 -1
  187. package/.tmp_test_zip/proj/.mcp.json +0 -1
  188. package/.tmp_test_zip/proj/CLAUDE.md +0 -1
@@ -0,0 +1,252 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://mova.dev/schemas/mova.control_v0.schema.json",
4
+ "type": "object",
5
+ "required": ["version", "claude_md", "overlay", "settings", "mcp", "policy", "assets", "observability"],
6
+ "additionalProperties": false,
7
+ "properties": {
8
+ "$schema": {
9
+ "type": "string"
10
+ },
11
+ "version": {
12
+ "type": "string",
13
+ "const": "control_v0"
14
+ },
15
+ "claude_md": {
16
+ "type": "object",
17
+ "required": ["inject_control_entry", "marker", "priority_sources"],
18
+ "additionalProperties": false,
19
+ "properties": {
20
+ "inject_control_entry": { "type": "boolean" },
21
+ "marker": { "type": "string" },
22
+ "priority_sources": {
23
+ "type": "array",
24
+ "items": { "type": "string" }
25
+ }
26
+ }
27
+ },
28
+ "claude_memory": {
29
+ "type": "object",
30
+ "required": ["enable", "sources"],
31
+ "additionalProperties": false,
32
+ "properties": {
33
+ "enable": { "type": "boolean" },
34
+ "sources": {
35
+ "type": "array",
36
+ "items": { "type": "string" }
37
+ }
38
+ }
39
+ },
40
+ "overlay": {
41
+ "type": "object",
42
+ "required": ["enable"],
43
+ "additionalProperties": false,
44
+ "properties": {
45
+ "enable": { "type": "boolean" }
46
+ }
47
+ },
48
+ "settings": {
49
+ "type": "object",
50
+ "required": ["include_co_authored_by", "env"],
51
+ "additionalProperties": false,
52
+ "properties": {
53
+ "include_co_authored_by": { "type": "boolean" },
54
+ "env": {
55
+ "type": "object",
56
+ "additionalProperties": { "type": "string" }
57
+ }
58
+ }
59
+ },
60
+ "mcp": {
61
+ "type": "object",
62
+ "required": [
63
+ "servers",
64
+ "enable_all_project_mcp_servers",
65
+ "enabled_mcpjson_servers",
66
+ "env_substitutions"
67
+ ],
68
+ "additionalProperties": false,
69
+ "properties": {
70
+ "servers": {
71
+ "anyOf": [
72
+ {
73
+ "type": "array"
74
+ },
75
+ {
76
+ "type": "object"
77
+ }
78
+ ]
79
+ },
80
+ "enable_all_project_mcp_servers": { "type": "boolean" },
81
+ "enabled_mcpjson_servers": {
82
+ "type": "array",
83
+ "items": { "type": "string" }
84
+ },
85
+ "env_substitutions": {
86
+ "type": "object",
87
+ "required": ["format", "default_format"],
88
+ "additionalProperties": false,
89
+ "properties": {
90
+ "format": { "type": "string" },
91
+ "default_format": { "type": "string" }
92
+ }
93
+ }
94
+ }
95
+ },
96
+ "policy": {
97
+ "type": "object",
98
+ "required": ["mode", "hooks", "permissions", "plugins"],
99
+ "additionalProperties": false,
100
+ "properties": {
101
+ "mode": { "type": "string" },
102
+ "hooks": {
103
+ "type": "object",
104
+ "required": ["enable", "on_invalid_hook", "definitions", "events"],
105
+ "additionalProperties": false,
106
+ "properties": {
107
+ "enable": { "type": "boolean" },
108
+ "on_invalid_hook": { "type": "string" },
109
+ "definitions": { "type": "array" },
110
+ "events": {
111
+ "type": "object",
112
+ "additionalProperties": true
113
+ }
114
+ }
115
+ },
116
+ "permissions": {
117
+ "type": "object",
118
+ "required": ["allow", "deny", "on_conflict", "on_unknown"],
119
+ "additionalProperties": false,
120
+ "properties": {
121
+ "allow": { "type": "array" },
122
+ "deny": { "type": "array" },
123
+ "on_conflict": { "type": "string" },
124
+ "on_unknown": { "type": "string" }
125
+ }
126
+ },
127
+ "plugins": {
128
+ "type": "object",
129
+ "required": ["enable", "allowed_plugin_ids", "denied_plugin_ids", "on_unknown", "enabled_plugins"],
130
+ "additionalProperties": false,
131
+ "properties": {
132
+ "enable": { "type": "boolean" },
133
+ "allowed_plugin_ids": { "type": "array" },
134
+ "denied_plugin_ids": { "type": "array" },
135
+ "on_unknown": { "type": "string" },
136
+ "enabled_plugins": {
137
+ "type": "object",
138
+ "additionalProperties": { "type": "boolean" }
139
+ }
140
+ }
141
+ }
142
+ }
143
+ },
144
+ "lsp": {
145
+ "type": "object",
146
+ "required": ["enabled_plugins", "config_path", "managed"],
147
+ "additionalProperties": false,
148
+ "properties": {
149
+ "enabled_plugins": {
150
+ "type": "array",
151
+ "items": { "type": "string" }
152
+ },
153
+ "config_path": { "type": "string" },
154
+ "managed": { "type": "boolean" }
155
+ }
156
+ },
157
+ "skill_eval": {
158
+ "type": "object",
159
+ "required": ["enable", "hooks", "rules_path", "scoring"],
160
+ "additionalProperties": false,
161
+ "properties": {
162
+ "enable": { "type": "boolean" },
163
+ "hooks": {
164
+ "type": "object",
165
+ "required": ["shell", "node"],
166
+ "additionalProperties": false,
167
+ "properties": {
168
+ "shell": { "type": "string" },
169
+ "node": { "type": "string" }
170
+ }
171
+ },
172
+ "rules_path": { "type": "string" },
173
+ "scoring": {
174
+ "type": "object",
175
+ "required": ["threshold"],
176
+ "additionalProperties": false,
177
+ "properties": {
178
+ "threshold": { "type": "number" }
179
+ }
180
+ }
181
+ }
182
+ },
183
+ "observability": {
184
+ "type": "object",
185
+ "required": [
186
+ "enable",
187
+ "mode",
188
+ "writer",
189
+ "output_dir",
190
+ "stdout_tail_bytes",
191
+ "stderr_tail_bytes",
192
+ "max_event_bytes",
193
+ "tail_lines",
194
+ "include_tools",
195
+ "include_events"
196
+ ],
197
+ "additionalProperties": false,
198
+ "properties": {
199
+ "enable": { "type": "boolean" },
200
+ "mode": { "type": "string" },
201
+ "writer": {
202
+ "type": "object",
203
+ "required": ["type", "script_path"],
204
+ "additionalProperties": false,
205
+ "properties": {
206
+ "type": { "type": "string", "const": "node" },
207
+ "script_path": { "type": "string" }
208
+ }
209
+ },
210
+ "output_dir": { "type": "string" },
211
+ "stdout_tail_bytes": { "type": "number" },
212
+ "stderr_tail_bytes": { "type": "number" },
213
+ "max_event_bytes": { "type": "number" },
214
+ "tail_lines": { "type": "number" },
215
+ "include_tools": { "type": "array", "items": { "type": "string" } },
216
+ "include_events": { "type": "array", "items": { "type": "string" } }
217
+ }
218
+ },
219
+ "assets": {
220
+ "type": "object",
221
+ "required": ["skills", "agents", "commands", "rules", "hooks", "workflows", "docs", "dotfiles", "schemas"],
222
+ "additionalProperties": false,
223
+ "properties": {
224
+ "skills": { "$ref": "#/$defs/asset_list" },
225
+ "agents": { "$ref": "#/$defs/asset_list" },
226
+ "commands": { "$ref": "#/$defs/asset_list" },
227
+ "rules": { "$ref": "#/$defs/asset_list" },
228
+ "hooks": { "$ref": "#/$defs/asset_list" },
229
+ "workflows": { "$ref": "#/$defs/asset_list" },
230
+ "docs": { "$ref": "#/$defs/asset_list" },
231
+ "dotfiles": { "$ref": "#/$defs/asset_list" },
232
+ "schemas": { "$ref": "#/$defs/asset_list" }
233
+ }
234
+ }
235
+ },
236
+ "$defs": {
237
+ "asset_list": {
238
+ "type": "array",
239
+ "items": { "$ref": "#/$defs/asset_item" }
240
+ },
241
+ "asset_item": {
242
+ "type": "object",
243
+ "required": ["path", "mode"],
244
+ "additionalProperties": false,
245
+ "properties": {
246
+ "path": { "type": "string" },
247
+ "mode": { "type": "string", "enum": ["copy_through", "managed"] },
248
+ "source_path": { "type": "string" }
249
+ }
250
+ }
251
+ }
252
+ }
@@ -7,6 +7,7 @@ export const anthropicProfileV0RequiredFiles = [
7
7
  ".claude/commands/mova_context.md",
8
8
  ".claude/commands/mova_lint.md",
9
9
  ".claude/skills/mova-layer-v0/SKILL.md",
10
+ "mova/control_v0.json",
10
11
  ] as const;
11
12
 
12
13
  export function getAnthropicProfileV0Files(): Record<string, string> {
package/src/cli.ts CHANGED
@@ -3,6 +3,8 @@ import { initProfileV0 } from "./init_v0.js";
3
3
  import { controlPrefillV0 } from "./control_prefill_v0.js";
4
4
  import { controlCheckV0 } from "./control_check_v0.js";
5
5
  import { controlApplyV0 } from "./control_apply_v0.js";
6
+ import { listObservabilityRuns, readObservabilitySummary, tailObservabilityEvents } from "./observe_v0.js";
7
+ import { listPresets, readPresetControlRaw, resolvePreset } from "./presets_v0.js";
6
8
 
7
9
  function getArg(name: string): string | undefined {
8
10
  const idx = process.argv.indexOf(name);
@@ -18,10 +20,15 @@ function usage(exitCode = 0) {
18
20
  "",
19
21
  "Usage:",
20
22
  " mova-claude-import --project <dir> [--out <dir>] [--dry-run] [--strict] [--include-local] [--include-user-settings] [--no-emit-profile] [--no-emit-overlay] [--zip] [--zip-name <name>]",
21
- " mova-claude-import init --out <dir> [--zip]",
23
+ " mova-claude-import init --out <dir> [--zip] [--preset <name>]",
22
24
  " mova-claude-import control prefill --project <dir> --out <dir> [--include-local]",
23
25
  " mova-claude-import control check --project <dir> --profile <file>",
24
- " mova-claude-import control apply --project <dir> --profile <file> [--mode preview|apply]",
26
+ " mova-claude-import control apply --project <dir> --profile <file> [--mode preview|apply|overlay] [--preset <name>]",
27
+ " mova-claude-import preset list",
28
+ " mova-claude-import preset show <name>",
29
+ " mova-claude-import observe list --project <dir>",
30
+ " mova-claude-import observe tail --project <dir> --run <id> [--limit <n>]",
31
+ " mova-claude-import observe summary --project <dir> --run <id>",
25
32
  "",
26
33
  "Notes:",
27
34
  " - CLAUDE.local.md and *.local.* are excluded unless --include-local",
@@ -30,6 +37,7 @@ function usage(exitCode = 0) {
30
37
  " - overlay emission is enabled by default; use --no-emit-overlay to skip",
31
38
  " - zip export is disabled by default; use --zip to enable",
32
39
  " - init creates a clean Anthropic profile v0 scaffold",
40
+ " - init --preset uses preset control_v0.json + assets",
33
41
  " - control commands run in preview by default",
34
42
  ].join("\n"));
35
43
  process.exit(exitCode);
@@ -49,15 +57,41 @@ if (subcommand === "init") {
49
57
  process.exit(2);
50
58
  }
51
59
  const emitZip = hasFlag("--zip");
52
- initProfileV0(out, emitZip)
53
- .then((res) => {
54
- process.stdout.write(JSON.stringify(res, null, 2) + "\n");
55
- process.exit(0);
56
- })
57
- .catch((err) => {
58
- console.error(err);
59
- process.exit(1);
60
- });
60
+ const presetName = getArg("--preset");
61
+ if (presetName) {
62
+ resolvePreset(presetName)
63
+ .then(async (preset) => {
64
+ if (!preset) {
65
+ console.error(`Preset not found: ${presetName}`);
66
+ process.exit(2);
67
+ }
68
+ const raw = await readPresetControlRaw(presetName);
69
+ const control = raw ? JSON.parse(raw) : null;
70
+ if (!control) {
71
+ console.error(`Preset control missing: ${presetName}`);
72
+ process.exit(2);
73
+ }
74
+ return initProfileV0(out, emitZip, { controlOverride: control, assetsRoot: preset.assets_root });
75
+ })
76
+ .then((res) => {
77
+ process.stdout.write(JSON.stringify(res, null, 2) + "\n");
78
+ process.exit(0);
79
+ })
80
+ .catch((err) => {
81
+ console.error(err);
82
+ process.exit(1);
83
+ });
84
+ } else {
85
+ initProfileV0(out, emitZip)
86
+ .then((res) => {
87
+ process.stdout.write(JSON.stringify(res, null, 2) + "\n");
88
+ process.exit(0);
89
+ })
90
+ .catch((err) => {
91
+ console.error(err);
92
+ process.exit(1);
93
+ });
94
+ }
61
95
  } else if (subcommand === "control") {
62
96
  const action = process.argv[3];
63
97
  const project = getArg("--project");
@@ -94,10 +128,12 @@ if (subcommand === "init") {
94
128
  controlCheckV0(project, profile, out)
95
129
  .then((res) => {
96
130
  console.log([
97
- "control check: ok",
131
+ res.exit_code && res.exit_code !== 0 ? "control check: issues" : "control check: ok",
98
132
  `plan: ${res.plan_path}`,
99
133
  `summary: ${res.summary_path}`,
100
- ].join("\n"));
134
+ res.exit_code ? `exit_code: ${res.exit_code}` : null,
135
+ ].filter(Boolean).join("\n"));
136
+ if (typeof res.exit_code === "number") process.exit(res.exit_code);
101
137
  process.exit(0);
102
138
  })
103
139
  .catch((err) => {
@@ -105,19 +141,154 @@ if (subcommand === "init") {
105
141
  process.exit(1);
106
142
  });
107
143
  } else if (action === "apply") {
108
- const profile = getArg("--profile");
109
- if (!profile) {
144
+ const out = getArg("--out") || project;
145
+ const mode = getArg("--mode");
146
+ const presetName = getArg("--preset");
147
+ if (presetName) {
148
+ resolvePreset(presetName)
149
+ .then(async (preset) => {
150
+ if (!preset) {
151
+ console.error(`Preset not found: ${presetName}`);
152
+ process.exit(2);
153
+ }
154
+ return controlApplyV0(project, preset.control_path, out, mode, {
155
+ assetSourceRoot: preset.assets_root,
156
+ });
157
+ })
158
+ .then((res) => {
159
+ console.log([
160
+ res.exit_code && res.exit_code !== 0 ? "control apply: issues" : "control apply: ok",
161
+ `report: ${res.report_path}`,
162
+ res.exit_code ? `exit_code: ${res.exit_code}` : null,
163
+ ].filter(Boolean).join("\n"));
164
+ if (typeof res.exit_code === "number") process.exit(res.exit_code);
165
+ process.exit(0);
166
+ })
167
+ .catch((err) => {
168
+ console.error(err);
169
+ process.exit(1);
170
+ });
171
+ } else {
172
+ const profile = getArg("--profile");
173
+ if (!profile) {
174
+ usage(2);
175
+ process.exit(2);
176
+ }
177
+ controlApplyV0(project, profile, out, mode)
178
+ .then((res) => {
179
+ console.log([
180
+ res.exit_code && res.exit_code !== 0 ? "control apply: issues" : "control apply: ok",
181
+ `report: ${res.report_path}`,
182
+ res.exit_code ? `exit_code: ${res.exit_code}` : null,
183
+ ].filter(Boolean).join("\n"));
184
+ if (typeof res.exit_code === "number") process.exit(res.exit_code);
185
+ process.exit(0);
186
+ })
187
+ .catch((err) => {
188
+ console.error(err);
189
+ process.exit(1);
190
+ });
191
+ }
192
+ } else {
193
+ usage(2);
194
+ process.exit(2);
195
+ }
196
+ } else if (subcommand === "preset") {
197
+ const action = process.argv[3];
198
+ if (action === "list") {
199
+ listPresets()
200
+ .then((presets) => {
201
+ for (const name of presets) {
202
+ console.log(name);
203
+ }
204
+ process.exit(0);
205
+ })
206
+ .catch((err) => {
207
+ console.error(err);
208
+ process.exit(1);
209
+ });
210
+ } else if (action === "show") {
211
+ const name = process.argv[4];
212
+ if (!name) {
110
213
  usage(2);
111
214
  process.exit(2);
112
215
  }
113
- const out = getArg("--out") || project;
114
- const mode = getArg("--mode");
115
- controlApplyV0(project, profile, out, mode)
116
- .then((res) => {
117
- console.log([
118
- "control apply: ok",
119
- `report: ${res.report_path}`,
120
- ].join("\n"));
216
+ readPresetControlRaw(name)
217
+ .then((raw) => {
218
+ if (!raw) {
219
+ console.error(`Preset not found: ${name}`);
220
+ process.exit(2);
221
+ }
222
+ process.stdout.write(raw + "\n");
223
+ process.exit(0);
224
+ })
225
+ .catch((err) => {
226
+ console.error(err);
227
+ process.exit(1);
228
+ });
229
+ } else {
230
+ usage(2);
231
+ process.exit(2);
232
+ }
233
+ } else if (subcommand === "observe") {
234
+ const action = process.argv[3];
235
+ const project = getArg("--project");
236
+ if (!project) {
237
+ usage(2);
238
+ process.exit(2);
239
+ }
240
+ if (action === "list") {
241
+ listObservabilityRuns(project)
242
+ .then((runs) => {
243
+ if (!runs.length) {
244
+ console.log("observe list: no runs");
245
+ process.exit(0);
246
+ }
247
+ for (const run of runs) {
248
+ console.log(JSON.stringify(run));
249
+ }
250
+ process.exit(0);
251
+ })
252
+ .catch((err) => {
253
+ console.error(err);
254
+ process.exit(1);
255
+ });
256
+ } else if (action === "tail") {
257
+ const runId = getArg("--run");
258
+ if (!runId) {
259
+ usage(2);
260
+ process.exit(2);
261
+ }
262
+ const limitRaw = getArg("--limit");
263
+ const limit = limitRaw ? Number(limitRaw) : 20;
264
+ tailObservabilityEvents(project, runId, Number.isFinite(limit) ? limit : 20)
265
+ .then((lines) => {
266
+ if (!lines.length) {
267
+ console.log("observe tail: no events");
268
+ process.exit(0);
269
+ }
270
+ for (const line of lines) {
271
+ console.log(line);
272
+ }
273
+ process.exit(0);
274
+ })
275
+ .catch((err) => {
276
+ console.error(err);
277
+ process.exit(1);
278
+ });
279
+ } else if (action === "summary") {
280
+ const runId = getArg("--run");
281
+ if (!runId) {
282
+ usage(2);
283
+ process.exit(2);
284
+ }
285
+ readObservabilitySummary(project, runId)
286
+ .then((summary) => {
287
+ if (!summary) {
288
+ console.log("observe summary: not found");
289
+ process.exit(0);
290
+ }
291
+ process.stdout.write(JSON.stringify(summary, null, 2) + "\n");
121
292
  process.exit(0);
122
293
  })
123
294
  .catch((err) => {