claude-kanban 0.6.1 → 0.6.3
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/bin/cli.js +90 -42
- package/dist/bin/cli.js.map +1 -1
- package/dist/server/index.js +90 -42
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -1841,11 +1841,33 @@ var RoadmapService = class extends EventEmitter2 {
|
|
|
1841
1841
|
let description = "";
|
|
1842
1842
|
let stack = [];
|
|
1843
1843
|
let existingFeatures = [];
|
|
1844
|
+
const claudeMdPaths = ["CLAUDE.md", "claude.md", ".claude/CLAUDE.md"];
|
|
1845
|
+
for (const claudePath of claudeMdPaths) {
|
|
1846
|
+
const fullPath = join5(this.projectPath, claudePath);
|
|
1847
|
+
if (existsSync3(fullPath)) {
|
|
1848
|
+
const claudeMd = readFileSync5(fullPath, "utf-8");
|
|
1849
|
+
const lines = claudeMd.split("\n");
|
|
1850
|
+
const contentLines = [];
|
|
1851
|
+
for (const line of lines) {
|
|
1852
|
+
const trimmed = line.trim();
|
|
1853
|
+
if (trimmed && !trimmed.startsWith("#") && !trimmed.startsWith("```")) {
|
|
1854
|
+
contentLines.push(trimmed);
|
|
1855
|
+
if (contentLines.join(" ").length > 300) break;
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
if (contentLines.length > 0) {
|
|
1859
|
+
description = contentLines.join(" ").slice(0, 500);
|
|
1860
|
+
}
|
|
1861
|
+
break;
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1844
1864
|
const packageJsonPath = join5(this.projectPath, "package.json");
|
|
1845
1865
|
if (existsSync3(packageJsonPath)) {
|
|
1846
1866
|
try {
|
|
1847
1867
|
const pkg = JSON.parse(readFileSync5(packageJsonPath, "utf-8"));
|
|
1848
|
-
description
|
|
1868
|
+
if (!description && pkg.description && !pkg.description.includes("<")) {
|
|
1869
|
+
description = pkg.description;
|
|
1870
|
+
}
|
|
1849
1871
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
1850
1872
|
if (deps.react) stack.push("React");
|
|
1851
1873
|
if (deps.vue) stack.push("Vue");
|
|
@@ -1855,23 +1877,43 @@ var RoadmapService = class extends EventEmitter2 {
|
|
|
1855
1877
|
if (deps.fastify) stack.push("Fastify");
|
|
1856
1878
|
if (deps.typescript) stack.push("TypeScript");
|
|
1857
1879
|
if (deps.tailwindcss) stack.push("Tailwind CSS");
|
|
1880
|
+
if (deps.laravel) stack.push("Laravel");
|
|
1858
1881
|
} catch {
|
|
1859
1882
|
}
|
|
1860
1883
|
}
|
|
1861
|
-
const
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1884
|
+
const composerPath = join5(this.projectPath, "composer.json");
|
|
1885
|
+
if (existsSync3(composerPath)) {
|
|
1886
|
+
try {
|
|
1887
|
+
const composer = JSON.parse(readFileSync5(composerPath, "utf-8"));
|
|
1888
|
+
if (!description && composer.description && !composer.description.includes("<")) {
|
|
1889
|
+
description = composer.description;
|
|
1890
|
+
}
|
|
1891
|
+
if (composer.require?.["laravel/framework"]) stack.push("Laravel");
|
|
1892
|
+
if (composer.require?.["livewire/livewire"]) stack.push("Livewire");
|
|
1893
|
+
if (composer.require?.["inertiajs/inertia-laravel"]) stack.push("Inertia.js");
|
|
1894
|
+
} catch {
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
if (!description) {
|
|
1898
|
+
const readmePaths = ["README.md", "readme.md", "README.txt", "readme.txt"];
|
|
1899
|
+
for (const readmePath of readmePaths) {
|
|
1900
|
+
const fullPath = join5(this.projectPath, readmePath);
|
|
1901
|
+
if (existsSync3(fullPath)) {
|
|
1902
|
+
const readme = readFileSync5(fullPath, "utf-8");
|
|
1903
|
+
const lines = readme.split("\n").filter((l) => {
|
|
1904
|
+
const trimmed = l.trim();
|
|
1905
|
+
return trimmed && !trimmed.startsWith("#") && !trimmed.startsWith("<") && !trimmed.startsWith("![") && !trimmed.startsWith("[!");
|
|
1906
|
+
});
|
|
1868
1907
|
if (lines.length > 0) {
|
|
1869
1908
|
description = lines[0].trim().slice(0, 500);
|
|
1870
1909
|
}
|
|
1910
|
+
break;
|
|
1871
1911
|
}
|
|
1872
|
-
break;
|
|
1873
1912
|
}
|
|
1874
1913
|
}
|
|
1914
|
+
if (!description) {
|
|
1915
|
+
description = `A ${stack.length > 0 ? stack.join("/") + " " : ""}software project`;
|
|
1916
|
+
}
|
|
1875
1917
|
const prdPath = join5(this.projectPath, ROADMAP_DIR, "prd.json");
|
|
1876
1918
|
if (existsSync3(prdPath)) {
|
|
1877
1919
|
try {
|
|
@@ -1956,19 +1998,24 @@ var RoadmapService = class extends EventEmitter2 {
|
|
|
1956
1998
|
* Build the competitor research prompt
|
|
1957
1999
|
*/
|
|
1958
2000
|
buildCompetitorResearchPrompt(projectInfo) {
|
|
1959
|
-
return `You are a product research analyst.
|
|
2001
|
+
return `You are a product research analyst. Your task is to research competitors and return ONLY JSON output.
|
|
1960
2002
|
|
|
1961
|
-
|
|
1962
|
-
Description: ${projectInfo.description}
|
|
1963
|
-
Tech Stack: ${projectInfo.stack.join(", ") || "Unknown"}
|
|
2003
|
+
IMPORTANT: Do not ask any questions. Do not request clarification. Just analyze and return the JSON.
|
|
1964
2004
|
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
2005
|
+
## Project Information
|
|
2006
|
+
- Name: ${projectInfo.name}
|
|
2007
|
+
- Description: ${projectInfo.description}
|
|
2008
|
+
- Tech Stack: ${projectInfo.stack.join(", ") || "Unknown"}
|
|
2009
|
+
|
|
2010
|
+
## Your Task
|
|
2011
|
+
1. Based on the project description, identify what type of product/service this is
|
|
2012
|
+
2. Find 3-5 competitors or similar projects in this space
|
|
2013
|
+
3. Analyze their strengths and weaknesses
|
|
2014
|
+
4. Identify differentiating features
|
|
2015
|
+
|
|
2016
|
+
## Required Output Format
|
|
2017
|
+
Return ONLY a JSON array (no markdown code blocks, no explanations):
|
|
1969
2018
|
|
|
1970
|
-
Return your findings as JSON in this format:
|
|
1971
|
-
\`\`\`json
|
|
1972
2019
|
[
|
|
1973
2020
|
{
|
|
1974
2021
|
"name": "Competitor Name",
|
|
@@ -1978,9 +2025,8 @@ Return your findings as JSON in this format:
|
|
|
1978
2025
|
"differentiators": ["feature 1", "feature 2"]
|
|
1979
2026
|
}
|
|
1980
2027
|
]
|
|
1981
|
-
\`\`\`
|
|
1982
2028
|
|
|
1983
|
-
|
|
2029
|
+
Begin your response with [ and end with ]. No other text.`;
|
|
1984
2030
|
}
|
|
1985
2031
|
/**
|
|
1986
2032
|
* Build the roadmap generation prompt
|
|
@@ -2020,7 +2066,9 @@ ${request.customPrompt}
|
|
|
2020
2066
|
`;
|
|
2021
2067
|
}
|
|
2022
2068
|
prompt += `
|
|
2023
|
-
##
|
|
2069
|
+
## Instructions
|
|
2070
|
+
IMPORTANT: Do not ask any questions. Do not request clarification. Generate the roadmap based on the information provided.
|
|
2071
|
+
|
|
2024
2072
|
Create a comprehensive product roadmap with features organized into phases.
|
|
2025
2073
|
|
|
2026
2074
|
Use the MoSCoW prioritization framework:
|
|
@@ -2035,8 +2083,9 @@ For each feature, estimate:
|
|
|
2035
2083
|
|
|
2036
2084
|
Categories should be one of: functional, ui, bug, enhancement, testing, refactor
|
|
2037
2085
|
|
|
2038
|
-
|
|
2039
|
-
|
|
2086
|
+
## Required Output Format
|
|
2087
|
+
Return ONLY valid JSON (no markdown code blocks, no explanations). Begin with { and end with }:
|
|
2088
|
+
|
|
2040
2089
|
{
|
|
2041
2090
|
"projectDescription": "Brief description of the project",
|
|
2042
2091
|
"targetAudience": "Who this project is for",
|
|
@@ -2064,11 +2113,10 @@ Return your roadmap as JSON:
|
|
|
2064
2113
|
}
|
|
2065
2114
|
]
|
|
2066
2115
|
}
|
|
2067
|
-
\`\`\`
|
|
2068
2116
|
|
|
2069
2117
|
Generate 10-20 strategic features across 3-4 phases. Be specific and actionable.
|
|
2070
2118
|
Don't duplicate features that already exist in the project.
|
|
2071
|
-
|
|
2119
|
+
Begin your response with { - no other text before or after the JSON.`;
|
|
2072
2120
|
return prompt;
|
|
2073
2121
|
}
|
|
2074
2122
|
/**
|
|
@@ -4273,33 +4321,33 @@ function renderRoadmapFeature(feature) {
|
|
|
4273
4321
|
|
|
4274
4322
|
function renderRoadmapModal() {
|
|
4275
4323
|
return \`
|
|
4276
|
-
<div class="modal-backdrop" onclick="state.showModal = null; render();">
|
|
4277
|
-
<div class="modal-content max-w-lg
|
|
4278
|
-
<div class="
|
|
4279
|
-
<
|
|
4280
|
-
<button onclick="state.showModal = null; render();" class="
|
|
4324
|
+
<div class="modal-backdrop fixed inset-0 flex items-center justify-center z-50" onclick="if(event.target === event.currentTarget) { state.showModal = null; render(); }">
|
|
4325
|
+
<div class="modal-content card rounded-xl w-full max-w-lg mx-4">
|
|
4326
|
+
<div class="px-6 py-4 border-b border-canvas-200 flex justify-between items-center">
|
|
4327
|
+
<h3 class="font-display font-semibold text-canvas-800 text-lg">\u{1F5FA}\uFE0F Generate Roadmap</h3>
|
|
4328
|
+
<button onclick="state.showModal = null; render();" class="text-canvas-400 hover:text-canvas-600 text-xl leading-none">×</button>
|
|
4281
4329
|
</div>
|
|
4282
|
-
<div class="
|
|
4283
|
-
<p class="text-sm text-canvas-500 mb-
|
|
4330
|
+
<div class="p-6">
|
|
4331
|
+
<p class="text-sm text-canvas-500 mb-6">
|
|
4284
4332
|
Generate a strategic feature roadmap by analyzing your project structure and optionally researching competitors.
|
|
4285
4333
|
</p>
|
|
4286
4334
|
|
|
4287
|
-
<div class="space-y-
|
|
4288
|
-
<label class="flex items-
|
|
4335
|
+
<div class="space-y-5">
|
|
4336
|
+
<label class="flex items-start gap-3 cursor-pointer p-3 rounded-lg border border-canvas-200 hover:border-canvas-300 transition-colors">
|
|
4289
4337
|
<input type="checkbox"
|
|
4290
4338
|
\${state.roadmapEnableCompetitors ? 'checked' : ''}
|
|
4291
4339
|
onchange="state.roadmapEnableCompetitors = this.checked; render();"
|
|
4292
|
-
class="w-4 h-4 accent-accent">
|
|
4340
|
+
class="w-4 h-4 mt-0.5 accent-accent">
|
|
4293
4341
|
<div>
|
|
4294
4342
|
<span class="text-sm font-medium text-canvas-700">Enable competitor research</span>
|
|
4295
|
-
<p class="text-xs text-canvas-400">Use web search to analyze competitors (takes longer)</p>
|
|
4343
|
+
<p class="text-xs text-canvas-400 mt-0.5">Use web search to analyze competitors (takes longer)</p>
|
|
4296
4344
|
</div>
|
|
4297
4345
|
</label>
|
|
4298
4346
|
|
|
4299
4347
|
<div>
|
|
4300
|
-
<label class="text-sm font-medium text-canvas-700">Additional context (optional)</label>
|
|
4348
|
+
<label class="block text-sm font-medium text-canvas-700 mb-1.5">Additional context (optional)</label>
|
|
4301
4349
|
<textarea
|
|
4302
|
-
class="input w-full
|
|
4350
|
+
class="input w-full text-sm"
|
|
4303
4351
|
rows="3"
|
|
4304
4352
|
placeholder="E.g., Focus on mobile features, target enterprise users..."
|
|
4305
4353
|
oninput="state.roadmapCustomPrompt = this.value;"
|
|
@@ -4307,9 +4355,9 @@ function renderRoadmapModal() {
|
|
|
4307
4355
|
</div>
|
|
4308
4356
|
</div>
|
|
4309
4357
|
</div>
|
|
4310
|
-
<div class="
|
|
4311
|
-
<button onclick="state.showModal = null; render();" class="btn btn-ghost">Cancel</button>
|
|
4312
|
-
<button onclick="generateRoadmap(); state.showModal = null; render();" class="btn btn-primary">
|
|
4358
|
+
<div class="px-6 py-4 border-t border-canvas-200 flex justify-end gap-3">
|
|
4359
|
+
<button onclick="state.showModal = null; render();" class="btn btn-ghost px-4 py-2">Cancel</button>
|
|
4360
|
+
<button onclick="generateRoadmap(); state.showModal = null; render();" class="btn btn-primary px-4 py-2">
|
|
4313
4361
|
\u{1F680} Generate Roadmap
|
|
4314
4362
|
</button>
|
|
4315
4363
|
</div>
|