mrvn-cli 0.2.6 → 0.2.9
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 +89 -3
- package/dist/index.d.ts +8 -1
- package/dist/index.js +968 -254
- package/dist/index.js.map +1 -1
- package/dist/marvin-serve.js +637 -46
- package/dist/marvin-serve.js.map +1 -1
- package/dist/marvin.js +968 -254
- package/dist/marvin.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -333,13 +333,10 @@ var DocumentStore = class {
|
|
|
333
333
|
if (!prefix) {
|
|
334
334
|
throw new Error(`Unknown document type: ${type}`);
|
|
335
335
|
}
|
|
336
|
-
const
|
|
337
|
-
const dir = path3.join(this.docsDir, dirName);
|
|
338
|
-
if (!fs3.existsSync(dir)) return `${prefix}-001`;
|
|
339
|
-
const files = fs3.readdirSync(dir).filter((f) => f.endsWith(".md"));
|
|
336
|
+
const pattern = new RegExp(`^${prefix}-(\\d+)$`);
|
|
340
337
|
let maxNum = 0;
|
|
341
|
-
for (const
|
|
342
|
-
const match =
|
|
338
|
+
for (const id of this.index.keys()) {
|
|
339
|
+
const match = id.match(pattern);
|
|
343
340
|
if (match) {
|
|
344
341
|
maxNum = Math.max(maxNum, parseInt(match[1], 10));
|
|
345
342
|
}
|
|
@@ -500,14 +497,14 @@ function getPersona(idOrShortName) {
|
|
|
500
497
|
function listPersonas() {
|
|
501
498
|
return [...BUILTIN_PERSONAS];
|
|
502
499
|
}
|
|
503
|
-
function resolvePersonaId(
|
|
504
|
-
const persona = getPersona(
|
|
500
|
+
function resolvePersonaId(input4) {
|
|
501
|
+
const persona = getPersona(input4);
|
|
505
502
|
if (!persona) {
|
|
506
503
|
const available = BUILTIN_PERSONAS.map(
|
|
507
504
|
(p) => `${p.shortName} (${p.name})`
|
|
508
505
|
).join(", ");
|
|
509
506
|
throw new Error(
|
|
510
|
-
`Unknown persona "${
|
|
507
|
+
`Unknown persona "${input4}". Available: ${available}`
|
|
511
508
|
);
|
|
512
509
|
}
|
|
513
510
|
return persona.id;
|
|
@@ -1266,8 +1263,8 @@ function cached(getter) {
|
|
|
1266
1263
|
}
|
|
1267
1264
|
};
|
|
1268
1265
|
}
|
|
1269
|
-
function nullish(
|
|
1270
|
-
return
|
|
1266
|
+
function nullish(input4) {
|
|
1267
|
+
return input4 === null || input4 === void 0;
|
|
1271
1268
|
}
|
|
1272
1269
|
function cleanRegex(source) {
|
|
1273
1270
|
const start = source.startsWith("^") ? 1 : 0;
|
|
@@ -1361,8 +1358,8 @@ function randomString(length = 10) {
|
|
|
1361
1358
|
function esc(str) {
|
|
1362
1359
|
return JSON.stringify(str);
|
|
1363
1360
|
}
|
|
1364
|
-
function slugify2(
|
|
1365
|
-
return
|
|
1361
|
+
function slugify2(input4) {
|
|
1362
|
+
return input4.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1366
1363
|
}
|
|
1367
1364
|
var captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => {
|
|
1368
1365
|
};
|
|
@@ -1744,19 +1741,19 @@ function finalizeIssue(iss, ctx, config2) {
|
|
|
1744
1741
|
}
|
|
1745
1742
|
return full;
|
|
1746
1743
|
}
|
|
1747
|
-
function getSizableOrigin(
|
|
1748
|
-
if (
|
|
1744
|
+
function getSizableOrigin(input4) {
|
|
1745
|
+
if (input4 instanceof Set)
|
|
1749
1746
|
return "set";
|
|
1750
|
-
if (
|
|
1747
|
+
if (input4 instanceof Map)
|
|
1751
1748
|
return "map";
|
|
1752
|
-
if (
|
|
1749
|
+
if (input4 instanceof File)
|
|
1753
1750
|
return "file";
|
|
1754
1751
|
return "unknown";
|
|
1755
1752
|
}
|
|
1756
|
-
function getLengthableOrigin(
|
|
1757
|
-
if (Array.isArray(
|
|
1753
|
+
function getLengthableOrigin(input4) {
|
|
1754
|
+
if (Array.isArray(input4))
|
|
1758
1755
|
return "array";
|
|
1759
|
-
if (typeof
|
|
1756
|
+
if (typeof input4 === "string")
|
|
1760
1757
|
return "string";
|
|
1761
1758
|
return "unknown";
|
|
1762
1759
|
}
|
|
@@ -1782,12 +1779,12 @@ function parsedType(data) {
|
|
|
1782
1779
|
return t;
|
|
1783
1780
|
}
|
|
1784
1781
|
function issue(...args) {
|
|
1785
|
-
const [iss,
|
|
1782
|
+
const [iss, input4, inst] = args;
|
|
1786
1783
|
if (typeof iss === "string") {
|
|
1787
1784
|
return {
|
|
1788
1785
|
message: iss,
|
|
1789
1786
|
code: "custom",
|
|
1790
|
-
input:
|
|
1787
|
+
input: input4,
|
|
1791
1788
|
inst
|
|
1792
1789
|
};
|
|
1793
1790
|
}
|
|
@@ -2326,23 +2323,23 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
|
|
|
2326
2323
|
bag.pattern = integer;
|
|
2327
2324
|
});
|
|
2328
2325
|
inst._zod.check = (payload) => {
|
|
2329
|
-
const
|
|
2326
|
+
const input4 = payload.value;
|
|
2330
2327
|
if (isInt) {
|
|
2331
|
-
if (!Number.isInteger(
|
|
2328
|
+
if (!Number.isInteger(input4)) {
|
|
2332
2329
|
payload.issues.push({
|
|
2333
2330
|
expected: origin,
|
|
2334
2331
|
format: def.format,
|
|
2335
2332
|
code: "invalid_type",
|
|
2336
2333
|
continue: false,
|
|
2337
|
-
input:
|
|
2334
|
+
input: input4,
|
|
2338
2335
|
inst
|
|
2339
2336
|
});
|
|
2340
2337
|
return;
|
|
2341
2338
|
}
|
|
2342
|
-
if (!Number.isSafeInteger(
|
|
2343
|
-
if (
|
|
2339
|
+
if (!Number.isSafeInteger(input4)) {
|
|
2340
|
+
if (input4 > 0) {
|
|
2344
2341
|
payload.issues.push({
|
|
2345
|
-
input:
|
|
2342
|
+
input: input4,
|
|
2346
2343
|
code: "too_big",
|
|
2347
2344
|
maximum: Number.MAX_SAFE_INTEGER,
|
|
2348
2345
|
note: "Integers must be within the safe integer range.",
|
|
@@ -2353,7 +2350,7 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
|
|
|
2353
2350
|
});
|
|
2354
2351
|
} else {
|
|
2355
2352
|
payload.issues.push({
|
|
2356
|
-
input:
|
|
2353
|
+
input: input4,
|
|
2357
2354
|
code: "too_small",
|
|
2358
2355
|
minimum: Number.MIN_SAFE_INTEGER,
|
|
2359
2356
|
note: "Integers must be within the safe integer range.",
|
|
@@ -2366,10 +2363,10 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
|
|
|
2366
2363
|
return;
|
|
2367
2364
|
}
|
|
2368
2365
|
}
|
|
2369
|
-
if (
|
|
2366
|
+
if (input4 < minimum) {
|
|
2370
2367
|
payload.issues.push({
|
|
2371
2368
|
origin: "number",
|
|
2372
|
-
input:
|
|
2369
|
+
input: input4,
|
|
2373
2370
|
code: "too_small",
|
|
2374
2371
|
minimum,
|
|
2375
2372
|
inclusive: true,
|
|
@@ -2377,10 +2374,10 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
|
|
|
2377
2374
|
continue: !def.abort
|
|
2378
2375
|
});
|
|
2379
2376
|
}
|
|
2380
|
-
if (
|
|
2377
|
+
if (input4 > maximum) {
|
|
2381
2378
|
payload.issues.push({
|
|
2382
2379
|
origin: "number",
|
|
2383
|
-
input:
|
|
2380
|
+
input: input4,
|
|
2384
2381
|
code: "too_big",
|
|
2385
2382
|
maximum,
|
|
2386
2383
|
inclusive: true,
|
|
@@ -2400,11 +2397,11 @@ var $ZodCheckBigIntFormat = /* @__PURE__ */ $constructor("$ZodCheckBigIntFormat"
|
|
|
2400
2397
|
bag.maximum = maximum;
|
|
2401
2398
|
});
|
|
2402
2399
|
inst._zod.check = (payload) => {
|
|
2403
|
-
const
|
|
2404
|
-
if (
|
|
2400
|
+
const input4 = payload.value;
|
|
2401
|
+
if (input4 < minimum) {
|
|
2405
2402
|
payload.issues.push({
|
|
2406
2403
|
origin: "bigint",
|
|
2407
|
-
input:
|
|
2404
|
+
input: input4,
|
|
2408
2405
|
code: "too_small",
|
|
2409
2406
|
minimum,
|
|
2410
2407
|
inclusive: true,
|
|
@@ -2412,10 +2409,10 @@ var $ZodCheckBigIntFormat = /* @__PURE__ */ $constructor("$ZodCheckBigIntFormat"
|
|
|
2412
2409
|
continue: !def.abort
|
|
2413
2410
|
});
|
|
2414
2411
|
}
|
|
2415
|
-
if (
|
|
2412
|
+
if (input4 > maximum) {
|
|
2416
2413
|
payload.issues.push({
|
|
2417
2414
|
origin: "bigint",
|
|
2418
|
-
input:
|
|
2415
|
+
input: input4,
|
|
2419
2416
|
code: "too_big",
|
|
2420
2417
|
maximum,
|
|
2421
2418
|
inclusive: true,
|
|
@@ -2438,16 +2435,16 @@ var $ZodCheckMaxSize = /* @__PURE__ */ $constructor("$ZodCheckMaxSize", (inst, d
|
|
|
2438
2435
|
inst2._zod.bag.maximum = def.maximum;
|
|
2439
2436
|
});
|
|
2440
2437
|
inst._zod.check = (payload) => {
|
|
2441
|
-
const
|
|
2442
|
-
const size =
|
|
2438
|
+
const input4 = payload.value;
|
|
2439
|
+
const size = input4.size;
|
|
2443
2440
|
if (size <= def.maximum)
|
|
2444
2441
|
return;
|
|
2445
2442
|
payload.issues.push({
|
|
2446
|
-
origin: getSizableOrigin(
|
|
2443
|
+
origin: getSizableOrigin(input4),
|
|
2447
2444
|
code: "too_big",
|
|
2448
2445
|
maximum: def.maximum,
|
|
2449
2446
|
inclusive: true,
|
|
2450
|
-
input:
|
|
2447
|
+
input: input4,
|
|
2451
2448
|
inst,
|
|
2452
2449
|
continue: !def.abort
|
|
2453
2450
|
});
|
|
@@ -2466,16 +2463,16 @@ var $ZodCheckMinSize = /* @__PURE__ */ $constructor("$ZodCheckMinSize", (inst, d
|
|
|
2466
2463
|
inst2._zod.bag.minimum = def.minimum;
|
|
2467
2464
|
});
|
|
2468
2465
|
inst._zod.check = (payload) => {
|
|
2469
|
-
const
|
|
2470
|
-
const size =
|
|
2466
|
+
const input4 = payload.value;
|
|
2467
|
+
const size = input4.size;
|
|
2471
2468
|
if (size >= def.minimum)
|
|
2472
2469
|
return;
|
|
2473
2470
|
payload.issues.push({
|
|
2474
|
-
origin: getSizableOrigin(
|
|
2471
|
+
origin: getSizableOrigin(input4),
|
|
2475
2472
|
code: "too_small",
|
|
2476
2473
|
minimum: def.minimum,
|
|
2477
2474
|
inclusive: true,
|
|
2478
|
-
input:
|
|
2475
|
+
input: input4,
|
|
2479
2476
|
inst,
|
|
2480
2477
|
continue: !def.abort
|
|
2481
2478
|
});
|
|
@@ -2495,13 +2492,13 @@ var $ZodCheckSizeEquals = /* @__PURE__ */ $constructor("$ZodCheckSizeEquals", (i
|
|
|
2495
2492
|
bag.size = def.size;
|
|
2496
2493
|
});
|
|
2497
2494
|
inst._zod.check = (payload) => {
|
|
2498
|
-
const
|
|
2499
|
-
const size =
|
|
2495
|
+
const input4 = payload.value;
|
|
2496
|
+
const size = input4.size;
|
|
2500
2497
|
if (size === def.size)
|
|
2501
2498
|
return;
|
|
2502
2499
|
const tooBig = size > def.size;
|
|
2503
2500
|
payload.issues.push({
|
|
2504
|
-
origin: getSizableOrigin(
|
|
2501
|
+
origin: getSizableOrigin(input4),
|
|
2505
2502
|
...tooBig ? { code: "too_big", maximum: def.size } : { code: "too_small", minimum: def.size },
|
|
2506
2503
|
inclusive: true,
|
|
2507
2504
|
exact: true,
|
|
@@ -2524,17 +2521,17 @@ var $ZodCheckMaxLength = /* @__PURE__ */ $constructor("$ZodCheckMaxLength", (ins
|
|
|
2524
2521
|
inst2._zod.bag.maximum = def.maximum;
|
|
2525
2522
|
});
|
|
2526
2523
|
inst._zod.check = (payload) => {
|
|
2527
|
-
const
|
|
2528
|
-
const length =
|
|
2524
|
+
const input4 = payload.value;
|
|
2525
|
+
const length = input4.length;
|
|
2529
2526
|
if (length <= def.maximum)
|
|
2530
2527
|
return;
|
|
2531
|
-
const origin = getLengthableOrigin(
|
|
2528
|
+
const origin = getLengthableOrigin(input4);
|
|
2532
2529
|
payload.issues.push({
|
|
2533
2530
|
origin,
|
|
2534
2531
|
code: "too_big",
|
|
2535
2532
|
maximum: def.maximum,
|
|
2536
2533
|
inclusive: true,
|
|
2537
|
-
input:
|
|
2534
|
+
input: input4,
|
|
2538
2535
|
inst,
|
|
2539
2536
|
continue: !def.abort
|
|
2540
2537
|
});
|
|
@@ -2553,17 +2550,17 @@ var $ZodCheckMinLength = /* @__PURE__ */ $constructor("$ZodCheckMinLength", (ins
|
|
|
2553
2550
|
inst2._zod.bag.minimum = def.minimum;
|
|
2554
2551
|
});
|
|
2555
2552
|
inst._zod.check = (payload) => {
|
|
2556
|
-
const
|
|
2557
|
-
const length =
|
|
2553
|
+
const input4 = payload.value;
|
|
2554
|
+
const length = input4.length;
|
|
2558
2555
|
if (length >= def.minimum)
|
|
2559
2556
|
return;
|
|
2560
|
-
const origin = getLengthableOrigin(
|
|
2557
|
+
const origin = getLengthableOrigin(input4);
|
|
2561
2558
|
payload.issues.push({
|
|
2562
2559
|
origin,
|
|
2563
2560
|
code: "too_small",
|
|
2564
2561
|
minimum: def.minimum,
|
|
2565
2562
|
inclusive: true,
|
|
2566
|
-
input:
|
|
2563
|
+
input: input4,
|
|
2567
2564
|
inst,
|
|
2568
2565
|
continue: !def.abort
|
|
2569
2566
|
});
|
|
@@ -2583,11 +2580,11 @@ var $ZodCheckLengthEquals = /* @__PURE__ */ $constructor("$ZodCheckLengthEquals"
|
|
|
2583
2580
|
bag.length = def.length;
|
|
2584
2581
|
});
|
|
2585
2582
|
inst._zod.check = (payload) => {
|
|
2586
|
-
const
|
|
2587
|
-
const length =
|
|
2583
|
+
const input4 = payload.value;
|
|
2584
|
+
const length = input4.length;
|
|
2588
2585
|
if (length === def.length)
|
|
2589
2586
|
return;
|
|
2590
|
-
const origin = getLengthableOrigin(
|
|
2587
|
+
const origin = getLengthableOrigin(input4);
|
|
2591
2588
|
const tooBig = length > def.length;
|
|
2592
2589
|
payload.issues.push({
|
|
2593
2590
|
origin,
|
|
@@ -3241,15 +3238,15 @@ var $ZodNumber = /* @__PURE__ */ $constructor("$ZodNumber", (inst, def) => {
|
|
|
3241
3238
|
payload.value = Number(payload.value);
|
|
3242
3239
|
} catch (_) {
|
|
3243
3240
|
}
|
|
3244
|
-
const
|
|
3245
|
-
if (typeof
|
|
3241
|
+
const input4 = payload.value;
|
|
3242
|
+
if (typeof input4 === "number" && !Number.isNaN(input4) && Number.isFinite(input4)) {
|
|
3246
3243
|
return payload;
|
|
3247
3244
|
}
|
|
3248
|
-
const received = typeof
|
|
3245
|
+
const received = typeof input4 === "number" ? Number.isNaN(input4) ? "NaN" : !Number.isFinite(input4) ? "Infinity" : void 0 : void 0;
|
|
3249
3246
|
payload.issues.push({
|
|
3250
3247
|
expected: "number",
|
|
3251
3248
|
code: "invalid_type",
|
|
3252
|
-
input:
|
|
3249
|
+
input: input4,
|
|
3253
3250
|
inst,
|
|
3254
3251
|
...received ? { received } : {}
|
|
3255
3252
|
});
|
|
@@ -3269,13 +3266,13 @@ var $ZodBoolean = /* @__PURE__ */ $constructor("$ZodBoolean", (inst, def) => {
|
|
|
3269
3266
|
payload.value = Boolean(payload.value);
|
|
3270
3267
|
} catch (_) {
|
|
3271
3268
|
}
|
|
3272
|
-
const
|
|
3273
|
-
if (typeof
|
|
3269
|
+
const input4 = payload.value;
|
|
3270
|
+
if (typeof input4 === "boolean")
|
|
3274
3271
|
return payload;
|
|
3275
3272
|
payload.issues.push({
|
|
3276
3273
|
expected: "boolean",
|
|
3277
3274
|
code: "invalid_type",
|
|
3278
|
-
input:
|
|
3275
|
+
input: input4,
|
|
3279
3276
|
inst
|
|
3280
3277
|
});
|
|
3281
3278
|
return payload;
|
|
@@ -3308,13 +3305,13 @@ var $ZodBigIntFormat = /* @__PURE__ */ $constructor("$ZodBigIntFormat", (inst, d
|
|
|
3308
3305
|
var $ZodSymbol = /* @__PURE__ */ $constructor("$ZodSymbol", (inst, def) => {
|
|
3309
3306
|
$ZodType.init(inst, def);
|
|
3310
3307
|
inst._zod.parse = (payload, _ctx) => {
|
|
3311
|
-
const
|
|
3312
|
-
if (typeof
|
|
3308
|
+
const input4 = payload.value;
|
|
3309
|
+
if (typeof input4 === "symbol")
|
|
3313
3310
|
return payload;
|
|
3314
3311
|
payload.issues.push({
|
|
3315
3312
|
expected: "symbol",
|
|
3316
3313
|
code: "invalid_type",
|
|
3317
|
-
input:
|
|
3314
|
+
input: input4,
|
|
3318
3315
|
inst
|
|
3319
3316
|
});
|
|
3320
3317
|
return payload;
|
|
@@ -3327,13 +3324,13 @@ var $ZodUndefined = /* @__PURE__ */ $constructor("$ZodUndefined", (inst, def) =>
|
|
|
3327
3324
|
inst._zod.optin = "optional";
|
|
3328
3325
|
inst._zod.optout = "optional";
|
|
3329
3326
|
inst._zod.parse = (payload, _ctx) => {
|
|
3330
|
-
const
|
|
3331
|
-
if (typeof
|
|
3327
|
+
const input4 = payload.value;
|
|
3328
|
+
if (typeof input4 === "undefined")
|
|
3332
3329
|
return payload;
|
|
3333
3330
|
payload.issues.push({
|
|
3334
3331
|
expected: "undefined",
|
|
3335
3332
|
code: "invalid_type",
|
|
3336
|
-
input:
|
|
3333
|
+
input: input4,
|
|
3337
3334
|
inst
|
|
3338
3335
|
});
|
|
3339
3336
|
return payload;
|
|
@@ -3344,13 +3341,13 @@ var $ZodNull = /* @__PURE__ */ $constructor("$ZodNull", (inst, def) => {
|
|
|
3344
3341
|
inst._zod.pattern = _null;
|
|
3345
3342
|
inst._zod.values = /* @__PURE__ */ new Set([null]);
|
|
3346
3343
|
inst._zod.parse = (payload, _ctx) => {
|
|
3347
|
-
const
|
|
3348
|
-
if (
|
|
3344
|
+
const input4 = payload.value;
|
|
3345
|
+
if (input4 === null)
|
|
3349
3346
|
return payload;
|
|
3350
3347
|
payload.issues.push({
|
|
3351
3348
|
expected: "null",
|
|
3352
3349
|
code: "invalid_type",
|
|
3353
|
-
input:
|
|
3350
|
+
input: input4,
|
|
3354
3351
|
inst
|
|
3355
3352
|
});
|
|
3356
3353
|
return payload;
|
|
@@ -3379,13 +3376,13 @@ var $ZodNever = /* @__PURE__ */ $constructor("$ZodNever", (inst, def) => {
|
|
|
3379
3376
|
var $ZodVoid = /* @__PURE__ */ $constructor("$ZodVoid", (inst, def) => {
|
|
3380
3377
|
$ZodType.init(inst, def);
|
|
3381
3378
|
inst._zod.parse = (payload, _ctx) => {
|
|
3382
|
-
const
|
|
3383
|
-
if (typeof
|
|
3379
|
+
const input4 = payload.value;
|
|
3380
|
+
if (typeof input4 === "undefined")
|
|
3384
3381
|
return payload;
|
|
3385
3382
|
payload.issues.push({
|
|
3386
3383
|
expected: "void",
|
|
3387
3384
|
code: "invalid_type",
|
|
3388
|
-
input:
|
|
3385
|
+
input: input4,
|
|
3389
3386
|
inst
|
|
3390
3387
|
});
|
|
3391
3388
|
return payload;
|
|
@@ -3400,15 +3397,15 @@ var $ZodDate = /* @__PURE__ */ $constructor("$ZodDate", (inst, def) => {
|
|
|
3400
3397
|
} catch (_err) {
|
|
3401
3398
|
}
|
|
3402
3399
|
}
|
|
3403
|
-
const
|
|
3404
|
-
const isDate =
|
|
3405
|
-
const isValidDate = isDate && !Number.isNaN(
|
|
3400
|
+
const input4 = payload.value;
|
|
3401
|
+
const isDate = input4 instanceof Date;
|
|
3402
|
+
const isValidDate = isDate && !Number.isNaN(input4.getTime());
|
|
3406
3403
|
if (isValidDate)
|
|
3407
3404
|
return payload;
|
|
3408
3405
|
payload.issues.push({
|
|
3409
3406
|
expected: "date",
|
|
3410
3407
|
code: "invalid_type",
|
|
3411
|
-
input:
|
|
3408
|
+
input: input4,
|
|
3412
3409
|
...isDate ? { received: "Invalid Date" } : {},
|
|
3413
3410
|
inst
|
|
3414
3411
|
});
|
|
@@ -3424,20 +3421,20 @@ function handleArrayResult(result, final, index) {
|
|
|
3424
3421
|
var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
|
|
3425
3422
|
$ZodType.init(inst, def);
|
|
3426
3423
|
inst._zod.parse = (payload, ctx) => {
|
|
3427
|
-
const
|
|
3428
|
-
if (!Array.isArray(
|
|
3424
|
+
const input4 = payload.value;
|
|
3425
|
+
if (!Array.isArray(input4)) {
|
|
3429
3426
|
payload.issues.push({
|
|
3430
3427
|
expected: "array",
|
|
3431
3428
|
code: "invalid_type",
|
|
3432
|
-
input:
|
|
3429
|
+
input: input4,
|
|
3433
3430
|
inst
|
|
3434
3431
|
});
|
|
3435
3432
|
return payload;
|
|
3436
3433
|
}
|
|
3437
|
-
payload.value = Array(
|
|
3434
|
+
payload.value = Array(input4.length);
|
|
3438
3435
|
const proms = [];
|
|
3439
|
-
for (let i = 0; i <
|
|
3440
|
-
const item =
|
|
3436
|
+
for (let i = 0; i < input4.length; i++) {
|
|
3437
|
+
const item = input4[i];
|
|
3441
3438
|
const result = def.element._zod.run({
|
|
3442
3439
|
value: item,
|
|
3443
3440
|
issues: []
|
|
@@ -3454,15 +3451,15 @@ var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
|
|
|
3454
3451
|
return payload;
|
|
3455
3452
|
};
|
|
3456
3453
|
});
|
|
3457
|
-
function handlePropertyResult(result, final, key,
|
|
3454
|
+
function handlePropertyResult(result, final, key, input4, isOptionalOut) {
|
|
3458
3455
|
if (result.issues.length) {
|
|
3459
|
-
if (isOptionalOut && !(key in
|
|
3456
|
+
if (isOptionalOut && !(key in input4)) {
|
|
3460
3457
|
return;
|
|
3461
3458
|
}
|
|
3462
3459
|
final.issues.push(...prefixIssues(key, result.issues));
|
|
3463
3460
|
}
|
|
3464
3461
|
if (result.value === void 0) {
|
|
3465
|
-
if (key in
|
|
3462
|
+
if (key in input4) {
|
|
3466
3463
|
final.value[key] = void 0;
|
|
3467
3464
|
}
|
|
3468
3465
|
} else {
|
|
@@ -3485,31 +3482,31 @@ function normalizeDef(def) {
|
|
|
3485
3482
|
optionalKeys: new Set(okeys)
|
|
3486
3483
|
};
|
|
3487
3484
|
}
|
|
3488
|
-
function handleCatchall(proms,
|
|
3485
|
+
function handleCatchall(proms, input4, payload, ctx, def, inst) {
|
|
3489
3486
|
const unrecognized = [];
|
|
3490
3487
|
const keySet = def.keySet;
|
|
3491
3488
|
const _catchall = def.catchall._zod;
|
|
3492
3489
|
const t = _catchall.def.type;
|
|
3493
3490
|
const isOptionalOut = _catchall.optout === "optional";
|
|
3494
|
-
for (const key in
|
|
3491
|
+
for (const key in input4) {
|
|
3495
3492
|
if (keySet.has(key))
|
|
3496
3493
|
continue;
|
|
3497
3494
|
if (t === "never") {
|
|
3498
3495
|
unrecognized.push(key);
|
|
3499
3496
|
continue;
|
|
3500
3497
|
}
|
|
3501
|
-
const r = _catchall.run({ value:
|
|
3498
|
+
const r = _catchall.run({ value: input4[key], issues: [] }, ctx);
|
|
3502
3499
|
if (r instanceof Promise) {
|
|
3503
|
-
proms.push(r.then((r2) => handlePropertyResult(r2, payload, key,
|
|
3500
|
+
proms.push(r.then((r2) => handlePropertyResult(r2, payload, key, input4, isOptionalOut)));
|
|
3504
3501
|
} else {
|
|
3505
|
-
handlePropertyResult(r, payload, key,
|
|
3502
|
+
handlePropertyResult(r, payload, key, input4, isOptionalOut);
|
|
3506
3503
|
}
|
|
3507
3504
|
}
|
|
3508
3505
|
if (unrecognized.length) {
|
|
3509
3506
|
payload.issues.push({
|
|
3510
3507
|
code: "unrecognized_keys",
|
|
3511
3508
|
keys: unrecognized,
|
|
3512
|
-
input:
|
|
3509
|
+
input: input4,
|
|
3513
3510
|
inst
|
|
3514
3511
|
});
|
|
3515
3512
|
}
|
|
@@ -3553,12 +3550,12 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
3553
3550
|
let value;
|
|
3554
3551
|
inst._zod.parse = (payload, ctx) => {
|
|
3555
3552
|
value ?? (value = _normalized.value);
|
|
3556
|
-
const
|
|
3557
|
-
if (!isObject2(
|
|
3553
|
+
const input4 = payload.value;
|
|
3554
|
+
if (!isObject2(input4)) {
|
|
3558
3555
|
payload.issues.push({
|
|
3559
3556
|
expected: "object",
|
|
3560
3557
|
code: "invalid_type",
|
|
3561
|
-
input:
|
|
3558
|
+
input: input4,
|
|
3562
3559
|
inst
|
|
3563
3560
|
});
|
|
3564
3561
|
return payload;
|
|
@@ -3569,17 +3566,17 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
3569
3566
|
for (const key of value.keys) {
|
|
3570
3567
|
const el = shape[key];
|
|
3571
3568
|
const isOptionalOut = el._zod.optout === "optional";
|
|
3572
|
-
const r = el._zod.run({ value:
|
|
3569
|
+
const r = el._zod.run({ value: input4[key], issues: [] }, ctx);
|
|
3573
3570
|
if (r instanceof Promise) {
|
|
3574
|
-
proms.push(r.then((r2) => handlePropertyResult(r2, payload, key,
|
|
3571
|
+
proms.push(r.then((r2) => handlePropertyResult(r2, payload, key, input4, isOptionalOut)));
|
|
3575
3572
|
} else {
|
|
3576
|
-
handlePropertyResult(r, payload, key,
|
|
3573
|
+
handlePropertyResult(r, payload, key, input4, isOptionalOut);
|
|
3577
3574
|
}
|
|
3578
3575
|
}
|
|
3579
3576
|
if (!catchall) {
|
|
3580
3577
|
return proms.length ? Promise.all(proms).then(() => payload) : payload;
|
|
3581
3578
|
}
|
|
3582
|
-
return handleCatchall(proms,
|
|
3579
|
+
return handleCatchall(proms, input4, payload, ctx, _normalized.value, inst);
|
|
3583
3580
|
};
|
|
3584
3581
|
});
|
|
3585
3582
|
var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) => {
|
|
@@ -3660,12 +3657,12 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
3660
3657
|
let value;
|
|
3661
3658
|
inst._zod.parse = (payload, ctx) => {
|
|
3662
3659
|
value ?? (value = _normalized.value);
|
|
3663
|
-
const
|
|
3664
|
-
if (!isObject2(
|
|
3660
|
+
const input4 = payload.value;
|
|
3661
|
+
if (!isObject2(input4)) {
|
|
3665
3662
|
payload.issues.push({
|
|
3666
3663
|
expected: "object",
|
|
3667
3664
|
code: "invalid_type",
|
|
3668
|
-
input:
|
|
3665
|
+
input: input4,
|
|
3669
3666
|
inst
|
|
3670
3667
|
});
|
|
3671
3668
|
return payload;
|
|
@@ -3676,7 +3673,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
3676
3673
|
payload = fastpass(payload, ctx);
|
|
3677
3674
|
if (!catchall)
|
|
3678
3675
|
return payload;
|
|
3679
|
-
return handleCatchall([],
|
|
3676
|
+
return handleCatchall([], input4, payload, ctx, value, inst);
|
|
3680
3677
|
}
|
|
3681
3678
|
return superParse(payload, ctx);
|
|
3682
3679
|
};
|
|
@@ -3838,17 +3835,17 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
|
|
|
3838
3835
|
return map2;
|
|
3839
3836
|
});
|
|
3840
3837
|
inst._zod.parse = (payload, ctx) => {
|
|
3841
|
-
const
|
|
3842
|
-
if (!isObject(
|
|
3838
|
+
const input4 = payload.value;
|
|
3839
|
+
if (!isObject(input4)) {
|
|
3843
3840
|
payload.issues.push({
|
|
3844
3841
|
code: "invalid_type",
|
|
3845
3842
|
expected: "object",
|
|
3846
|
-
input:
|
|
3843
|
+
input: input4,
|
|
3847
3844
|
inst
|
|
3848
3845
|
});
|
|
3849
3846
|
return payload;
|
|
3850
3847
|
}
|
|
3851
|
-
const opt = disc.value.get(
|
|
3848
|
+
const opt = disc.value.get(input4?.[def.discriminator]);
|
|
3852
3849
|
if (opt) {
|
|
3853
3850
|
return opt._zod.run(payload, ctx);
|
|
3854
3851
|
}
|
|
@@ -3860,7 +3857,7 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
|
|
|
3860
3857
|
errors: [],
|
|
3861
3858
|
note: "No matching discriminator",
|
|
3862
3859
|
discriminator: def.discriminator,
|
|
3863
|
-
input:
|
|
3860
|
+
input: input4,
|
|
3864
3861
|
path: [def.discriminator],
|
|
3865
3862
|
inst
|
|
3866
3863
|
});
|
|
@@ -3870,9 +3867,9 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
|
|
|
3870
3867
|
var $ZodIntersection = /* @__PURE__ */ $constructor("$ZodIntersection", (inst, def) => {
|
|
3871
3868
|
$ZodType.init(inst, def);
|
|
3872
3869
|
inst._zod.parse = (payload, ctx) => {
|
|
3873
|
-
const
|
|
3874
|
-
const left = def.left._zod.run({ value:
|
|
3875
|
-
const right = def.right._zod.run({ value:
|
|
3870
|
+
const input4 = payload.value;
|
|
3871
|
+
const left = def.left._zod.run({ value: input4, issues: [] }, ctx);
|
|
3872
|
+
const right = def.right._zod.run({ value: input4, issues: [] }, ctx);
|
|
3876
3873
|
const async = left instanceof Promise || right instanceof Promise;
|
|
3877
3874
|
if (async) {
|
|
3878
3875
|
return Promise.all([left, right]).then(([left2, right2]) => {
|
|
@@ -3969,10 +3966,10 @@ var $ZodTuple = /* @__PURE__ */ $constructor("$ZodTuple", (inst, def) => {
|
|
|
3969
3966
|
$ZodType.init(inst, def);
|
|
3970
3967
|
const items = def.items;
|
|
3971
3968
|
inst._zod.parse = (payload, ctx) => {
|
|
3972
|
-
const
|
|
3973
|
-
if (!Array.isArray(
|
|
3969
|
+
const input4 = payload.value;
|
|
3970
|
+
if (!Array.isArray(input4)) {
|
|
3974
3971
|
payload.issues.push({
|
|
3975
|
-
input:
|
|
3972
|
+
input: input4,
|
|
3976
3973
|
inst,
|
|
3977
3974
|
expected: "tuple",
|
|
3978
3975
|
code: "invalid_type"
|
|
@@ -3984,12 +3981,12 @@ var $ZodTuple = /* @__PURE__ */ $constructor("$ZodTuple", (inst, def) => {
|
|
|
3984
3981
|
const reversedIndex = [...items].reverse().findIndex((item) => item._zod.optin !== "optional");
|
|
3985
3982
|
const optStart = reversedIndex === -1 ? 0 : items.length - reversedIndex;
|
|
3986
3983
|
if (!def.rest) {
|
|
3987
|
-
const tooBig =
|
|
3988
|
-
const tooSmall =
|
|
3984
|
+
const tooBig = input4.length > items.length;
|
|
3985
|
+
const tooSmall = input4.length < optStart - 1;
|
|
3989
3986
|
if (tooBig || tooSmall) {
|
|
3990
3987
|
payload.issues.push({
|
|
3991
3988
|
...tooBig ? { code: "too_big", maximum: items.length, inclusive: true } : { code: "too_small", minimum: items.length },
|
|
3992
|
-
input:
|
|
3989
|
+
input: input4,
|
|
3993
3990
|
inst,
|
|
3994
3991
|
origin: "array"
|
|
3995
3992
|
});
|
|
@@ -3999,12 +3996,12 @@ var $ZodTuple = /* @__PURE__ */ $constructor("$ZodTuple", (inst, def) => {
|
|
|
3999
3996
|
let i = -1;
|
|
4000
3997
|
for (const item of items) {
|
|
4001
3998
|
i++;
|
|
4002
|
-
if (i >=
|
|
3999
|
+
if (i >= input4.length) {
|
|
4003
4000
|
if (i >= optStart)
|
|
4004
4001
|
continue;
|
|
4005
4002
|
}
|
|
4006
4003
|
const result = item._zod.run({
|
|
4007
|
-
value:
|
|
4004
|
+
value: input4[i],
|
|
4008
4005
|
issues: []
|
|
4009
4006
|
}, ctx);
|
|
4010
4007
|
if (result instanceof Promise) {
|
|
@@ -4014,7 +4011,7 @@ var $ZodTuple = /* @__PURE__ */ $constructor("$ZodTuple", (inst, def) => {
|
|
|
4014
4011
|
}
|
|
4015
4012
|
}
|
|
4016
4013
|
if (def.rest) {
|
|
4017
|
-
const rest =
|
|
4014
|
+
const rest = input4.slice(items.length);
|
|
4018
4015
|
for (const el of rest) {
|
|
4019
4016
|
i++;
|
|
4020
4017
|
const result = def.rest._zod.run({
|
|
@@ -4042,12 +4039,12 @@ function handleTupleResult(result, final, index) {
|
|
|
4042
4039
|
var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
4043
4040
|
$ZodType.init(inst, def);
|
|
4044
4041
|
inst._zod.parse = (payload, ctx) => {
|
|
4045
|
-
const
|
|
4046
|
-
if (!isPlainObject(
|
|
4042
|
+
const input4 = payload.value;
|
|
4043
|
+
if (!isPlainObject(input4)) {
|
|
4047
4044
|
payload.issues.push({
|
|
4048
4045
|
expected: "record",
|
|
4049
4046
|
code: "invalid_type",
|
|
4050
|
-
input:
|
|
4047
|
+
input: input4,
|
|
4051
4048
|
inst
|
|
4052
4049
|
});
|
|
4053
4050
|
return payload;
|
|
@@ -4060,7 +4057,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
4060
4057
|
for (const key of values) {
|
|
4061
4058
|
if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
|
|
4062
4059
|
recordKeys.add(typeof key === "number" ? key.toString() : key);
|
|
4063
|
-
const result = def.valueType._zod.run({ value:
|
|
4060
|
+
const result = def.valueType._zod.run({ value: input4[key], issues: [] }, ctx);
|
|
4064
4061
|
if (result instanceof Promise) {
|
|
4065
4062
|
proms.push(result.then((result2) => {
|
|
4066
4063
|
if (result2.issues.length) {
|
|
@@ -4077,7 +4074,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
4077
4074
|
}
|
|
4078
4075
|
}
|
|
4079
4076
|
let unrecognized;
|
|
4080
|
-
for (const key in
|
|
4077
|
+
for (const key in input4) {
|
|
4081
4078
|
if (!recordKeys.has(key)) {
|
|
4082
4079
|
unrecognized = unrecognized ?? [];
|
|
4083
4080
|
unrecognized.push(key);
|
|
@@ -4086,14 +4083,14 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
4086
4083
|
if (unrecognized && unrecognized.length > 0) {
|
|
4087
4084
|
payload.issues.push({
|
|
4088
4085
|
code: "unrecognized_keys",
|
|
4089
|
-
input:
|
|
4086
|
+
input: input4,
|
|
4090
4087
|
inst,
|
|
4091
4088
|
keys: unrecognized
|
|
4092
4089
|
});
|
|
4093
4090
|
}
|
|
4094
4091
|
} else {
|
|
4095
4092
|
payload.value = {};
|
|
4096
|
-
for (const key of Reflect.ownKeys(
|
|
4093
|
+
for (const key of Reflect.ownKeys(input4)) {
|
|
4097
4094
|
if (key === "__proto__")
|
|
4098
4095
|
continue;
|
|
4099
4096
|
let keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);
|
|
@@ -4112,7 +4109,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
4112
4109
|
}
|
|
4113
4110
|
if (keyResult.issues.length) {
|
|
4114
4111
|
if (def.mode === "loose") {
|
|
4115
|
-
payload.value[key] =
|
|
4112
|
+
payload.value[key] = input4[key];
|
|
4116
4113
|
} else {
|
|
4117
4114
|
payload.issues.push({
|
|
4118
4115
|
code: "invalid_key",
|
|
@@ -4125,7 +4122,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
4125
4122
|
}
|
|
4126
4123
|
continue;
|
|
4127
4124
|
}
|
|
4128
|
-
const result = def.valueType._zod.run({ value:
|
|
4125
|
+
const result = def.valueType._zod.run({ value: input4[key], issues: [] }, ctx);
|
|
4129
4126
|
if (result instanceof Promise) {
|
|
4130
4127
|
proms.push(result.then((result2) => {
|
|
4131
4128
|
if (result2.issues.length) {
|
|
@@ -4150,27 +4147,27 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
4150
4147
|
var $ZodMap = /* @__PURE__ */ $constructor("$ZodMap", (inst, def) => {
|
|
4151
4148
|
$ZodType.init(inst, def);
|
|
4152
4149
|
inst._zod.parse = (payload, ctx) => {
|
|
4153
|
-
const
|
|
4154
|
-
if (!(
|
|
4150
|
+
const input4 = payload.value;
|
|
4151
|
+
if (!(input4 instanceof Map)) {
|
|
4155
4152
|
payload.issues.push({
|
|
4156
4153
|
expected: "map",
|
|
4157
4154
|
code: "invalid_type",
|
|
4158
|
-
input:
|
|
4155
|
+
input: input4,
|
|
4159
4156
|
inst
|
|
4160
4157
|
});
|
|
4161
4158
|
return payload;
|
|
4162
4159
|
}
|
|
4163
4160
|
const proms = [];
|
|
4164
4161
|
payload.value = /* @__PURE__ */ new Map();
|
|
4165
|
-
for (const [key, value] of
|
|
4162
|
+
for (const [key, value] of input4) {
|
|
4166
4163
|
const keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);
|
|
4167
4164
|
const valueResult = def.valueType._zod.run({ value, issues: [] }, ctx);
|
|
4168
4165
|
if (keyResult instanceof Promise || valueResult instanceof Promise) {
|
|
4169
4166
|
proms.push(Promise.all([keyResult, valueResult]).then(([keyResult2, valueResult2]) => {
|
|
4170
|
-
handleMapResult(keyResult2, valueResult2, payload, key,
|
|
4167
|
+
handleMapResult(keyResult2, valueResult2, payload, key, input4, inst, ctx);
|
|
4171
4168
|
}));
|
|
4172
4169
|
} else {
|
|
4173
|
-
handleMapResult(keyResult, valueResult, payload, key,
|
|
4170
|
+
handleMapResult(keyResult, valueResult, payload, key, input4, inst, ctx);
|
|
4174
4171
|
}
|
|
4175
4172
|
}
|
|
4176
4173
|
if (proms.length)
|
|
@@ -4178,7 +4175,7 @@ var $ZodMap = /* @__PURE__ */ $constructor("$ZodMap", (inst, def) => {
|
|
|
4178
4175
|
return payload;
|
|
4179
4176
|
};
|
|
4180
4177
|
});
|
|
4181
|
-
function handleMapResult(keyResult, valueResult, final, key,
|
|
4178
|
+
function handleMapResult(keyResult, valueResult, final, key, input4, inst, ctx) {
|
|
4182
4179
|
if (keyResult.issues.length) {
|
|
4183
4180
|
if (propertyKeyTypes.has(typeof key)) {
|
|
4184
4181
|
final.issues.push(...prefixIssues(key, keyResult.issues));
|
|
@@ -4186,7 +4183,7 @@ function handleMapResult(keyResult, valueResult, final, key, input3, inst, ctx)
|
|
|
4186
4183
|
final.issues.push({
|
|
4187
4184
|
code: "invalid_key",
|
|
4188
4185
|
origin: "map",
|
|
4189
|
-
input:
|
|
4186
|
+
input: input4,
|
|
4190
4187
|
inst,
|
|
4191
4188
|
issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config()))
|
|
4192
4189
|
});
|
|
@@ -4199,7 +4196,7 @@ function handleMapResult(keyResult, valueResult, final, key, input3, inst, ctx)
|
|
|
4199
4196
|
final.issues.push({
|
|
4200
4197
|
origin: "map",
|
|
4201
4198
|
code: "invalid_element",
|
|
4202
|
-
input:
|
|
4199
|
+
input: input4,
|
|
4203
4200
|
inst,
|
|
4204
4201
|
key,
|
|
4205
4202
|
issues: valueResult.issues.map((iss) => finalizeIssue(iss, ctx, config()))
|
|
@@ -4211,10 +4208,10 @@ function handleMapResult(keyResult, valueResult, final, key, input3, inst, ctx)
|
|
|
4211
4208
|
var $ZodSet = /* @__PURE__ */ $constructor("$ZodSet", (inst, def) => {
|
|
4212
4209
|
$ZodType.init(inst, def);
|
|
4213
4210
|
inst._zod.parse = (payload, ctx) => {
|
|
4214
|
-
const
|
|
4215
|
-
if (!(
|
|
4211
|
+
const input4 = payload.value;
|
|
4212
|
+
if (!(input4 instanceof Set)) {
|
|
4216
4213
|
payload.issues.push({
|
|
4217
|
-
input:
|
|
4214
|
+
input: input4,
|
|
4218
4215
|
inst,
|
|
4219
4216
|
expected: "set",
|
|
4220
4217
|
code: "invalid_type"
|
|
@@ -4223,7 +4220,7 @@ var $ZodSet = /* @__PURE__ */ $constructor("$ZodSet", (inst, def) => {
|
|
|
4223
4220
|
}
|
|
4224
4221
|
const proms = [];
|
|
4225
4222
|
payload.value = /* @__PURE__ */ new Set();
|
|
4226
|
-
for (const item of
|
|
4223
|
+
for (const item of input4) {
|
|
4227
4224
|
const result = def.valueType._zod.run({ value: item, issues: [] }, ctx);
|
|
4228
4225
|
if (result instanceof Promise) {
|
|
4229
4226
|
proms.push(result.then((result2) => handleSetResult(result2, payload)));
|
|
@@ -4248,14 +4245,14 @@ var $ZodEnum = /* @__PURE__ */ $constructor("$ZodEnum", (inst, def) => {
|
|
|
4248
4245
|
inst._zod.values = valuesSet;
|
|
4249
4246
|
inst._zod.pattern = new RegExp(`^(${values.filter((k) => propertyKeyTypes.has(typeof k)).map((o) => typeof o === "string" ? escapeRegex(o) : o.toString()).join("|")})$`);
|
|
4250
4247
|
inst._zod.parse = (payload, _ctx) => {
|
|
4251
|
-
const
|
|
4252
|
-
if (valuesSet.has(
|
|
4248
|
+
const input4 = payload.value;
|
|
4249
|
+
if (valuesSet.has(input4)) {
|
|
4253
4250
|
return payload;
|
|
4254
4251
|
}
|
|
4255
4252
|
payload.issues.push({
|
|
4256
4253
|
code: "invalid_value",
|
|
4257
4254
|
values,
|
|
4258
|
-
input:
|
|
4255
|
+
input: input4,
|
|
4259
4256
|
inst
|
|
4260
4257
|
});
|
|
4261
4258
|
return payload;
|
|
@@ -4270,14 +4267,14 @@ var $ZodLiteral = /* @__PURE__ */ $constructor("$ZodLiteral", (inst, def) => {
|
|
|
4270
4267
|
inst._zod.values = values;
|
|
4271
4268
|
inst._zod.pattern = new RegExp(`^(${def.values.map((o) => typeof o === "string" ? escapeRegex(o) : o ? escapeRegex(o.toString()) : String(o)).join("|")})$`);
|
|
4272
4269
|
inst._zod.parse = (payload, _ctx) => {
|
|
4273
|
-
const
|
|
4274
|
-
if (values.has(
|
|
4270
|
+
const input4 = payload.value;
|
|
4271
|
+
if (values.has(input4)) {
|
|
4275
4272
|
return payload;
|
|
4276
4273
|
}
|
|
4277
4274
|
payload.issues.push({
|
|
4278
4275
|
code: "invalid_value",
|
|
4279
4276
|
values: def.values,
|
|
4280
|
-
input:
|
|
4277
|
+
input: input4,
|
|
4281
4278
|
inst
|
|
4282
4279
|
});
|
|
4283
4280
|
return payload;
|
|
@@ -4286,13 +4283,13 @@ var $ZodLiteral = /* @__PURE__ */ $constructor("$ZodLiteral", (inst, def) => {
|
|
|
4286
4283
|
var $ZodFile = /* @__PURE__ */ $constructor("$ZodFile", (inst, def) => {
|
|
4287
4284
|
$ZodType.init(inst, def);
|
|
4288
4285
|
inst._zod.parse = (payload, _ctx) => {
|
|
4289
|
-
const
|
|
4290
|
-
if (
|
|
4286
|
+
const input4 = payload.value;
|
|
4287
|
+
if (input4 instanceof File)
|
|
4291
4288
|
return payload;
|
|
4292
4289
|
payload.issues.push({
|
|
4293
4290
|
expected: "file",
|
|
4294
4291
|
code: "invalid_type",
|
|
4295
|
-
input:
|
|
4292
|
+
input: input4,
|
|
4296
4293
|
inst
|
|
4297
4294
|
});
|
|
4298
4295
|
return payload;
|
|
@@ -4319,8 +4316,8 @@ var $ZodTransform = /* @__PURE__ */ $constructor("$ZodTransform", (inst, def) =>
|
|
|
4319
4316
|
return payload;
|
|
4320
4317
|
};
|
|
4321
4318
|
});
|
|
4322
|
-
function handleOptionalResult(result,
|
|
4323
|
-
if (result.issues.length &&
|
|
4319
|
+
function handleOptionalResult(result, input4) {
|
|
4320
|
+
if (result.issues.length && input4 === void 0) {
|
|
4324
4321
|
return { issues: [], value: void 0 };
|
|
4325
4322
|
}
|
|
4326
4323
|
return result;
|
|
@@ -4756,20 +4753,20 @@ var $ZodCustom = /* @__PURE__ */ $constructor("$ZodCustom", (inst, def) => {
|
|
|
4756
4753
|
return payload;
|
|
4757
4754
|
};
|
|
4758
4755
|
inst._zod.check = (payload) => {
|
|
4759
|
-
const
|
|
4760
|
-
const r = def.fn(
|
|
4756
|
+
const input4 = payload.value;
|
|
4757
|
+
const r = def.fn(input4);
|
|
4761
4758
|
if (r instanceof Promise) {
|
|
4762
|
-
return r.then((r2) => handleRefineResult(r2, payload,
|
|
4759
|
+
return r.then((r2) => handleRefineResult(r2, payload, input4, inst));
|
|
4763
4760
|
}
|
|
4764
|
-
handleRefineResult(r, payload,
|
|
4761
|
+
handleRefineResult(r, payload, input4, inst);
|
|
4765
4762
|
return;
|
|
4766
4763
|
};
|
|
4767
4764
|
});
|
|
4768
|
-
function handleRefineResult(result, payload,
|
|
4765
|
+
function handleRefineResult(result, payload, input4, inst) {
|
|
4769
4766
|
if (!result) {
|
|
4770
4767
|
const _iss = {
|
|
4771
4768
|
code: "custom",
|
|
4772
|
-
input:
|
|
4769
|
+
input: input4,
|
|
4773
4770
|
inst,
|
|
4774
4771
|
// incorporates params.error into issue reporting
|
|
4775
4772
|
path: [...inst._zod.def.path ?? []],
|
|
@@ -11079,23 +11076,23 @@ function _overwrite(tx) {
|
|
|
11079
11076
|
}
|
|
11080
11077
|
// @__NO_SIDE_EFFECTS__
|
|
11081
11078
|
function _normalize(form) {
|
|
11082
|
-
return /* @__PURE__ */ _overwrite((
|
|
11079
|
+
return /* @__PURE__ */ _overwrite((input4) => input4.normalize(form));
|
|
11083
11080
|
}
|
|
11084
11081
|
// @__NO_SIDE_EFFECTS__
|
|
11085
11082
|
function _trim() {
|
|
11086
|
-
return /* @__PURE__ */ _overwrite((
|
|
11083
|
+
return /* @__PURE__ */ _overwrite((input4) => input4.trim());
|
|
11087
11084
|
}
|
|
11088
11085
|
// @__NO_SIDE_EFFECTS__
|
|
11089
11086
|
function _toLowerCase() {
|
|
11090
|
-
return /* @__PURE__ */ _overwrite((
|
|
11087
|
+
return /* @__PURE__ */ _overwrite((input4) => input4.toLowerCase());
|
|
11091
11088
|
}
|
|
11092
11089
|
// @__NO_SIDE_EFFECTS__
|
|
11093
11090
|
function _toUpperCase() {
|
|
11094
|
-
return /* @__PURE__ */ _overwrite((
|
|
11091
|
+
return /* @__PURE__ */ _overwrite((input4) => input4.toUpperCase());
|
|
11095
11092
|
}
|
|
11096
11093
|
// @__NO_SIDE_EFFECTS__
|
|
11097
11094
|
function _slugify() {
|
|
11098
|
-
return /* @__PURE__ */ _overwrite((
|
|
11095
|
+
return /* @__PURE__ */ _overwrite((input4) => slugify2(input4));
|
|
11099
11096
|
}
|
|
11100
11097
|
// @__NO_SIDE_EFFECTS__
|
|
11101
11098
|
function _array(Class2, element, params) {
|
|
@@ -11400,8 +11397,8 @@ function _stringbool(Classes, _params) {
|
|
|
11400
11397
|
type: "pipe",
|
|
11401
11398
|
in: stringSchema,
|
|
11402
11399
|
out: booleanSchema,
|
|
11403
|
-
transform: ((
|
|
11404
|
-
let data =
|
|
11400
|
+
transform: ((input4, payload) => {
|
|
11401
|
+
let data = input4;
|
|
11405
11402
|
if (params.case !== "sensitive")
|
|
11406
11403
|
data = data.toLowerCase();
|
|
11407
11404
|
if (truthySet.has(data)) {
|
|
@@ -11420,8 +11417,8 @@ function _stringbool(Classes, _params) {
|
|
|
11420
11417
|
return {};
|
|
11421
11418
|
}
|
|
11422
11419
|
}),
|
|
11423
|
-
reverseTransform: ((
|
|
11424
|
-
if (
|
|
11420
|
+
reverseTransform: ((input4, _payload) => {
|
|
11421
|
+
if (input4 === true) {
|
|
11425
11422
|
return truthyArray[0] || "true";
|
|
11426
11423
|
} else {
|
|
11427
11424
|
return falsyArray[0] || "false";
|
|
@@ -12317,9 +12314,9 @@ var allProcessors = {
|
|
|
12317
12314
|
optional: optionalProcessor,
|
|
12318
12315
|
lazy: lazyProcessor
|
|
12319
12316
|
};
|
|
12320
|
-
function toJSONSchema(
|
|
12321
|
-
if ("_idmap" in
|
|
12322
|
-
const registry2 =
|
|
12317
|
+
function toJSONSchema(input4, params) {
|
|
12318
|
+
if ("_idmap" in input4) {
|
|
12319
|
+
const registry2 = input4;
|
|
12323
12320
|
const ctx2 = initializeContext({ ...params, processors: allProcessors });
|
|
12324
12321
|
const defs = {};
|
|
12325
12322
|
for (const entry of registry2._idmap.entries()) {
|
|
@@ -12347,9 +12344,9 @@ function toJSONSchema(input3, params) {
|
|
|
12347
12344
|
return { schemas };
|
|
12348
12345
|
}
|
|
12349
12346
|
const ctx = initializeContext({ ...params, processors: allProcessors });
|
|
12350
|
-
process2(
|
|
12351
|
-
extractDefs(ctx,
|
|
12352
|
-
return finalize(ctx,
|
|
12347
|
+
process2(input4, ctx);
|
|
12348
|
+
extractDefs(ctx, input4);
|
|
12349
|
+
return finalize(ctx, input4);
|
|
12353
12350
|
}
|
|
12354
12351
|
|
|
12355
12352
|
// node_modules/zod/v4/core/json-schema-generator.js
|
|
@@ -15302,6 +15299,128 @@ function createMeetingTools(store) {
|
|
|
15302
15299
|
|
|
15303
15300
|
// src/plugins/builtin/tools/reports.ts
|
|
15304
15301
|
import { tool as tool8 } from "@anthropic-ai/claude-agent-sdk";
|
|
15302
|
+
|
|
15303
|
+
// src/reports/gar/collector.ts
|
|
15304
|
+
function collectGarMetrics(store) {
|
|
15305
|
+
const allActions = store.list({ type: "action" });
|
|
15306
|
+
const openActions = allActions.filter((d) => d.frontmatter.status === "open");
|
|
15307
|
+
const doneActions = allActions.filter((d) => d.frontmatter.status === "done");
|
|
15308
|
+
const allDocs = store.list();
|
|
15309
|
+
const blockedItems = allDocs.filter(
|
|
15310
|
+
(d) => d.frontmatter.tags?.includes("blocked")
|
|
15311
|
+
);
|
|
15312
|
+
const overdueItems = allDocs.filter(
|
|
15313
|
+
(d) => d.frontmatter.tags?.includes("overdue")
|
|
15314
|
+
);
|
|
15315
|
+
const openQuestions = store.list({ type: "question", status: "open" });
|
|
15316
|
+
const riskItems = allDocs.filter(
|
|
15317
|
+
(d) => d.frontmatter.tags?.includes("risk")
|
|
15318
|
+
);
|
|
15319
|
+
const unownedActions = openActions.filter((d) => !d.frontmatter.owner);
|
|
15320
|
+
const total = allActions.length;
|
|
15321
|
+
const done = doneActions.length;
|
|
15322
|
+
const completionPct = total > 0 ? Math.round(done / total * 100) : 100;
|
|
15323
|
+
const scheduleItems = [
|
|
15324
|
+
...blockedItems,
|
|
15325
|
+
...overdueItems
|
|
15326
|
+
].filter(
|
|
15327
|
+
(d, i, arr) => arr.findIndex((x) => x.frontmatter.id === d.frontmatter.id) === i
|
|
15328
|
+
).map((d) => ({ id: d.frontmatter.id, title: d.frontmatter.title }));
|
|
15329
|
+
const qualityItems = [
|
|
15330
|
+
...riskItems,
|
|
15331
|
+
...openQuestions
|
|
15332
|
+
].filter(
|
|
15333
|
+
(d, i, arr) => arr.findIndex((x) => x.frontmatter.id === d.frontmatter.id) === i
|
|
15334
|
+
).map((d) => ({ id: d.frontmatter.id, title: d.frontmatter.title }));
|
|
15335
|
+
const resourceItems = unownedActions.map((d) => ({
|
|
15336
|
+
id: d.frontmatter.id,
|
|
15337
|
+
title: d.frontmatter.title
|
|
15338
|
+
}));
|
|
15339
|
+
return {
|
|
15340
|
+
scope: {
|
|
15341
|
+
total,
|
|
15342
|
+
open: openActions.length,
|
|
15343
|
+
done,
|
|
15344
|
+
completionPct
|
|
15345
|
+
},
|
|
15346
|
+
schedule: {
|
|
15347
|
+
blocked: blockedItems.length,
|
|
15348
|
+
overdue: overdueItems.length,
|
|
15349
|
+
items: scheduleItems
|
|
15350
|
+
},
|
|
15351
|
+
quality: {
|
|
15352
|
+
risks: riskItems.length,
|
|
15353
|
+
openQuestions: openQuestions.length,
|
|
15354
|
+
items: qualityItems
|
|
15355
|
+
},
|
|
15356
|
+
resources: {
|
|
15357
|
+
unowned: unownedActions.length,
|
|
15358
|
+
items: resourceItems
|
|
15359
|
+
}
|
|
15360
|
+
};
|
|
15361
|
+
}
|
|
15362
|
+
|
|
15363
|
+
// src/reports/gar/evaluator.ts
|
|
15364
|
+
function worstStatus(statuses) {
|
|
15365
|
+
if (statuses.includes("red")) return "red";
|
|
15366
|
+
if (statuses.includes("amber")) return "amber";
|
|
15367
|
+
return "green";
|
|
15368
|
+
}
|
|
15369
|
+
function evaluateGar(projectName, metrics) {
|
|
15370
|
+
const areas = [];
|
|
15371
|
+
const scopePct = metrics.scope.completionPct;
|
|
15372
|
+
const scopeStatus = scopePct >= 70 ? "green" : scopePct >= 40 ? "amber" : "red";
|
|
15373
|
+
areas.push({
|
|
15374
|
+
name: "Scope",
|
|
15375
|
+
status: scopeStatus,
|
|
15376
|
+
summary: `${scopePct}% complete (${metrics.scope.done}/${metrics.scope.total})`,
|
|
15377
|
+
items: []
|
|
15378
|
+
});
|
|
15379
|
+
const scheduleCount = metrics.schedule.blocked + metrics.schedule.overdue;
|
|
15380
|
+
const scheduleStatus = scheduleCount === 0 ? "green" : scheduleCount <= 2 ? "amber" : "red";
|
|
15381
|
+
const scheduleParts = [];
|
|
15382
|
+
if (metrics.schedule.blocked > 0)
|
|
15383
|
+
scheduleParts.push(`${metrics.schedule.blocked} blocked`);
|
|
15384
|
+
if (metrics.schedule.overdue > 0)
|
|
15385
|
+
scheduleParts.push(`${metrics.schedule.overdue} overdue`);
|
|
15386
|
+
areas.push({
|
|
15387
|
+
name: "Schedule",
|
|
15388
|
+
status: scheduleStatus,
|
|
15389
|
+
summary: scheduleParts.length > 0 ? scheduleParts.join(", ") : "on track",
|
|
15390
|
+
items: metrics.schedule.items
|
|
15391
|
+
});
|
|
15392
|
+
const qualityCount = metrics.quality.risks + metrics.quality.openQuestions;
|
|
15393
|
+
const qualityStatus = qualityCount === 0 ? "green" : qualityCount <= 2 ? "amber" : "red";
|
|
15394
|
+
const qualityParts = [];
|
|
15395
|
+
if (metrics.quality.risks > 0)
|
|
15396
|
+
qualityParts.push(`${metrics.quality.risks} risk(s)`);
|
|
15397
|
+
if (metrics.quality.openQuestions > 0)
|
|
15398
|
+
qualityParts.push(`${metrics.quality.openQuestions} open question(s)`);
|
|
15399
|
+
areas.push({
|
|
15400
|
+
name: "Quality",
|
|
15401
|
+
status: qualityStatus,
|
|
15402
|
+
summary: qualityParts.length > 0 ? qualityParts.join(", ") : "no issues",
|
|
15403
|
+
items: metrics.quality.items
|
|
15404
|
+
});
|
|
15405
|
+
const resourceCount = metrics.resources.unowned;
|
|
15406
|
+
const resourceStatus = resourceCount === 0 ? "green" : resourceCount <= 2 ? "amber" : "red";
|
|
15407
|
+
areas.push({
|
|
15408
|
+
name: "Resources",
|
|
15409
|
+
status: resourceStatus,
|
|
15410
|
+
summary: resourceCount > 0 ? `${resourceCount} unowned action(s)` : "all assigned",
|
|
15411
|
+
items: metrics.resources.items
|
|
15412
|
+
});
|
|
15413
|
+
const overall = worstStatus(areas.map((a) => a.status));
|
|
15414
|
+
return {
|
|
15415
|
+
projectName,
|
|
15416
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
15417
|
+
overall,
|
|
15418
|
+
areas,
|
|
15419
|
+
metrics
|
|
15420
|
+
};
|
|
15421
|
+
}
|
|
15422
|
+
|
|
15423
|
+
// src/plugins/builtin/tools/reports.ts
|
|
15305
15424
|
function createReportTools(store) {
|
|
15306
15425
|
return [
|
|
15307
15426
|
tool8(
|
|
@@ -15390,41 +15509,10 @@ function createReportTools(store) {
|
|
|
15390
15509
|
"Generate a Green-Amber-Red report with metrics across scope, schedule, quality, and resources",
|
|
15391
15510
|
{},
|
|
15392
15511
|
async () => {
|
|
15393
|
-
const
|
|
15394
|
-
const
|
|
15395
|
-
const doneActions = allActions.filter((d) => d.frontmatter.status === "done");
|
|
15396
|
-
const allDocs = store.list();
|
|
15397
|
-
const blockedItems = allDocs.filter(
|
|
15398
|
-
(d) => d.frontmatter.tags?.includes("blocked")
|
|
15399
|
-
);
|
|
15400
|
-
const overdueItems = allDocs.filter(
|
|
15401
|
-
(d) => d.frontmatter.tags?.includes("overdue")
|
|
15402
|
-
);
|
|
15403
|
-
const openQuestions = store.list({ type: "question", status: "open" });
|
|
15404
|
-
const riskItems = allDocs.filter(
|
|
15405
|
-
(d) => d.frontmatter.tags?.includes("risk")
|
|
15406
|
-
);
|
|
15407
|
-
const unownedActions = openActions.filter((d) => !d.frontmatter.owner);
|
|
15408
|
-
const areas = {
|
|
15409
|
-
scope: {
|
|
15410
|
-
total: allActions.length,
|
|
15411
|
-
open: openActions.length,
|
|
15412
|
-
done: doneActions.length
|
|
15413
|
-
},
|
|
15414
|
-
schedule: {
|
|
15415
|
-
blocked: blockedItems.length,
|
|
15416
|
-
overdue: overdueItems.length
|
|
15417
|
-
},
|
|
15418
|
-
quality: {
|
|
15419
|
-
openQuestions: openQuestions.length,
|
|
15420
|
-
risks: riskItems.length
|
|
15421
|
-
},
|
|
15422
|
-
resources: {
|
|
15423
|
-
unowned: unownedActions.length
|
|
15424
|
-
}
|
|
15425
|
-
};
|
|
15512
|
+
const metrics = collectGarMetrics(store);
|
|
15513
|
+
const report = evaluateGar("project", metrics);
|
|
15426
15514
|
return {
|
|
15427
|
-
content: [{ type: "text", text: JSON.stringify(
|
|
15515
|
+
content: [{ type: "text", text: JSON.stringify(report, null, 2) }]
|
|
15428
15516
|
};
|
|
15429
15517
|
},
|
|
15430
15518
|
{ annotations: { readOnly: true } }
|
|
@@ -17502,9 +17590,492 @@ Be thorough but concise. Focus on actionable insights.`,
|
|
|
17502
17590
|
]
|
|
17503
17591
|
};
|
|
17504
17592
|
|
|
17593
|
+
// src/skills/builtin/jira/tools.ts
|
|
17594
|
+
import { tool as tool19 } from "@anthropic-ai/claude-agent-sdk";
|
|
17595
|
+
|
|
17596
|
+
// src/skills/builtin/jira/client.ts
|
|
17597
|
+
var JiraClient = class {
|
|
17598
|
+
baseUrl;
|
|
17599
|
+
authHeader;
|
|
17600
|
+
constructor(config2) {
|
|
17601
|
+
this.baseUrl = `https://${config2.host}/rest/api/2`;
|
|
17602
|
+
this.authHeader = "Basic " + Buffer.from(`${config2.email}:${config2.apiToken}`).toString("base64");
|
|
17603
|
+
}
|
|
17604
|
+
async request(path18, method = "GET", body) {
|
|
17605
|
+
const url2 = `${this.baseUrl}${path18}`;
|
|
17606
|
+
const headers = {
|
|
17607
|
+
Authorization: this.authHeader,
|
|
17608
|
+
"Content-Type": "application/json",
|
|
17609
|
+
Accept: "application/json"
|
|
17610
|
+
};
|
|
17611
|
+
const response = await fetch(url2, {
|
|
17612
|
+
method,
|
|
17613
|
+
headers,
|
|
17614
|
+
body: body ? JSON.stringify(body) : void 0
|
|
17615
|
+
});
|
|
17616
|
+
if (!response.ok) {
|
|
17617
|
+
const text = await response.text().catch(() => "");
|
|
17618
|
+
throw new Error(
|
|
17619
|
+
`Jira API error ${response.status} ${method} ${path18}: ${text}`
|
|
17620
|
+
);
|
|
17621
|
+
}
|
|
17622
|
+
if (response.status === 204) return void 0;
|
|
17623
|
+
return response.json();
|
|
17624
|
+
}
|
|
17625
|
+
async searchIssues(jql, maxResults = 50) {
|
|
17626
|
+
const params = new URLSearchParams({
|
|
17627
|
+
jql,
|
|
17628
|
+
maxResults: String(maxResults)
|
|
17629
|
+
});
|
|
17630
|
+
return this.request(`/search?${params}`);
|
|
17631
|
+
}
|
|
17632
|
+
async getIssue(key) {
|
|
17633
|
+
return this.request(`/issue/${encodeURIComponent(key)}`);
|
|
17634
|
+
}
|
|
17635
|
+
async createIssue(fields) {
|
|
17636
|
+
return this.request("/issue", "POST", { fields });
|
|
17637
|
+
}
|
|
17638
|
+
async updateIssue(key, fields) {
|
|
17639
|
+
await this.request(
|
|
17640
|
+
`/issue/${encodeURIComponent(key)}`,
|
|
17641
|
+
"PUT",
|
|
17642
|
+
{ fields }
|
|
17643
|
+
);
|
|
17644
|
+
}
|
|
17645
|
+
async addComment(key, body) {
|
|
17646
|
+
await this.request(
|
|
17647
|
+
`/issue/${encodeURIComponent(key)}/comment`,
|
|
17648
|
+
"POST",
|
|
17649
|
+
{ body }
|
|
17650
|
+
);
|
|
17651
|
+
}
|
|
17652
|
+
};
|
|
17653
|
+
function createJiraClient(jiraUserConfig) {
|
|
17654
|
+
const host = jiraUserConfig?.host ?? process.env.JIRA_HOST;
|
|
17655
|
+
const email3 = jiraUserConfig?.email ?? process.env.JIRA_EMAIL;
|
|
17656
|
+
const apiToken = jiraUserConfig?.apiToken ?? process.env.JIRA_API_TOKEN;
|
|
17657
|
+
if (!host || !email3 || !apiToken) return null;
|
|
17658
|
+
return { client: new JiraClient({ host, email: email3, apiToken }), host };
|
|
17659
|
+
}
|
|
17660
|
+
|
|
17661
|
+
// src/skills/builtin/jira/tools.ts
|
|
17662
|
+
var JIRA_TYPE = "jira-issue";
|
|
17663
|
+
function jiraNotConfiguredError() {
|
|
17664
|
+
return {
|
|
17665
|
+
content: [
|
|
17666
|
+
{
|
|
17667
|
+
type: "text",
|
|
17668
|
+
text: 'Jira is not configured. Run "marvin config jira" or set JIRA_HOST, JIRA_EMAIL, and JIRA_API_TOKEN environment variables.'
|
|
17669
|
+
}
|
|
17670
|
+
],
|
|
17671
|
+
isError: true
|
|
17672
|
+
};
|
|
17673
|
+
}
|
|
17674
|
+
function mapJiraStatus(jiraStatus) {
|
|
17675
|
+
const lower = jiraStatus.toLowerCase();
|
|
17676
|
+
if (lower === "done" || lower === "closed" || lower === "resolved") return "done";
|
|
17677
|
+
if (lower === "in progress" || lower === "in review") return "in-progress";
|
|
17678
|
+
return "open";
|
|
17679
|
+
}
|
|
17680
|
+
function jiraIssueToFrontmatter(issue2, host, linkedArtifacts) {
|
|
17681
|
+
return {
|
|
17682
|
+
title: issue2.fields.summary,
|
|
17683
|
+
status: mapJiraStatus(issue2.fields.status.name),
|
|
17684
|
+
jiraKey: issue2.key,
|
|
17685
|
+
jiraUrl: `https://${host}/browse/${issue2.key}`,
|
|
17686
|
+
issueType: issue2.fields.issuetype.name,
|
|
17687
|
+
priority: issue2.fields.priority?.name ?? "None",
|
|
17688
|
+
assignee: issue2.fields.assignee?.displayName ?? "",
|
|
17689
|
+
labels: issue2.fields.labels ?? [],
|
|
17690
|
+
linkedArtifacts: linkedArtifacts ?? [],
|
|
17691
|
+
tags: [`jira:${issue2.key}`],
|
|
17692
|
+
lastSyncedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
17693
|
+
};
|
|
17694
|
+
}
|
|
17695
|
+
function findByJiraKey(store, jiraKey) {
|
|
17696
|
+
const docs = store.list({ type: JIRA_TYPE });
|
|
17697
|
+
return docs.find((d) => d.frontmatter.jiraKey === jiraKey);
|
|
17698
|
+
}
|
|
17699
|
+
function createJiraTools(store) {
|
|
17700
|
+
const jiraUserConfig = loadUserConfig().jira;
|
|
17701
|
+
return [
|
|
17702
|
+
// --- Local read tools ---
|
|
17703
|
+
tool19(
|
|
17704
|
+
"list_jira_issues",
|
|
17705
|
+
"List locally synced Jira issues (JI-xxx documents), optionally filtered by status or Jira key",
|
|
17706
|
+
{
|
|
17707
|
+
status: external_exports.enum(["open", "in-progress", "done"]).optional().describe("Filter by local status"),
|
|
17708
|
+
jiraKey: external_exports.string().optional().describe("Filter by Jira issue key (e.g. 'PROJ-123')")
|
|
17709
|
+
},
|
|
17710
|
+
async (args) => {
|
|
17711
|
+
let docs = store.list({ type: JIRA_TYPE, status: args.status });
|
|
17712
|
+
if (args.jiraKey) {
|
|
17713
|
+
docs = docs.filter((d) => d.frontmatter.jiraKey === args.jiraKey);
|
|
17714
|
+
}
|
|
17715
|
+
const summary = docs.map((d) => ({
|
|
17716
|
+
id: d.frontmatter.id,
|
|
17717
|
+
title: d.frontmatter.title,
|
|
17718
|
+
status: d.frontmatter.status,
|
|
17719
|
+
jiraKey: d.frontmatter.jiraKey,
|
|
17720
|
+
issueType: d.frontmatter.issueType,
|
|
17721
|
+
priority: d.frontmatter.priority,
|
|
17722
|
+
assignee: d.frontmatter.assignee,
|
|
17723
|
+
linkedArtifacts: d.frontmatter.linkedArtifacts
|
|
17724
|
+
}));
|
|
17725
|
+
return {
|
|
17726
|
+
content: [{ type: "text", text: JSON.stringify(summary, null, 2) }]
|
|
17727
|
+
};
|
|
17728
|
+
},
|
|
17729
|
+
{ annotations: { readOnly: true } }
|
|
17730
|
+
),
|
|
17731
|
+
tool19(
|
|
17732
|
+
"get_jira_issue",
|
|
17733
|
+
"Get the full content of a locally synced Jira issue by local ID (JI-xxx) or Jira key (PROJ-123)",
|
|
17734
|
+
{
|
|
17735
|
+
id: external_exports.string().describe("Local ID (e.g. 'JI-001') or Jira key (e.g. 'PROJ-123')")
|
|
17736
|
+
},
|
|
17737
|
+
async (args) => {
|
|
17738
|
+
let doc = store.get(args.id);
|
|
17739
|
+
if (!doc) {
|
|
17740
|
+
doc = findByJiraKey(store, args.id);
|
|
17741
|
+
}
|
|
17742
|
+
if (!doc) {
|
|
17743
|
+
return {
|
|
17744
|
+
content: [{ type: "text", text: `Jira issue ${args.id} not found locally` }],
|
|
17745
|
+
isError: true
|
|
17746
|
+
};
|
|
17747
|
+
}
|
|
17748
|
+
return {
|
|
17749
|
+
content: [
|
|
17750
|
+
{
|
|
17751
|
+
type: "text",
|
|
17752
|
+
text: JSON.stringify(
|
|
17753
|
+
{ ...doc.frontmatter, content: doc.content },
|
|
17754
|
+
null,
|
|
17755
|
+
2
|
|
17756
|
+
)
|
|
17757
|
+
}
|
|
17758
|
+
]
|
|
17759
|
+
};
|
|
17760
|
+
},
|
|
17761
|
+
{ annotations: { readOnly: true } }
|
|
17762
|
+
),
|
|
17763
|
+
// --- Jira → Local tools ---
|
|
17764
|
+
tool19(
|
|
17765
|
+
"pull_jira_issue",
|
|
17766
|
+
"Fetch a single Jira issue by key and create/update a local JI-xxx document",
|
|
17767
|
+
{
|
|
17768
|
+
key: external_exports.string().describe("Jira issue key (e.g. 'PROJ-123')")
|
|
17769
|
+
},
|
|
17770
|
+
async (args) => {
|
|
17771
|
+
const jira = createJiraClient(jiraUserConfig);
|
|
17772
|
+
if (!jira) return jiraNotConfiguredError();
|
|
17773
|
+
const issue2 = await jira.client.getIssue(args.key);
|
|
17774
|
+
const existing = findByJiraKey(store, args.key);
|
|
17775
|
+
if (existing) {
|
|
17776
|
+
const fm2 = jiraIssueToFrontmatter(
|
|
17777
|
+
issue2,
|
|
17778
|
+
jira.host,
|
|
17779
|
+
existing.frontmatter.linkedArtifacts
|
|
17780
|
+
);
|
|
17781
|
+
const doc2 = store.update(
|
|
17782
|
+
existing.frontmatter.id,
|
|
17783
|
+
fm2,
|
|
17784
|
+
issue2.fields.description ?? ""
|
|
17785
|
+
);
|
|
17786
|
+
return {
|
|
17787
|
+
content: [
|
|
17788
|
+
{
|
|
17789
|
+
type: "text",
|
|
17790
|
+
text: `Updated ${doc2.frontmatter.id} from Jira ${args.key}`
|
|
17791
|
+
}
|
|
17792
|
+
]
|
|
17793
|
+
};
|
|
17794
|
+
}
|
|
17795
|
+
const fm = jiraIssueToFrontmatter(issue2, jira.host);
|
|
17796
|
+
const doc = store.create(
|
|
17797
|
+
JIRA_TYPE,
|
|
17798
|
+
fm,
|
|
17799
|
+
issue2.fields.description ?? ""
|
|
17800
|
+
);
|
|
17801
|
+
return {
|
|
17802
|
+
content: [
|
|
17803
|
+
{
|
|
17804
|
+
type: "text",
|
|
17805
|
+
text: `Created ${doc.frontmatter.id} from Jira ${args.key}`
|
|
17806
|
+
}
|
|
17807
|
+
]
|
|
17808
|
+
};
|
|
17809
|
+
}
|
|
17810
|
+
),
|
|
17811
|
+
tool19(
|
|
17812
|
+
"pull_jira_issues_jql",
|
|
17813
|
+
"Bulk fetch Jira issues via JQL query and create/update local JI-xxx documents",
|
|
17814
|
+
{
|
|
17815
|
+
jql: external_exports.string().describe(`JQL query (e.g. 'project = PROJ AND status = "In Progress"')`),
|
|
17816
|
+
maxResults: external_exports.number().optional().describe("Max issues to fetch (default 50)")
|
|
17817
|
+
},
|
|
17818
|
+
async (args) => {
|
|
17819
|
+
const jira = createJiraClient(jiraUserConfig);
|
|
17820
|
+
if (!jira) return jiraNotConfiguredError();
|
|
17821
|
+
const result = await jira.client.searchIssues(args.jql, args.maxResults);
|
|
17822
|
+
const created = [];
|
|
17823
|
+
const updated = [];
|
|
17824
|
+
for (const issue2 of result.issues) {
|
|
17825
|
+
const existing = findByJiraKey(store, issue2.key);
|
|
17826
|
+
if (existing) {
|
|
17827
|
+
const fm = jiraIssueToFrontmatter(
|
|
17828
|
+
issue2,
|
|
17829
|
+
jira.host,
|
|
17830
|
+
existing.frontmatter.linkedArtifacts
|
|
17831
|
+
);
|
|
17832
|
+
store.update(
|
|
17833
|
+
existing.frontmatter.id,
|
|
17834
|
+
fm,
|
|
17835
|
+
issue2.fields.description ?? ""
|
|
17836
|
+
);
|
|
17837
|
+
updated.push(`${existing.frontmatter.id} (${issue2.key})`);
|
|
17838
|
+
} else {
|
|
17839
|
+
const fm = jiraIssueToFrontmatter(issue2, jira.host);
|
|
17840
|
+
const doc = store.create(
|
|
17841
|
+
JIRA_TYPE,
|
|
17842
|
+
fm,
|
|
17843
|
+
issue2.fields.description ?? ""
|
|
17844
|
+
);
|
|
17845
|
+
created.push(`${doc.frontmatter.id} (${issue2.key})`);
|
|
17846
|
+
}
|
|
17847
|
+
}
|
|
17848
|
+
const parts = [
|
|
17849
|
+
`Fetched ${result.issues.length} of ${result.total} matching issues.`
|
|
17850
|
+
];
|
|
17851
|
+
if (created.length > 0) parts.push(`Created: ${created.join(", ")}`);
|
|
17852
|
+
if (updated.length > 0) parts.push(`Updated: ${updated.join(", ")}`);
|
|
17853
|
+
return {
|
|
17854
|
+
content: [{ type: "text", text: parts.join("\n") }]
|
|
17855
|
+
};
|
|
17856
|
+
}
|
|
17857
|
+
),
|
|
17858
|
+
// --- Local → Jira tools ---
|
|
17859
|
+
tool19(
|
|
17860
|
+
"push_artifact_to_jira",
|
|
17861
|
+
"Create a Jira issue from any Marvin artifact (D/A/Q/F/E) and create a tracking JI-xxx document",
|
|
17862
|
+
{
|
|
17863
|
+
artifactId: external_exports.string().describe("Marvin artifact ID (e.g. 'D-001', 'F-003', 'E-002')"),
|
|
17864
|
+
projectKey: external_exports.string().describe("Jira project key (e.g. 'PROJ')"),
|
|
17865
|
+
issueType: external_exports.enum(["Story", "Task", "Bug", "Epic"]).optional().describe("Jira issue type (default: 'Task')")
|
|
17866
|
+
},
|
|
17867
|
+
async (args) => {
|
|
17868
|
+
const jira = createJiraClient(jiraUserConfig);
|
|
17869
|
+
if (!jira) return jiraNotConfiguredError();
|
|
17870
|
+
const artifact = store.get(args.artifactId);
|
|
17871
|
+
if (!artifact) {
|
|
17872
|
+
return {
|
|
17873
|
+
content: [
|
|
17874
|
+
{ type: "text", text: `Artifact ${args.artifactId} not found` }
|
|
17875
|
+
],
|
|
17876
|
+
isError: true
|
|
17877
|
+
};
|
|
17878
|
+
}
|
|
17879
|
+
const description = [
|
|
17880
|
+
artifact.content,
|
|
17881
|
+
"",
|
|
17882
|
+
`---`,
|
|
17883
|
+
`Marvin artifact: ${artifact.frontmatter.id} (${artifact.frontmatter.type})`,
|
|
17884
|
+
`Status: ${artifact.frontmatter.status}`
|
|
17885
|
+
].join("\n");
|
|
17886
|
+
const jiraResult = await jira.client.createIssue({
|
|
17887
|
+
project: { key: args.projectKey },
|
|
17888
|
+
summary: artifact.frontmatter.title,
|
|
17889
|
+
description,
|
|
17890
|
+
issuetype: { name: args.issueType ?? "Task" }
|
|
17891
|
+
});
|
|
17892
|
+
const jiDoc = store.create(
|
|
17893
|
+
JIRA_TYPE,
|
|
17894
|
+
{
|
|
17895
|
+
title: artifact.frontmatter.title,
|
|
17896
|
+
status: "open",
|
|
17897
|
+
jiraKey: jiraResult.key,
|
|
17898
|
+
jiraUrl: `https://${jira.host}/browse/${jiraResult.key}`,
|
|
17899
|
+
issueType: args.issueType ?? "Task",
|
|
17900
|
+
priority: "Medium",
|
|
17901
|
+
assignee: "",
|
|
17902
|
+
labels: [],
|
|
17903
|
+
linkedArtifacts: [args.artifactId],
|
|
17904
|
+
tags: [`jira:${jiraResult.key}`],
|
|
17905
|
+
lastSyncedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
17906
|
+
},
|
|
17907
|
+
""
|
|
17908
|
+
);
|
|
17909
|
+
return {
|
|
17910
|
+
content: [
|
|
17911
|
+
{
|
|
17912
|
+
type: "text",
|
|
17913
|
+
text: `Created Jira ${jiraResult.key} from ${args.artifactId}. Tracking locally as ${jiDoc.frontmatter.id}.`
|
|
17914
|
+
}
|
|
17915
|
+
]
|
|
17916
|
+
};
|
|
17917
|
+
}
|
|
17918
|
+
),
|
|
17919
|
+
// --- Bidirectional sync ---
|
|
17920
|
+
tool19(
|
|
17921
|
+
"sync_jira_issue",
|
|
17922
|
+
"Bidirectional sync: push local title/description to Jira, pull latest status/assignee/labels back",
|
|
17923
|
+
{
|
|
17924
|
+
id: external_exports.string().describe("Local JI-xxx ID")
|
|
17925
|
+
},
|
|
17926
|
+
async (args) => {
|
|
17927
|
+
const jira = createJiraClient(jiraUserConfig);
|
|
17928
|
+
if (!jira) return jiraNotConfiguredError();
|
|
17929
|
+
const doc = store.get(args.id);
|
|
17930
|
+
if (!doc || doc.frontmatter.type !== JIRA_TYPE) {
|
|
17931
|
+
return {
|
|
17932
|
+
content: [
|
|
17933
|
+
{ type: "text", text: `Jira issue ${args.id} not found locally` }
|
|
17934
|
+
],
|
|
17935
|
+
isError: true
|
|
17936
|
+
};
|
|
17937
|
+
}
|
|
17938
|
+
const jiraKey = doc.frontmatter.jiraKey;
|
|
17939
|
+
await jira.client.updateIssue(jiraKey, {
|
|
17940
|
+
summary: doc.frontmatter.title,
|
|
17941
|
+
description: doc.content || void 0
|
|
17942
|
+
});
|
|
17943
|
+
const issue2 = await jira.client.getIssue(jiraKey);
|
|
17944
|
+
const fm = jiraIssueToFrontmatter(
|
|
17945
|
+
issue2,
|
|
17946
|
+
jira.host,
|
|
17947
|
+
doc.frontmatter.linkedArtifacts
|
|
17948
|
+
);
|
|
17949
|
+
store.update(args.id, fm, issue2.fields.description ?? "");
|
|
17950
|
+
return {
|
|
17951
|
+
content: [
|
|
17952
|
+
{
|
|
17953
|
+
type: "text",
|
|
17954
|
+
text: `Synced ${args.id} \u2194 ${jiraKey}. Status: ${fm.status}, Assignee: ${fm.assignee || "unassigned"}`
|
|
17955
|
+
}
|
|
17956
|
+
]
|
|
17957
|
+
};
|
|
17958
|
+
}
|
|
17959
|
+
),
|
|
17960
|
+
// --- Local link tool ---
|
|
17961
|
+
tool19(
|
|
17962
|
+
"link_artifact_to_jira",
|
|
17963
|
+
"Add a Marvin artifact ID to a JI-xxx document's linkedArtifacts field",
|
|
17964
|
+
{
|
|
17965
|
+
jiraIssueId: external_exports.string().describe("Local JI-xxx ID"),
|
|
17966
|
+
artifactId: external_exports.string().describe("Marvin artifact ID to link (e.g. 'D-001', 'F-003')")
|
|
17967
|
+
},
|
|
17968
|
+
async (args) => {
|
|
17969
|
+
const doc = store.get(args.jiraIssueId);
|
|
17970
|
+
if (!doc || doc.frontmatter.type !== JIRA_TYPE) {
|
|
17971
|
+
return {
|
|
17972
|
+
content: [
|
|
17973
|
+
{
|
|
17974
|
+
type: "text",
|
|
17975
|
+
text: `Jira issue ${args.jiraIssueId} not found locally`
|
|
17976
|
+
}
|
|
17977
|
+
],
|
|
17978
|
+
isError: true
|
|
17979
|
+
};
|
|
17980
|
+
}
|
|
17981
|
+
const artifact = store.get(args.artifactId);
|
|
17982
|
+
if (!artifact) {
|
|
17983
|
+
return {
|
|
17984
|
+
content: [
|
|
17985
|
+
{ type: "text", text: `Artifact ${args.artifactId} not found` }
|
|
17986
|
+
],
|
|
17987
|
+
isError: true
|
|
17988
|
+
};
|
|
17989
|
+
}
|
|
17990
|
+
const linked = doc.frontmatter.linkedArtifacts ?? [];
|
|
17991
|
+
if (linked.includes(args.artifactId)) {
|
|
17992
|
+
return {
|
|
17993
|
+
content: [
|
|
17994
|
+
{
|
|
17995
|
+
type: "text",
|
|
17996
|
+
text: `${args.artifactId} is already linked to ${args.jiraIssueId}`
|
|
17997
|
+
}
|
|
17998
|
+
]
|
|
17999
|
+
};
|
|
18000
|
+
}
|
|
18001
|
+
store.update(args.jiraIssueId, {
|
|
18002
|
+
linkedArtifacts: [...linked, args.artifactId]
|
|
18003
|
+
});
|
|
18004
|
+
return {
|
|
18005
|
+
content: [
|
|
18006
|
+
{
|
|
18007
|
+
type: "text",
|
|
18008
|
+
text: `Linked ${args.artifactId} to ${args.jiraIssueId}`
|
|
18009
|
+
}
|
|
18010
|
+
]
|
|
18011
|
+
};
|
|
18012
|
+
}
|
|
18013
|
+
)
|
|
18014
|
+
];
|
|
18015
|
+
}
|
|
18016
|
+
|
|
18017
|
+
// src/skills/builtin/jira/index.ts
|
|
18018
|
+
var jiraSkill = {
|
|
18019
|
+
id: "jira",
|
|
18020
|
+
name: "Jira Integration",
|
|
18021
|
+
description: "Bidirectional sync between Marvin artifacts and Jira issues",
|
|
18022
|
+
version: "1.0.0",
|
|
18023
|
+
format: "builtin-ts",
|
|
18024
|
+
// No default persona affinity — opt-in via config.yaml skills section
|
|
18025
|
+
documentTypeRegistrations: [
|
|
18026
|
+
{ type: "jira-issue", dirName: "jira-issues", idPrefix: "JI" }
|
|
18027
|
+
],
|
|
18028
|
+
tools: (store) => createJiraTools(store),
|
|
18029
|
+
promptFragments: {
|
|
18030
|
+
"product-owner": `You have the **Jira Integration** skill. You can pull issues from Jira and push Marvin artifacts to Jira.
|
|
18031
|
+
|
|
18032
|
+
**Available tools:**
|
|
18033
|
+
- \`list_jira_issues\` / \`get_jira_issue\` \u2014 browse locally synced Jira issues
|
|
18034
|
+
- \`pull_jira_issue\` / \`pull_jira_issues_jql\` \u2014 import issues from Jira by key or JQL query
|
|
18035
|
+
- \`push_artifact_to_jira\` \u2014 create a Jira issue from a Marvin artifact (decision, feature, etc.)
|
|
18036
|
+
- \`sync_jira_issue\` \u2014 bidirectional sync of a local JI-xxx with Jira
|
|
18037
|
+
- \`link_artifact_to_jira\` \u2014 link a Marvin artifact to an existing JI-xxx
|
|
18038
|
+
|
|
18039
|
+
**As Product Owner, use Jira integration to:**
|
|
18040
|
+
- Pull stakeholder-reported issues for triage and prioritization
|
|
18041
|
+
- Push approved features as Stories for development tracking
|
|
18042
|
+
- Link decisions to Jira issues for audit trail and traceability
|
|
18043
|
+
- Use JQL queries to review backlog status (e.g. \`project = PROJ AND status = "To Do"\`)`,
|
|
18044
|
+
"tech-lead": `You have the **Jira Integration** skill. You can pull issues from Jira and push Marvin artifacts to Jira.
|
|
18045
|
+
|
|
18046
|
+
**Available tools:**
|
|
18047
|
+
- \`list_jira_issues\` / \`get_jira_issue\` \u2014 browse locally synced Jira issues
|
|
18048
|
+
- \`pull_jira_issue\` / \`pull_jira_issues_jql\` \u2014 import issues from Jira by key or JQL query
|
|
18049
|
+
- \`push_artifact_to_jira\` \u2014 create a Jira issue from a Marvin artifact (decision, action, epic, etc.)
|
|
18050
|
+
- \`sync_jira_issue\` \u2014 bidirectional sync of a local JI-xxx with Jira
|
|
18051
|
+
- \`link_artifact_to_jira\` \u2014 link a Marvin artifact to an existing JI-xxx
|
|
18052
|
+
|
|
18053
|
+
**As Tech Lead, use Jira integration to:**
|
|
18054
|
+
- Pull technical issues and bugs for sprint planning and estimation
|
|
18055
|
+
- Push epics and technical decisions to Jira for cross-team visibility
|
|
18056
|
+
- Bidirectional sync to keep local governance and Jira in alignment
|
|
18057
|
+
- Use JQL queries to track technical debt (e.g. \`labels = "tech-debt" AND status != "Done"\`)`,
|
|
18058
|
+
"delivery-manager": `You have the **Jira Integration** skill. You can pull issues from Jira and push Marvin artifacts to Jira.
|
|
18059
|
+
|
|
18060
|
+
**Available tools:**
|
|
18061
|
+
- \`list_jira_issues\` / \`get_jira_issue\` \u2014 browse locally synced Jira issues
|
|
18062
|
+
- \`pull_jira_issue\` / \`pull_jira_issues_jql\` \u2014 import issues from Jira by key or JQL query
|
|
18063
|
+
- \`push_artifact_to_jira\` \u2014 create a Jira issue from a Marvin artifact (decision, action, etc.)
|
|
18064
|
+
- \`sync_jira_issue\` \u2014 bidirectional sync of a local JI-xxx with Jira
|
|
18065
|
+
- \`link_artifact_to_jira\` \u2014 link a Marvin artifact to an existing JI-xxx
|
|
18066
|
+
|
|
18067
|
+
**As Delivery Manager, use Jira integration to:**
|
|
18068
|
+
- Pull sprint issues for tracking progress and blockers
|
|
18069
|
+
- Push actions and decisions to Jira for stakeholder visibility
|
|
18070
|
+
- Use JQL queries for reporting (e.g. \`sprint in openSprints() AND assignee = currentUser()\`)
|
|
18071
|
+
- Sync status between Marvin governance items and Jira issues`
|
|
18072
|
+
}
|
|
18073
|
+
};
|
|
18074
|
+
|
|
17505
18075
|
// src/skills/registry.ts
|
|
17506
18076
|
var BUILTIN_SKILLS = {
|
|
17507
|
-
"governance-review": governanceReviewSkill
|
|
18077
|
+
"governance-review": governanceReviewSkill,
|
|
18078
|
+
"jira": jiraSkill
|
|
17508
18079
|
};
|
|
17509
18080
|
var GOVERNANCE_TOOL_NAMES = [
|
|
17510
18081
|
"mcp__marvin-governance__list_decisions",
|
|
@@ -17653,6 +18224,16 @@ function resolveSkillsForPersona(personaId, skillsConfig, allSkills) {
|
|
|
17653
18224
|
}
|
|
17654
18225
|
return result;
|
|
17655
18226
|
}
|
|
18227
|
+
function collectSkillRegistrations(skillIds, allSkills) {
|
|
18228
|
+
const registrations = [];
|
|
18229
|
+
for (const id of skillIds) {
|
|
18230
|
+
const skill = allSkills.get(id);
|
|
18231
|
+
if (skill?.documentTypeRegistrations) {
|
|
18232
|
+
registrations.push(...skill.documentTypeRegistrations);
|
|
18233
|
+
}
|
|
18234
|
+
}
|
|
18235
|
+
return registrations;
|
|
18236
|
+
}
|
|
17656
18237
|
function getSkillTools(skillIds, allSkills, store) {
|
|
17657
18238
|
const tools = [];
|
|
17658
18239
|
for (const id of skillIds) {
|
|
@@ -17764,16 +18345,17 @@ ${wildcardPrompt}
|
|
|
17764
18345
|
async function startSession(options) {
|
|
17765
18346
|
const { persona, config: config2, marvinDir, projectRoot } = options;
|
|
17766
18347
|
const plugin = resolvePlugin(config2.project.methodology);
|
|
17767
|
-
const
|
|
17768
|
-
const
|
|
18348
|
+
const pluginRegistrations = plugin?.documentTypeRegistrations ?? [];
|
|
18349
|
+
const allSkills = loadAllSkills(marvinDir);
|
|
18350
|
+
const skillIds = resolveSkillsForPersona(persona.id, config2.project.skills, allSkills);
|
|
18351
|
+
const skillRegistrations = collectSkillRegistrations(skillIds, allSkills);
|
|
18352
|
+
const store = new DocumentStore(marvinDir, [...pluginRegistrations, ...skillRegistrations]);
|
|
17769
18353
|
const sessionStore = new SessionStore(marvinDir);
|
|
17770
18354
|
const sourcesDir = path8.join(marvinDir, "sources");
|
|
17771
18355
|
const hasSourcesDir = fs8.existsSync(sourcesDir);
|
|
17772
18356
|
const manifest = hasSourcesDir ? new SourceManifestManager(marvinDir) : void 0;
|
|
17773
18357
|
const pluginTools = plugin ? getPluginTools(plugin, store, marvinDir) : [];
|
|
17774
18358
|
const pluginPromptFragment = plugin ? getPluginPromptFragment(plugin, persona.id) : void 0;
|
|
17775
|
-
const allSkills = loadAllSkills(marvinDir);
|
|
17776
|
-
const skillIds = resolveSkillsForPersona(persona.id, config2.project.skills, allSkills);
|
|
17777
18359
|
const codeSkillTools = getSkillTools(skillIds, allSkills, store);
|
|
17778
18360
|
const skillAgents = getSkillAgentDefinitions(skillIds, allSkills);
|
|
17779
18361
|
const skillPromptFragment = getSkillPromptFragment(skillIds, allSkills, persona.id);
|
|
@@ -17820,10 +18402,10 @@ Marvin \u2014 ${persona.name}
|
|
|
17820
18402
|
});
|
|
17821
18403
|
try {
|
|
17822
18404
|
while (true) {
|
|
17823
|
-
const
|
|
18405
|
+
const input4 = await new Promise((resolve5) => {
|
|
17824
18406
|
rl.question(chalk.green("\nYou: "), resolve5);
|
|
17825
18407
|
});
|
|
17826
|
-
const trimmed =
|
|
18408
|
+
const trimmed = input4.trim();
|
|
17827
18409
|
if (trimmed === "exit" || trimmed === "quit") {
|
|
17828
18410
|
break;
|
|
17829
18411
|
}
|
|
@@ -17970,7 +18552,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
17970
18552
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
17971
18553
|
|
|
17972
18554
|
// src/skills/action-tools.ts
|
|
17973
|
-
import { tool as
|
|
18555
|
+
import { tool as tool20 } from "@anthropic-ai/claude-agent-sdk";
|
|
17974
18556
|
|
|
17975
18557
|
// src/skills/action-runner.ts
|
|
17976
18558
|
import { query as query3 } from "@anthropic-ai/claude-agent-sdk";
|
|
@@ -18036,7 +18618,7 @@ function createSkillActionTools(skills, context) {
|
|
|
18036
18618
|
if (!skill.actions) continue;
|
|
18037
18619
|
for (const action of skill.actions) {
|
|
18038
18620
|
tools.push(
|
|
18039
|
-
|
|
18621
|
+
tool20(
|
|
18040
18622
|
`${skill.id}__${action.id}`,
|
|
18041
18623
|
action.description,
|
|
18042
18624
|
{
|
|
@@ -18128,10 +18710,10 @@ ${lines.join("\n\n")}`;
|
|
|
18128
18710
|
}
|
|
18129
18711
|
|
|
18130
18712
|
// src/mcp/persona-tools.ts
|
|
18131
|
-
import { tool as
|
|
18713
|
+
import { tool as tool21 } from "@anthropic-ai/claude-agent-sdk";
|
|
18132
18714
|
function createPersonaTools(ctx, marvinDir) {
|
|
18133
18715
|
return [
|
|
18134
|
-
|
|
18716
|
+
tool21(
|
|
18135
18717
|
"set_persona",
|
|
18136
18718
|
"Set the active persona for this session. Returns full guidance for the selected persona including behavioral rules, allowed document types, and scope. Call this before working to ensure persona-appropriate behavior.",
|
|
18137
18719
|
{
|
|
@@ -18161,7 +18743,7 @@ ${summaries}`
|
|
|
18161
18743
|
};
|
|
18162
18744
|
}
|
|
18163
18745
|
),
|
|
18164
|
-
|
|
18746
|
+
tool21(
|
|
18165
18747
|
"get_persona_guidance",
|
|
18166
18748
|
"Get guidance for a persona without changing the active persona. If no persona is specified, lists all available personas with summaries.",
|
|
18167
18749
|
{
|
|
@@ -18614,23 +19196,29 @@ Project: ${project.config.name}
|
|
|
18614
19196
|
|
|
18615
19197
|
// src/cli/commands/config.ts
|
|
18616
19198
|
import chalk6 from "chalk";
|
|
18617
|
-
import { password } from "@inquirer/prompts";
|
|
19199
|
+
import { input as input2, password } from "@inquirer/prompts";
|
|
18618
19200
|
async function configCommand(key, value) {
|
|
18619
19201
|
if (key === "api-key") {
|
|
18620
19202
|
return setApiKey();
|
|
18621
19203
|
}
|
|
19204
|
+
if (key === "jira") {
|
|
19205
|
+
return setJira();
|
|
19206
|
+
}
|
|
18622
19207
|
if (!key) {
|
|
18623
19208
|
const config2 = loadUserConfig();
|
|
18624
19209
|
console.log(chalk6.bold("\nUser Configuration:\n"));
|
|
18625
19210
|
console.log(
|
|
18626
|
-
` API Key:
|
|
19211
|
+
` API Key: ${config2.apiKey ? chalk6.green("configured") : chalk6.red("not set")}`
|
|
18627
19212
|
);
|
|
18628
19213
|
console.log(
|
|
18629
|
-
` Default Model:
|
|
19214
|
+
` Default Model: ${config2.defaultModel ?? chalk6.dim("(default: claude-sonnet-4-5-20250929)")}`
|
|
18630
19215
|
);
|
|
18631
19216
|
console.log(
|
|
18632
19217
|
` Default Persona: ${config2.defaultPersona ?? chalk6.dim("(default: product-owner)")}`
|
|
18633
19218
|
);
|
|
19219
|
+
console.log(
|
|
19220
|
+
` Jira: ${config2.jira?.host ? chalk6.green(`configured (${config2.jira.host})`) : chalk6.red("not set")}`
|
|
19221
|
+
);
|
|
18634
19222
|
console.log();
|
|
18635
19223
|
return;
|
|
18636
19224
|
}
|
|
@@ -18663,6 +19251,37 @@ async function configCommand(key, value) {
|
|
|
18663
19251
|
}
|
|
18664
19252
|
}
|
|
18665
19253
|
}
|
|
19254
|
+
async function setJira() {
|
|
19255
|
+
const host = await input2({
|
|
19256
|
+
message: "Jira host (e.g. mycompany.atlassian.net):"
|
|
19257
|
+
});
|
|
19258
|
+
if (!host.trim()) {
|
|
19259
|
+
console.log(chalk6.red("No host provided."));
|
|
19260
|
+
return;
|
|
19261
|
+
}
|
|
19262
|
+
const email3 = await input2({
|
|
19263
|
+
message: "Jira email:"
|
|
19264
|
+
});
|
|
19265
|
+
if (!email3.trim()) {
|
|
19266
|
+
console.log(chalk6.red("No email provided."));
|
|
19267
|
+
return;
|
|
19268
|
+
}
|
|
19269
|
+
const apiToken = await password({
|
|
19270
|
+
message: "Jira API token:"
|
|
19271
|
+
});
|
|
19272
|
+
if (!apiToken.trim()) {
|
|
19273
|
+
console.log(chalk6.red("No API token provided."));
|
|
19274
|
+
return;
|
|
19275
|
+
}
|
|
19276
|
+
const config2 = loadUserConfig();
|
|
19277
|
+
config2.jira = {
|
|
19278
|
+
host: host.trim(),
|
|
19279
|
+
email: email3.trim(),
|
|
19280
|
+
apiToken: apiToken.trim()
|
|
19281
|
+
};
|
|
19282
|
+
saveUserConfig(config2);
|
|
19283
|
+
console.log(chalk6.green("Jira credentials saved."));
|
|
19284
|
+
}
|
|
18666
19285
|
async function setApiKey() {
|
|
18667
19286
|
const apiKey = await password({
|
|
18668
19287
|
message: "Enter your Anthropic API key:"
|
|
@@ -18976,7 +19595,7 @@ ${pending} file${pending === 1 ? "" : "s"} ready to process. Run "marvin ingest
|
|
|
18976
19595
|
// src/cli/commands/sync.ts
|
|
18977
19596
|
import chalk9 from "chalk";
|
|
18978
19597
|
import ora3 from "ora";
|
|
18979
|
-
import { input as
|
|
19598
|
+
import { input as input3 } from "@inquirer/prompts";
|
|
18980
19599
|
|
|
18981
19600
|
// src/git/repository.ts
|
|
18982
19601
|
import * as path13 from "path";
|
|
@@ -19183,7 +19802,7 @@ async function syncInitCommand(opts) {
|
|
|
19183
19802
|
const git = new MarvinGit(project.marvinDir);
|
|
19184
19803
|
let remote = opts.remote;
|
|
19185
19804
|
if (!remote) {
|
|
19186
|
-
remote = await
|
|
19805
|
+
remote = await input3({
|
|
19187
19806
|
message: "Remote repository URL (leave blank to skip):"
|
|
19188
19807
|
}) || void 0;
|
|
19189
19808
|
}
|
|
@@ -19404,20 +20023,23 @@ async function skillsInstallCommand(skillId, options) {
|
|
|
19404
20023
|
console.log(chalk10.red("Please specify a persona with --as <persona>."));
|
|
19405
20024
|
return;
|
|
19406
20025
|
}
|
|
20026
|
+
const targets = persona === "all" ? listPersonas().map((p) => p.id) : [persona];
|
|
19407
20027
|
const config2 = loadProjectConfig(project.marvinDir);
|
|
19408
20028
|
if (!config2.skills) {
|
|
19409
20029
|
config2.skills = {};
|
|
19410
20030
|
}
|
|
19411
|
-
|
|
19412
|
-
config2.skills[
|
|
19413
|
-
|
|
19414
|
-
|
|
19415
|
-
|
|
19416
|
-
|
|
20031
|
+
for (const target of targets) {
|
|
20032
|
+
if (!config2.skills[target]) {
|
|
20033
|
+
config2.skills[target] = [];
|
|
20034
|
+
}
|
|
20035
|
+
if (config2.skills[target].includes(skillId)) {
|
|
20036
|
+
console.log(chalk10.yellow(`Skill "${skillId}" is already assigned to ${target}.`));
|
|
20037
|
+
continue;
|
|
20038
|
+
}
|
|
20039
|
+
config2.skills[target].push(skillId);
|
|
20040
|
+
console.log(chalk10.green(`Assigned skill "${skillId}" to ${target}.`));
|
|
19417
20041
|
}
|
|
19418
|
-
config2.skills[persona].push(skillId);
|
|
19419
20042
|
saveProjectConfig(project.marvinDir, config2);
|
|
19420
|
-
console.log(chalk10.green(`Assigned skill "${skillId}" to ${persona}.`));
|
|
19421
20043
|
}
|
|
19422
20044
|
async function skillsRemoveCommand(skillId, options) {
|
|
19423
20045
|
const project = loadProject();
|
|
@@ -19426,25 +20048,28 @@ async function skillsRemoveCommand(skillId, options) {
|
|
|
19426
20048
|
console.log(chalk10.red("Please specify a persona with --as <persona>."));
|
|
19427
20049
|
return;
|
|
19428
20050
|
}
|
|
20051
|
+
const targets = persona === "all" ? listPersonas().map((p) => p.id) : [persona];
|
|
19429
20052
|
const config2 = loadProjectConfig(project.marvinDir);
|
|
19430
|
-
|
|
19431
|
-
|
|
19432
|
-
|
|
19433
|
-
|
|
19434
|
-
|
|
19435
|
-
|
|
19436
|
-
|
|
19437
|
-
|
|
19438
|
-
|
|
19439
|
-
|
|
19440
|
-
|
|
19441
|
-
|
|
20053
|
+
for (const target of targets) {
|
|
20054
|
+
if (!config2.skills?.[target]) {
|
|
20055
|
+
console.log(chalk10.yellow(`No skills configured for ${target}.`));
|
|
20056
|
+
continue;
|
|
20057
|
+
}
|
|
20058
|
+
const idx = config2.skills[target].indexOf(skillId);
|
|
20059
|
+
if (idx === -1) {
|
|
20060
|
+
console.log(chalk10.yellow(`Skill "${skillId}" is not assigned to ${target}.`));
|
|
20061
|
+
continue;
|
|
20062
|
+
}
|
|
20063
|
+
config2.skills[target].splice(idx, 1);
|
|
20064
|
+
if (config2.skills[target].length === 0) {
|
|
20065
|
+
delete config2.skills[target];
|
|
20066
|
+
}
|
|
20067
|
+
console.log(chalk10.green(`Removed skill "${skillId}" from ${target}.`));
|
|
19442
20068
|
}
|
|
19443
|
-
if (Object.keys(config2.skills).length === 0) {
|
|
20069
|
+
if (config2.skills && Object.keys(config2.skills).length === 0) {
|
|
19444
20070
|
delete config2.skills;
|
|
19445
20071
|
}
|
|
19446
20072
|
saveProjectConfig(project.marvinDir, config2);
|
|
19447
|
-
console.log(chalk10.green(`Removed skill "${skillId}" from ${persona}.`));
|
|
19448
20073
|
}
|
|
19449
20074
|
async function skillsCreateCommand(name) {
|
|
19450
20075
|
const project = loadProject();
|
|
@@ -20691,12 +21316,94 @@ Contribution: ${options.type}`));
|
|
|
20691
21316
|
});
|
|
20692
21317
|
}
|
|
20693
21318
|
|
|
21319
|
+
// src/reports/gar/render-ascii.ts
|
|
21320
|
+
import chalk16 from "chalk";
|
|
21321
|
+
var STATUS_DOT = {
|
|
21322
|
+
green: chalk16.green("\u25CF"),
|
|
21323
|
+
amber: chalk16.yellow("\u25CF"),
|
|
21324
|
+
red: chalk16.red("\u25CF")
|
|
21325
|
+
};
|
|
21326
|
+
var STATUS_LABEL = {
|
|
21327
|
+
green: chalk16.green.bold("GREEN"),
|
|
21328
|
+
amber: chalk16.yellow.bold("AMBER"),
|
|
21329
|
+
red: chalk16.red.bold("RED")
|
|
21330
|
+
};
|
|
21331
|
+
var SEPARATOR = chalk16.dim("\u2500".repeat(60));
|
|
21332
|
+
function renderAscii(report) {
|
|
21333
|
+
const lines = [];
|
|
21334
|
+
lines.push("");
|
|
21335
|
+
lines.push(chalk16.bold(` GAR Report \xB7 ${report.projectName}`));
|
|
21336
|
+
lines.push(chalk16.dim(` ${report.generatedAt}`));
|
|
21337
|
+
lines.push("");
|
|
21338
|
+
lines.push(` Overall: ${STATUS_LABEL[report.overall]}`);
|
|
21339
|
+
lines.push("");
|
|
21340
|
+
lines.push(` ${SEPARATOR}`);
|
|
21341
|
+
for (const area of report.areas) {
|
|
21342
|
+
lines.push(` ${STATUS_DOT[area.status]} ${chalk16.bold(area.name.padEnd(12))} ${area.summary}`);
|
|
21343
|
+
for (const item of area.items) {
|
|
21344
|
+
lines.push(` ${chalk16.dim("\u2514")} ${item.id} ${item.title}`);
|
|
21345
|
+
}
|
|
21346
|
+
}
|
|
21347
|
+
lines.push(` ${SEPARATOR}`);
|
|
21348
|
+
lines.push("");
|
|
21349
|
+
return lines.join("\n");
|
|
21350
|
+
}
|
|
21351
|
+
|
|
21352
|
+
// src/reports/gar/render-confluence.ts
|
|
21353
|
+
var EMOJI = {
|
|
21354
|
+
green: ":green_circle:",
|
|
21355
|
+
amber: ":yellow_circle:",
|
|
21356
|
+
red: ":red_circle:"
|
|
21357
|
+
};
|
|
21358
|
+
function renderConfluence(report) {
|
|
21359
|
+
const lines = [];
|
|
21360
|
+
lines.push(`# GAR Report \u2014 ${report.projectName}`);
|
|
21361
|
+
lines.push("");
|
|
21362
|
+
lines.push(`**Date:** ${report.generatedAt}`);
|
|
21363
|
+
lines.push(`**Overall:** ${EMOJI[report.overall]} ${report.overall.toUpperCase()}`);
|
|
21364
|
+
lines.push("");
|
|
21365
|
+
lines.push("| Area | Status | Summary |");
|
|
21366
|
+
lines.push("|------|--------|---------|");
|
|
21367
|
+
for (const area of report.areas) {
|
|
21368
|
+
lines.push(
|
|
21369
|
+
`| ${area.name} | ${EMOJI[area.status]} ${area.status.toUpperCase()} | ${area.summary} |`
|
|
21370
|
+
);
|
|
21371
|
+
}
|
|
21372
|
+
lines.push("");
|
|
21373
|
+
for (const area of report.areas) {
|
|
21374
|
+
if (area.items.length === 0) continue;
|
|
21375
|
+
lines.push(`## ${area.name}`);
|
|
21376
|
+
lines.push("");
|
|
21377
|
+
for (const item of area.items) {
|
|
21378
|
+
lines.push(`- **${item.id}** ${item.title}`);
|
|
21379
|
+
}
|
|
21380
|
+
lines.push("");
|
|
21381
|
+
}
|
|
21382
|
+
return lines.join("\n");
|
|
21383
|
+
}
|
|
21384
|
+
|
|
21385
|
+
// src/cli/commands/report.ts
|
|
21386
|
+
async function garReportCommand(options) {
|
|
21387
|
+
const project = loadProject();
|
|
21388
|
+
const plugin = resolvePlugin(project.config.methodology);
|
|
21389
|
+
const registrations = plugin?.documentTypeRegistrations ?? [];
|
|
21390
|
+
const store = new DocumentStore(project.marvinDir, registrations);
|
|
21391
|
+
const metrics = collectGarMetrics(store);
|
|
21392
|
+
const report = evaluateGar(project.config.name, metrics);
|
|
21393
|
+
const format = options.format ?? "ascii";
|
|
21394
|
+
if (format === "confluence") {
|
|
21395
|
+
console.log(renderConfluence(report));
|
|
21396
|
+
} else {
|
|
21397
|
+
console.log(renderAscii(report));
|
|
21398
|
+
}
|
|
21399
|
+
}
|
|
21400
|
+
|
|
20694
21401
|
// src/cli/program.ts
|
|
20695
21402
|
function createProgram() {
|
|
20696
21403
|
const program = new Command();
|
|
20697
21404
|
program.name("marvin").description(
|
|
20698
21405
|
"AI-powered product development assistant with Product Owner, Delivery Manager, and Technical Lead personas"
|
|
20699
|
-
).version("0.2.
|
|
21406
|
+
).version("0.2.9");
|
|
20700
21407
|
program.command("init").description("Initialize a new Marvin project in the current directory").action(async () => {
|
|
20701
21408
|
await initCommand();
|
|
20702
21409
|
});
|
|
@@ -20766,6 +21473,13 @@ function createProgram() {
|
|
|
20766
21473
|
skillsCmd.command("migrate").description("Migrate YAML skill files to SKILL.md directory format").action(async () => {
|
|
20767
21474
|
await skillsMigrateCommand();
|
|
20768
21475
|
});
|
|
21476
|
+
const reportCmd = program.command("report").description("Generate project reports");
|
|
21477
|
+
reportCmd.command("gar").description("Generate a Green/Amber/Red status report").option(
|
|
21478
|
+
"--format <format>",
|
|
21479
|
+
"Output format: ascii or confluence (default: ascii)"
|
|
21480
|
+
).action(async (options) => {
|
|
21481
|
+
await garReportCommand(options);
|
|
21482
|
+
});
|
|
20769
21483
|
return program;
|
|
20770
21484
|
}
|
|
20771
21485
|
export {
|