claude-kan 1.0.0
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/LICENSE +21 -0
- package/README.md +136 -0
- package/dist/cli/index.d.ts +11 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +70 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +5 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +206 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +299 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/card.d.ts +29 -0
- package/dist/core/card.d.ts.map +1 -0
- package/dist/core/card.js +188 -0
- package/dist/core/card.js.map +1 -0
- package/dist/core/conflict.d.ts +13 -0
- package/dist/core/conflict.d.ts.map +1 -0
- package/dist/core/conflict.js +85 -0
- package/dist/core/conflict.js.map +1 -0
- package/dist/core/kanban.d.ts +22 -0
- package/dist/core/kanban.d.ts.map +1 -0
- package/dist/core/kanban.js +53 -0
- package/dist/core/kanban.js.map +1 -0
- package/dist/core/session.d.ts +21 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +115 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/types.d.ts +50 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +6 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/skills/kanboard.d.ts +8 -0
- package/dist/skills/kanboard.d.ts.map +1 -0
- package/dist/skills/kanboard.js +118 -0
- package/dist/skills/kanboard.js.map +1 -0
- package/dist/skills/kanboardfull.d.ts +7 -0
- package/dist/skills/kanboardfull.d.ts.map +1 -0
- package/dist/skills/kanboardfull.js +137 -0
- package/dist/skills/kanboardfull.js.map +1 -0
- package/dist/skills/kanboardweb.d.ts +11 -0
- package/dist/skills/kanboardweb.d.ts.map +1 -0
- package/dist/skills/kanboardweb.js +489 -0
- package/dist/skills/kanboardweb.js.map +1 -0
- package/dist/skills/kancard.d.ts +10 -0
- package/dist/skills/kancard.d.ts.map +1 -0
- package/dist/skills/kancard.js +169 -0
- package/dist/skills/kancard.js.map +1 -0
- package/dist/skills/kancreate.d.ts +6 -0
- package/dist/skills/kancreate.d.ts.map +1 -0
- package/dist/skills/kancreate.js +60 -0
- package/dist/skills/kancreate.js.map +1 -0
- package/dist/skills/kandoctor.d.ts +17 -0
- package/dist/skills/kandoctor.d.ts.map +1 -0
- package/dist/skills/kandoctor.js +401 -0
- package/dist/skills/kandoctor.js.map +1 -0
- package/dist/skills/kanhelp.d.ts +7 -0
- package/dist/skills/kanhelp.d.ts.map +1 -0
- package/dist/skills/kanhelp.js +194 -0
- package/dist/skills/kanhelp.js.map +1 -0
- package/dist/skills/kanprune.d.ts +11 -0
- package/dist/skills/kanprune.d.ts.map +1 -0
- package/dist/skills/kanprune.js +131 -0
- package/dist/skills/kanprune.js.map +1 -0
- package/dist/skills/kansync.d.ts +7 -0
- package/dist/skills/kansync.d.ts.map +1 -0
- package/dist/skills/kansync.js +41 -0
- package/dist/skills/kansync.js.map +1 -0
- package/dist/skills/kanupdate.d.ts +6 -0
- package/dist/skills/kanupdate.d.ts.map +1 -0
- package/dist/skills/kanupdate.js +74 -0
- package/dist/skills/kanupdate.js.map +1 -0
- package/dist/skills/session-debug.d.ts +6 -0
- package/dist/skills/session-debug.d.ts.map +1 -0
- package/dist/skills/session-debug.js +124 -0
- package/dist/skills/session-debug.js.map +1 -0
- package/dist/templates/skill-templates/kanboard/SKILL.md +26 -0
- package/dist/templates/skill-templates/kanboardfull/SKILL.md +28 -0
- package/dist/templates/skill-templates/kanboardweb/SKILL.md +137 -0
- package/dist/templates/skill-templates/kancard/SKILL.md +70 -0
- package/dist/templates/skill-templates/kancreate/SKILL.md +45 -0
- package/dist/templates/skill-templates/kandoctor/SKILL.md +58 -0
- package/dist/templates/skill-templates/kanhelp/SKILL.md +34 -0
- package/dist/templates/skill-templates/kanprune/SKILL.md +102 -0
- package/dist/templates/skill-templates/kansync/SKILL.md +21 -0
- package/dist/templates/skill-templates/kanupdate/SKILL.md +44 -0
- package/dist/templates/skill-templates/session-debug/SKILL.md +25 -0
- package/package.json +50 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* CLI tool for Claude Kanban initialization and management
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const conflict_1 = require("./core/conflict");
|
|
13
|
+
async function main() {
|
|
14
|
+
const args = process.argv.slice(2);
|
|
15
|
+
const command = args[0] || 'help';
|
|
16
|
+
switch (command) {
|
|
17
|
+
case 'init':
|
|
18
|
+
await initCommand();
|
|
19
|
+
break;
|
|
20
|
+
case 'check':
|
|
21
|
+
await checkCommand();
|
|
22
|
+
break;
|
|
23
|
+
case 'help':
|
|
24
|
+
default:
|
|
25
|
+
showHelp();
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function initCommand() {
|
|
30
|
+
console.log('🎯 Initializing Claude Kanban System...\n');
|
|
31
|
+
// 1. Analyze current project structure
|
|
32
|
+
const analysis = (0, conflict_1.analyzeProject)();
|
|
33
|
+
// 2. Detect conflicts
|
|
34
|
+
const conflicts = (0, conflict_1.detectConflicts)(analysis);
|
|
35
|
+
// 3. Generate report
|
|
36
|
+
console.log('📊 Project Analysis Report:\n');
|
|
37
|
+
console.log(`- Existing docs/tasks/: ${analysis.hasTasksDir ? '✅' : '❌'}`);
|
|
38
|
+
console.log(`- Existing todo.md: ${analysis.hasTodoMd ? '✅' : '❌'}`);
|
|
39
|
+
console.log(`- Existing lessons.md: ${analysis.hasLessonsMd ? '✅' : '❌'}`);
|
|
40
|
+
console.log(`- Git repository: ${analysis.isGitRepo ? '✅' : '❌'}\n`);
|
|
41
|
+
if (conflicts.length > 0) {
|
|
42
|
+
console.log('⚠️ Potential Conflicts Detected:\n');
|
|
43
|
+
conflicts.forEach(conflict => {
|
|
44
|
+
const icon = conflict.severity === 'error' ? '❌' : '⚠️ ';
|
|
45
|
+
console.log(`${icon} ${conflict.file}: ${conflict.message}`);
|
|
46
|
+
console.log(` Resolution: ${conflict.resolution}\n`);
|
|
47
|
+
});
|
|
48
|
+
// For now, auto-proceed (in production, use inquirer to ask)
|
|
49
|
+
console.log('Proceeding with installation...\n');
|
|
50
|
+
}
|
|
51
|
+
// 4. Create Kanban structure
|
|
52
|
+
await createKanbanStructure(analysis);
|
|
53
|
+
// 5. Install plugin
|
|
54
|
+
await installPlugin();
|
|
55
|
+
// 6. Install skills
|
|
56
|
+
await installSkills();
|
|
57
|
+
console.log('\n✅ Installation complete!\n');
|
|
58
|
+
console.log('Next steps:');
|
|
59
|
+
console.log(' 1. Run: claude (to start Claude Code)');
|
|
60
|
+
console.log(' 2. Use: /kanboard (to view your Kanban board)');
|
|
61
|
+
console.log(' 3. Use: /kansync (to manually sync tasks)\n');
|
|
62
|
+
}
|
|
63
|
+
async function checkCommand() {
|
|
64
|
+
console.log('🔍 Checking Claude Kanban installation...\n');
|
|
65
|
+
const analysis = (0, conflict_1.analyzeProject)();
|
|
66
|
+
// Check Kanban structure
|
|
67
|
+
const statuses = ['todo', 'inprogress', 'done', 'parkinglot'];
|
|
68
|
+
console.log('Kanban Structure:');
|
|
69
|
+
for (const status of statuses) {
|
|
70
|
+
const exists = fs_1.default.existsSync(`docs/tasks/${status}`);
|
|
71
|
+
console.log(` - docs/tasks/${status}/: ${exists ? '✅' : '❌'}`);
|
|
72
|
+
}
|
|
73
|
+
// Check plugin
|
|
74
|
+
console.log('\nPlugin:');
|
|
75
|
+
console.log(` - .claude/plugins/kanban/: ${fs_1.default.existsSync('.claude/plugins/kanban') ? '✅' : '❌'}`);
|
|
76
|
+
// Check skills
|
|
77
|
+
console.log('\nSkills:');
|
|
78
|
+
console.log(` - .claude/skills/kanboard/: ${fs_1.default.existsSync('.claude/skills/kanboard') ? '✅' : '❌'}`);
|
|
79
|
+
console.log(` - .claude/skills/kansync/: ${fs_1.default.existsSync('.claude/skills/kansync') ? '✅' : '❌'}`);
|
|
80
|
+
console.log(` - .claude/skills/kanhelp/: ${fs_1.default.existsSync('.claude/skills/kanhelp') ? '✅' : '❌'}`);
|
|
81
|
+
console.log(` - .claude/skills/kandoctor/: ${fs_1.default.existsSync('.claude/skills/kandoctor') ? '✅' : '❌'}`);
|
|
82
|
+
console.log('\n');
|
|
83
|
+
}
|
|
84
|
+
function showHelp() {
|
|
85
|
+
console.log(`
|
|
86
|
+
Claude Kanban - Persistent task management for Claude Code
|
|
87
|
+
|
|
88
|
+
Usage:
|
|
89
|
+
claude-kanban init Initialize Kanban system in current project
|
|
90
|
+
claude-kanban check Verify installation
|
|
91
|
+
claude-kanban help Show this help message
|
|
92
|
+
|
|
93
|
+
Examples:
|
|
94
|
+
npx @findependence/claude-kanban init
|
|
95
|
+
npx @findependence/claude-kanban check
|
|
96
|
+
`);
|
|
97
|
+
}
|
|
98
|
+
async function createKanbanStructure(analysis) {
|
|
99
|
+
console.log('📁 Creating Kanban directory structure...');
|
|
100
|
+
// Create status folders
|
|
101
|
+
const statuses = ['todo', 'inprogress', 'done', 'parkinglot'];
|
|
102
|
+
for (const status of statuses) {
|
|
103
|
+
const dirPath = `docs/tasks/${status}`;
|
|
104
|
+
fs_1.default.mkdirSync(dirPath, { recursive: true });
|
|
105
|
+
// Create .gitkeep file
|
|
106
|
+
fs_1.default.writeFileSync(path_1.default.join(dirPath, '.gitkeep'), '');
|
|
107
|
+
}
|
|
108
|
+
// Backup existing todo.md if needed
|
|
109
|
+
if (analysis.hasTodoMd) {
|
|
110
|
+
const content = fs_1.default.readFileSync('docs/tasks/todo.md', 'utf-8');
|
|
111
|
+
if (content.length > 100) {
|
|
112
|
+
fs_1.default.copyFileSync('docs/tasks/todo.md', 'docs/tasks/todo.md.backup');
|
|
113
|
+
console.log(' ✅ Backed up existing todo.md');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
console.log(' ✅ Created status folders (todo, inprogress, done, parkinglot)');
|
|
117
|
+
}
|
|
118
|
+
async function installPlugin() {
|
|
119
|
+
console.log('🔌 Installing Kanban plugin...');
|
|
120
|
+
const pluginDir = '.claude/plugins/kanban';
|
|
121
|
+
fs_1.default.mkdirSync(pluginDir, { recursive: true });
|
|
122
|
+
fs_1.default.mkdirSync(path_1.default.join(pluginDir, 'hooks'), { recursive: true });
|
|
123
|
+
// Create plugin.json
|
|
124
|
+
const pluginJson = {
|
|
125
|
+
name: 'kanban',
|
|
126
|
+
description: 'Persistent Kanban system for Claude Code tasks',
|
|
127
|
+
author: {
|
|
128
|
+
name: 'Findependence',
|
|
129
|
+
email: 'support@findependence.com'
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
fs_1.default.writeFileSync(path_1.default.join(pluginDir, 'plugin.json'), JSON.stringify(pluginJson, null, 2));
|
|
133
|
+
// Create hooks.json
|
|
134
|
+
const hooksJson = {
|
|
135
|
+
description: 'Kanban task sync hooks',
|
|
136
|
+
hooks: {
|
|
137
|
+
PreToolUse: [
|
|
138
|
+
{
|
|
139
|
+
toolName: 'TaskCreate',
|
|
140
|
+
hooks: [
|
|
141
|
+
{
|
|
142
|
+
type: 'command',
|
|
143
|
+
command: 'node ${CLAUDE_CWD}/.kanhelper/dist/hooks/pre-tool.js'
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
],
|
|
148
|
+
PostToolUse: [
|
|
149
|
+
{
|
|
150
|
+
toolName: 'TaskUpdate',
|
|
151
|
+
hooks: [
|
|
152
|
+
{
|
|
153
|
+
type: 'command',
|
|
154
|
+
command: 'node ${CLAUDE_CWD}/.kanhelper/dist/hooks/post-tool.js'
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
fs_1.default.writeFileSync(path_1.default.join(pluginDir, 'hooks', 'hooks.json'), JSON.stringify(hooksJson, null, 2));
|
|
162
|
+
console.log(' ✅ Plugin installed');
|
|
163
|
+
}
|
|
164
|
+
async function installSkills() {
|
|
165
|
+
console.log('⚡ Installing skills...');
|
|
166
|
+
// Create kanboard skill
|
|
167
|
+
const kanboardDir = '.claude/skills/kanboard';
|
|
168
|
+
fs_1.default.mkdirSync(kanboardDir, { recursive: true });
|
|
169
|
+
const kanboardSkill = `---
|
|
170
|
+
name: kanboard
|
|
171
|
+
description: Display text-based Kanban board in console
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
# Kanboard Skill
|
|
175
|
+
|
|
176
|
+
Displays all tasks organized by status in a text-based Kanban board.
|
|
177
|
+
|
|
178
|
+
When invoked, this skill executes:
|
|
179
|
+
\`node .kanhelper/dist/skills/kanboard.js\`
|
|
180
|
+
|
|
181
|
+
## Usage
|
|
182
|
+
|
|
183
|
+
Simply type \`/kanboard\` in Claude Code to view your current Kanban board.
|
|
184
|
+
|
|
185
|
+
## Board Structure
|
|
186
|
+
|
|
187
|
+
- **TODO**: Pending tasks
|
|
188
|
+
- **IN PROGRESS**: Active work
|
|
189
|
+
- **DONE**: Completed tasks
|
|
190
|
+
- **PARKING LOT**: Deferred/blocked tasks
|
|
191
|
+
|
|
192
|
+
Each card shows:
|
|
193
|
+
- Task title
|
|
194
|
+
- Session ID (first 8 characters)
|
|
195
|
+
`;
|
|
196
|
+
fs_1.default.writeFileSync(path_1.default.join(kanboardDir, 'SKILL.md'), kanboardSkill);
|
|
197
|
+
// Create kansync skill
|
|
198
|
+
const kansyncDir = '.claude/skills/kansync';
|
|
199
|
+
fs_1.default.mkdirSync(kansyncDir, { recursive: true });
|
|
200
|
+
const kansyncSkill = `---
|
|
201
|
+
name: kansync
|
|
202
|
+
description: Manually sync task state with Kanban board
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
# Kansync Skill
|
|
206
|
+
|
|
207
|
+
Manually synchronizes the current task state with the Kanban board.
|
|
208
|
+
|
|
209
|
+
When invoked, this skill executes:
|
|
210
|
+
\`node .kanhelper/dist/skills/kansync.js\`
|
|
211
|
+
|
|
212
|
+
## Usage
|
|
213
|
+
|
|
214
|
+
Type \`/kansync\` in Claude Code to manually sync tasks.
|
|
215
|
+
|
|
216
|
+
## What It Does
|
|
217
|
+
|
|
218
|
+
- Scans all Kanban folders
|
|
219
|
+
- Verifies card consistency
|
|
220
|
+
- Reports sync status
|
|
221
|
+
`;
|
|
222
|
+
fs_1.default.writeFileSync(path_1.default.join(kansyncDir, 'SKILL.md'), kansyncSkill);
|
|
223
|
+
// Create kanhelp skill
|
|
224
|
+
const kanhelpDir = '.claude/skills/kanhelp';
|
|
225
|
+
fs_1.default.mkdirSync(kanhelpDir, { recursive: true });
|
|
226
|
+
const kanhelpSkill = `---
|
|
227
|
+
name: kanhelp
|
|
228
|
+
description: Display all available Kanban commands and features
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
# Kanhelp Skill
|
|
232
|
+
|
|
233
|
+
Shows comprehensive help for the Claude Kanban system.
|
|
234
|
+
|
|
235
|
+
When invoked, this skill executes:
|
|
236
|
+
\`node .kanhelper/dist/skills/kanhelp.js\`
|
|
237
|
+
|
|
238
|
+
## Usage
|
|
239
|
+
|
|
240
|
+
Type \`/kanhelp\` in Claude Code to view the complete help guide.
|
|
241
|
+
|
|
242
|
+
## What It Shows
|
|
243
|
+
|
|
244
|
+
- Available skills and commands
|
|
245
|
+
- Native tools integration (TaskCreate, TaskUpdate)
|
|
246
|
+
- Status mapping between task statuses and folders
|
|
247
|
+
- Directory structure
|
|
248
|
+
- Card format examples
|
|
249
|
+
- Session recovery guide
|
|
250
|
+
- CLI commands
|
|
251
|
+
- Tips and best practices
|
|
252
|
+
- Resource links
|
|
253
|
+
`;
|
|
254
|
+
fs_1.default.writeFileSync(path_1.default.join(kanhelpDir, 'SKILL.md'), kanhelpSkill);
|
|
255
|
+
// Create kandoctor skill
|
|
256
|
+
const kandoctorDir = '.claude/skills/kandoctor';
|
|
257
|
+
fs_1.default.mkdirSync(kandoctorDir, { recursive: true });
|
|
258
|
+
const kandoctorSkill = `---
|
|
259
|
+
name: kandoctor
|
|
260
|
+
description: Validate Kanban system installation and health
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
# Kandoctor Skill
|
|
264
|
+
|
|
265
|
+
Runs comprehensive diagnostics on the Kanban system installation.
|
|
266
|
+
|
|
267
|
+
When invoked, this skill executes:
|
|
268
|
+
\`node .kanhelper/dist/skills/kandoctor.js\`
|
|
269
|
+
|
|
270
|
+
## Usage
|
|
271
|
+
|
|
272
|
+
Type \`/kandoctor\` in Claude Code to run system diagnostics.
|
|
273
|
+
|
|
274
|
+
## What It Checks
|
|
275
|
+
|
|
276
|
+
- **Directory Structure**: All Kanban folders and index files
|
|
277
|
+
- **Kanban Helper**: Compiled code and dependencies
|
|
278
|
+
- **Plugin Installation**: Plugin config and hooks
|
|
279
|
+
- **Skills Installation**: All skill definitions
|
|
280
|
+
- **Configuration**: todo.md frontmatter, .gitignore settings
|
|
281
|
+
- **Session & Cards**: Current session and card counts
|
|
282
|
+
|
|
283
|
+
## Output
|
|
284
|
+
|
|
285
|
+
- ✅ Passed checks
|
|
286
|
+
- ⚠️ Warnings (non-critical issues)
|
|
287
|
+
- ❌ Failed checks (critical issues)
|
|
288
|
+
- Overall health percentage
|
|
289
|
+
- Recommendations for fixes
|
|
290
|
+
`;
|
|
291
|
+
fs_1.default.writeFileSync(path_1.default.join(kandoctorDir, 'SKILL.md'), kandoctorSkill);
|
|
292
|
+
console.log(' ✅ Skills installed (kanboard, kansync, kanhelp, kandoctor)');
|
|
293
|
+
}
|
|
294
|
+
// Run the CLI
|
|
295
|
+
main().catch(error => {
|
|
296
|
+
console.error('Error:', error.message);
|
|
297
|
+
process.exit(1);
|
|
298
|
+
});
|
|
299
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AACA;;GAEG;;;;;AAEH,4CAAoB;AACpB,gDAAwB;AACxB,8CAAkE;AAGlE,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;IAElC,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM;YACT,MAAM,WAAW,EAAE,CAAC;YACpB,MAAM;QACR,KAAK,OAAO;YACV,MAAM,YAAY,EAAE,CAAC;YACrB,MAAM;QACR,KAAK,MAAM,CAAC;QACZ;YACE,QAAQ,EAAE,CAAC;YACX,MAAM;IACV,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW;IACxB,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IAEzD,uCAAuC;IACvC,MAAM,QAAQ,GAAG,IAAA,yBAAc,GAAE,CAAC;IAElC,sBAAsB;IACtB,MAAM,SAAS,GAAG,IAAA,0BAAe,EAAC,QAAQ,CAAC,CAAC;IAE5C,qBAAqB;IACrB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,2BAA2B,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,uBAAuB,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,0BAA0B,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,qBAAqB,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAErE,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;QACnD,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;YAC3B,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;YACzD,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;YAC7D,OAAO,CAAC,GAAG,CAAC,mBAAmB,QAAQ,CAAC,UAAU,IAAI,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,6DAA6D;QAC7D,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IACnD,CAAC;IAED,6BAA6B;IAC7B,MAAM,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAEtC,oBAAoB;IACpB,MAAM,aAAa,EAAE,CAAC;IAEtB,oBAAoB;IACpB,MAAM,aAAa,EAAE,CAAC;IAEtB,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC3B,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;AAC/D,CAAC;AAED,KAAK,UAAU,YAAY;IACzB,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAE3D,MAAM,QAAQ,GAAG,IAAA,yBAAc,GAAE,CAAC;IAElC,yBAAyB;IACzB,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjC,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,YAAE,CAAC,UAAU,CAAC,cAAc,MAAM,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,kBAAkB,MAAM,MAAM,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,eAAe;IACf,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACzB,OAAO,CAAC,GAAG,CAAC,gCAAgC,YAAE,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAEnG,eAAe;IACf,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACzB,OAAO,CAAC,GAAG,CAAC,iCAAiC,YAAE,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACrG,OAAO,CAAC,GAAG,CAAC,gCAAgC,YAAE,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACnG,OAAO,CAAC,GAAG,CAAC,gCAAgC,YAAE,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACnG,OAAO,CAAC,GAAG,CAAC,kCAAkC,YAAE,CAAC,UAAU,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAEvG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC;AAED,SAAS,QAAQ;IACf,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;CAWb,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,QAAyB;IAC5D,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IAEzD,wBAAwB;IACxB,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IAC9D,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,cAAc,MAAM,EAAE,CAAC;QACvC,YAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3C,uBAAuB;QACvB,YAAE,CAAC,aAAa,CAAC,cAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,oCAAoC;IACpC,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,YAAE,CAAC,YAAY,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC;QAC/D,IAAI,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACzB,YAAE,CAAC,YAAY,CAAC,oBAAoB,EAAE,2BAA2B,CAAC,CAAC;YACnE,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC;AACjF,CAAC;AAED,KAAK,UAAU,aAAa;IAC1B,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAE9C,MAAM,SAAS,GAAG,wBAAwB,CAAC;IAC3C,YAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,YAAE,CAAC,SAAS,CAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEjE,qBAAqB;IACrB,MAAM,UAAU,GAAG;QACjB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,gDAAgD;QAC7D,MAAM,EAAE;YACN,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,2BAA2B;SACnC;KACF,CAAC;IAEF,YAAE,CAAC,aAAa,CACd,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,EACnC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CACpC,CAAC;IAEF,oBAAoB;IACpB,MAAM,SAAS,GAAG;QAChB,WAAW,EAAE,wBAAwB;QACrC,KAAK,EAAE;YACL,UAAU,EAAE;gBACV;oBACE,QAAQ,EAAE,YAAY;oBACtB,KAAK,EAAE;wBACL;4BACE,IAAI,EAAE,SAAS;4BACf,OAAO,EAAE,sDAAsD;yBAChE;qBACF;iBACF;aACF;YACD,WAAW,EAAE;gBACX;oBACE,QAAQ,EAAE,YAAY;oBACtB,KAAK,EAAE;wBACL;4BACE,IAAI,EAAE,SAAS;4BACf,OAAO,EAAE,uDAAuD;yBACjE;qBACF;iBACF;aACF;SACF;KACF,CAAC;IAEF,YAAE,CAAC,aAAa,CACd,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC,EAC3C,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CACnC,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AACtC,CAAC;AAED,KAAK,UAAU,aAAa;IAC1B,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAEtC,wBAAwB;IACxB,MAAM,WAAW,GAAG,yBAAyB,CAAC;IAC9C,YAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC;IAE9C,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BvB,CAAC;IAEA,YAAE,CAAC,aAAa,CAAC,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,aAAa,CAAC,CAAC;IAEpE,uBAAuB;IACvB,MAAM,UAAU,GAAG,wBAAwB,CAAC;IAC5C,YAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE9C,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBtB,CAAC;IAEA,YAAE,CAAC,aAAa,CAAC,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,YAAY,CAAC,CAAC;IAElE,uBAAuB;IACvB,MAAM,UAAU,GAAG,wBAAwB,CAAC;IAC5C,YAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE9C,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BtB,CAAC;IAEA,YAAE,CAAC,aAAa,CAAC,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,YAAY,CAAC,CAAC;IAElE,yBAAyB;IACzB,MAAM,YAAY,GAAG,0BAA0B,CAAC;IAChD,YAAE,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhD,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCxB,CAAC;IAEA,YAAE,CAAC,aAAa,CAAC,cAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,EAAE,cAAc,CAAC,CAAC;IAEtE,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;AAC9E,CAAC;AAED,cAAc;AACd,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task card CRUD operations
|
|
3
|
+
*/
|
|
4
|
+
import { TaskCard, KanbanStatus } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Create a new task card in the Kanban structure
|
|
7
|
+
*/
|
|
8
|
+
export declare function createCard(subject: string, description: string, status?: KanbanStatus, taskId?: string, cardName?: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Move a card to a different status column
|
|
11
|
+
*/
|
|
12
|
+
export declare function moveCard(cardPath: string, newStatus: KanbanStatus): string;
|
|
13
|
+
/**
|
|
14
|
+
* Find a card by searching for it across all statuses
|
|
15
|
+
* This is used to locate a card when we only have limited info
|
|
16
|
+
*/
|
|
17
|
+
export declare function findCardByTaskId(taskId: string): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* Read a card and parse its frontmatter
|
|
20
|
+
*/
|
|
21
|
+
export declare function readCard(cardPath: string): TaskCard | null;
|
|
22
|
+
/**
|
|
23
|
+
* Get all cards for a specific status
|
|
24
|
+
*/
|
|
25
|
+
export declare function getCardsByStatus(status: KanbanStatus): Array<{
|
|
26
|
+
path: string;
|
|
27
|
+
card: TaskCard;
|
|
28
|
+
}>;
|
|
29
|
+
//# sourceMappingURL=card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../src/core/card.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAejD;;GAEG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,MAAM,GAAE,YAAwB,EAChC,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CA0DR;AAED;;GAEG;AACH,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,YAAY,GACtB,MAAM,CAoCR;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgC9D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAa1D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAwB9F"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Task card CRUD operations
|
|
4
|
+
*/
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.createCard = createCard;
|
|
10
|
+
exports.moveCard = moveCard;
|
|
11
|
+
exports.findCardByTaskId = findCardByTaskId;
|
|
12
|
+
exports.readCard = readCard;
|
|
13
|
+
exports.getCardsByStatus = getCardsByStatus;
|
|
14
|
+
const fs_1 = __importDefault(require("fs"));
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
16
|
+
const yaml_1 = __importDefault(require("yaml"));
|
|
17
|
+
const session_1 = require("./session");
|
|
18
|
+
/**
|
|
19
|
+
* Sanitize a card name for use as a filename
|
|
20
|
+
*/
|
|
21
|
+
function sanitizeCardName(name) {
|
|
22
|
+
return name
|
|
23
|
+
.toLowerCase()
|
|
24
|
+
.replace(/\s+/g, '-') // Replace spaces with hyphens
|
|
25
|
+
.replace(/[^a-z0-9-_]/g, '') // Remove special characters
|
|
26
|
+
.replace(/-+/g, '-') // Collapse multiple hyphens
|
|
27
|
+
.replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create a new task card in the Kanban structure
|
|
31
|
+
*/
|
|
32
|
+
function createCard(subject, description, status = 'pending', taskId, cardName) {
|
|
33
|
+
const sessionId = (0, session_1.getSessionId)();
|
|
34
|
+
const timestamp = Date.now();
|
|
35
|
+
// Use provided name or default to ITEM_{epoch_time}
|
|
36
|
+
let fileName;
|
|
37
|
+
if (cardName) {
|
|
38
|
+
const sanitized = sanitizeCardName(cardName);
|
|
39
|
+
fileName = sanitized ? `${sanitized}.md` : `ITEM_${timestamp}.md`;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
fileName = `ITEM_${timestamp}.md`;
|
|
43
|
+
}
|
|
44
|
+
const dirPath = path_1.default.join('docs/tasks', status, sessionId);
|
|
45
|
+
const filePath = path_1.default.join(dirPath, fileName);
|
|
46
|
+
const card = {
|
|
47
|
+
session: sessionId,
|
|
48
|
+
status,
|
|
49
|
+
created: new Date().toISOString(),
|
|
50
|
+
updated: new Date().toISOString(),
|
|
51
|
+
subject,
|
|
52
|
+
description,
|
|
53
|
+
steps: []
|
|
54
|
+
};
|
|
55
|
+
if (taskId) {
|
|
56
|
+
card.taskId = taskId;
|
|
57
|
+
}
|
|
58
|
+
const frontmatter = `---
|
|
59
|
+
session: ${card.session}
|
|
60
|
+
status: ${card.status}
|
|
61
|
+
created: ${card.created}
|
|
62
|
+
updated: ${card.updated}
|
|
63
|
+
${taskId ? `taskId: "${taskId}"\n` : ''}subject: ${card.subject}
|
|
64
|
+
description: ${card.description}
|
|
65
|
+
steps: []
|
|
66
|
+
---`;
|
|
67
|
+
const content = `${frontmatter}
|
|
68
|
+
|
|
69
|
+
# ${card.subject}
|
|
70
|
+
|
|
71
|
+
${card.description}
|
|
72
|
+
|
|
73
|
+
## Steps
|
|
74
|
+
- [ ] TODO: Add implementation steps
|
|
75
|
+
|
|
76
|
+
## Notes
|
|
77
|
+
- Session: ${sessionId}
|
|
78
|
+
${taskId ? `- Task ID: ${taskId}\n` : ''}- Created: ${new Date(card.created).toLocaleString()}
|
|
79
|
+
`;
|
|
80
|
+
fs_1.default.mkdirSync(dirPath, { recursive: true });
|
|
81
|
+
fs_1.default.writeFileSync(filePath, content);
|
|
82
|
+
return filePath;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Move a card to a different status column
|
|
86
|
+
*/
|
|
87
|
+
function moveCard(cardPath, newStatus) {
|
|
88
|
+
if (!fs_1.default.existsSync(cardPath)) {
|
|
89
|
+
throw new Error(`Card not found: ${cardPath}`);
|
|
90
|
+
}
|
|
91
|
+
const content = fs_1.default.readFileSync(cardPath, 'utf-8');
|
|
92
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
93
|
+
if (!frontmatterMatch) {
|
|
94
|
+
throw new Error(`Invalid card format (no frontmatter): ${cardPath}`);
|
|
95
|
+
}
|
|
96
|
+
const frontmatter = yaml_1.default.parse(frontmatterMatch[1]);
|
|
97
|
+
frontmatter.status = newStatus;
|
|
98
|
+
frontmatter.updated = new Date().toISOString();
|
|
99
|
+
const sessionId = frontmatter.session || 'unknown';
|
|
100
|
+
const fileName = path_1.default.basename(cardPath);
|
|
101
|
+
const newPath = path_1.default.join('docs/tasks', newStatus, sessionId, fileName);
|
|
102
|
+
// Update frontmatter
|
|
103
|
+
const newFrontmatter = `---\n${yaml_1.default.stringify(frontmatter)}---\n`;
|
|
104
|
+
const bodyMatch = content.match(/---\n[\s\S]*?\n---\n([\s\S]*)/);
|
|
105
|
+
const body = bodyMatch ? bodyMatch[1] : '';
|
|
106
|
+
const newContent = newFrontmatter + body;
|
|
107
|
+
// Move file (create dir if needed)
|
|
108
|
+
fs_1.default.mkdirSync(path_1.default.dirname(newPath), { recursive: true });
|
|
109
|
+
fs_1.default.writeFileSync(newPath, newContent);
|
|
110
|
+
// Delete old file (only if new path is different)
|
|
111
|
+
if (cardPath !== newPath) {
|
|
112
|
+
fs_1.default.unlinkSync(cardPath);
|
|
113
|
+
}
|
|
114
|
+
return newPath;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Find a card by searching for it across all statuses
|
|
118
|
+
* This is used to locate a card when we only have limited info
|
|
119
|
+
*/
|
|
120
|
+
function findCardByTaskId(taskId) {
|
|
121
|
+
const statuses = ['pending', 'in_progress', 'completed', 'parkinglot', 'deleted'];
|
|
122
|
+
for (const status of statuses) {
|
|
123
|
+
const statusDir = path_1.default.join('docs/tasks', status);
|
|
124
|
+
if (!fs_1.default.existsSync(statusDir))
|
|
125
|
+
continue;
|
|
126
|
+
const sessions = fs_1.default.readdirSync(statusDir);
|
|
127
|
+
for (const session of sessions) {
|
|
128
|
+
const sessionPath = path_1.default.join(statusDir, session);
|
|
129
|
+
if (!fs_1.default.statSync(sessionPath).isDirectory())
|
|
130
|
+
continue;
|
|
131
|
+
const cards = fs_1.default.readdirSync(sessionPath).filter(f => f.endsWith('.md'));
|
|
132
|
+
for (const card of cards) {
|
|
133
|
+
const cardPath = path_1.default.join(sessionPath, card);
|
|
134
|
+
// Check frontmatter first (reliable)
|
|
135
|
+
const cardData = readCard(cardPath);
|
|
136
|
+
if (cardData?.taskId === taskId) {
|
|
137
|
+
return cardPath;
|
|
138
|
+
}
|
|
139
|
+
// Fallback: Check content (backward compatibility)
|
|
140
|
+
const content = fs_1.default.readFileSync(cardPath, 'utf-8');
|
|
141
|
+
if (content.includes(taskId)) {
|
|
142
|
+
return cardPath;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Read a card and parse its frontmatter
|
|
151
|
+
*/
|
|
152
|
+
function readCard(cardPath) {
|
|
153
|
+
if (!fs_1.default.existsSync(cardPath)) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
const content = fs_1.default.readFileSync(cardPath, 'utf-8');
|
|
157
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
158
|
+
if (!frontmatterMatch) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
return yaml_1.default.parse(frontmatterMatch[1]);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get all cards for a specific status
|
|
165
|
+
*/
|
|
166
|
+
function getCardsByStatus(status) {
|
|
167
|
+
const statusDir = path_1.default.join('docs/tasks', status);
|
|
168
|
+
if (!fs_1.default.existsSync(statusDir)) {
|
|
169
|
+
return [];
|
|
170
|
+
}
|
|
171
|
+
const results = [];
|
|
172
|
+
const sessions = fs_1.default.readdirSync(statusDir);
|
|
173
|
+
for (const session of sessions) {
|
|
174
|
+
const sessionPath = path_1.default.join(statusDir, session);
|
|
175
|
+
if (!fs_1.default.statSync(sessionPath).isDirectory())
|
|
176
|
+
continue;
|
|
177
|
+
const cards = fs_1.default.readdirSync(sessionPath).filter(f => f.endsWith('.md'));
|
|
178
|
+
for (const cardFile of cards) {
|
|
179
|
+
const cardPath = path_1.default.join(sessionPath, cardFile);
|
|
180
|
+
const card = readCard(cardPath);
|
|
181
|
+
if (card) {
|
|
182
|
+
results.push({ path: cardPath, card });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return results;
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.js","sourceRoot":"","sources":["../../src/core/card.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conflict detection for installation
|
|
3
|
+
*/
|
|
4
|
+
import { ProjectAnalysis, Conflict } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Analyze the current project structure
|
|
7
|
+
*/
|
|
8
|
+
export declare function analyzeProject(): ProjectAnalysis;
|
|
9
|
+
/**
|
|
10
|
+
* Detect potential conflicts before installation
|
|
11
|
+
*/
|
|
12
|
+
export declare function detectConflicts(analysis: ProjectAnalysis): Conflict[];
|
|
13
|
+
//# sourceMappingURL=conflict.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conflict.d.ts","sourceRoot":"","sources":["../../src/core/conflict.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEpD;;GAEG;AACH,wBAAgB,cAAc,IAAI,eAAe,CAShD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,GAAG,QAAQ,EAAE,CA4DrE"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Conflict detection for installation
|
|
4
|
+
*/
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.analyzeProject = analyzeProject;
|
|
10
|
+
exports.detectConflicts = detectConflicts;
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
/**
|
|
13
|
+
* Analyze the current project structure
|
|
14
|
+
*/
|
|
15
|
+
function analyzeProject() {
|
|
16
|
+
return {
|
|
17
|
+
hasTasksDir: fs_1.default.existsSync('docs/tasks'),
|
|
18
|
+
hasTodoMd: fs_1.default.existsSync('docs/tasks/todo.md'),
|
|
19
|
+
hasLessonsMd: fs_1.default.existsSync('docs/tasks/lessons.md'),
|
|
20
|
+
isGitRepo: fs_1.default.existsSync('.git'),
|
|
21
|
+
hasClaudeDir: fs_1.default.existsSync('.claude'),
|
|
22
|
+
projectRoot: process.cwd()
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Detect potential conflicts before installation
|
|
27
|
+
*/
|
|
28
|
+
function detectConflicts(analysis) {
|
|
29
|
+
const conflicts = [];
|
|
30
|
+
// Check if todo.md exists and has content
|
|
31
|
+
if (analysis.hasTodoMd) {
|
|
32
|
+
const content = fs_1.default.readFileSync('docs/tasks/todo.md', 'utf-8');
|
|
33
|
+
if (content.length > 100) {
|
|
34
|
+
conflicts.push({
|
|
35
|
+
file: 'docs/tasks/todo.md',
|
|
36
|
+
message: 'Existing todo.md has content',
|
|
37
|
+
resolution: 'Will backup to todo.md.backup before modifying',
|
|
38
|
+
severity: 'warning'
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Check if Kanban folders already exist
|
|
43
|
+
const kanbanFolders = ['todo', 'inprogress', 'done', 'parkinglot'];
|
|
44
|
+
for (const folder of kanbanFolders) {
|
|
45
|
+
if (fs_1.default.existsSync(`docs/tasks/${folder}`)) {
|
|
46
|
+
conflicts.push({
|
|
47
|
+
file: `docs/tasks/${folder}`,
|
|
48
|
+
message: 'Folder already exists',
|
|
49
|
+
resolution: 'Will merge existing files into Kanban structure',
|
|
50
|
+
severity: 'warning'
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Check if .claude directory exists
|
|
55
|
+
if (!analysis.hasClaudeDir) {
|
|
56
|
+
conflicts.push({
|
|
57
|
+
file: '.claude/',
|
|
58
|
+
message: '.claude directory does not exist',
|
|
59
|
+
resolution: 'Will create .claude/plugins/kanban/ and .claude/skills/',
|
|
60
|
+
severity: 'error'
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// Check if kanban plugin already exists
|
|
65
|
+
if (fs_1.default.existsSync('.claude/plugins/kanban')) {
|
|
66
|
+
conflicts.push({
|
|
67
|
+
file: '.claude/plugins/kanban',
|
|
68
|
+
message: 'Kanban plugin already installed',
|
|
69
|
+
resolution: 'Will overwrite with new version',
|
|
70
|
+
severity: 'warning'
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Check if .kanhelper already exists
|
|
75
|
+
if (fs_1.default.existsSync('.kanhelper')) {
|
|
76
|
+
conflicts.push({
|
|
77
|
+
file: '.kanhelper/',
|
|
78
|
+
message: '.kanhelper directory already exists',
|
|
79
|
+
resolution: 'Will update scripts to latest version',
|
|
80
|
+
severity: 'warning'
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return conflicts;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=conflict.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conflict.js","sourceRoot":"","sources":["../../src/core/conflict.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;AAQH,wCASC;AAKD,0CA4DC;AAhFD,4CAAoB;AAGpB;;GAEG;AACH,SAAgB,cAAc;IAC5B,OAAO;QACL,WAAW,EAAE,YAAE,CAAC,UAAU,CAAC,YAAY,CAAC;QACxC,SAAS,EAAE,YAAE,CAAC,UAAU,CAAC,oBAAoB,CAAC;QAC9C,YAAY,EAAE,YAAE,CAAC,UAAU,CAAC,uBAAuB,CAAC;QACpD,SAAS,EAAE,YAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAChC,YAAY,EAAE,YAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QACtC,WAAW,EAAE,OAAO,CAAC,GAAG,EAAE;KAC3B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,QAAyB;IACvD,MAAM,SAAS,GAAe,EAAE,CAAC;IAEjC,0CAA0C;IAC1C,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,YAAE,CAAC,YAAY,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC;QAC/D,IAAI,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACzB,SAAS,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,oBAAoB;gBAC1B,OAAO,EAAE,8BAA8B;gBACvC,UAAU,EAAE,gDAAgD;gBAC5D,QAAQ,EAAE,SAAS;aACpB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IACnE,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,IAAI,YAAE,CAAC,UAAU,CAAC,cAAc,MAAM,EAAE,CAAC,EAAE,CAAC;YAC1C,SAAS,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,cAAc,MAAM,EAAE;gBAC5B,OAAO,EAAE,uBAAuB;gBAChC,UAAU,EAAE,iDAAiD;gBAC7D,QAAQ,EAAE,SAAS;aACpB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;QAC3B,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,kCAAkC;YAC3C,UAAU,EAAE,yDAAyD;YACrE,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,wCAAwC;QACxC,IAAI,YAAE,CAAC,UAAU,CAAC,wBAAwB,CAAC,EAAE,CAAC;YAC5C,SAAS,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,wBAAwB;gBAC9B,OAAO,EAAE,iCAAiC;gBAC1C,UAAU,EAAE,iCAAiC;gBAC7C,QAAQ,EAAE,SAAS;aACpB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,IAAI,YAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,qCAAqC;YAC9C,UAAU,EAAE,uCAAuC;YACnD,QAAQ,EAAE,SAAS;SACpB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|