aidflow 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 +147 -0
- package/dist/context/session.d.ts +35 -0
- package/dist/context/session.d.ts.map +1 -0
- package/dist/context/session.js +120 -0
- package/dist/context/session.js.map +1 -0
- package/dist/context/workspace.d.ts +21 -0
- package/dist/context/workspace.d.ts.map +1 -0
- package/dist/context/workspace.js +79 -0
- package/dist/context/workspace.js.map +1 -0
- package/dist/context/yaml.d.ts +8 -0
- package/dist/context/yaml.d.ts.map +1 -0
- package/dist/context/yaml.js +73 -0
- package/dist/context/yaml.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +105 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/guide/description.d.ts +2 -0
- package/dist/tools/guide/description.d.ts.map +1 -0
- package/dist/tools/guide/description.js +7 -0
- package/dist/tools/guide/description.js.map +1 -0
- package/dist/tools/guide/handler.d.ts +3 -0
- package/dist/tools/guide/handler.d.ts.map +1 -0
- package/dist/tools/guide/handler.js +68 -0
- package/dist/tools/guide/handler.js.map +1 -0
- package/dist/tools/guide/index.d.ts +4 -0
- package/dist/tools/guide/index.d.ts.map +1 -0
- package/dist/tools/guide/index.js +4 -0
- package/dist/tools/guide/index.js.map +1 -0
- package/dist/tools/guide/schema.d.ts +13 -0
- package/dist/tools/guide/schema.d.ts.map +1 -0
- package/dist/tools/guide/schema.js +12 -0
- package/dist/tools/guide/schema.js.map +1 -0
- package/dist/tools/init/description.d.ts +2 -0
- package/dist/tools/init/description.d.ts.map +1 -0
- package/dist/tools/init/description.js +6 -0
- package/dist/tools/init/description.js.map +1 -0
- package/dist/tools/init/handler.d.ts +3 -0
- package/dist/tools/init/handler.d.ts.map +1 -0
- package/dist/tools/init/handler.js +114 -0
- package/dist/tools/init/handler.js.map +1 -0
- package/dist/tools/init/index.d.ts +4 -0
- package/dist/tools/init/index.d.ts.map +1 -0
- package/dist/tools/init/index.js +4 -0
- package/dist/tools/init/index.js.map +1 -0
- package/dist/tools/init/schema.d.ts +10 -0
- package/dist/tools/init/schema.d.ts.map +1 -0
- package/dist/tools/init/schema.js +9 -0
- package/dist/tools/init/schema.js.map +1 -0
- package/dist/tools/plan/description.d.ts +2 -0
- package/dist/tools/plan/description.d.ts.map +1 -0
- package/dist/tools/plan/description.js +7 -0
- package/dist/tools/plan/description.js.map +1 -0
- package/dist/tools/plan/handler.d.ts +3 -0
- package/dist/tools/plan/handler.d.ts.map +1 -0
- package/dist/tools/plan/handler.js +65 -0
- package/dist/tools/plan/handler.js.map +1 -0
- package/dist/tools/plan/index.d.ts +4 -0
- package/dist/tools/plan/index.d.ts.map +1 -0
- package/dist/tools/plan/index.js +4 -0
- package/dist/tools/plan/index.js.map +1 -0
- package/dist/tools/plan/schema.d.ts +13 -0
- package/dist/tools/plan/schema.d.ts.map +1 -0
- package/dist/tools/plan/schema.js +12 -0
- package/dist/tools/plan/schema.js.map +1 -0
- package/dist/tools/session/description.d.ts +2 -0
- package/dist/tools/session/description.d.ts.map +1 -0
- package/dist/tools/session/description.js +9 -0
- package/dist/tools/session/description.js.map +1 -0
- package/dist/tools/session/handler.d.ts +3 -0
- package/dist/tools/session/handler.d.ts.map +1 -0
- package/dist/tools/session/handler.js +185 -0
- package/dist/tools/session/handler.js.map +1 -0
- package/dist/tools/session/index.d.ts +4 -0
- package/dist/tools/session/index.d.ts.map +1 -0
- package/dist/tools/session/index.js +4 -0
- package/dist/tools/session/index.js.map +1 -0
- package/dist/tools/session/schema.d.ts +19 -0
- package/dist/tools/session/schema.d.ts.map +1 -0
- package/dist/tools/session/schema.js +20 -0
- package/dist/tools/session/schema.js.map +1 -0
- package/dist/worktree/manager.d.ts +9 -0
- package/dist/worktree/manager.d.ts.map +1 -0
- package/dist/worktree/manager.js +92 -0
- package/dist/worktree/manager.js.map +1 -0
- package/package.json +49 -0
- package/templates/README.md +146 -0
- package/templates/config.yaml +20 -0
- package/templates/guides/getting-started.md +21 -0
- package/templates/skills/report.md +52 -0
- package/templates/skills/review.md +69 -0
- package/templates/skills/spec.md +120 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ghyeong
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# aidflow
|
|
2
|
+
|
|
3
|
+
Session-based development workflow MCP server for Claude Code.
|
|
4
|
+
|
|
5
|
+
Every development task gets its own session with a plan, progress tracking, and archiving. Claude Code automatically resumes where you left off, even in new conversations.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g aidflow
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Add to your Claude Code MCP configuration (`~/.claude/settings.json` or project `.mcp.json`):
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"mcpServers": {
|
|
18
|
+
"aidflow": {
|
|
19
|
+
"command": "aidflow",
|
|
20
|
+
"env": {
|
|
21
|
+
"DEVPILOT_ROOT": "/path/to/your/project"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or run with npx (no install):
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"mcpServers": {
|
|
33
|
+
"aidflow": {
|
|
34
|
+
"command": "npx",
|
|
35
|
+
"args": ["-y", "aidflow"],
|
|
36
|
+
"env": {
|
|
37
|
+
"DEVPILOT_ROOT": "/path/to/your/project"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
> `DEVPILOT_ROOT` defaults to `process.cwd()` if not set.
|
|
45
|
+
|
|
46
|
+
## What It Does
|
|
47
|
+
|
|
48
|
+
aidflow structures your Claude Code workflow into **sessions** - isolated units of work with plans, progress tracking, and completion reports.
|
|
49
|
+
|
|
50
|
+
### Development Cycle
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
init -> /spec -> session create -> plan create -> work -> /review -> session complete -> /report
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
1. **`init`** - Set up `.devpilot/` directory and configuration
|
|
57
|
+
2. **`/spec`** - Define project engineering foundations (SPEC.md)
|
|
58
|
+
3. **`session create`** - Start a new work session
|
|
59
|
+
4. **`plan create`** - Structured planning with multi-round requirements gathering
|
|
60
|
+
5. **Work** - Implement using Claude Code's native tools, following the plan
|
|
61
|
+
6. **`/review`** - Quality gate before completing
|
|
62
|
+
7. **`session complete`** - Archive the session to history
|
|
63
|
+
8. **`/report`** - Generate a completion report
|
|
64
|
+
|
|
65
|
+
### Context Recovery
|
|
66
|
+
|
|
67
|
+
When you start a new conversation, aidflow automatically detects active sessions and resumes where you left off - reading the plan, checking progress, and continuing work without losing context.
|
|
68
|
+
|
|
69
|
+
### Git Worktree Support
|
|
70
|
+
|
|
71
|
+
Each session can optionally create a git worktree, giving you an isolated branch for the work. Useful for parallel tasks.
|
|
72
|
+
|
|
73
|
+
## Tools
|
|
74
|
+
|
|
75
|
+
| Tool | Actions | Description |
|
|
76
|
+
|------|---------|-------------|
|
|
77
|
+
| `init` | - | Initialize aidflow in a project |
|
|
78
|
+
| `session` | create, list, status, complete | Manage development sessions |
|
|
79
|
+
| `plan` | create, get | Create and track work plans |
|
|
80
|
+
| `guide` | list, read | Access project-specific guide documents |
|
|
81
|
+
|
|
82
|
+
## Skills
|
|
83
|
+
|
|
84
|
+
Installed to `.claude/commands/` during init:
|
|
85
|
+
|
|
86
|
+
| Skill | Description |
|
|
87
|
+
|-------|-------------|
|
|
88
|
+
| `/spec` | Create or update SPEC.md (project conventions) |
|
|
89
|
+
| `/review` | Quality review before session complete |
|
|
90
|
+
| `/report` | Generate completion report after archiving |
|
|
91
|
+
|
|
92
|
+
## Project Structure
|
|
93
|
+
|
|
94
|
+
After `init`, your project gets:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
your-project/
|
|
98
|
+
SPEC.md # Project engineering foundations (via /spec)
|
|
99
|
+
.devpilot/
|
|
100
|
+
config.yaml # Configuration
|
|
101
|
+
README.md # Internal documentation
|
|
102
|
+
sessions/ # Active sessions
|
|
103
|
+
{name}/
|
|
104
|
+
meta.json # Session metadata
|
|
105
|
+
plan.md # Work plan (optional)
|
|
106
|
+
history/ # Archived sessions
|
|
107
|
+
YYMMDD_{name}/
|
|
108
|
+
meta.json
|
|
109
|
+
plan.md
|
|
110
|
+
report.md
|
|
111
|
+
guides/ # Project-specific guides
|
|
112
|
+
worktrees/ # Git worktrees (gitignored)
|
|
113
|
+
.claude/
|
|
114
|
+
commands/ # Claude Code skills
|
|
115
|
+
spec.md
|
|
116
|
+
review.md
|
|
117
|
+
report.md
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Configuration
|
|
121
|
+
|
|
122
|
+
`.devpilot/config.yaml`:
|
|
123
|
+
|
|
124
|
+
```yaml
|
|
125
|
+
version: 1
|
|
126
|
+
|
|
127
|
+
worktree:
|
|
128
|
+
auto: false # Auto-create worktree per session
|
|
129
|
+
path: ".devpilot/worktrees"
|
|
130
|
+
branch_prefix: "" # e.g., "feature/", "fix/"
|
|
131
|
+
|
|
132
|
+
session:
|
|
133
|
+
history_path: ".devpilot/history"
|
|
134
|
+
date_format: "YYMMDD" # or "YYYYMMDD"
|
|
135
|
+
|
|
136
|
+
guides:
|
|
137
|
+
path: ".devpilot/guides"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Requirements
|
|
141
|
+
|
|
142
|
+
- Node.js >= 22
|
|
143
|
+
- Claude Code (or any MCP-compatible AI client)
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
MIT
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface SessionMeta {
|
|
2
|
+
name: string;
|
|
3
|
+
created_at: string;
|
|
4
|
+
status: "active" | "completed";
|
|
5
|
+
completed_at?: string;
|
|
6
|
+
worktree?: {
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
path: string;
|
|
9
|
+
branch: string;
|
|
10
|
+
};
|
|
11
|
+
changed_files?: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface PlanProgressItem {
|
|
14
|
+
text: string;
|
|
15
|
+
completed: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface PlanProgress {
|
|
18
|
+
exists: boolean;
|
|
19
|
+
total: number;
|
|
20
|
+
completed: number;
|
|
21
|
+
items: PlanProgressItem[];
|
|
22
|
+
}
|
|
23
|
+
export declare function sessionExists(name: string): boolean;
|
|
24
|
+
export declare function createSession(name: string, worktreeInfo?: {
|
|
25
|
+
path: string;
|
|
26
|
+
branch: string;
|
|
27
|
+
}): SessionMeta;
|
|
28
|
+
export declare function getMeta(name: string): SessionMeta;
|
|
29
|
+
export declare function updateMeta(name: string, updates: Partial<SessionMeta>): SessionMeta;
|
|
30
|
+
export declare function listSessions(): SessionMeta[];
|
|
31
|
+
export declare function findActiveSession(): SessionMeta | null;
|
|
32
|
+
export declare function archiveSession(name: string, changedFiles?: string[]): string;
|
|
33
|
+
export declare function getPlanProgress(name: string): PlanProgress;
|
|
34
|
+
export declare function getPlanContent(name: string): string | null;
|
|
35
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/context/session.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,QAAQ,GAAG,WAAW,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAcD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,CAwBxG;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAMjD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAKnF;AAED,wBAAgB,YAAY,IAAI,WAAW,EAAE,CAQ5C;AAED,wBAAgB,iBAAiB,IAAI,WAAW,GAAG,IAAI,CAGtD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAsB5E;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAoB1D;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI1D"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, renameSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { getConfig, resolve } from "./workspace.js";
|
|
4
|
+
function sessionsDir() {
|
|
5
|
+
return resolve(".devpilot", "sessions");
|
|
6
|
+
}
|
|
7
|
+
function sessionDir(name) {
|
|
8
|
+
return join(sessionsDir(), name);
|
|
9
|
+
}
|
|
10
|
+
function metaPath(name) {
|
|
11
|
+
return join(sessionDir(name), "meta.json");
|
|
12
|
+
}
|
|
13
|
+
export function sessionExists(name) {
|
|
14
|
+
return existsSync(metaPath(name));
|
|
15
|
+
}
|
|
16
|
+
export function createSession(name, worktreeInfo) {
|
|
17
|
+
const dir = sessionDir(name);
|
|
18
|
+
if (existsSync(dir)) {
|
|
19
|
+
throw new Error(`Session "${name}" already exists.`);
|
|
20
|
+
}
|
|
21
|
+
mkdirSync(dir, { recursive: true });
|
|
22
|
+
const meta = {
|
|
23
|
+
name,
|
|
24
|
+
created_at: new Date().toISOString(),
|
|
25
|
+
status: "active",
|
|
26
|
+
};
|
|
27
|
+
if (worktreeInfo) {
|
|
28
|
+
meta.worktree = {
|
|
29
|
+
enabled: true,
|
|
30
|
+
path: worktreeInfo.path,
|
|
31
|
+
branch: worktreeInfo.branch,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
writeFileSync(metaPath(name), JSON.stringify(meta, null, 2));
|
|
35
|
+
return meta;
|
|
36
|
+
}
|
|
37
|
+
export function getMeta(name) {
|
|
38
|
+
const path = metaPath(name);
|
|
39
|
+
if (!existsSync(path)) {
|
|
40
|
+
throw new Error(`Session "${name}" not found.`);
|
|
41
|
+
}
|
|
42
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
43
|
+
}
|
|
44
|
+
export function updateMeta(name, updates) {
|
|
45
|
+
const meta = getMeta(name);
|
|
46
|
+
const updated = { ...meta, ...updates };
|
|
47
|
+
writeFileSync(metaPath(name), JSON.stringify(updated, null, 2));
|
|
48
|
+
return updated;
|
|
49
|
+
}
|
|
50
|
+
export function listSessions() {
|
|
51
|
+
const dir = sessionsDir();
|
|
52
|
+
if (!existsSync(dir))
|
|
53
|
+
return [];
|
|
54
|
+
return readdirSync(dir, { withFileTypes: true })
|
|
55
|
+
.filter((d) => d.isDirectory() && existsSync(join(dir, d.name, "meta.json")))
|
|
56
|
+
.map((d) => getMeta(d.name))
|
|
57
|
+
.sort((a, b) => b.created_at.localeCompare(a.created_at));
|
|
58
|
+
}
|
|
59
|
+
export function findActiveSession() {
|
|
60
|
+
const sessions = listSessions().filter((s) => s.status === "active");
|
|
61
|
+
return sessions.length === 1 ? sessions[0] : null;
|
|
62
|
+
}
|
|
63
|
+
export function archiveSession(name, changedFiles) {
|
|
64
|
+
const config = getConfig();
|
|
65
|
+
const srcDir = sessionDir(name);
|
|
66
|
+
// 완료 정보를 한 번에 업데이트
|
|
67
|
+
updateMeta(name, {
|
|
68
|
+
status: "completed",
|
|
69
|
+
completed_at: new Date().toISOString(),
|
|
70
|
+
...(changedFiles ? { changed_files: changedFiles } : {}),
|
|
71
|
+
});
|
|
72
|
+
// Generate archive directory name
|
|
73
|
+
const now = new Date();
|
|
74
|
+
const dateStr = formatDate(now, config.session.date_format);
|
|
75
|
+
const archiveName = `${dateStr}_${name}`;
|
|
76
|
+
const historyDir = resolve(config.session.history_path);
|
|
77
|
+
const destDir = join(historyDir, archiveName);
|
|
78
|
+
mkdirSync(historyDir, { recursive: true });
|
|
79
|
+
renameSync(srcDir, destDir);
|
|
80
|
+
return destDir;
|
|
81
|
+
}
|
|
82
|
+
export function getPlanProgress(name) {
|
|
83
|
+
const planPath = join(sessionDir(name), "plan.md");
|
|
84
|
+
if (!existsSync(planPath)) {
|
|
85
|
+
return { exists: false, total: 0, completed: 0, items: [] };
|
|
86
|
+
}
|
|
87
|
+
const content = readFileSync(planPath, "utf-8");
|
|
88
|
+
const checkboxes = content.match(/- \[[ x]\] .+/g) ?? [];
|
|
89
|
+
const items = checkboxes.map((line) => ({
|
|
90
|
+
text: line.replace(/- \[[ x]\] /, ""),
|
|
91
|
+
completed: line.startsWith("- [x]"),
|
|
92
|
+
}));
|
|
93
|
+
const completed = items.filter((item) => item.completed).length;
|
|
94
|
+
return {
|
|
95
|
+
exists: true,
|
|
96
|
+
total: checkboxes.length,
|
|
97
|
+
completed,
|
|
98
|
+
items,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
export function getPlanContent(name) {
|
|
102
|
+
const planPath = join(sessionDir(name), "plan.md");
|
|
103
|
+
if (!existsSync(planPath))
|
|
104
|
+
return null;
|
|
105
|
+
return readFileSync(planPath, "utf-8");
|
|
106
|
+
}
|
|
107
|
+
function formatDate(date, format) {
|
|
108
|
+
const yy = String(date.getFullYear()).slice(-2);
|
|
109
|
+
const mm = String(date.getMonth() + 1).padStart(2, "0");
|
|
110
|
+
const dd = String(date.getDate()).padStart(2, "0");
|
|
111
|
+
switch (format) {
|
|
112
|
+
case "YYMMDD":
|
|
113
|
+
return `${yy}${mm}${dd}`;
|
|
114
|
+
case "YYYYMMDD":
|
|
115
|
+
return `${date.getFullYear()}${mm}${dd}`;
|
|
116
|
+
default:
|
|
117
|
+
return `${yy}${mm}${dd}`;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/context/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACtG,OAAO,EAAE,IAAI,EAAY,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AA2BpD,SAAS,WAAW;IAClB,OAAO,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,YAA+C;IACzF,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,mBAAmB,CAAC,CAAC;IACvD,CAAC;IAED,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpC,MAAM,IAAI,GAAgB;QACxB,IAAI;QACJ,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,MAAM,EAAE,QAAQ;KACjB,CAAC;IAEF,IAAI,YAAY,EAAE,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG;YACd,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,YAAY,CAAC,IAAI;YACvB,MAAM,EAAE,YAAY,CAAC,MAAM;SAC5B,CAAC;IACJ,CAAC;IAED,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,cAAc,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,OAA6B;IACpE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,OAAO,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC;IACxC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAChE,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;IAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAEhC,OAAO,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SAC7C,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;SAC5E,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SAC3B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;IACrE,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,YAAuB;IAClE,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAEhC,mBAAmB;IACnB,UAAU,CAAC,IAAI,EAAE;QACf,MAAM,EAAE,WAAW;QACnB,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACtC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACzD,CAAC,CAAC;IAEH,kCAAkC;IAClC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5D,MAAM,WAAW,GAAG,GAAG,OAAO,IAAI,IAAI,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAE9C,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE5B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;IACnD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAC9D,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;IACzD,MAAM,KAAK,GAAuB,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1D,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;QACrC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;KACpC,CAAC,CAAC,CAAC;IACJ,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC;IAEhE,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,UAAU,CAAC,MAAM;QACxB,SAAS;QACT,KAAK;KACN,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;IACnD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,UAAU,CAAC,IAAU,EAAE,MAAc;IAC5C,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxD,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAEnD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,QAAQ;YACX,OAAO,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC;QAC3B,KAAK,UAAU;YACb,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC;QAC3C;YACE,OAAO,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC;IAC7B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface DevpilotConfig {
|
|
2
|
+
version: number;
|
|
3
|
+
worktree: {
|
|
4
|
+
auto: boolean;
|
|
5
|
+
path: string;
|
|
6
|
+
branch_prefix: string;
|
|
7
|
+
};
|
|
8
|
+
session: {
|
|
9
|
+
history_path: string;
|
|
10
|
+
date_format: string;
|
|
11
|
+
};
|
|
12
|
+
guides: {
|
|
13
|
+
path: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export declare function setWorkspaceRoot(root: string): void;
|
|
17
|
+
export declare function getWorkspaceRoot(): string;
|
|
18
|
+
export declare function isInitialized(): boolean;
|
|
19
|
+
export declare function getConfig(): DevpilotConfig;
|
|
20
|
+
export declare function resolve(...segments: string[]): string;
|
|
21
|
+
//# sourceMappingURL=workspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/context/workspace.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE;QACR,IAAI,EAAE,OAAO,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,OAAO,EAAE;QACP,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAqBD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAGnD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAKzC;AAED,wBAAgB,aAAa,IAAI,OAAO,CAOvC;AAED,wBAAgB,SAAS,IAAI,cAAc,CAuB1C;AAED,wBAAgB,OAAO,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAErD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { parse as parseYaml } from "./yaml.js";
|
|
4
|
+
const DEFAULT_CONFIG = {
|
|
5
|
+
version: 1,
|
|
6
|
+
worktree: {
|
|
7
|
+
auto: false,
|
|
8
|
+
path: ".devpilot/worktrees",
|
|
9
|
+
branch_prefix: "",
|
|
10
|
+
},
|
|
11
|
+
session: {
|
|
12
|
+
history_path: ".devpilot/history",
|
|
13
|
+
date_format: "YYMMDD",
|
|
14
|
+
},
|
|
15
|
+
guides: {
|
|
16
|
+
path: ".devpilot/guides",
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
let workspaceRoot = null;
|
|
20
|
+
let cachedConfig = null;
|
|
21
|
+
export function setWorkspaceRoot(root) {
|
|
22
|
+
workspaceRoot = root;
|
|
23
|
+
cachedConfig = null;
|
|
24
|
+
}
|
|
25
|
+
export function getWorkspaceRoot() {
|
|
26
|
+
if (!workspaceRoot) {
|
|
27
|
+
throw new Error("Workspace root not set. MCP roots/list may not have been received.");
|
|
28
|
+
}
|
|
29
|
+
return workspaceRoot;
|
|
30
|
+
}
|
|
31
|
+
export function isInitialized() {
|
|
32
|
+
try {
|
|
33
|
+
const root = getWorkspaceRoot();
|
|
34
|
+
return existsSync(join(root, ".devpilot"));
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function getConfig() {
|
|
41
|
+
if (cachedConfig)
|
|
42
|
+
return cachedConfig;
|
|
43
|
+
const root = getWorkspaceRoot();
|
|
44
|
+
const configPath = join(root, ".devpilot", "config.yaml");
|
|
45
|
+
if (!existsSync(configPath)) {
|
|
46
|
+
cachedConfig = DEFAULT_CONFIG;
|
|
47
|
+
return cachedConfig;
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
51
|
+
const parsed = parseYaml(raw);
|
|
52
|
+
cachedConfig = deepMerge(structuredClone(DEFAULT_CONFIG), parsed);
|
|
53
|
+
return cachedConfig;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
cachedConfig = DEFAULT_CONFIG;
|
|
57
|
+
return cachedConfig;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export function resolve(...segments) {
|
|
61
|
+
return join(getWorkspaceRoot(), ...segments);
|
|
62
|
+
}
|
|
63
|
+
function deepMerge(target, source) {
|
|
64
|
+
const result = { ...target };
|
|
65
|
+
for (const key of Object.keys(source)) {
|
|
66
|
+
if (source[key] &&
|
|
67
|
+
typeof source[key] === "object" &&
|
|
68
|
+
!Array.isArray(source[key]) &&
|
|
69
|
+
target[key] &&
|
|
70
|
+
typeof target[key] === "object") {
|
|
71
|
+
result[key] = deepMerge(target[key], source[key]);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
result[key] = source[key];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/context/workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal YAML parser for config.yaml.
|
|
3
|
+
* Handles simple key-value pairs and nested objects (indent-based).
|
|
4
|
+
* No external dependency needed for our simple config format.
|
|
5
|
+
*/
|
|
6
|
+
export declare function parse(yaml: string): Record<string, unknown>;
|
|
7
|
+
export declare function stringify(obj: Record<string, unknown>, indent?: number): string;
|
|
8
|
+
//# sourceMappingURL=yaml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../../src/context/yaml.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoC3D;AAkBD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,SAAI,GAAG,MAAM,CAgB1E"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal YAML parser for config.yaml.
|
|
3
|
+
* Handles simple key-value pairs and nested objects (indent-based).
|
|
4
|
+
* No external dependency needed for our simple config format.
|
|
5
|
+
*/
|
|
6
|
+
export function parse(yaml) {
|
|
7
|
+
const lines = yaml.split("\n");
|
|
8
|
+
const result = {};
|
|
9
|
+
const stack = [
|
|
10
|
+
{ indent: -1, obj: result },
|
|
11
|
+
];
|
|
12
|
+
for (const line of lines) {
|
|
13
|
+
const trimmed = line.replace(/\s+$/, "");
|
|
14
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
15
|
+
continue;
|
|
16
|
+
const indent = line.length - line.trimStart().length;
|
|
17
|
+
const match = trimmed.match(/^(\s*)([^:]+):\s*(.*)?$/);
|
|
18
|
+
if (!match)
|
|
19
|
+
continue;
|
|
20
|
+
const key = match[2].trim();
|
|
21
|
+
const rawValue = (match[3] ?? "").trim();
|
|
22
|
+
// Pop stack to find parent
|
|
23
|
+
while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {
|
|
24
|
+
stack.pop();
|
|
25
|
+
}
|
|
26
|
+
const parent = stack[stack.length - 1].obj;
|
|
27
|
+
if (!rawValue) {
|
|
28
|
+
// Nested object
|
|
29
|
+
const child = {};
|
|
30
|
+
parent[key] = child;
|
|
31
|
+
stack.push({ indent, obj: child });
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// Scalar value
|
|
35
|
+
parent[key] = parseValue(rawValue);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
function parseValue(raw) {
|
|
41
|
+
if (raw === "true")
|
|
42
|
+
return true;
|
|
43
|
+
if (raw === "false")
|
|
44
|
+
return false;
|
|
45
|
+
if (raw === "null")
|
|
46
|
+
return null;
|
|
47
|
+
// Remove quotes
|
|
48
|
+
if ((raw.startsWith('"') && raw.endsWith('"')) || (raw.startsWith("'") && raw.endsWith("'"))) {
|
|
49
|
+
return raw.slice(1, -1);
|
|
50
|
+
}
|
|
51
|
+
const num = Number(raw);
|
|
52
|
+
if (!isNaN(num) && raw !== "")
|
|
53
|
+
return num;
|
|
54
|
+
return raw;
|
|
55
|
+
}
|
|
56
|
+
export function stringify(obj, indent = 0) {
|
|
57
|
+
const lines = [];
|
|
58
|
+
const prefix = " ".repeat(indent);
|
|
59
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
60
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
61
|
+
lines.push(`${prefix}${key}:`);
|
|
62
|
+
lines.push(stringify(value, indent + 1));
|
|
63
|
+
}
|
|
64
|
+
else if (typeof value === "string") {
|
|
65
|
+
lines.push(`${prefix}${key}: "${value}"`);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
lines.push(`${prefix}${key}: ${value}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return lines.join("\n");
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=yaml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml.js","sourceRoot":"","sources":["../../src/context/yaml.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,MAAM,KAAK,GAAuD;QAChE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE;KAC5B,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAElD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC;QACrD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACvD,IAAI,CAAC,KAAK;YAAE,SAAS;QAErB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAEzC,2BAA2B;QAC3B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;YACpE,KAAK,CAAC,GAAG,EAAE,CAAC;QACd,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAE3C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,gBAAgB;YAChB,MAAM,KAAK,GAA4B,EAAE,CAAC;YAC1C,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,eAAe;YACf,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAClC,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAEhC,gBAAgB;IAChB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC7F,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,GAAG,CAAC;IAE1C,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAA4B,EAAE,MAAM,GAAG,CAAC;IAChE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEnC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC;YAC/B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAgC,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QACtE,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,GAAG,MAAM,KAAK,GAAG,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { setWorkspaceRoot } from "./context/workspace.js";
|
|
5
|
+
import { InitInputSchema, handleInit, description as initDesc } from "./tools/init/index.js";
|
|
6
|
+
import { SessionInputSchema, handleSession, description as sessionDesc } from "./tools/session/index.js";
|
|
7
|
+
import { PlanInputSchema, handlePlan, description as planDesc } from "./tools/plan/index.js";
|
|
8
|
+
import { GuideInputSchema, handleGuide, description as guideDesc } from "./tools/guide/index.js";
|
|
9
|
+
const INSTRUCTIONS = `# devpilot
|
|
10
|
+
|
|
11
|
+
Session-based development workflow manager.
|
|
12
|
+
|
|
13
|
+
## On Every New Conversation (CRITICAL)
|
|
14
|
+
Before doing ANYTHING, check for existing context:
|
|
15
|
+
1. Run \`session list\` to check for active sessions.
|
|
16
|
+
2. If active session exists:
|
|
17
|
+
- Run \`session status\` to understand current progress.
|
|
18
|
+
- Read the session's plan.md for full task context.
|
|
19
|
+
- Read SPEC.md for project conventions.
|
|
20
|
+
- Inform the user: "Found active session '{name}'. Resuming where you left off."
|
|
21
|
+
- Continue work from where it was left off.
|
|
22
|
+
3. If no active session:
|
|
23
|
+
- Check if devpilot is initialized (.devpilot/ exists). If not, run \`init\` first.
|
|
24
|
+
- Proceed with normal workflow below.
|
|
25
|
+
|
|
26
|
+
This ensures seamless context recovery across conversation sessions.
|
|
27
|
+
|
|
28
|
+
## First-time Setup
|
|
29
|
+
1. \`init\` to create .devpilot/ directory and configuration.
|
|
30
|
+
2. \`/spec\` to define project-level engineering foundations (SPEC.md).
|
|
31
|
+
|
|
32
|
+
## Development Cycle
|
|
33
|
+
1. \`session create\` to start work. Read SPEC.md for project conventions.
|
|
34
|
+
2. \`plan create\` for medium/large tasks. Plan references SPEC.md, only adds task-specific decisions.
|
|
35
|
+
3. Work using Claude Code's native tools. Follow plan.md as the execution spec.
|
|
36
|
+
4. \`/review\` before completing - quality gate to catch issues while they're still fixable.
|
|
37
|
+
5. \`session complete\` to archive. If new patterns/conventions were introduced, update SPEC.md with \`/spec\`.
|
|
38
|
+
6. \`/report\` to generate a completion report for the archived session.
|
|
39
|
+
|
|
40
|
+
## Rules
|
|
41
|
+
- **All development work MUST go through devpilot**. Always use \`session create\` before coding.
|
|
42
|
+
- Always confirm with the user before proceeding (use AskUserQuestion).
|
|
43
|
+
- Use \`guide list\` to find relevant guides, then let the user choose.
|
|
44
|
+
- For parallel work, create multiple sessions with worktrees and use Subagents.
|
|
45
|
+
|
|
46
|
+
## User Expertise Support
|
|
47
|
+
- When gathering requirements (plan, /spec), always offer "Let AI research best practices" as an option.
|
|
48
|
+
- If the user is unfamiliar with the tech stack, use WebSearch to find latest stable best practices and present recommendations.
|
|
49
|
+
- Never assume the user knows framework-specific conventions. Explain and offer choices.
|
|
50
|
+
|
|
51
|
+
## External Tool Collaboration
|
|
52
|
+
- devpilot manages the development workflow (session, plan, spec). Actual coding uses the AI client's native tools.
|
|
53
|
+
- Other MCP servers, skills, and plugins are encouraged for information gathering, code analysis, and specialized tasks.
|
|
54
|
+
- Use the best tool for each job: devpilot for structure, native tools for implementation, external tools for everything else.`;
|
|
55
|
+
const server = new McpServer({ name: "devpilot", version: "1.0.0" }, {
|
|
56
|
+
capabilities: {
|
|
57
|
+
tools: {},
|
|
58
|
+
},
|
|
59
|
+
instructions: INSTRUCTIONS,
|
|
60
|
+
});
|
|
61
|
+
// Register tools using registerTool (non-deprecated API)
|
|
62
|
+
server.registerTool("init", {
|
|
63
|
+
description: initDesc,
|
|
64
|
+
inputSchema: InitInputSchema,
|
|
65
|
+
}, async (params) => {
|
|
66
|
+
const input = InitInputSchema.parse(params);
|
|
67
|
+
const result = await handleInit(input);
|
|
68
|
+
return { content: [{ type: "text", text: result }] };
|
|
69
|
+
});
|
|
70
|
+
server.registerTool("session", {
|
|
71
|
+
description: sessionDesc,
|
|
72
|
+
inputSchema: SessionInputSchema,
|
|
73
|
+
}, async (params) => {
|
|
74
|
+
const input = SessionInputSchema.parse(params);
|
|
75
|
+
const result = await handleSession(input);
|
|
76
|
+
return { content: [{ type: "text", text: result }] };
|
|
77
|
+
});
|
|
78
|
+
server.registerTool("plan", {
|
|
79
|
+
description: planDesc,
|
|
80
|
+
inputSchema: PlanInputSchema,
|
|
81
|
+
}, async (params) => {
|
|
82
|
+
const input = PlanInputSchema.parse(params);
|
|
83
|
+
const result = await handlePlan(input);
|
|
84
|
+
return { content: [{ type: "text", text: result }] };
|
|
85
|
+
});
|
|
86
|
+
server.registerTool("guide", {
|
|
87
|
+
description: guideDesc,
|
|
88
|
+
inputSchema: GuideInputSchema,
|
|
89
|
+
}, async (params) => {
|
|
90
|
+
const input = GuideInputSchema.parse(params);
|
|
91
|
+
const result = await handleGuide(input);
|
|
92
|
+
return { content: [{ type: "text", text: result }] };
|
|
93
|
+
});
|
|
94
|
+
async function main() {
|
|
95
|
+
const transport = new StdioServerTransport();
|
|
96
|
+
// Workspace root from environment or cwd
|
|
97
|
+
const root = process.env.DEVPILOT_ROOT ?? process.cwd();
|
|
98
|
+
setWorkspaceRoot(root);
|
|
99
|
+
await server.connect(transport);
|
|
100
|
+
}
|
|
101
|
+
main().catch((err) => {
|
|
102
|
+
console.error("Failed to start devpilot MCP server:", err);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
});
|
|
105
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|