lean-spec 0.2.5-dev.20251120070726 → 0.2.5-dev.20251120072524

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.
@@ -6984,7 +6984,7 @@ function detectPackageManager(baseDir = process.cwd()) {
6984
6984
 
6985
6985
  // src/commands/ui.ts
6986
6986
  function uiCommand() {
6987
- return new Command("ui").description("Start local web UI for spec management").option("-s, --specs <dir>", "Specs directory (auto-detected if not specified)").option("-p, --port <port>", "Port to run on", "3000").option("--no-open", "Don't open browser automatically").option("--dev", "Run in development mode (only works in LeanSpec monorepo)").option("--dry-run", "Show what would run without executing").action(async (options) => {
6987
+ return new Command("ui").description("Start local web UI for spec management").option("-s, --specs <dir>", "Specs directory (auto-detected if not specified)").option("-p, --port <port>", "Port to run on", "3000").option("--no-open", "Don't open browser automatically").option("--multi-project", "Enable multi-project mode").option("--add-project <path>", "Add a project to multi-project registry").option("--discover <path>", "Discover LeanSpec projects in directory tree").option("--dev", "Run in development mode (only works in LeanSpec monorepo)").option("--dry-run", "Show what would run without executing").action(async (options) => {
6988
6988
  try {
6989
6989
  await startUi(options);
6990
6990
  } catch (error) {
@@ -7000,17 +7000,28 @@ async function startUi(options) {
7000
7000
  throw new Error(`Invalid port: ${options.port}`);
7001
7001
  }
7002
7002
  const cwd = process.cwd();
7003
- let specsDir;
7004
- if (options.specs) {
7005
- specsDir = resolve(cwd, options.specs);
7003
+ const specsMode = options.multiProject ? "multi-project" : "filesystem";
7004
+ let specsDir = "";
7005
+ if (!options.multiProject) {
7006
+ if (options.specs) {
7007
+ specsDir = resolve(cwd, options.specs);
7008
+ } else {
7009
+ const config = await loadConfig(cwd);
7010
+ specsDir = join(cwd, config.specsDir);
7011
+ }
7012
+ if (!existsSync(specsDir)) {
7013
+ console.error(chalk18.red(`\u2717 Specs directory not found: ${specsDir}`));
7014
+ console.log(chalk18.dim("\nRun `lean-spec init` to initialize LeanSpec in this directory."));
7015
+ throw new Error(`Specs directory not found: ${specsDir}`);
7016
+ }
7006
7017
  } else {
7007
- const config = await loadConfig(cwd);
7008
- specsDir = join(cwd, config.specsDir);
7009
- }
7010
- if (!existsSync(specsDir)) {
7011
- console.error(chalk18.red(`\u2717 Specs directory not found: ${specsDir}`));
7012
- console.log(chalk18.dim("\nRun `lean-spec init` to initialize LeanSpec in this directory."));
7013
- throw new Error(`Specs directory not found: ${specsDir}`);
7018
+ console.log(chalk18.cyan("\u2192 Multi-project mode enabled"));
7019
+ if (options.addProject) {
7020
+ console.log(chalk18.dim(` Adding project: ${options.addProject}`));
7021
+ }
7022
+ if (options.discover) {
7023
+ console.log(chalk18.dim(` Will discover projects in: ${options.discover}`));
7024
+ }
7014
7025
  }
7015
7026
  if (options.dev) {
7016
7027
  const isLeanSpecMonorepo = checkIsLeanSpecMonorepo(cwd);
@@ -7020,9 +7031,9 @@ async function startUi(options) {
7020
7031
  throw new Error("Not in LeanSpec monorepo");
7021
7032
  }
7022
7033
  const localUiDir = join(cwd, "packages/ui");
7023
- return runLocalWeb(localUiDir, specsDir, options);
7034
+ return runLocalWeb(localUiDir, specsDir, specsMode, options);
7024
7035
  }
7025
- return runPublishedUI(cwd, specsDir, options);
7036
+ return runPublishedUI(cwd, specsDir, specsMode, options);
7026
7037
  }
7027
7038
  function checkIsLeanSpecMonorepo(cwd) {
7028
7039
  const localUiDir = join(cwd, "packages/ui");
@@ -7037,14 +7048,14 @@ function checkIsLeanSpecMonorepo(cwd) {
7037
7048
  return false;
7038
7049
  }
7039
7050
  }
7040
- async function runLocalWeb(uiDir, specsDir, options) {
7051
+ async function runLocalWeb(uiDir, specsDir, specsMode, options) {
7041
7052
  console.log(chalk18.dim("\u2192 Detected LeanSpec monorepo, using local ui package\n"));
7042
7053
  const repoRoot = resolve(uiDir, "..", "..");
7043
7054
  const packageManager = detectPackageManager(repoRoot);
7044
7055
  if (options.dryRun) {
7045
7056
  console.log(chalk18.cyan("Would run:"));
7046
7057
  console.log(chalk18.dim(` cd ${uiDir}`));
7047
- console.log(chalk18.dim(` SPECS_MODE=filesystem SPECS_DIR=${specsDir} PORT=${options.port} ${packageManager} run dev`));
7058
+ console.log(chalk18.dim(` SPECS_MODE=${specsMode} SPECS_DIR=${specsDir} PORT=${options.port} ${packageManager} run dev`));
7048
7059
  if (options.open) {
7049
7060
  console.log(chalk18.dim(` open http://localhost:${options.port}`));
7050
7061
  }
@@ -7053,8 +7064,8 @@ async function runLocalWeb(uiDir, specsDir, options) {
7053
7064
  const spinner = ora("Starting web UI...").start();
7054
7065
  const env = {
7055
7066
  ...process.env,
7056
- SPECS_MODE: "filesystem",
7057
- SPECS_DIR: specsDir,
7067
+ SPECS_MODE: specsMode,
7068
+ SPECS_DIR: specsDir || "",
7058
7069
  PORT: options.port
7059
7070
  };
7060
7071
  const child = spawn(packageManager, ["run", "dev"], {
@@ -7068,7 +7079,16 @@ async function runLocalWeb(uiDir, specsDir, options) {
7068
7079
  console.log(chalk18.green(`
7069
7080
  \u2728 LeanSpec UI: http://localhost:${options.port}
7070
7081
  `));
7071
- console.log(chalk18.dim("Press Ctrl+C to stop\n"));
7082
+ if (options.multiProject) {
7083
+ console.log(chalk18.cyan("Multi-project mode is active"));
7084
+ if (options.addProject) {
7085
+ console.log(chalk18.dim(` Project to add: ${options.addProject}`));
7086
+ }
7087
+ if (options.discover) {
7088
+ console.log(chalk18.dim(` Discovery path: ${options.discover}`));
7089
+ }
7090
+ }
7091
+ console.log(chalk18.dim("\nPress Ctrl+C to stop\n"));
7072
7092
  if (options.open) {
7073
7093
  try {
7074
7094
  const openModule = await import('open');
@@ -7115,10 +7135,10 @@ Process exited with code ${code}`));
7115
7135
  process.exit(0);
7116
7136
  });
7117
7137
  }
7118
- async function runPublishedUI(cwd, specsDir, options) {
7138
+ async function runPublishedUI(cwd, specsDir, specsMode, options) {
7119
7139
  console.log(chalk18.dim("\u2192 Using published @leanspec/ui package\n"));
7120
7140
  const packageManager = detectPackageManager(cwd);
7121
- const { command, args, preview } = buildUiRunner(packageManager, specsDir, options.port, options.open);
7141
+ const { command, args, preview } = buildUiRunner(packageManager, specsDir, specsMode, options.port, options.open, options.multiProject);
7122
7142
  if (options.dryRun) {
7123
7143
  console.log(chalk18.cyan("Would run:"));
7124
7144
  console.log(chalk18.dim(` ${preview}`));
@@ -7165,8 +7185,14 @@ async function runPublishedUI(cwd, specsDir, options) {
7165
7185
  process.exit(1);
7166
7186
  });
7167
7187
  }
7168
- function buildUiRunner(packageManager, specsDir, port, openBrowser) {
7169
- const uiArgs = ["@leanspec/ui", "--specs", specsDir, "--port", port];
7188
+ function buildUiRunner(packageManager, specsDir, specsMode, port, openBrowser, multiProject) {
7189
+ const uiArgs = ["@leanspec/ui"];
7190
+ if (!multiProject) {
7191
+ uiArgs.push("--specs", specsDir);
7192
+ } else {
7193
+ uiArgs.push("--multi-project");
7194
+ }
7195
+ uiArgs.push("--port", port);
7170
7196
  if (!openBrowser) {
7171
7197
  uiArgs.push("--no-open");
7172
7198
  }
@@ -8348,53 +8374,83 @@ function registerResources(server) {
8348
8374
  server.registerResource(...specResource());
8349
8375
  server.registerResource(...statsResource());
8350
8376
  }
8351
- function createFeatureSpecPrompt() {
8377
+ function planProjectRoadmapPrompt() {
8352
8378
  return [
8353
- "create-feature-spec",
8379
+ "plan-project-roadmap",
8354
8380
  {
8355
- title: "Create Feature Spec",
8356
- description: "Guided workflow to create a new feature specification",
8381
+ title: "Plan Project Roadmap",
8382
+ description: "Interactive roadmap planning with phases, tasks, and dependencies",
8357
8383
  argsSchema: {
8358
- featureName: z.string(),
8359
- description: z.string().optional()
8384
+ goal: z.string()
8360
8385
  }
8361
8386
  },
8362
- ({ featureName, description }) => ({
8387
+ ({ goal }) => ({
8363
8388
  messages: [
8364
8389
  {
8365
8390
  role: "user",
8366
8391
  content: {
8367
8392
  type: "text",
8368
- text: `Create a new feature specification for: ${featureName}${description ? `
8393
+ text: `Plan a project roadmap for: ${goal}
8394
+
8395
+ 1. **Review Existing Work**: Analyze current specs using \`list\`/\`board\`, identify what's already planned/in-progress, assess how existing work relates to the new goal
8396
+ 2. **Break Down Goal**: Decompose the goal into logical phases or milestones
8397
+ 3. **Identify Tasks**: List key tasks and work items for each phase
8398
+ 4. **Map Dependencies**: Establish dependencies between tasks (what must be done first)
8399
+ 5. **Create Specs**: Create specification documents for major work items using the \`create\` tool
8400
+ 6. **Set Relationships**: Use \`link\` tool to establish \`depends_on\` and \`related\` relationships
8401
+ 7. **Timeline Estimation**: Provide realistic timeline based on task complexity and project velocity
8402
+ 8. **Risk Analysis**: Identify risks, unknowns, and mitigation strategies
8369
8403
 
8370
- Description: ${description}` : ""}
8404
+ Use the following tools to build the roadmap:
8405
+ - \`list\` / \`board\` / \`stats\` - Understand current project state
8406
+ - \`create\` - Create new specs for roadmap items
8407
+ - \`link\` - Establish dependencies between specs
8408
+ - \`update\` - Set priority and metadata
8371
8409
 
8372
- Please create this spec with appropriate metadata (status, priority, tags) and include standard sections like Overview, Design, Plan, and Test.`
8410
+ Provide a clear roadmap with:
8411
+ - Phases/milestones with descriptions
8412
+ - Key specs to create
8413
+ - Dependency relationships
8414
+ - Recommended execution order
8415
+ - Actionable next steps to implement this plan`
8373
8416
  }
8374
8417
  }
8375
8418
  ]
8376
8419
  })
8377
8420
  ];
8378
8421
  }
8379
- function findRelatedSpecsPrompt() {
8422
+
8423
+ // src/mcp/prompts/project-progress-overview.ts
8424
+ function projectProgressOverviewPrompt() {
8380
8425
  return [
8381
- "find-related-specs",
8426
+ "project-progress-overview",
8382
8427
  {
8383
- title: "Find Related Specs",
8384
- description: "Discover specifications related to a topic or feature",
8385
- argsSchema: {
8386
- topic: z.string()
8387
- }
8428
+ title: "Project Progress Overview",
8429
+ description: "Generate comprehensive project status report combining specs, git history, and metrics"
8388
8430
  },
8389
- ({ topic }) => ({
8431
+ () => ({
8390
8432
  messages: [
8391
8433
  {
8392
8434
  role: "user",
8393
8435
  content: {
8394
8436
  type: "text",
8395
- text: `Find all specifications related to: ${topic}
8437
+ text: `Analyze project progress and provide a comprehensive overview:
8438
+
8439
+ 1. **Spec Analysis**: Review all specs using \`board\` and \`stats\`, group by status (planned/in-progress/complete), highlight any blockers or dependencies
8440
+ 2. **Recent Activity**: Examine git commit history (last 2 weeks), identify key changes and development patterns
8441
+ 3. **Current State**: Assess what's actively being worked on, what's completed, what's planned
8442
+ 4. **Velocity Metrics**: Calculate completion rates, average time in each status, and throughput trends
8443
+ 5. **Risk Assessment**: Identify stalled specs, missing dependencies, potential bottlenecks
8444
+ 6. **Next Steps**: Recommend priority actions based on current project state
8396
8445
 
8397
- Please search for this topic and show me the dependencies between related specs.`
8446
+ Use the following tools to gather data:
8447
+ - \`board\` - Get Kanban view of specs by status
8448
+ - \`stats\` - Get project metrics
8449
+ - \`list\` - List specs with filters
8450
+ - \`deps\` - Analyze dependencies for critical specs
8451
+ - Terminal git commands - Analyze recent commit history
8452
+
8453
+ Provide a clear, actionable summary that helps understand project health and next steps.`
8398
8454
  }
8399
8455
  }
8400
8456
  ]
@@ -8409,16 +8465,18 @@ function updateSpecStatusPrompt() {
8409
8465
  description: "Quick workflow to update specification status",
8410
8466
  argsSchema: {
8411
8467
  specPath: z.string(),
8412
- newStatus: z.enum(["planned", "in-progress", "complete", "archived"])
8468
+ status: z.enum(["planned", "in-progress", "complete", "archived"])
8413
8469
  }
8414
8470
  },
8415
- ({ specPath, newStatus }) => ({
8471
+ ({ specPath, status }) => ({
8416
8472
  messages: [
8417
8473
  {
8418
8474
  role: "user",
8419
8475
  content: {
8420
8476
  type: "text",
8421
- text: `Update the status of spec "${specPath}" to "${newStatus}". Use the update tool to make this change.`
8477
+ text: `Update the status of spec "${specPath}" to "${status}".
8478
+
8479
+ Use the \`update\` tool: \`update <spec> --status ${status}\``
8422
8480
  }
8423
8481
  }
8424
8482
  ]
@@ -8428,8 +8486,8 @@ function updateSpecStatusPrompt() {
8428
8486
 
8429
8487
  // src/mcp/prompts/registry.ts
8430
8488
  function registerPrompts(server) {
8431
- server.registerPrompt(...createFeatureSpecPrompt());
8432
- server.registerPrompt(...findRelatedSpecsPrompt());
8489
+ server.registerPrompt(...projectProgressOverviewPrompt());
8490
+ server.registerPrompt(...planProjectRoadmapPrompt());
8433
8491
  server.registerPrompt(...updateSpecStatusPrompt());
8434
8492
  }
8435
8493
 
@@ -8465,5 +8523,5 @@ if (import.meta.url === `file://${process.argv[1]}`) {
8465
8523
  }
8466
8524
 
8467
8525
  export { analyzeCommand, archiveCommand, backfillCommand, boardCommand, checkCommand, compactCommand, createCommand, createMcpServer, depsCommand, filesCommand, ganttCommand, initCommand, linkCommand, listCommand, mcpCommand, migrateCommand, openCommand, searchCommand, splitCommand, statsCommand, templatesCommand, timelineCommand, tokensCommand, uiCommand, unlinkCommand, updateCommand, validateCommand, viewCommand };
8468
- //# sourceMappingURL=chunk-D5HD2K67.js.map
8469
- //# sourceMappingURL=chunk-D5HD2K67.js.map
8526
+ //# sourceMappingURL=chunk-J5KH6MJR.js.map
8527
+ //# sourceMappingURL=chunk-J5KH6MJR.js.map