@moda-ai/cli 1.22.1 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/dist/cli-c4se7a5d.js +762 -0
  2. package/dist/cli-mnqa4rp6.js +1563 -0
  3. package/dist/cli-stmjdgvy.js +2842 -0
  4. package/dist/cli-y55bgg14.js +6980 -0
  5. package/dist/cli-ysegdrm5.js +286 -0
  6. package/dist/cli.js +4779 -1159
  7. package/dist/harness-github-actions-7t3cncnt.js +95 -0
  8. package/dist/index-4ser01zr.js +2769 -0
  9. package/dist/provision-hm1ppwj6.js +74 -0
  10. package/package.json +3 -2
  11. package/skills/integration/index.json +2 -2
  12. package/dist/agent-schemas.d.ts +0 -3
  13. package/dist/agent-schemas.js +0 -358
  14. package/dist/agent.d.ts +0 -5
  15. package/dist/agent.js +0 -477
  16. package/dist/analyst-tui.d.ts +0 -81
  17. package/dist/analyst-tui.js +0 -314
  18. package/dist/api-client.d.ts +0 -46
  19. package/dist/api-client.js +0 -120
  20. package/dist/ask-stream.d.ts +0 -146
  21. package/dist/ask-stream.js +0 -473
  22. package/dist/auth-storage.d.ts +0 -35
  23. package/dist/auth-storage.js +0 -159
  24. package/dist/auth.d.ts +0 -50
  25. package/dist/auth.js +0 -694
  26. package/dist/cli-session.d.ts +0 -26
  27. package/dist/cli-session.js +0 -169
  28. package/dist/cli.d.ts +0 -44
  29. package/dist/command-context.d.ts +0 -62
  30. package/dist/command-context.js +0 -57
  31. package/dist/command-registry.d.ts +0 -22
  32. package/dist/command-registry.js +0 -15
  33. package/dist/config.d.ts +0 -60
  34. package/dist/config.js +0 -110
  35. package/dist/doctor.d.ts +0 -79
  36. package/dist/doctor.js +0 -1182
  37. package/dist/errors.d.ts +0 -50
  38. package/dist/errors.js +0 -64
  39. package/dist/exit-funnel.d.ts +0 -14
  40. package/dist/exit-funnel.js +0 -53
  41. package/dist/harness-artifact-bodies.d.ts +0 -28
  42. package/dist/harness-artifact-bodies.js +0 -276
  43. package/dist/harness-candidates.d.ts +0 -77
  44. package/dist/harness-candidates.js +0 -482
  45. package/dist/harness-remote.d.ts +0 -135
  46. package/dist/harness-remote.js +0 -540
  47. package/dist/harness-report.d.ts +0 -145
  48. package/dist/harness-report.js +0 -1579
  49. package/dist/harness-sync-limits.d.ts +0 -8
  50. package/dist/harness-sync-limits.js +0 -21
  51. package/dist/harness.d.ts +0 -463
  52. package/dist/harness.js +0 -4009
  53. package/dist/init/index.d.ts +0 -78
  54. package/dist/init/index.js +0 -1442
  55. package/dist/init/mcp.d.ts +0 -2
  56. package/dist/init/mcp.js +0 -27
  57. package/dist/init/progress-board.d.ts +0 -80
  58. package/dist/init/progress-board.js +0 -225
  59. package/dist/init/rules.d.ts +0 -6
  60. package/dist/init/rules.js +0 -171
  61. package/dist/init/sdk-catalog.d.ts +0 -10
  62. package/dist/init/sdk-catalog.js +0 -80
  63. package/dist/init/sdk-guide.d.ts +0 -19
  64. package/dist/init/sdk-guide.js +0 -185
  65. package/dist/init/sdk-integration.d.ts +0 -53
  66. package/dist/init/sdk-integration.js +0 -835
  67. package/dist/init/sdk-protocol.d.ts +0 -135
  68. package/dist/init/sdk-protocol.js +0 -152
  69. package/dist/init/sdk-verification.d.ts +0 -27
  70. package/dist/init/sdk-verification.js +0 -123
  71. package/dist/init/tenant.d.ts +0 -67
  72. package/dist/init/tenant.js +0 -421
  73. package/dist/intelligence-schema.d.ts +0 -349
  74. package/dist/intelligence-schema.js +0 -174
  75. package/dist/keys.d.ts +0 -47
  76. package/dist/keys.js +0 -136
  77. package/dist/manifest.d.ts +0 -5
  78. package/dist/manifest.js +0 -114
  79. package/dist/markdown-terminal.d.ts +0 -49
  80. package/dist/markdown-terminal.js +0 -212
  81. package/dist/output.d.ts +0 -191
  82. package/dist/output.js +0 -624
  83. package/dist/production-intelligence.d.ts +0 -175
  84. package/dist/production-intelligence.js +0 -1430
  85. package/dist/profile-commands.d.ts +0 -10
  86. package/dist/profile-commands.js +0 -342
  87. package/dist/profiles.d.ts +0 -112
  88. package/dist/profiles.js +0 -573
  89. package/dist/prompts-ab.d.ts +0 -71
  90. package/dist/prompts-ab.js +0 -313
  91. package/dist/prompts-propose.d.ts +0 -15
  92. package/dist/prompts-propose.js +0 -212
  93. package/dist/prompts.d.ts +0 -58
  94. package/dist/prompts.js +0 -418
  95. package/dist/provision.d.ts +0 -28
  96. package/dist/provision.js +0 -104
  97. package/dist/redact.d.ts +0 -2
  98. package/dist/redact.js +0 -90
  99. package/dist/schemas.d.ts +0 -225
  100. package/dist/schemas.js +0 -126
  101. package/dist/skills-bundled.d.ts +0 -35
  102. package/dist/skills-bundled.js +0 -157
  103. package/dist/skills-manifest.d.ts +0 -33
  104. package/dist/skills-manifest.js +0 -244
  105. package/dist/skills.d.ts +0 -57
  106. package/dist/skills.js +0 -783
  107. package/dist/sync.d.ts +0 -5
  108. package/dist/sync.js +0 -36
  109. package/dist/telemetry.d.ts +0 -56
  110. package/dist/telemetry.js +0 -167
  111. package/dist/transforms.d.ts +0 -25
  112. package/dist/transforms.js +0 -102
  113. package/dist/tui.d.ts +0 -48
  114. package/dist/tui.js +0 -393
  115. package/dist/update-check.d.ts +0 -31
  116. package/dist/update-check.js +0 -141
  117. package/dist/workspace.d.ts +0 -12
  118. package/dist/workspace.js +0 -1294
