@dunnewold-labs/mr-manager 0.4.20 → 0.4.21
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/dist/index.mjs +199 -43
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// cli/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command29 } from "commander";
|
|
5
5
|
import { existsSync as existsSync17 } from "fs";
|
|
6
6
|
import { homedir as homedir3 } from "os";
|
|
7
7
|
import { join as join12 } from "path";
|
|
@@ -185,7 +185,7 @@ import { fileURLToPath } from "url";
|
|
|
185
185
|
// cli/package.json
|
|
186
186
|
var package_default = {
|
|
187
187
|
name: "@dunnewold-labs/mr-manager",
|
|
188
|
-
version: "0.4.
|
|
188
|
+
version: "0.4.21",
|
|
189
189
|
description: "Mr. Manager - Task and project management CLI",
|
|
190
190
|
bin: {
|
|
191
191
|
mr: "./dist/index.mjs"
|
|
@@ -1341,6 +1341,19 @@ Rules:
|
|
|
1341
1341
|
- The "context" field should be a single sentence.
|
|
1342
1342
|
- Use sequential IDs: q1, q2, q3, etc.
|
|
1343
1343
|
- Place the JSON block at the very end of the "Open Questions" section.`;
|
|
1344
|
+
var SYSTEM_SECTION_MR_TESTS = `## MR Tests \u2014 Feature Testing Scenarios
|
|
1345
|
+
|
|
1346
|
+
Before writing your test plan, run:
|
|
1347
|
+
mr tests
|
|
1348
|
+
|
|
1349
|
+
This lists all human-authored test scenarios for this project. Each scenario describes how to navigate to a specific feature, what interactions to perform, and what to verify.
|
|
1350
|
+
|
|
1351
|
+
If a scenario name matches the feature you're testing (by name or keyword):
|
|
1352
|
+
1. Use its interaction steps as the basis for your test plan.
|
|
1353
|
+
2. Adapt specific assertions to the task's requirements.
|
|
1354
|
+
3. Note in your test plan summary which scenario you used.
|
|
1355
|
+
|
|
1356
|
+
If no matching scenario exists, infer interactions from the codebase as normal.`;
|
|
1344
1357
|
var SYSTEM_SECTIONS = {
|
|
1345
1358
|
"status-updates": SYSTEM_SECTION_STATUS_UPDATES,
|
|
1346
1359
|
"screenshots": SYSTEM_SECTION_SCREENSHOTS,
|
|
@@ -1348,12 +1361,13 @@ var SYSTEM_SECTIONS = {
|
|
|
1348
1361
|
"no-mr": SYSTEM_SECTION_NO_MR,
|
|
1349
1362
|
"features-workflow": SYSTEM_SECTION_FEATURES_WORKFLOW,
|
|
1350
1363
|
"prd-format": SYSTEM_SECTION_PRD_FORMAT,
|
|
1351
|
-
"prd-open-questions": SYSTEM_SECTION_PRD_OPEN_QUESTIONS
|
|
1364
|
+
"prd-open-questions": SYSTEM_SECTION_PRD_OPEN_QUESTIONS,
|
|
1365
|
+
"mr-tests": SYSTEM_SECTION_MR_TESTS
|
|
1352
1366
|
};
|
|
1353
1367
|
function composeSystemPrompt(sections) {
|
|
1354
1368
|
return sections.map((s) => SYSTEM_SECTIONS[s]).join("\n\n");
|
|
1355
1369
|
}
|
|
1356
|
-
var EXECUTION_SYSTEM_SECTIONS = ["status-updates", "screenshots", "test-plan", "no-mr", "features-workflow"];
|
|
1370
|
+
var EXECUTION_SYSTEM_SECTIONS = ["status-updates", "screenshots", "test-plan", "mr-tests", "no-mr", "features-workflow"];
|
|
1357
1371
|
var PRD_SYSTEM_SECTIONS = ["prd-format", "prd-open-questions"];
|
|
1358
1372
|
var c = {
|
|
1359
1373
|
reset: "\x1B[0m",
|
|
@@ -2166,6 +2180,7 @@ ${initPrompt}`] : [],
|
|
|
2166
2180
|
].join("\n");
|
|
2167
2181
|
}
|
|
2168
2182
|
function buildPrototypePrompt(proto, repoDir) {
|
|
2183
|
+
const prototypeType = proto.prototypeType ?? "web_app";
|
|
2169
2184
|
const variantSteps = [];
|
|
2170
2185
|
for (let i = 1; i <= proto.variantCount; i++) {
|
|
2171
2186
|
const filename = `prototype-${i}.html`;
|
|
@@ -2178,14 +2193,87 @@ function buildPrototypePrompt(proto, repoDir) {
|
|
|
2178
2193
|
);
|
|
2179
2194
|
}
|
|
2180
2195
|
const variantList = Array.from({ length: proto.variantCount }, (_, i) => `prototype-${i + 1}.html`);
|
|
2196
|
+
const typeConfig = {
|
|
2197
|
+
web_app: {
|
|
2198
|
+
role: "You are a UI designer and frontend engineer. Your job is to generate high-quality, visually distinct web app prototype variants based on the user's design request.",
|
|
2199
|
+
guidelines: [
|
|
2200
|
+
`- **Layout**: Grid, list, card, single-page, multi-section`,
|
|
2201
|
+
`- **Style**: Minimal, bold, playful, corporate, retro, futuristic`,
|
|
2202
|
+
`- **Color scheme**: Light, dark, colorful, monochrome`,
|
|
2203
|
+
`- **Interaction model**: Click-heavy, scroll-based, hover effects, animated`,
|
|
2204
|
+
`- **Information density**: Sparse, balanced, dense`,
|
|
2205
|
+
`- **Navigation**: Sidebar, top nav, bottom nav, hamburger, tabs`
|
|
2206
|
+
],
|
|
2207
|
+
rules: [
|
|
2208
|
+
`- Each file must be a complete, functional page \u2014 pure HTML/CSS/JS, no external libraries (Tailwind CDN is acceptable).`
|
|
2209
|
+
]
|
|
2210
|
+
},
|
|
2211
|
+
mobile_app: {
|
|
2212
|
+
role: "You are a mobile UI designer and frontend engineer. Your job is to generate high-quality, visually distinct mobile app prototype variants based on the user's design request.",
|
|
2213
|
+
guidelines: [
|
|
2214
|
+
`- **Viewport**: Use a mobile viewport (375px wide max, 812px tall). Center the phone frame on a neutral background.`,
|
|
2215
|
+
`- **Layout**: Bottom tabs, stack navigation, cards, lists, full-screen views`,
|
|
2216
|
+
`- **Style**: iOS-inspired, Material Design, custom/brand-driven, minimal`,
|
|
2217
|
+
`- **Color scheme**: Light mode, dark mode, brand-colored`,
|
|
2218
|
+
`- **Touch patterns**: Large tap targets (44px+), swipe gestures indicated, thumb-friendly navigation`,
|
|
2219
|
+
`- **Typography**: Mobile-scale fonts (14-18px body), clear hierarchy`,
|
|
2220
|
+
`- **Navigation**: Bottom tab bar, top navigation bar, hamburger drawer, floating action button`
|
|
2221
|
+
],
|
|
2222
|
+
rules: [
|
|
2223
|
+
`- Render the app as a phone-sized frame (375\xD7812px) centered on a light gray page background.`,
|
|
2224
|
+
`- Use a \`<meta name="viewport" content="width=375">\` tag.`,
|
|
2225
|
+
`- Each file must be a complete, functional HTML page \u2014 pure HTML/CSS/JS, no external libraries (Tailwind CDN is acceptable).`
|
|
2226
|
+
]
|
|
2227
|
+
},
|
|
2228
|
+
desktop_app: {
|
|
2229
|
+
role: "You are a desktop UI designer and frontend engineer. Your job is to generate high-quality, visually distinct desktop application prototype variants based on the user's design request.",
|
|
2230
|
+
guidelines: [
|
|
2231
|
+
`- **Viewport**: Full-width desktop layout (1280px+). Use the full browser window.`,
|
|
2232
|
+
`- **Layout**: Multi-panel, sidebar + main content, menubar, toolbar, status bar`,
|
|
2233
|
+
`- **Style**: Native OS-inspired (macOS, Windows), Electron-style, productivity tool, pro/creative app`,
|
|
2234
|
+
`- **Color scheme**: Light, dark, system-default`,
|
|
2235
|
+
`- **Interaction**: Dense information layouts, keyboard shortcuts shown, right-click context menus, drag handles`,
|
|
2236
|
+
`- **Navigation**: Left sidebar tree, top tabs, ribbon toolbar, split panes`
|
|
2237
|
+
],
|
|
2238
|
+
rules: [
|
|
2239
|
+
`- Design for 1280px+ wide layouts. Use the full browser viewport width.`,
|
|
2240
|
+
`- Each file must be a complete, functional HTML page \u2014 pure HTML/CSS/JS, no external libraries (Tailwind CDN is acceptable).`
|
|
2241
|
+
]
|
|
2242
|
+
},
|
|
2243
|
+
logo: {
|
|
2244
|
+
role: "You are a graphic designer specializing in logo and brand identity. Your job is to generate high-quality, visually distinct logo variants based on the user's brand brief.",
|
|
2245
|
+
guidelines: [
|
|
2246
|
+
`- **Style**: Wordmark, lettermark, icon + wordmark, abstract symbol, emblem/badge`,
|
|
2247
|
+
`- **Visual language**: Minimal/geometric, organic/hand-drawn, bold/impactful, elegant/luxury, playful/friendly`,
|
|
2248
|
+
`- **Color scheme**: Monochrome, duotone, full-color (max 3 colors), gradient`,
|
|
2249
|
+
`- **Typography**: Serif, sans-serif, display/decorative, script`,
|
|
2250
|
+
`- **Symbolism**: Use shapes, negative space, and iconography that reflect the brand concept`
|
|
2251
|
+
],
|
|
2252
|
+
rules: [
|
|
2253
|
+
`- Each file is an HTML page that displays the logo centered on a white background with a dark mode toggle.`,
|
|
2254
|
+
`- The logo itself MUST be created as inline SVG \u2014 no raster images, no external assets.`,
|
|
2255
|
+
`- Show the logo at three sizes: large (400px wide), medium (200px), small (80px) stacked vertically.`,
|
|
2256
|
+
`- Include a dark background preview section below the logo to test contrast.`,
|
|
2257
|
+
`- The SVG must be clean and production-ready \u2014 no lorem ipsum, placeholder paths, or broken shapes.`
|
|
2258
|
+
]
|
|
2259
|
+
}
|
|
2260
|
+
};
|
|
2261
|
+
const config = typeConfig[prototypeType] ?? typeConfig.web_app;
|
|
2262
|
+
const typeLabel = {
|
|
2263
|
+
web_app: "Web App",
|
|
2264
|
+
mobile_app: "Mobile App",
|
|
2265
|
+
desktop_app: "Desktop App",
|
|
2266
|
+
logo: "Logo"
|
|
2267
|
+
};
|
|
2181
2268
|
return [
|
|
2182
|
-
|
|
2269
|
+
`${config.role}`,
|
|
2183
2270
|
``,
|
|
2184
2271
|
`Working directory: ${repoDir}`,
|
|
2185
2272
|
``,
|
|
2186
2273
|
`## Prototype Request`,
|
|
2187
2274
|
`Title: ${proto.title}`,
|
|
2188
2275
|
`ID: ${proto.id}`,
|
|
2276
|
+
`Type: ${typeLabel[prototypeType] ?? prototypeType}`,
|
|
2189
2277
|
``,
|
|
2190
2278
|
`## Design Prompt`,
|
|
2191
2279
|
`${proto.prompt}`,
|
|
@@ -2196,17 +2284,12 @@ function buildPrototypePrompt(proto, repoDir) {
|
|
|
2196
2284
|
``,
|
|
2197
2285
|
`Each file must be completely self-contained (inline all CSS and JS \u2014 no external dependencies). Tailwind CDN is acceptable.`,
|
|
2198
2286
|
``,
|
|
2199
|
-
`##
|
|
2287
|
+
`## Variation Guidelines`,
|
|
2200
2288
|
``,
|
|
2201
|
-
`When generating multiple
|
|
2202
|
-
|
|
2203
|
-
`- **Style**: Minimal, bold, playful, corporate, retro, futuristic`,
|
|
2204
|
-
`- **Color scheme**: Light, dark, colorful, monochrome`,
|
|
2205
|
-
`- **Interaction model**: Click-heavy, scroll-based, hover effects, animated`,
|
|
2206
|
-
`- **Information density**: Sparse, balanced, dense`,
|
|
2207
|
-
`- **Navigation**: Sidebar, top nav, bottom nav, hamburger, tabs`,
|
|
2289
|
+
`When generating multiple variants, vary these aspects:`,
|
|
2290
|
+
...config.guidelines,
|
|
2208
2291
|
``,
|
|
2209
|
-
`
|
|
2292
|
+
`Variants should demonstrate different interpretations, not just color swaps. Vary from very similar to wildly different approaches.`,
|
|
2210
2293
|
``,
|
|
2211
2294
|
...variantSteps,
|
|
2212
2295
|
`### Final verification`,
|
|
@@ -2216,7 +2299,7 @@ function buildPrototypePrompt(proto, repoDir) {
|
|
|
2216
2299
|
`- You MUST produce exactly ${proto.variantCount} files: ${variantList.join(", ")}`,
|
|
2217
2300
|
`- Generate them ONE AT A TIME \u2014 design each variant, write the file, then move to the next.`,
|
|
2218
2301
|
`- Each variant must look visually DISTINCT from the others.`,
|
|
2219
|
-
|
|
2302
|
+
...config.rules,
|
|
2220
2303
|
`- Do NOT upload or POST the files anywhere. The watch handler will upload them automatically after you exit.`,
|
|
2221
2304
|
`- Do NOT exit until ALL ${proto.variantCount} files have been written and verified.`
|
|
2222
2305
|
].join("\n");
|
|
@@ -2251,14 +2334,28 @@ function buildRefinementPrompt(proto, parentFiles, repoDir) {
|
|
|
2251
2334
|
existingVariantLines.push(``);
|
|
2252
2335
|
}
|
|
2253
2336
|
const existingVariants = existingVariantLines.join("\n");
|
|
2337
|
+
const prototypeType = proto.prototypeType ?? "web_app";
|
|
2338
|
+
const typeRoleMap = {
|
|
2339
|
+
web_app: "You are a UI designer and frontend engineer. Your job is to REFINE an existing web app prototype based on user feedback.",
|
|
2340
|
+
mobile_app: "You are a mobile UI designer and frontend engineer. Your job is to REFINE an existing mobile app prototype based on user feedback.",
|
|
2341
|
+
desktop_app: "You are a desktop UI designer and frontend engineer. Your job is to REFINE an existing desktop app prototype based on user feedback.",
|
|
2342
|
+
logo: "You are a graphic designer specializing in logo and brand identity. Your job is to REFINE an existing logo prototype based on user feedback."
|
|
2343
|
+
};
|
|
2344
|
+
const typeLabel = {
|
|
2345
|
+
web_app: "Web App",
|
|
2346
|
+
mobile_app: "Mobile App",
|
|
2347
|
+
desktop_app: "Desktop App",
|
|
2348
|
+
logo: "Logo"
|
|
2349
|
+
};
|
|
2254
2350
|
return [
|
|
2255
|
-
|
|
2351
|
+
`${typeRoleMap[prototypeType] ?? typeRoleMap.web_app}`,
|
|
2256
2352
|
``,
|
|
2257
2353
|
`Working directory: ${repoDir}`,
|
|
2258
2354
|
``,
|
|
2259
2355
|
`## Prototype Request`,
|
|
2260
2356
|
`Title: ${proto.title}`,
|
|
2261
2357
|
`ID: ${proto.id}`,
|
|
2358
|
+
`Type: ${typeLabel[prototypeType] ?? prototypeType}`,
|
|
2262
2359
|
``,
|
|
2263
2360
|
`## Original Design Prompt`,
|
|
2264
2361
|
`${proto.prompt}`,
|
|
@@ -2400,7 +2497,10 @@ ${systemPrompt}` : prompt2;
|
|
|
2400
2497
|
if (mode === "plan") {
|
|
2401
2498
|
return { bin: "claude", args: [...sessionArgs, ...nameArgs, ...systemArgs, ...turnsArgs, "--permission-mode", "plan", "-p", prompt2] };
|
|
2402
2499
|
}
|
|
2403
|
-
|
|
2500
|
+
const cfg = loadConfig();
|
|
2501
|
+
const permissionMode = cfg.claudePermissionMode ?? "auto";
|
|
2502
|
+
const permissionArgs = permissionMode === "dangerously-skip-permissions" ? ["--dangerously-skip-permissions"] : ["--permission-mode", "auto", "--enable-auto-mode"];
|
|
2503
|
+
return { bin: "claude", args: [...sessionArgs, ...nameArgs, ...systemArgs, ...turnsArgs, ...permissionArgs, "-p", prompt2] };
|
|
2404
2504
|
}
|
|
2405
2505
|
function commandExists(cmd) {
|
|
2406
2506
|
return new Promise((resolve8) => {
|
|
@@ -4260,28 +4360,45 @@ var prototypeCommand = new Command13("prototype").description("Manage prototypes
|
|
|
4260
4360
|
return;
|
|
4261
4361
|
}
|
|
4262
4362
|
console.log();
|
|
4363
|
+
const typeLabels = {
|
|
4364
|
+
web_app: "web",
|
|
4365
|
+
mobile_app: "mobile",
|
|
4366
|
+
desktop_app: "desktop",
|
|
4367
|
+
logo: "logo"
|
|
4368
|
+
};
|
|
4263
4369
|
for (const p of prototypes) {
|
|
4264
4370
|
const date = new Date(p.createdAt).toLocaleDateString();
|
|
4371
|
+
const typeLabel = typeLabels[p.prototypeType] ?? p.prototypeType ?? "web";
|
|
4265
4372
|
console.log(
|
|
4266
|
-
` ${paint4("bold", p.title)} ${statusBadge(p.status)} ${paint4("gray", p.id.slice(0, 8))} ${paint4("dim", date)}`
|
|
4373
|
+
` ${paint4("bold", p.title)} ${statusBadge(p.status)} ${paint4("blue", `[${typeLabel}]`)} ${paint4("gray", p.id.slice(0, 8))} ${paint4("dim", date)}`
|
|
4267
4374
|
);
|
|
4268
4375
|
console.log(` ${paint4("dim", p.prompt.slice(0, 80) + (p.prompt.length > 80 ? "\u2026" : ""))}`);
|
|
4269
4376
|
console.log();
|
|
4270
4377
|
}
|
|
4271
4378
|
})
|
|
4272
4379
|
).addCommand(
|
|
4273
|
-
new Command13("create").description("Create a new prototype").argument("<title>", "Title of the prototype").requiredOption("--prompt <prompt>", "Design description / prompt").option("--project <projectId>", "Project ID (defaults to linked project, when available)").option("--variants <count>", "Number of variants to generate (1-50)", "5").action(async (title, opts) => {
|
|
4380
|
+
new Command13("create").description("Create a new prototype").argument("<title>", "Title of the prototype").requiredOption("--prompt <prompt>", "Design description / prompt").option("--project <projectId>", "Project ID (defaults to linked project, when available)").option("--variants <count>", "Number of variants to generate (1-50)", "5").option("--type <type>", "Prototype type: web_app, mobile_app, desktop_app, logo (default: web_app)", "web_app").action(async (title, opts) => {
|
|
4274
4381
|
const projectId = opts.project ?? getLinkedProjectId();
|
|
4275
4382
|
const variantCount = Math.max(1, Math.min(50, parseInt(opts.variants, 10) || 5));
|
|
4383
|
+
const validTypes = ["web_app", "mobile_app", "desktop_app", "logo"];
|
|
4384
|
+
const prototypeType = validTypes.includes(opts.type) ? opts.type : "web_app";
|
|
4276
4385
|
const prototype = await api.post("/api/prototypes", {
|
|
4277
4386
|
title,
|
|
4278
4387
|
prompt: opts.prompt,
|
|
4388
|
+
prototypeType,
|
|
4279
4389
|
variantCount,
|
|
4280
4390
|
projectId: projectId ?? null
|
|
4281
4391
|
});
|
|
4392
|
+
const typeLabels = {
|
|
4393
|
+
web_app: "Web App",
|
|
4394
|
+
mobile_app: "Mobile App",
|
|
4395
|
+
desktop_app: "Desktop App",
|
|
4396
|
+
logo: "Logo"
|
|
4397
|
+
};
|
|
4282
4398
|
console.log();
|
|
4283
4399
|
console.log(` ${paint4("green", "\u2713")} Created prototype: ${paint4("bold", prototype.title)}`);
|
|
4284
4400
|
console.log(` ${paint4("gray", "ID:")} ${prototype.id}`);
|
|
4401
|
+
console.log(` ${paint4("gray", "Type:")} ${typeLabels[prototype.prototypeType] ?? prototype.prototypeType}`);
|
|
4285
4402
|
if (!prototype.projectId) {
|
|
4286
4403
|
console.log(` ${paint4("gray", "Project:")} none (will generate in the active watch directory)`);
|
|
4287
4404
|
}
|
|
@@ -4569,7 +4686,7 @@ async function checkApiConnectivity() {
|
|
|
4569
4686
|
}
|
|
4570
4687
|
}
|
|
4571
4688
|
function printResults(checks) {
|
|
4572
|
-
const maxNameLen = Math.max(...checks.map((
|
|
4689
|
+
const maxNameLen = Math.max(...checks.map((c12) => c12.name.length));
|
|
4573
4690
|
let allOk = true;
|
|
4574
4691
|
for (const check of checks) {
|
|
4575
4692
|
const isOptional = check.optional ?? false;
|
|
@@ -4583,10 +4700,10 @@ function printResults(checks) {
|
|
|
4583
4700
|
}
|
|
4584
4701
|
async function autoFix(checks, agent) {
|
|
4585
4702
|
const { spawn: spawn8 } = await import("child_process");
|
|
4586
|
-
const ghInstalled = checks.find((
|
|
4587
|
-
const ghAuthed = checks.find((
|
|
4588
|
-
const mrAuthed = checks.find((
|
|
4589
|
-
const claudeCheck = checks.find((
|
|
4703
|
+
const ghInstalled = checks.find((c12) => c12.name === "GitHub CLI (gh)").ok;
|
|
4704
|
+
const ghAuthed = checks.find((c12) => c12.name === "GitHub CLI auth").ok;
|
|
4705
|
+
const mrAuthed = checks.find((c12) => c12.name === "Mr. Manager CLI auth").ok;
|
|
4706
|
+
const claudeCheck = checks.find((c12) => c12.name === "Claude Code (claude)");
|
|
4590
4707
|
if (claudeCheck && !claudeCheck.ok && agent === "claude") {
|
|
4591
4708
|
console.log(paint5("cyan", " Installing Claude Code..."));
|
|
4592
4709
|
console.log(paint5("dim", " Running: curl -fsSL https://claude.ai/install.sh | bash"));
|
|
@@ -4649,7 +4766,7 @@ var setupCommand = new Command14("setup").description("Check that all dependenci
|
|
|
4649
4766
|
console.log("");
|
|
4650
4767
|
return;
|
|
4651
4768
|
}
|
|
4652
|
-
const fixes = checks.filter((
|
|
4769
|
+
const fixes = checks.filter((c12) => !c12.ok && c12.fix && !c12.optional);
|
|
4653
4770
|
if (fixes.length > 0) {
|
|
4654
4771
|
console.log(paint5("yellow", " To fix:"));
|
|
4655
4772
|
for (const fix of fixes) {
|
|
@@ -5787,10 +5904,10 @@ ${codebaseAnalysis.routes.map((r) => `- ${r}`).join("\n")}
|
|
|
5787
5904
|
${codebaseAnalysis.prismaModels.map((m) => `- ${m}`).join("\n")}
|
|
5788
5905
|
|
|
5789
5906
|
**Components:**
|
|
5790
|
-
${codebaseAnalysis.components.slice(0, 15).map((
|
|
5907
|
+
${codebaseAnalysis.components.slice(0, 15).map((c12) => `- ${c12}`).join("\n")}
|
|
5791
5908
|
|
|
5792
5909
|
**Recent Git Commits:**
|
|
5793
|
-
${codebaseAnalysis.recentCommits.slice(0, 8).map((
|
|
5910
|
+
${codebaseAnalysis.recentCommits.slice(0, 8).map((c12) => `- ${c12}`).join("\n")}
|
|
5794
5911
|
|
|
5795
5912
|
**Completed Tasks:**
|
|
5796
5913
|
${context.completedTasks.slice(0, 10).map((t) => `- ${t.title}`).join("\n") || "None"}
|
|
@@ -6437,7 +6554,7 @@ var doctorCommand = new Command25("doctor").description("Diagnose Mr. Manager CL
|
|
|
6437
6554
|
console.log("");
|
|
6438
6555
|
return;
|
|
6439
6556
|
}
|
|
6440
|
-
const fixes = checks.filter((
|
|
6557
|
+
const fixes = checks.filter((c12) => !c12.ok && c12.fix && !c12.optional);
|
|
6441
6558
|
if (fixes.length > 0) {
|
|
6442
6559
|
console.log(paint5("yellow", " To fix:"));
|
|
6443
6560
|
for (const fix of fixes) {
|
|
@@ -6768,6 +6885,44 @@ skillCommand.command("generate").alias("gen").description("Generate a new skill
|
|
|
6768
6885
|
}
|
|
6769
6886
|
});
|
|
6770
6887
|
|
|
6888
|
+
// cli/commands/tests.ts
|
|
6889
|
+
import { Command as Command28 } from "commander";
|
|
6890
|
+
var c11 = {
|
|
6891
|
+
reset: "\x1B[0m",
|
|
6892
|
+
dim: "\x1B[2m",
|
|
6893
|
+
yellow: "\x1B[33m"
|
|
6894
|
+
};
|
|
6895
|
+
var testsCommand = new Command28("tests").description("List MR Test scenarios for the linked project").action(async () => {
|
|
6896
|
+
const projectId = getLinkedProjectId();
|
|
6897
|
+
if (!projectId) {
|
|
6898
|
+
console.error(
|
|
6899
|
+
`${c11.yellow}No project linked to this directory.${c11.reset} Run "mr link <project-id>" first.`
|
|
6900
|
+
);
|
|
6901
|
+
process.exit(1);
|
|
6902
|
+
}
|
|
6903
|
+
const params = new URLSearchParams({ category: "test", projectId });
|
|
6904
|
+
let scenarios;
|
|
6905
|
+
try {
|
|
6906
|
+
scenarios = await api.get(`/api/skills?${params}`);
|
|
6907
|
+
} catch (err) {
|
|
6908
|
+
console.error(`Failed to fetch test scenarios: ${err.message}`);
|
|
6909
|
+
process.exit(1);
|
|
6910
|
+
}
|
|
6911
|
+
if (scenarios.length === 0) {
|
|
6912
|
+
console.log(`${c11.dim}No test scenarios found for this project.${c11.reset}`);
|
|
6913
|
+
return;
|
|
6914
|
+
}
|
|
6915
|
+
for (const scenario of scenarios) {
|
|
6916
|
+
console.log(`### ${scenario.name}`);
|
|
6917
|
+
if (scenario.description) {
|
|
6918
|
+
console.log(`${c11.dim}${scenario.description}${c11.reset}`);
|
|
6919
|
+
console.log();
|
|
6920
|
+
}
|
|
6921
|
+
console.log(scenario.content);
|
|
6922
|
+
console.log();
|
|
6923
|
+
}
|
|
6924
|
+
});
|
|
6925
|
+
|
|
6771
6926
|
// cli/index.ts
|
|
6772
6927
|
var configPath = join12(homedir3(), ".mr-manager", "config.json");
|
|
6773
6928
|
var isFirstRun = !existsSync17(configPath);
|
|
@@ -6775,7 +6930,7 @@ var userArgs = process.argv.slice(2);
|
|
|
6775
6930
|
var bypassCommands = /* @__PURE__ */ new Set(["login", "init", "auth", "help", "--help", "-h", "--version", "-V", "doctor", "setup"]);
|
|
6776
6931
|
var shouldBypass = userArgs.length > 0 && bypassCommands.has(userArgs[0]);
|
|
6777
6932
|
if (isFirstRun && !shouldBypass) {
|
|
6778
|
-
const
|
|
6933
|
+
const c12 = {
|
|
6779
6934
|
reset: "\x1B[0m",
|
|
6780
6935
|
bold: "\x1B[1m",
|
|
6781
6936
|
dim: "\x1B[2m",
|
|
@@ -6785,28 +6940,28 @@ if (isFirstRun && !shouldBypass) {
|
|
|
6785
6940
|
magenta: "\x1B[35m"
|
|
6786
6941
|
};
|
|
6787
6942
|
console.log("");
|
|
6788
|
-
console.log(`${
|
|
6789
|
-
console.log(`${
|
|
6790
|
-
console.log(`${
|
|
6791
|
-
console.log(`${
|
|
6943
|
+
console.log(`${c12.cyan} \u2554\u2566\u2557\u2566\u2550\u2557 \u2554\u2566\u2557\u2554\u2550\u2557\u2554\u2557\u2554\u2554\u2550\u2557\u2554\u2550\u2557\u2554\u2550\u2557\u2566\u2550\u2557${c12.reset}`);
|
|
6944
|
+
console.log(`${c12.magenta} \u2551\u2551\u2551\u2560\u2566\u255D \u2551\u2551\u2551\u2560\u2550\u2563\u2551\u2551\u2551\u2560\u2550\u2563\u2551 \u2566\u2551\u2563 \u2560\u2566\u255D${c12.reset}`);
|
|
6945
|
+
console.log(`${c12.cyan} \u2569 \u2569\u2569\u255A\u2550 \u2569 \u2569\u2569 \u2569\u255D\u255A\u255D\u2569 \u2569\u255A\u2550\u255D\u255A\u2550\u255D\u2569\u255A\u2550${c12.reset}`);
|
|
6946
|
+
console.log(`${c12.dim} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c12.reset}`);
|
|
6792
6947
|
console.log("");
|
|
6793
|
-
console.log(`${
|
|
6794
|
-
console.log(`${
|
|
6948
|
+
console.log(`${c12.bold} Welcome to Mr. Manager!${c12.reset}`);
|
|
6949
|
+
console.log(`${c12.dim} Let's get you set up in a few quick steps.${c12.reset}`);
|
|
6795
6950
|
console.log("");
|
|
6796
|
-
console.log(` ${
|
|
6797
|
-
console.log(` ${
|
|
6951
|
+
console.log(` ${c12.yellow}Step 1:${c12.reset} Authenticate via Google OAuth`);
|
|
6952
|
+
console.log(` ${c12.dim}Run:${c12.reset} ${c12.cyan}mr login${c12.reset}`);
|
|
6798
6953
|
console.log("");
|
|
6799
|
-
console.log(` ${
|
|
6800
|
-
console.log(` ${
|
|
6954
|
+
console.log(` ${c12.yellow}Step 2:${c12.reset} Verify your environment`);
|
|
6955
|
+
console.log(` ${c12.dim}Run:${c12.reset} ${c12.cyan}mr setup${c12.reset}`);
|
|
6801
6956
|
console.log("");
|
|
6802
|
-
console.log(` ${
|
|
6803
|
-
console.log(` ${
|
|
6957
|
+
console.log(` ${c12.yellow}Step 3:${c12.reset} Link a repo and start watching`);
|
|
6958
|
+
console.log(` ${c12.dim}Run:${c12.reset} ${c12.cyan}mr link${c12.reset} ${c12.dim}&&${c12.reset} ${c12.cyan}mr watch${c12.reset}`);
|
|
6804
6959
|
console.log("");
|
|
6805
|
-
console.log(`${
|
|
6960
|
+
console.log(`${c12.dim} Or run ${c12.reset}${c12.cyan}mr login${c12.reset}${c12.dim} to get started now.${c12.reset}`);
|
|
6806
6961
|
console.log("");
|
|
6807
6962
|
process.exit(0);
|
|
6808
6963
|
}
|
|
6809
|
-
var program = new
|
|
6964
|
+
var program = new Command29();
|
|
6810
6965
|
program.name("mr").description("Mr. Manager - Task and project management CLI").version(CLI_VERSION);
|
|
6811
6966
|
program.addCommand(initCommand);
|
|
6812
6967
|
program.addCommand(authCommand);
|
|
@@ -6838,4 +6993,5 @@ program.addCommand(ideaCommand);
|
|
|
6838
6993
|
program.addCommand(doctorCommand);
|
|
6839
6994
|
program.addCommand(promptAuditCommand);
|
|
6840
6995
|
program.addCommand(skillCommand);
|
|
6996
|
+
program.addCommand(testsCommand);
|
|
6841
6997
|
program.parse();
|