lean-spec 0.2.5-dev.20251120060929 → 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
|
-
|
|
7004
|
-
|
|
7005
|
-
|
|
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
|
-
|
|
7008
|
-
|
|
7009
|
-
}
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
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
|
|
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:
|
|
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
|
-
|
|
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"
|
|
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
|
|
8377
|
+
function planProjectRoadmapPrompt() {
|
|
8352
8378
|
return [
|
|
8353
|
-
"
|
|
8379
|
+
"plan-project-roadmap",
|
|
8354
8380
|
{
|
|
8355
|
-
title: "
|
|
8356
|
-
description: "
|
|
8381
|
+
title: "Plan Project Roadmap",
|
|
8382
|
+
description: "Interactive roadmap planning with phases, tasks, and dependencies",
|
|
8357
8383
|
argsSchema: {
|
|
8358
|
-
|
|
8359
|
-
description: z.string().optional()
|
|
8384
|
+
goal: z.string()
|
|
8360
8385
|
}
|
|
8361
8386
|
},
|
|
8362
|
-
({
|
|
8387
|
+
({ goal }) => ({
|
|
8363
8388
|
messages: [
|
|
8364
8389
|
{
|
|
8365
8390
|
role: "user",
|
|
8366
8391
|
content: {
|
|
8367
8392
|
type: "text",
|
|
8368
|
-
text: `
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
8422
|
+
|
|
8423
|
+
// src/mcp/prompts/project-progress-overview.ts
|
|
8424
|
+
function projectProgressOverviewPrompt() {
|
|
8380
8425
|
return [
|
|
8381
|
-
"
|
|
8426
|
+
"project-progress-overview",
|
|
8382
8427
|
{
|
|
8383
|
-
title: "
|
|
8384
|
-
description: "
|
|
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
|
-
(
|
|
8431
|
+
() => ({
|
|
8390
8432
|
messages: [
|
|
8391
8433
|
{
|
|
8392
8434
|
role: "user",
|
|
8393
8435
|
content: {
|
|
8394
8436
|
type: "text",
|
|
8395
|
-
text: `
|
|
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
|
-
|
|
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
|
-
|
|
8468
|
+
status: z.enum(["planned", "in-progress", "complete", "archived"])
|
|
8413
8469
|
}
|
|
8414
8470
|
},
|
|
8415
|
-
({ specPath,
|
|
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 "${
|
|
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(...
|
|
8432
|
-
server.registerPrompt(...
|
|
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-
|
|
8469
|
-
//# sourceMappingURL=chunk-
|
|
8526
|
+
//# sourceMappingURL=chunk-J5KH6MJR.js.map
|
|
8527
|
+
//# sourceMappingURL=chunk-J5KH6MJR.js.map
|