package/dist/schemas.d.ts DELETED
@@ -1,225 +0,0 @@
1
- import { z } from 'zod';
2
- export declare const OverviewSchema: z.ZodObject<{
3
- days_back: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
4
- }, "strip", z.ZodTypeAny, {
5
- days_back?: number | undefined;
6
- }, {
7
- days_back?: number | undefined;
8
- }>;
9
- export declare const ClustersSchema: z.ZodObject<{
10
- parent_id: z.ZodOptional<z.ZodString>;
11
- time_range: z.ZodOptional<z.ZodDefault<z.ZodEnum<["all", "1h", "3d", "7d", "24h", "30d", "90d"]>>>;
12
- }, "strip", z.ZodTypeAny, {
13
- parent_id?: string | undefined;
14
- time_range?: "all" | "1h" | "3d" | "7d" | "24h" | "30d" | "90d" | undefined;
15
- }, {
16
- parent_id?: string | undefined;
17
- time_range?: "all" | "1h" | "3d" | "7d" | "24h" | "30d" | "90d" | undefined;
18
- }>;
19
- export declare const ClusterConversationsSchema: z.ZodObject<{
20
- node_id: z.ZodString;
21
- limit: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
22
- offset: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
23
- }, "strip", z.ZodTypeAny, {
24
- node_id: string;
25
- limit?: number | undefined;
26
- offset?: number | undefined;
27
- }, {
28
- node_id: string;
29
- limit?: number | undefined;
30
- offset?: number | undefined;
31
- }>;
32
- export declare const ConversationsSchema: z.ZodObject<{
33
- search: z.ZodOptional<z.ZodString>;
34
- cluster_id: z.ZodOptional<z.ZodString>;
35
- user_id: z.ZodOptional<z.ZodString>;
36
- time_range: z.ZodOptional<z.ZodDefault<z.ZodEnum<["all", "1h", "3d", "24h", "7d", "30d", "90d"]>>>;
37
- environment: z.ZodOptional<z.ZodDefault<z.ZodEnum<["all", "development", "staging", "production"]>>>;
38
- world_state: z.ZodOptional<z.ZodString>;
39
- outcome: z.ZodOptional<z.ZodDefault<z.ZodEnum<["any", "positive", "negative"]>>>;
40
- include_world_state: z.ZodOptional<z.ZodEffects<z.ZodBoolean, boolean, unknown>>;
41
- limit: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
42
- offset: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
43
- }, "strip", z.ZodTypeAny, {
44
- search?: string | undefined;
45
- environment?: "staging" | "all" | "development" | "production" | undefined;
46
- outcome?: "any" | "positive" | "negative" | undefined;
47
- time_range?: "all" | "1h" | "3d" | "7d" | "24h" | "30d" | "90d" | undefined;
48
- limit?: number | undefined;
49
- offset?: number | undefined;
50
- cluster_id?: string | undefined;
51
- user_id?: string | undefined;
52
- world_state?: string | undefined;
53
- include_world_state?: boolean | undefined;
54
- }, {
55
- search?: string | undefined;
56
- environment?: "staging" | "all" | "development" | "production" | undefined;
57
- outcome?: "any" | "positive" | "negative" | undefined;
58
- time_range?: "all" | "1h" | "3d" | "7d" | "24h" | "30d" | "90d" | undefined;
59
- limit?: number | undefined;
60
- offset?: number | undefined;
61
- cluster_id?: string | undefined;
62
- user_id?: string | undefined;
63
- world_state?: string | undefined;
64
- include_world_state?: unknown;
65
- }>;
66
- /** moda world-state <conversationId> — per-conversation world-state drill-in. */
67
- export declare const WorldStateSchema: z.ZodObject<{
68
- conversation_id: z.ZodString;
69
- summary_only: z.ZodOptional<z.ZodEffects<z.ZodBoolean, boolean, unknown>>;
70
- event_limit: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
71
- }, "strip", z.ZodTypeAny, {
72
- conversation_id: string;
73
- summary_only?: boolean | undefined;
74
- event_limit?: number | undefined;
75
- }, {
76
- conversation_id: string;
77
- summary_only?: unknown;
78
- event_limit?: number | undefined;
79
- }>;
80
- export declare const ContextSchema: z.ZodObject<{
81
- conversation_id: z.ZodString;
82
- msg_index: z.ZodOptional<z.ZodNumber>;
83
- window: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
84
- }, "strip", z.ZodTypeAny, {
85
- conversation_id: string;
86
- window?: number | undefined;
87
- msg_index?: number | undefined;
88
- }, {
89
- conversation_id: string;
90
- window?: number | undefined;
91
- msg_index?: number | undefined;
92
- }>;
93
- export declare const FrustrationsSchema: z.ZodObject<{
94
- days_back: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
95
- limit: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
96
- offset: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
97
- include_window: z.ZodOptional<z.ZodEffects<z.ZodBoolean, boolean, unknown>>;
98
- window: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
99
- }, "strip", z.ZodTypeAny, {
100
- window?: number | undefined;
101
- days_back?: number | undefined;
102
- limit?: number | undefined;
103
- offset?: number | undefined;
104
- include_window?: boolean | undefined;
105
- }, {
106
- window?: number | undefined;
107
- days_back?: number | undefined;
108
- limit?: number | undefined;
109
- offset?: number | undefined;
110
- include_window?: unknown;
111
- }>;
112
- export declare const ToolFailuresSchema: z.ZodObject<{
113
- days_back: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
114
- }, "strip", z.ZodTypeAny, {
115
- days_back?: number | undefined;
116
- }, {
117
- days_back?: number | undefined;
118
- }>;
119
- export declare const ToolFailureDetailSchema: z.ZodObject<{
120
- tool_name: z.ZodString;
121
- subtype: z.ZodOptional<z.ZodString>;
122
- days_back: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
123
- limit: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
124
- offset: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
125
- include_window: z.ZodOptional<z.ZodEffects<z.ZodBoolean, boolean, unknown>>;
126
- window: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
127
- }, "strip", z.ZodTypeAny, {
128
- tool_name: string;
129
- window?: number | undefined;
130
- subtype?: string | undefined;
131
- days_back?: number | undefined;
132
- limit?: number | undefined;
133
- offset?: number | undefined;
134
- include_window?: boolean | undefined;
135
- }, {
136
- tool_name: string;
137
- window?: number | undefined;
138
- subtype?: string | undefined;
139
- days_back?: number | undefined;
140
- limit?: number | undefined;
141
- offset?: number | undefined;
142
- include_window?: unknown;
143
- }>;
144
- /**
145
- * moda audit <conversation_id|trace_id> — raw, non-deduped span/trace read.
146
- * `kind=auto` (default) lets the backend try trace first, then conversation.
147
- */
148
- export declare const AuditSchema: z.ZodObject<{
149
- id: z.ZodString;
150
- kind: z.ZodOptional<z.ZodDefault<z.ZodEnum<["auto", "trace", "conversation"]>>>;
151
- include_raw: z.ZodOptional<z.ZodEffects<z.ZodBoolean, boolean, unknown>>;
152
- limit: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
153
- }, "strip", z.ZodTypeAny, {
154
- id: string;
155
- kind?: "auto" | "trace" | "conversation" | undefined;
156
- limit?: number | undefined;
157
- include_raw?: boolean | undefined;
158
- }, {
159
- id: string;
160
- kind?: "auto" | "trace" | "conversation" | undefined;
161
- limit?: number | undefined;
162
- include_raw?: unknown;
163
- }>;
164
- /**
165
- * moda search "<query>" — keyword/semantic/hybrid search across conversation
166
- * messages. `q` arrives as a positional arg; the runCommand handler rejects an
167
- * empty/whitespace query before parsing, and min(1) guards the schema path too.
168
- */
169
- export declare const SearchSchema: z.ZodObject<{
170
- q: z.ZodString;
171
- mode: z.ZodOptional<z.ZodDefault<z.ZodEnum<["keyword", "semantic", "hybrid"]>>>;
172
- user_id: z.ZodOptional<z.ZodString>;
173
- time_range: z.ZodOptional<z.ZodDefault<z.ZodEnum<["all", "1h", "3d", "7d", "24h", "30d", "90d"]>>>;
174
- limit: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
175
- include_tool_io: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
176
- }, "strip", z.ZodTypeAny, {
177
- q: string;
178
- mode?: "keyword" | "semantic" | "hybrid" | undefined;
179
- time_range?: "all" | "1h" | "3d" | "7d" | "24h" | "30d" | "90d" | undefined;
180
- limit?: number | undefined;
181
- user_id?: string | undefined;
182
- include_tool_io?: boolean | undefined;
183
- }, {
184
- q: string;
185
- mode?: "keyword" | "semantic" | "hybrid" | undefined;
186
- time_range?: "all" | "1h" | "3d" | "7d" | "24h" | "30d" | "90d" | undefined;
187
- limit?: number | undefined;
188
- user_id?: string | undefined;
189
- include_tool_io?: boolean | undefined;
190
- }>;
191
- export declare const FEEDBACK_CATEGORIES: readonly ["bad_cluster_label", "mismatched_frustration", "missing_data", "noisy_data", "wrong_tool_failure", "incorrect_loop", "api_quirk", "other"];
192
- export declare const FEEDBACK_SEVERITIES: readonly ["info", "low", "medium", "high"];
193
- /**
194
- * moda feedback "<note>": flag wrong/missing data or CLI quirks to the Moda
195
- * team. The handler builds this input from raw flag strings (NOT flagsToArgs,
196
- * whose numeric coercion would turn "--conversation-id=873459" into a number
197
- * that z.string() rejects). max(4000) on note mirrors the backend
198
- * @MaxLength(4000); the capped id fields become the POST body's `refs`.
199
- */
200
- export declare const FeedbackSchema: z.ZodObject<{
201
- note: z.ZodString;
202
- category: z.ZodOptional<z.ZodDefault<z.ZodEnum<["bad_cluster_label", "mismatched_frustration", "missing_data", "noisy_data", "wrong_tool_failure", "incorrect_loop", "api_quirk", "other"]>>>;
203
- severity: z.ZodOptional<z.ZodDefault<z.ZodEnum<["info", "low", "medium", "high"]>>>;
204
- conversation_id: z.ZodOptional<z.ZodString>;
205
- cluster_id: z.ZodOptional<z.ZodString>;
206
- tool_name: z.ZodOptional<z.ZodString>;
207
- run_id: z.ZodOptional<z.ZodString>;
208
- }, "strip", z.ZodTypeAny, {
209
- note: string;
210
- run_id?: string | undefined;
211
- severity?: "high" | "medium" | "low" | "info" | undefined;
212
- category?: "bad_cluster_label" | "mismatched_frustration" | "missing_data" | "noisy_data" | "wrong_tool_failure" | "incorrect_loop" | "api_quirk" | "other" | undefined;
213
- conversation_id?: string | undefined;
214
- tool_name?: string | undefined;
215
- cluster_id?: string | undefined;
216
- }, {
217
- note: string;
218
- run_id?: string | undefined;
219
- severity?: "high" | "medium" | "low" | "info" | undefined;
220
- category?: "bad_cluster_label" | "mismatched_frustration" | "missing_data" | "noisy_data" | "wrong_tool_failure" | "incorrect_loop" | "api_quirk" | "other" | undefined;
221
- conversation_id?: string | undefined;
222
- tool_name?: string | undefined;
223
- cluster_id?: string | undefined;
224
- }>;
225
- //# sourceMappingURL=schemas.d.ts.map
package/dist/schemas.js DELETED
@@ -1,126 +0,0 @@
1
- // src/schemas.ts
2
- import { z } from 'zod';
3
- // CLI flags arrive as strings; this coerces 'true'/'false' to booleans
4
- // at parse time so individual schemas can declare boolean fields cleanly.
5
- const boolFlag = () => z
6
- .preprocess((val) => (val === 'true' ? true : val === 'false' ? false : val), z.boolean())
7
- .optional();
8
- export const OverviewSchema = z.object({
9
- days_back: z.number().min(1).max(90).default(7).optional(),
10
- });
11
- // FIX: Add '1h', '24h', '90d' to match backend ClustersQueryDto
12
- export const ClustersSchema = z.object({
13
- parent_id: z.string().optional(),
14
- time_range: z.enum(['all', '1h', '3d', '7d', '24h', '30d', '90d']).default('all').optional(),
15
- });
16
- export const ClusterConversationsSchema = z.object({
17
- node_id: z.string(),
18
- limit: z.number().min(1).max(100).default(10).optional(),
19
- offset: z.number().min(0).default(0).optional(),
20
- });
21
- // FIX: Add '3d' to match backend ConversationsQueryDto
22
- export const ConversationsSchema = z.object({
23
- search: z.string().optional(),
24
- cluster_id: z.string().optional(),
25
- user_id: z.string().optional(),
26
- time_range: z.enum(['all', '1h', '3d', '24h', '7d', '30d', '90d']).default('all').optional(),
27
- environment: z.enum(['all', 'development', 'staging', 'production']).default('all').optional(),
28
- // Keyword(s) matched against conversation world-state content (segment slots
29
- // + carried-in durable profile slots). Comma-separated terms are ANDed.
30
- // max(200) mirrors the backend ConversationsQueryDto @MaxLength(200) so an
31
- // over-long value fails locally instead of round-tripping a 400.
32
- world_state: z.string().max(200).optional(),
33
- // Filter by conversation outcome (trajectory + frustration).
34
- outcome: z.enum(['any', 'positive', 'negative']).default('any').optional(),
35
- include_world_state: boolFlag(),
36
- limit: z.number().min(1).max(100).default(20).optional(),
37
- offset: z.number().min(0).default(0).optional(),
38
- });
39
- /** moda world-state <conversationId> — per-conversation world-state drill-in. */
40
- export const WorldStateSchema = z.object({
41
- conversation_id: z.string(),
42
- summary_only: boolFlag(),
43
- event_limit: z.number().min(1).max(5000).default(2000).optional(),
44
- });
45
- export const ContextSchema = z.object({
46
- conversation_id: z.string(),
47
- msg_index: z.number().min(0).optional(),
48
- window: z.number().min(1).max(5).default(2).optional(),
49
- });
50
- // FIX: Change limit max from 100 to 20 to match backend clamp
51
- export const FrustrationsSchema = z.object({
52
- days_back: z.number().min(1).max(90).default(7).optional(),
53
- limit: z.number().min(1).max(20).default(10).optional(),
54
- offset: z.number().min(0).default(0).optional(),
55
- include_window: boolFlag(),
56
- window: z.number().min(1).max(5).default(1).optional(),
57
- });
58
- export const ToolFailuresSchema = z.object({
59
- days_back: z.number().min(1).max(90).default(7).optional(),
60
- });
61
- // FIX: Change limit max from 100 to 20 to match backend clamp
62
- export const ToolFailureDetailSchema = z.object({
63
- tool_name: z.string(),
64
- subtype: z.string().optional(),
65
- days_back: z.number().min(1).max(90).default(7).optional(),
66
- limit: z.number().min(1).max(20).default(5).optional(),
67
- offset: z.number().min(0).default(0).optional(),
68
- include_window: boolFlag(),
69
- window: z.number().min(1).max(5).default(1).optional(),
70
- });
71
- /**
72
- * moda audit <conversation_id|trace_id> — raw, non-deduped span/trace read.
73
- * `kind=auto` (default) lets the backend try trace first, then conversation.
74
- */
75
- export const AuditSchema = z.object({
76
- id: z.string().min(1),
77
- kind: z.enum(['auto', 'trace', 'conversation']).default('auto').optional(),
78
- include_raw: boolFlag(),
79
- limit: z.number().min(1).max(1000).default(200).optional(),
80
- });
81
- const TIME_RANGES = ['all', '1h', '3d', '7d', '24h', '30d', '90d'];
82
- const SEARCH_MODES = ['keyword', 'semantic', 'hybrid'];
83
- /**
84
- * moda search "<query>" — keyword/semantic/hybrid search across conversation
85
- * messages. `q` arrives as a positional arg; the runCommand handler rejects an
86
- * empty/whitespace query before parsing, and min(1) guards the schema path too.
87
- */
88
- export const SearchSchema = z.object({
89
- q: z.string().min(1).max(500),
90
- mode: z.enum(SEARCH_MODES).default('hybrid').optional(),
91
- user_id: z.string().optional(),
92
- time_range: z.enum(TIME_RANGES).default('all').optional(),
93
- limit: z.number().min(1).max(100).default(20).optional(),
94
- include_tool_io: z.boolean().default(false).optional(),
95
- });
96
- // Enums mirror the backend FeedbackBodyDto (VALID_FEEDBACK_CATEGORIES /
97
- // VALID_FEEDBACK_SEVERITIES) so a bad value fails locally instead of
98
- // round-tripping a 400.
99
- export const FEEDBACK_CATEGORIES = [
100
- 'bad_cluster_label',
101
- 'mismatched_frustration',
102
- 'missing_data',
103
- 'noisy_data',
104
- 'wrong_tool_failure',
105
- 'incorrect_loop',
106
- 'api_quirk',
107
- 'other',
108
- ];
109
- export const FEEDBACK_SEVERITIES = ['info', 'low', 'medium', 'high'];
110
- /**
111
- * moda feedback "<note>": flag wrong/missing data or CLI quirks to the Moda
112
- * team. The handler builds this input from raw flag strings (NOT flagsToArgs,
113
- * whose numeric coercion would turn "--conversation-id=873459" into a number
114
- * that z.string() rejects). max(4000) on note mirrors the backend
115
- * @MaxLength(4000); the capped id fields become the POST body's `refs`.
116
- */
117
- export const FeedbackSchema = z.object({
118
- note: z.string().min(1).max(4000),
119
- category: z.enum(FEEDBACK_CATEGORIES).default('other').optional(),
120
- severity: z.enum(FEEDBACK_SEVERITIES).default('low').optional(),
121
- conversation_id: z.string().min(1).max(256).optional(),
122
- cluster_id: z.string().min(1).max(256).optional(),
123
- tool_name: z.string().min(1).max(256).optional(),
124
- run_id: z.string().min(1).max(256).optional(),
125
- });
126
- //# sourceMappingURL=schemas.js.map
@@ -1,35 +0,0 @@
1
- export interface BundledSkillIndexEntry {
2
- id: string;
3
- version: string;
4
- summary: string;
5
- targets: {
6
- language: string;
7
- frameworks: string[];
8
- providers: string[];
9
- };
10
- }
11
- export interface BundledSkillIndex {
12
- schema_version: string;
13
- bundled_at: string;
14
- cli_version: string;
15
- skills: BundledSkillIndexEntry[];
16
- }
17
- export interface IntegrationSkillInstallResult {
18
- skillId: string;
19
- status: 'installed' | 'unchanged';
20
- paths: string[];
21
- }
22
- /** Directory holding the bundled skills (overridable for tests). */
23
- export declare function bundledSkillsDir(): string;
24
- /** Read the bundled skill menu, or null when no bundle is present. */
25
- export declare function readBundledIndex(): BundledSkillIndex | null;
26
- /** Read a bundled skill's SKILL.md, or null when it is not bundled. */
27
- export declare function readBundledSkillMd(skillId: string): string | null;
28
- /**
29
- * Materialize a bundled integration skill into the project.
30
- *
31
- * Idempotent: unchanged files are left untouched, and a second install with
32
- * identical content reports status 'unchanged' without writing.
33
- */
34
- export declare function installIntegrationSkill(skillId: string, cwd?: string): IntegrationSkillInstallResult;
35
- //# sourceMappingURL=skills-bundled.d.ts.map
@@ -1,157 +0,0 @@
1
- // src/skills-bundled.ts — read and materialize the integration skills bundled
2
- // inside the npm package (skills/integration/, generated at build time by
3
- // scripts/bundle-skills.ts from packages/integration-skills/).
4
- //
5
- // Materialization copies the full skill directory (SKILL.md, EXAMPLE.md,
6
- // references/) into the project's .claude/skills/<id>/, translates SKILL.md
7
- // into a Cursor rule when the project uses Cursor, and records the install in
8
- // .moda/skills.yml with source: integration-bundled so `skills sync` never
9
- // pushes these files and harness release changes never prune them.
10
- import { createHash } from 'node:crypto';
11
- import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
12
- import { dirname, join, relative } from 'node:path';
13
- import { fileURLToPath } from 'node:url';
14
- import { claudeSkillToCursorRule } from './init/rules.js';
15
- import { detectAgents } from './init/mcp.js';
16
- import { readSkillsManifest, SKILL_SOURCE_INTEGRATION_BUNDLED, upsertSkillManifestRecord, } from './skills-manifest.js';
17
- // Resolved relative to this module so it works from src/ in dev and from the
18
- // published dist/ inside node_modules (same pattern as src/init/rules.ts).
19
- const PACKAGE_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
20
- const BUNDLED_SKILLS_DIR = join(PACKAGE_ROOT, 'skills', 'integration');
21
- /** Directory holding the bundled skills (overridable for tests). */
22
- export function bundledSkillsDir() {
23
- return process.env.MODA_BUNDLED_SKILLS_DIR || BUNDLED_SKILLS_DIR;
24
- }
25
- /** Read the bundled skill menu, or null when no bundle is present. */
26
- export function readBundledIndex() {
27
- const indexPath = join(bundledSkillsDir(), 'index.json');
28
- if (!existsSync(indexPath))
29
- return null;
30
- try {
31
- const parsed = JSON.parse(readFileSync(indexPath, 'utf8'));
32
- if (!Array.isArray(parsed.skills))
33
- return null;
34
- return parsed;
35
- }
36
- catch {
37
- return null;
38
- }
39
- }
40
- /** Read a bundled skill's SKILL.md, or null when it is not bundled. */
41
- export function readBundledSkillMd(skillId) {
42
- const path = join(bundledSkillsDir(), skillId, 'SKILL.md');
43
- if (!existsSync(path))
44
- return null;
45
- try {
46
- return readFileSync(path, 'utf8');
47
- }
48
- catch {
49
- return null;
50
- }
51
- }
52
- /**
53
- * Materialize a bundled integration skill into the project.
54
- *
55
- * Idempotent: unchanged files are left untouched, and a second install with
56
- * identical content reports status 'unchanged' without writing.
57
- */
58
- export function installIntegrationSkill(skillId, cwd = process.cwd()) {
59
- if (!/^[a-z0-9-]+$/.test(skillId)) {
60
- throw new Error(`Invalid integration skill id: ${JSON.stringify(skillId).slice(0, 80)}`);
61
- }
62
- const sourceDir = join(bundledSkillsDir(), skillId);
63
- if (!existsSync(join(sourceDir, 'SKILL.md'))) {
64
- const bundled = readBundledIndex()?.skills.map((skill) => skill.id) ?? [];
65
- throw new Error(`Integration skill '${skillId}' is not bundled with this CLI.${bundled.length > 0 ? ` Bundled skills: ${bundled.join(', ')}` : ''}`);
66
- }
67
- const files = listFilesRecursive(sourceDir).sort();
68
- // Plan every write up front (skill files + optional Cursor rule) so the
69
- // ownership guard can reject the whole install before touching disk.
70
- const plannedWrites = [];
71
- for (const file of files) {
72
- const relPath = relative(sourceDir, file).replace(/\\/g, '/');
73
- plannedWrites.push({
74
- targetRelPath: `.claude/skills/${skillId}/${relPath}`,
75
- targetPath: join(cwd, '.claude', 'skills', skillId, relPath),
76
- content: readFileSync(file, 'utf8'),
77
- });
78
- }
79
- // Cursor translation of the entry point, when the project uses Cursor.
80
- const writeCursor = detectAgents().includes('Cursor') || existsSync(join(cwd, '.cursor'));
81
- if (writeCursor) {
82
- const skillMd = readFileSync(join(sourceDir, 'SKILL.md'), 'utf8');
83
- plannedWrites.push({
84
- targetRelPath: `.cursor/rules/${skillId}.mdc`,
85
- targetPath: join(cwd, '.cursor', 'rules', `${skillId}.mdc`),
86
- content: claudeSkillToCursorRule(skillMd),
87
- });
88
- }
89
- // Ownership guard: never clobber a file Moda does not already manage. A repo
90
- // that happens to carry a user-authored .claude/skills/<id>/... or
91
- // .cursor/rules/<id>.mdc at one of our target paths must not be silently
92
- // overwritten. Paths recorded in .moda/skills.yml (any source) are ours, so
93
- // idempotent re-installs still pass; only genuinely foreign files trip this.
94
- const ownedPaths = new Set((readSkillsManifest(cwd)?.records ?? []).flatMap((record) => record.paths));
95
- const collisions = plannedWrites.filter((write) => existsSync(write.targetPath) && !ownedPaths.has(write.targetRelPath));
96
- if (collisions.length > 0) {
97
- throw new Error(`Refusing to overwrite ${collisions.length} existing file(s) not managed by Moda: ` +
98
- `${collisions.map((write) => write.targetRelPath).join(', ')}. ` +
99
- 'Move or remove them, then re-run to install the bundled integration skill.');
100
- }
101
- const paths = [];
102
- let wroteAny = false;
103
- for (const write of plannedWrites) {
104
- if (writeIfChanged(write.targetPath, write.content))
105
- wroteAny = true;
106
- paths.push(write.targetRelPath);
107
- }
108
- upsertSkillManifestRecord(cwd, {
109
- skillId,
110
- contentHash: hashSkillDir(sourceDir, files),
111
- source: SKILL_SOURCE_INTEGRATION_BUNDLED,
112
- paths,
113
- });
114
- return { skillId, status: wroteAny ? 'installed' : 'unchanged', paths };
115
- }
116
- function writeIfChanged(path, content) {
117
- if (existsSync(path)) {
118
- try {
119
- if (readFileSync(path, 'utf8') === content)
120
- return false;
121
- }
122
- catch {
123
- // Unreadable existing file: fall through and rewrite.
124
- }
125
- }
126
- mkdirSync(dirname(path), { recursive: true });
127
- writeFileSync(path, content);
128
- return true;
129
- }
130
- function listFilesRecursive(dir) {
131
- const files = [];
132
- const stack = [dir];
133
- while (stack.length > 0) {
134
- const current = stack.pop();
135
- if (!current)
136
- continue;
137
- for (const entry of readdirSync(current, { withFileTypes: true })) {
138
- const path = join(current, entry.name);
139
- if (entry.isDirectory())
140
- stack.push(path);
141
- else if (entry.isFile())
142
- files.push(path);
143
- }
144
- }
145
- return files;
146
- }
147
- function hashSkillDir(sourceDir, files) {
148
- const hash = createHash('sha256');
149
- for (const file of files) {
150
- hash.update(relative(sourceDir, file).replace(/\\/g, '/'));
151
- hash.update('\0');
152
- hash.update(readFileSync(file));
153
- hash.update('\0');
154
- }
155
- return hash.digest('hex');
156
- }
157
- //# sourceMappingURL=skills-bundled.js.map
@@ -1,33 +0,0 @@
1
- export declare const SKILLS_MANIFEST_PATH: string;
2
- export declare const SKILL_SOURCE_HARNESS = "moda";
3
- export declare const SKILL_SOURCE_INTEGRATION_BUNDLED = "integration-bundled";
4
- export interface SkillInstallRecord {
5
- skillId: string;
6
- contentHash: string;
7
- source: string;
8
- paths: string[];
9
- }
10
- export interface ManifestHeader {
11
- tenantId: string;
12
- releaseKey: string;
13
- statusFilter: string;
14
- generationRunId: string;
15
- generationVersion: number;
16
- releasedAt: string;
17
- }
18
- export interface SkillsManifest extends ManifestHeader {
19
- managedPaths: string[];
20
- records: SkillInstallRecord[];
21
- }
22
- export declare function readSkillsManifest(cwd: string): SkillsManifest | null;
23
- export declare function manifestHeaderFrom(manifest: SkillsManifest | null): ManifestHeader;
24
- export declare function writeSkillsManifest(cwd: string, header: ManifestHeader, records: SkillInstallRecord[]): void;
25
- /**
26
- * Upsert a skill record into .moda/skills.yml, preserving the harness release
27
- * header and all other records. Used by the bundled integration-skill
28
- * installer so its materialized files become managed paths (excluded from
29
- * `skills sync`, never pruned by harness release changes).
30
- */
31
- export declare function upsertSkillManifestRecord(cwd: string, record: SkillInstallRecord): void;
32
- export declare function pruneManagedSkillPaths(cwd: string, managedPaths: string[], log: (msg: string) => void): number;
33
- //# sourceMappingURL=skills-manifest.d.ts.map