@moda-ai/cli 1.1.1 → 1.3.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.
- package/README.md +36 -0
- package/dist/agent.d.ts +5 -0
- package/dist/agent.js +477 -0
- package/dist/analyst-tui.d.ts +81 -0
- package/dist/analyst-tui.js +314 -0
- package/dist/api-client.d.ts +4 -0
- package/dist/api-client.js +20 -3
- package/dist/auth.d.ts +22 -3
- package/dist/auth.js +230 -66
- package/dist/cli.d.ts +20 -3
- package/dist/cli.js +745 -93
- package/dist/command-context.d.ts +34 -0
- package/dist/command-context.js +38 -0
- package/dist/command-registry.d.ts +22 -0
- package/dist/command-registry.js +15 -0
- package/dist/config.d.ts +40 -1
- package/dist/config.js +70 -3
- package/dist/doctor.d.ts +79 -0
- package/dist/doctor.js +1111 -0
- package/dist/errors.d.ts +5 -0
- package/dist/errors.js +9 -0
- package/dist/harness-report.d.ts +138 -0
- package/dist/harness-report.js +1464 -0
- package/dist/harness.d.ts +233 -0
- package/dist/harness.js +3264 -0
- package/dist/init/index.d.ts +30 -1
- package/dist/init/index.js +389 -23
- package/dist/init/rules.d.ts +5 -1
- package/dist/init/rules.js +22 -16
- package/dist/init/sdk-guide.d.ts +3 -0
- package/dist/init/sdk-guide.js +397 -0
- package/dist/init/tenant.js +12 -3
- package/dist/keys.d.ts +47 -0
- package/dist/keys.js +136 -0
- package/dist/output.d.ts +118 -0
- package/dist/output.js +228 -0
- package/dist/production-intelligence.d.ts +134 -0
- package/dist/production-intelligence.js +1113 -0
- package/dist/profile-commands.d.ts +10 -0
- package/dist/profile-commands.js +252 -0
- package/dist/profiles.d.ts +90 -0
- package/dist/profiles.js +432 -0
- package/dist/prompts.d.ts +6 -0
- package/dist/prompts.js +368 -0
- package/dist/schemas.d.ts +4 -4
- package/dist/skills.d.ts +25 -0
- package/dist/skills.js +468 -0
- package/dist/sync.d.ts +5 -0
- package/dist/sync.js +27 -0
- package/dist/telemetry.d.ts +18 -0
- package/dist/telemetry.js +63 -0
- package/dist/tui.d.ts +40 -0
- package/dist/tui.js +387 -0
- package/dist/workspace.d.ts +12 -0
- package/dist/workspace.js +1294 -0
- package/hooks/moda-snapshot.sh +41 -0
- package/package.json +10 -7
- package/skills/moda-cli/SKILL.md +48 -4
- package/skills/integrate-moda/SKILL.md +0 -63
package/dist/prompts.js
ADDED
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, writeFileSync, } from 'node:fs';
|
|
4
|
+
import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
|
|
5
|
+
import { callControlAPI } from './api-client.js';
|
|
6
|
+
const MODA_DIR = '.moda';
|
|
7
|
+
const MANIFEST_PATH = join(MODA_DIR, 'prompts.yml');
|
|
8
|
+
const LOCK_PATH = join(MODA_DIR, 'prompts.lock.json');
|
|
9
|
+
const DEFAULT_PROMPT_PATHS = [
|
|
10
|
+
'prompts/**/*.prompt.md',
|
|
11
|
+
'prompts/**/*.prompt.json',
|
|
12
|
+
'prompts/**/*.prompt.yaml',
|
|
13
|
+
'prompts/**/*.prompt.yml',
|
|
14
|
+
];
|
|
15
|
+
export async function runPromptsCommand(positionals, flags, profileOptions = { profile: flags.profile }) {
|
|
16
|
+
const subcommand = positionals[0] || 'status';
|
|
17
|
+
switch (subcommand) {
|
|
18
|
+
case 'init':
|
|
19
|
+
await initPrompts();
|
|
20
|
+
break;
|
|
21
|
+
case 'status':
|
|
22
|
+
printJson(await getPromptStatus());
|
|
23
|
+
break;
|
|
24
|
+
case 'diff':
|
|
25
|
+
printJson(await getPromptStatus());
|
|
26
|
+
break;
|
|
27
|
+
case 'sync':
|
|
28
|
+
await syncPrompts(flags, profileOptions);
|
|
29
|
+
break;
|
|
30
|
+
case 'promote':
|
|
31
|
+
await promotePrompt(positionals, flags, profileOptions);
|
|
32
|
+
break;
|
|
33
|
+
default:
|
|
34
|
+
throw new Error(`Unknown prompts command '${subcommand}'. Use init, status, diff, sync, or promote.`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export async function initPrompts(options = {}) {
|
|
38
|
+
mkdirSync(MODA_DIR, { recursive: true });
|
|
39
|
+
if (!existsSync(MANIFEST_PATH)) {
|
|
40
|
+
writeFileSync(MANIFEST_PATH, [
|
|
41
|
+
'version: 1',
|
|
42
|
+
'prompt_paths:',
|
|
43
|
+
...DEFAULT_PROMPT_PATHS.map((path) => ` - "${path}"`),
|
|
44
|
+
'',
|
|
45
|
+
].join('\n'));
|
|
46
|
+
}
|
|
47
|
+
if (!options.silent) {
|
|
48
|
+
printJson({
|
|
49
|
+
manifest: MANIFEST_PATH,
|
|
50
|
+
lockfile: LOCK_PATH,
|
|
51
|
+
promptPaths: readManifest().promptPaths,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function syncPrompts(flags, profileOptions) {
|
|
56
|
+
if (flags.watch === 'true') {
|
|
57
|
+
await watchPromptSync(flags, profileOptions);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
await syncPromptsOnce(flags, profileOptions);
|
|
61
|
+
}
|
|
62
|
+
async function syncPromptsOnce(flags, profileOptions) {
|
|
63
|
+
await initPrompts({ silent: true });
|
|
64
|
+
const prompts = discoverPrompts();
|
|
65
|
+
const sourceCommit = getGitCommit();
|
|
66
|
+
const manifestHash = hashFile(MANIFEST_PATH);
|
|
67
|
+
const dryRun = flags['dry-run'] === 'true';
|
|
68
|
+
const response = await callControlAPI('/prompts/sync', {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
body: JSON.stringify({
|
|
71
|
+
prompts: prompts.map((prompt) => ({
|
|
72
|
+
...prompt,
|
|
73
|
+
sourceCommit,
|
|
74
|
+
manifestHash,
|
|
75
|
+
})),
|
|
76
|
+
sourceCommit,
|
|
77
|
+
manifestHash,
|
|
78
|
+
dryRun,
|
|
79
|
+
}),
|
|
80
|
+
}, profileOptions);
|
|
81
|
+
if (!dryRun) {
|
|
82
|
+
writeLock(prompts, response.synced ?? []);
|
|
83
|
+
}
|
|
84
|
+
printJson({
|
|
85
|
+
synced: response.synced ?? [],
|
|
86
|
+
lockfile: dryRun ? undefined : LOCK_PATH,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async function watchPromptSync(flags, profileOptions) {
|
|
90
|
+
console.error('Watching prompt files. Press Ctrl+C to stop.');
|
|
91
|
+
let lastSignature = '';
|
|
92
|
+
const intervalMs = Math.max(1000, Number(flags.interval ?? 2500));
|
|
93
|
+
while (true) {
|
|
94
|
+
const status = await getPromptStatus();
|
|
95
|
+
const signature = stableJson(status.prompts);
|
|
96
|
+
if (signature !== lastSignature) {
|
|
97
|
+
lastSignature = signature;
|
|
98
|
+
if (status.changed > 0 || status.new > 0 || status.deleted > 0) {
|
|
99
|
+
await syncPromptsOnce({ ...flags, watch: 'false' }, profileOptions);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async function promotePrompt(positionals, flags, profileOptions) {
|
|
106
|
+
const key = positionals[1];
|
|
107
|
+
const label = flags.label;
|
|
108
|
+
const versionId = flags.version || flags['version-id'];
|
|
109
|
+
if (!key)
|
|
110
|
+
throw new Error('Usage: moda prompts promote <prompt_key> --label=prod --version=<version_id>');
|
|
111
|
+
if (!label)
|
|
112
|
+
throw new Error('Missing required flag: --label=dev|staging|prod');
|
|
113
|
+
if (!versionId)
|
|
114
|
+
throw new Error('Missing required flag: --version=<version_id>');
|
|
115
|
+
const response = await callControlAPI(`/prompts/${encodeURIComponent(key)}/labels`, {
|
|
116
|
+
method: 'POST',
|
|
117
|
+
body: JSON.stringify({ label, versionId }),
|
|
118
|
+
}, profileOptions);
|
|
119
|
+
printJson(response);
|
|
120
|
+
}
|
|
121
|
+
async function getPromptStatus() {
|
|
122
|
+
await initPrompts({ silent: true });
|
|
123
|
+
const prompts = discoverPrompts();
|
|
124
|
+
const lock = readLock();
|
|
125
|
+
const rows = prompts.map((prompt) => {
|
|
126
|
+
const locked = lock?.prompts[prompt.key];
|
|
127
|
+
const state = !locked
|
|
128
|
+
? 'new'
|
|
129
|
+
: locked.contentHash === prompt.contentHash
|
|
130
|
+
? 'unchanged'
|
|
131
|
+
: 'changed';
|
|
132
|
+
return {
|
|
133
|
+
key: prompt.key,
|
|
134
|
+
sourcePath: prompt.sourcePath,
|
|
135
|
+
contentHash: prompt.contentHash,
|
|
136
|
+
lockedHash: locked?.contentHash ?? null,
|
|
137
|
+
versionId: locked?.versionId ?? null,
|
|
138
|
+
state,
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
const discoveredKeys = new Set(prompts.map((prompt) => prompt.key));
|
|
142
|
+
for (const [key, locked] of Object.entries(lock?.prompts ?? {})) {
|
|
143
|
+
if (!discoveredKeys.has(key)) {
|
|
144
|
+
rows.push({
|
|
145
|
+
key,
|
|
146
|
+
sourcePath: locked.sourcePath,
|
|
147
|
+
contentHash: null,
|
|
148
|
+
lockedHash: locked.contentHash,
|
|
149
|
+
versionId: locked.versionId ?? null,
|
|
150
|
+
state: 'deleted',
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
manifest: MANIFEST_PATH,
|
|
156
|
+
lockfile: LOCK_PATH,
|
|
157
|
+
total: rows.length,
|
|
158
|
+
changed: rows.filter((row) => row.state === 'changed').length,
|
|
159
|
+
new: rows.filter((row) => row.state === 'new').length,
|
|
160
|
+
deleted: rows.filter((row) => row.state === 'deleted').length,
|
|
161
|
+
prompts: rows,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function discoverPrompts() {
|
|
165
|
+
const manifest = readManifest();
|
|
166
|
+
// A pattern like `src/prompts/**/*.prompt.md` should *only* match files under
|
|
167
|
+
// src/prompts. Extract both the base directory (everything up to the first
|
|
168
|
+
// glob segment) and the file suffix so we can scope `walk()` accordingly.
|
|
169
|
+
const rules = manifest.promptPaths
|
|
170
|
+
.map((pattern) => {
|
|
171
|
+
const suffixMatch = pattern.match(/\.prompt\.(md|json|ya?ml)$/i);
|
|
172
|
+
if (!suffixMatch)
|
|
173
|
+
return null;
|
|
174
|
+
const suffix = `.prompt.${suffixMatch[1]}`;
|
|
175
|
+
const globIndex = pattern.search(/[*?[]/);
|
|
176
|
+
const baseRaw = globIndex === -1 ? dirname(pattern) : pattern.slice(0, globIndex);
|
|
177
|
+
const base = baseRaw.replace(/[\\/]+$/, '') || '.';
|
|
178
|
+
const baseAbs = isAbsolute(base) ? base : resolve(process.cwd(), base);
|
|
179
|
+
return { baseAbs, suffix };
|
|
180
|
+
})
|
|
181
|
+
.filter((rule) => Boolean(rule));
|
|
182
|
+
const effectiveRules = rules.length
|
|
183
|
+
? rules
|
|
184
|
+
: [
|
|
185
|
+
{ baseAbs: process.cwd(), suffix: '.prompt.md' },
|
|
186
|
+
{ baseAbs: process.cwd(), suffix: '.prompt.json' },
|
|
187
|
+
];
|
|
188
|
+
const discovered = new Set();
|
|
189
|
+
for (const { baseAbs, suffix } of effectiveRules) {
|
|
190
|
+
if (!existsSync(baseAbs))
|
|
191
|
+
continue;
|
|
192
|
+
for (const file of walk(baseAbs)) {
|
|
193
|
+
if (file.endsWith(suffix))
|
|
194
|
+
discovered.add(file);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return [...discovered].sort().map(parsePromptFile);
|
|
198
|
+
}
|
|
199
|
+
function parsePromptFile(absPath) {
|
|
200
|
+
const sourcePath = relative(process.cwd(), absPath);
|
|
201
|
+
const raw = readFileSync(absPath, 'utf8');
|
|
202
|
+
if (absPath.endsWith('.json')) {
|
|
203
|
+
const parsed = JSON.parse(raw);
|
|
204
|
+
const key = parsed.key || keyFromPath(sourcePath);
|
|
205
|
+
const content = parsed.content || JSON.stringify(parsed.messages ?? [], null, 2);
|
|
206
|
+
return normalizePrompt({ ...parsed, key, name: parsed.name || key, sourcePath, content });
|
|
207
|
+
}
|
|
208
|
+
const { frontmatter, body } = parseFrontmatter(raw);
|
|
209
|
+
const key = frontmatter.key || keyFromPath(sourcePath);
|
|
210
|
+
return normalizePrompt({
|
|
211
|
+
key,
|
|
212
|
+
name: frontmatter.name || key,
|
|
213
|
+
description: frontmatter.description,
|
|
214
|
+
category: frontmatter.category,
|
|
215
|
+
systemPrompt: frontmatter.system_prompt || frontmatter.systemPrompt,
|
|
216
|
+
modelConfig: frontmatter.model ? { model: frontmatter.model } : undefined,
|
|
217
|
+
sourcePath,
|
|
218
|
+
content: body.trim(),
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
function normalizePrompt(prompt) {
|
|
222
|
+
const normalized = stableJson({
|
|
223
|
+
key: prompt.key,
|
|
224
|
+
content: prompt.content,
|
|
225
|
+
systemPrompt: prompt.systemPrompt ?? null,
|
|
226
|
+
messages: prompt.messages ?? [],
|
|
227
|
+
variables: prompt.variables ?? [],
|
|
228
|
+
variablesSchema: prompt.variablesSchema ?? {},
|
|
229
|
+
modelConfig: prompt.modelConfig ?? {},
|
|
230
|
+
toolRefs: prompt.toolRefs ?? [],
|
|
231
|
+
responseSchema: prompt.responseSchema ?? null,
|
|
232
|
+
});
|
|
233
|
+
return {
|
|
234
|
+
key: prompt.key,
|
|
235
|
+
name: prompt.name || prompt.key,
|
|
236
|
+
description: prompt.description,
|
|
237
|
+
sourcePath: prompt.sourcePath,
|
|
238
|
+
content: prompt.content,
|
|
239
|
+
systemPrompt: prompt.systemPrompt,
|
|
240
|
+
messages: prompt.messages,
|
|
241
|
+
variables: prompt.variables,
|
|
242
|
+
variablesSchema: prompt.variablesSchema,
|
|
243
|
+
modelConfig: prompt.modelConfig,
|
|
244
|
+
toolRefs: prompt.toolRefs,
|
|
245
|
+
responseSchema: prompt.responseSchema,
|
|
246
|
+
contentHash: sha256(normalized),
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function readManifest() {
|
|
250
|
+
if (!existsSync(MANIFEST_PATH)) {
|
|
251
|
+
return { promptPaths: DEFAULT_PROMPT_PATHS };
|
|
252
|
+
}
|
|
253
|
+
const text = readFileSync(MANIFEST_PATH, 'utf8');
|
|
254
|
+
const promptPaths = [...text.matchAll(/^\s*-\s*["']?([^"'\n]+)["']?\s*$/gm)]
|
|
255
|
+
.map((match) => match[1])
|
|
256
|
+
.filter((path) => path.includes('.prompt.'));
|
|
257
|
+
return { promptPaths: promptPaths.length ? promptPaths : DEFAULT_PROMPT_PATHS };
|
|
258
|
+
}
|
|
259
|
+
function readLock() {
|
|
260
|
+
if (!existsSync(LOCK_PATH))
|
|
261
|
+
return null;
|
|
262
|
+
return JSON.parse(readFileSync(LOCK_PATH, 'utf8'));
|
|
263
|
+
}
|
|
264
|
+
function writeLock(prompts, synced) {
|
|
265
|
+
const syncedByKey = new Map(synced.map((item) => [item.key, item]));
|
|
266
|
+
const lock = {
|
|
267
|
+
version: 1,
|
|
268
|
+
generatedAt: new Date().toISOString(),
|
|
269
|
+
prompts: Object.fromEntries(prompts.map((prompt) => {
|
|
270
|
+
const result = syncedByKey.get(prompt.key);
|
|
271
|
+
return [prompt.key, {
|
|
272
|
+
key: prompt.key,
|
|
273
|
+
sourcePath: prompt.sourcePath,
|
|
274
|
+
contentHash: prompt.contentHash,
|
|
275
|
+
promptId: result?.promptId,
|
|
276
|
+
versionId: result?.versionId,
|
|
277
|
+
}];
|
|
278
|
+
})),
|
|
279
|
+
};
|
|
280
|
+
mkdirSync(dirname(LOCK_PATH), { recursive: true });
|
|
281
|
+
writeFileSync(LOCK_PATH, `${JSON.stringify(lock, null, 2)}\n`);
|
|
282
|
+
}
|
|
283
|
+
function walk(dir) {
|
|
284
|
+
let entries;
|
|
285
|
+
try {
|
|
286
|
+
entries = readdirSync(dir);
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
return [];
|
|
290
|
+
}
|
|
291
|
+
const files = [];
|
|
292
|
+
for (const entry of entries) {
|
|
293
|
+
if (entry === 'node_modules' || entry === '.git' || entry === 'dist' || entry === 'build')
|
|
294
|
+
continue;
|
|
295
|
+
const fullPath = join(dir, entry);
|
|
296
|
+
// lstatSync — never follow symlinks. A symlink in the tree could otherwise
|
|
297
|
+
// (a) loop into an ancestor and recurse forever, or (b) silently point at a
|
|
298
|
+
// sensitive file like .env that would then get uploaded as prompt content.
|
|
299
|
+
let stat;
|
|
300
|
+
try {
|
|
301
|
+
stat = lstatSync(fullPath);
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
if (stat.isSymbolicLink())
|
|
307
|
+
continue;
|
|
308
|
+
if (stat.isDirectory())
|
|
309
|
+
files.push(...walk(fullPath));
|
|
310
|
+
else if (stat.isFile())
|
|
311
|
+
files.push(fullPath);
|
|
312
|
+
}
|
|
313
|
+
return files;
|
|
314
|
+
}
|
|
315
|
+
function parseFrontmatter(raw) {
|
|
316
|
+
if (!raw.startsWith('---'))
|
|
317
|
+
return { frontmatter: {}, body: raw };
|
|
318
|
+
const end = raw.indexOf('\n---', 3);
|
|
319
|
+
if (end === -1)
|
|
320
|
+
return { frontmatter: {}, body: raw };
|
|
321
|
+
const frontmatterText = raw.slice(3, end).trim();
|
|
322
|
+
const frontmatter = Object.fromEntries(frontmatterText
|
|
323
|
+
.split('\n')
|
|
324
|
+
.map((line) => line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/))
|
|
325
|
+
.filter((match) => Boolean(match))
|
|
326
|
+
.map((match) => [match[1], match[2].replace(/^["']|["']$/g, '')]));
|
|
327
|
+
return { frontmatter, body: raw.slice(end + 4) };
|
|
328
|
+
}
|
|
329
|
+
function keyFromPath(path) {
|
|
330
|
+
return path
|
|
331
|
+
.replace(/^prompts\//, '')
|
|
332
|
+
.replace(/\.prompt\.(md|json|ya?ml)$/i, '')
|
|
333
|
+
.replace(/[\\/]/g, '.');
|
|
334
|
+
}
|
|
335
|
+
function hashFile(path) {
|
|
336
|
+
return existsSync(path) ? sha256(readFileSync(path, 'utf8')) : '';
|
|
337
|
+
}
|
|
338
|
+
function getGitCommit() {
|
|
339
|
+
try {
|
|
340
|
+
return execFileSync('git', ['rev-parse', 'HEAD'], {
|
|
341
|
+
encoding: 'utf8',
|
|
342
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
343
|
+
}).trim();
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
return undefined;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
function stableJson(value) {
|
|
350
|
+
return JSON.stringify(sortJson(value));
|
|
351
|
+
}
|
|
352
|
+
function sortJson(value) {
|
|
353
|
+
if (Array.isArray(value))
|
|
354
|
+
return value.map(sortJson);
|
|
355
|
+
if (value && typeof value === 'object') {
|
|
356
|
+
return Object.fromEntries(Object.entries(value)
|
|
357
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
358
|
+
.map(([key, item]) => [key, sortJson(item)]));
|
|
359
|
+
}
|
|
360
|
+
return value;
|
|
361
|
+
}
|
|
362
|
+
function sha256(input) {
|
|
363
|
+
return createHash('sha256').update(input).digest('hex');
|
|
364
|
+
}
|
|
365
|
+
function printJson(value) {
|
|
366
|
+
console.log(JSON.stringify(value, null, 2));
|
|
367
|
+
}
|
|
368
|
+
//# sourceMappingURL=prompts.js.map
|
package/dist/schemas.d.ts
CHANGED
|
@@ -39,20 +39,20 @@ export declare const ConversationsSchema: z.ZodObject<{
|
|
|
39
39
|
offset: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
40
40
|
}, "strip", z.ZodTypeAny, {
|
|
41
41
|
search?: string | undefined;
|
|
42
|
+
environment?: "staging" | "all" | "development" | "production" | undefined;
|
|
42
43
|
time_range?: "all" | "1h" | "3d" | "7d" | "24h" | "30d" | "90d" | undefined;
|
|
43
44
|
limit?: number | undefined;
|
|
44
45
|
offset?: number | undefined;
|
|
45
46
|
cluster_id?: string | undefined;
|
|
46
47
|
user_id?: string | undefined;
|
|
47
|
-
environment?: "all" | "development" | "staging" | "production" | undefined;
|
|
48
48
|
}, {
|
|
49
49
|
search?: string | undefined;
|
|
50
|
+
environment?: "staging" | "all" | "development" | "production" | undefined;
|
|
50
51
|
time_range?: "all" | "1h" | "3d" | "7d" | "24h" | "30d" | "90d" | undefined;
|
|
51
52
|
limit?: number | undefined;
|
|
52
53
|
offset?: number | undefined;
|
|
53
54
|
cluster_id?: string | undefined;
|
|
54
55
|
user_id?: string | undefined;
|
|
55
|
-
environment?: "all" | "development" | "staging" | "production" | undefined;
|
|
56
56
|
}>;
|
|
57
57
|
export declare const ContextSchema: z.ZodObject<{
|
|
58
58
|
conversation_id: z.ZodString;
|
|
@@ -143,14 +143,14 @@ export declare const RunsSchema: z.ZodObject<{
|
|
|
143
143
|
limit?: number | undefined;
|
|
144
144
|
offset?: number | undefined;
|
|
145
145
|
user_id?: string | undefined;
|
|
146
|
-
outcome?: "
|
|
146
|
+
outcome?: "unknown" | "running" | "failed" | "succeeded" | "partial" | "loop" | "abandoned" | undefined;
|
|
147
147
|
class_id?: string | undefined;
|
|
148
148
|
}, {
|
|
149
149
|
time_range?: "all" | "1h" | "3d" | "7d" | "24h" | "30d" | "90d" | undefined;
|
|
150
150
|
limit?: number | undefined;
|
|
151
151
|
offset?: number | undefined;
|
|
152
152
|
user_id?: string | undefined;
|
|
153
|
-
outcome?: "
|
|
153
|
+
outcome?: "unknown" | "running" | "failed" | "succeeded" | "partial" | "loop" | "abandoned" | undefined;
|
|
154
154
|
class_id?: string | undefined;
|
|
155
155
|
}>;
|
|
156
156
|
/** moda run <runId> — single execution detail with side-effect receipts. */
|
package/dist/skills.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ParsedArgs } from './cli.js';
|
|
2
|
+
interface PullSummary {
|
|
3
|
+
total: number;
|
|
4
|
+
pruned: number;
|
|
5
|
+
wrote: number;
|
|
6
|
+
updated: number;
|
|
7
|
+
unchanged: number;
|
|
8
|
+
failed: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Pull generated skills into the detected coding agents' skill directories.
|
|
12
|
+
* Exported so `moda init` can run it as a setup step. Best-effort and quiet on
|
|
13
|
+
* an empty store; never throws for "no skills yet".
|
|
14
|
+
*/
|
|
15
|
+
export declare function pullSkills(options?: {
|
|
16
|
+
status?: string;
|
|
17
|
+
cwd?: string;
|
|
18
|
+
silent?: boolean;
|
|
19
|
+
}): Promise<PullSummary>;
|
|
20
|
+
/**
|
|
21
|
+
* `moda skills <subcommand>` dispatcher.
|
|
22
|
+
*/
|
|
23
|
+
export declare function runSkillsCommand(args: ParsedArgs): Promise<number>;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=skills.d.ts.map
|