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
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { isInitialized, getConfig, getWorkspaceRoot } from "../../context/workspace.js";
|
|
4
|
+
import { createSession, listSessions, getMeta, archiveSession, findActiveSession, getPlanProgress, sessionExists, } from "../../context/session.js";
|
|
5
|
+
import { createWorktree, getChangedFiles, getGitDiffStat } from "../../worktree/manager.js";
|
|
6
|
+
export async function handleSession(input) {
|
|
7
|
+
if (!isInitialized()) {
|
|
8
|
+
return "devpilot is not initialized. Run `init` first.";
|
|
9
|
+
}
|
|
10
|
+
switch (input.action) {
|
|
11
|
+
case "create":
|
|
12
|
+
return handleCreate(input);
|
|
13
|
+
case "list":
|
|
14
|
+
return handleList();
|
|
15
|
+
case "status":
|
|
16
|
+
return handleStatus(input);
|
|
17
|
+
case "complete":
|
|
18
|
+
return handleComplete(input);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function handleCreate(input) {
|
|
22
|
+
if (!input.name) {
|
|
23
|
+
return "Session name is required for create action.";
|
|
24
|
+
}
|
|
25
|
+
if (sessionExists(input.name)) {
|
|
26
|
+
return `Session "${input.name}" already exists. Choose a different name or complete the existing one.`;
|
|
27
|
+
}
|
|
28
|
+
const config = getConfig();
|
|
29
|
+
const useWorktree = input.worktree ?? config.worktree.auto;
|
|
30
|
+
let worktreeInfo;
|
|
31
|
+
let worktreeWarning;
|
|
32
|
+
if (useWorktree) {
|
|
33
|
+
try {
|
|
34
|
+
worktreeInfo = createWorktree(input.name);
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
38
|
+
worktreeWarning = `Worktree creation failed: ${msg}`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const meta = createSession(input.name, worktreeInfo);
|
|
42
|
+
const lines = [
|
|
43
|
+
`Session "${meta.name}" created.`,
|
|
44
|
+
`Path: .devpilot/sessions/${meta.name}/`,
|
|
45
|
+
];
|
|
46
|
+
if (worktreeWarning) {
|
|
47
|
+
lines.push(`Warning: ${worktreeWarning} (proceeding without worktree)`);
|
|
48
|
+
}
|
|
49
|
+
else if (worktreeInfo) {
|
|
50
|
+
lines.push(`Worktree: ${worktreeInfo.path} (branch: ${worktreeInfo.branch})`);
|
|
51
|
+
}
|
|
52
|
+
const hasSpec = existsSync(join(getWorkspaceRoot(), "SPEC.md"));
|
|
53
|
+
lines.push("");
|
|
54
|
+
if (hasSpec) {
|
|
55
|
+
lines.push("Read SPEC.md first for project conventions and engineering foundations.");
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
lines.push("**No SPEC.md found.** Use AskUserQuestion to ask the user:", "\"SPEC.md (project engineering foundations) does not exist yet. Run /spec first, or proceed without it?\"");
|
|
59
|
+
}
|
|
60
|
+
lines.push("Use `plan create` if you need upfront planning.", "Run `session complete` when done.");
|
|
61
|
+
return lines.join("\n");
|
|
62
|
+
}
|
|
63
|
+
function handleList() {
|
|
64
|
+
const sessions = listSessions();
|
|
65
|
+
if (sessions.length === 0) {
|
|
66
|
+
return "No active sessions. Create one with `session create`.";
|
|
67
|
+
}
|
|
68
|
+
const activeSessions = sessions.filter((s) => s.status === "active");
|
|
69
|
+
const lines = [`Sessions (${sessions.length} total, ${activeSessions.length} active):\n`];
|
|
70
|
+
for (const session of sessions) {
|
|
71
|
+
const plan = getPlanProgress(session.name);
|
|
72
|
+
const wt = session.worktree?.enabled ? " (worktree)" : "";
|
|
73
|
+
const status = session.status === "active" ? "[active]" : "[completed]";
|
|
74
|
+
lines.push(`- **${session.name}** ${status}${wt}`);
|
|
75
|
+
lines.push(` Created: ${session.created_at}`);
|
|
76
|
+
if (plan.exists) {
|
|
77
|
+
lines.push(` Plan: ${plan.completed}/${plan.total} items`);
|
|
78
|
+
}
|
|
79
|
+
lines.push("");
|
|
80
|
+
}
|
|
81
|
+
if (activeSessions.length > 0) {
|
|
82
|
+
lines.push("To resume an active session, run `session status` to see full details and continue working.");
|
|
83
|
+
}
|
|
84
|
+
return lines.join("\n");
|
|
85
|
+
}
|
|
86
|
+
function handleStatus(input) {
|
|
87
|
+
let name = input.name;
|
|
88
|
+
if (!name) {
|
|
89
|
+
const active = findActiveSession();
|
|
90
|
+
if (!active) {
|
|
91
|
+
const sessions = listSessions();
|
|
92
|
+
if (sessions.length === 0) {
|
|
93
|
+
return "No active sessions.";
|
|
94
|
+
}
|
|
95
|
+
return `Multiple active sessions found. Specify a name:\n${sessions.map((s) => `- ${s.name}`).join("\n")}`;
|
|
96
|
+
}
|
|
97
|
+
name = active.name;
|
|
98
|
+
}
|
|
99
|
+
const meta = getMeta(name);
|
|
100
|
+
const plan = getPlanProgress(name);
|
|
101
|
+
const changedFiles = getChangedFiles(name);
|
|
102
|
+
const diffStat = getGitDiffStat(name);
|
|
103
|
+
const lines = [
|
|
104
|
+
`Session: **${meta.name}**`,
|
|
105
|
+
`Status: ${meta.status}`,
|
|
106
|
+
`Created: ${meta.created_at}`,
|
|
107
|
+
];
|
|
108
|
+
if (meta.worktree?.enabled) {
|
|
109
|
+
lines.push(`Worktree: ${meta.worktree.path} (${meta.worktree.branch})`);
|
|
110
|
+
}
|
|
111
|
+
if (plan.exists) {
|
|
112
|
+
lines.push(`\nPlan: ${plan.completed}/${plan.total} items completed`);
|
|
113
|
+
lines.push(`Plan file: .devpilot/sessions/${name}/plan.md (read for full context)`);
|
|
114
|
+
const remaining = plan.items.filter((item) => !item.completed);
|
|
115
|
+
if (remaining.length > 0) {
|
|
116
|
+
lines.push("Remaining:");
|
|
117
|
+
remaining.slice(0, 5).forEach((item) => lines.push(` - ${item.text}`));
|
|
118
|
+
if (remaining.length > 5) {
|
|
119
|
+
lines.push(` ... and ${remaining.length - 5} more`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
lines.push("\nNo plan found. Use `plan create` if needed, or continue working directly.");
|
|
125
|
+
}
|
|
126
|
+
if (changedFiles.length > 0) {
|
|
127
|
+
lines.push(`\nChanged files (${changedFiles.length}):`);
|
|
128
|
+
changedFiles.slice(0, 10).forEach((f) => lines.push(` - ${f}`));
|
|
129
|
+
if (changedFiles.length > 10) {
|
|
130
|
+
lines.push(` ... and ${changedFiles.length - 10} more`);
|
|
131
|
+
}
|
|
132
|
+
if (diffStat) {
|
|
133
|
+
lines.push(`\n${diffStat}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Suggestion
|
|
137
|
+
lines.push("");
|
|
138
|
+
if (!plan.exists) {
|
|
139
|
+
// plan 미존재 메시지는 위에서 이미 출력됨
|
|
140
|
+
}
|
|
141
|
+
else if (plan.completed < plan.total) {
|
|
142
|
+
const nextItem = plan.items.find((item) => !item.completed);
|
|
143
|
+
if (nextItem) {
|
|
144
|
+
lines.push(`Next suggested item: "${nextItem.text}"`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
lines.push("All plan items completed. Run `session complete` to archive.");
|
|
149
|
+
}
|
|
150
|
+
return lines.join("\n");
|
|
151
|
+
}
|
|
152
|
+
function handleComplete(input) {
|
|
153
|
+
let name = input.name;
|
|
154
|
+
if (!name) {
|
|
155
|
+
const active = findActiveSession();
|
|
156
|
+
if (!active) {
|
|
157
|
+
return "Specify a session name to complete.";
|
|
158
|
+
}
|
|
159
|
+
name = active.name;
|
|
160
|
+
}
|
|
161
|
+
const meta = getMeta(name);
|
|
162
|
+
const plan = getPlanProgress(name);
|
|
163
|
+
if (plan.exists && plan.completed < plan.total && !input.force) {
|
|
164
|
+
return [
|
|
165
|
+
`Session "${name}" has incomplete plan items (${plan.completed}/${plan.total}).`,
|
|
166
|
+
"Use `force: true` to archive anyway.",
|
|
167
|
+
"",
|
|
168
|
+
"Remaining items:",
|
|
169
|
+
...plan.items.filter((item) => !item.completed).map((item) => ` - ${item.text}`),
|
|
170
|
+
].join("\n");
|
|
171
|
+
}
|
|
172
|
+
const changedFiles = getChangedFiles(name);
|
|
173
|
+
const archivePath = archiveSession(name, changedFiles);
|
|
174
|
+
const lines = [
|
|
175
|
+
`Session "${name}" archived.`,
|
|
176
|
+
`Location: ${archivePath.split("/").slice(-2).join("/")}`,
|
|
177
|
+
`Changed files: ${changedFiles.length}`,
|
|
178
|
+
];
|
|
179
|
+
if (meta.worktree?.enabled) {
|
|
180
|
+
lines.push("", "Worktree cleanup needed. Ask the user with AskUserQuestion:", `- Merge branch "${meta.worktree.branch}" into main?`, "- Remove the worktree?");
|
|
181
|
+
}
|
|
182
|
+
lines.push("", "Post-completion actions:", "1. Run /report to generate a completion report.", "2. Ask the user with AskUserQuestion: \"Did this session introduce new patterns, conventions, or architectural changes that should be reflected in SPEC.md?\"", " If yes, run /spec to update.");
|
|
183
|
+
return lines.join("\n");
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/tools/session/handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/session/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/session/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const SessionInputSchema: z.ZodObject<{
|
|
3
|
+
action: z.ZodEnum<["create", "list", "status", "complete"]>;
|
|
4
|
+
name: z.ZodOptional<z.ZodString>;
|
|
5
|
+
worktree: z.ZodOptional<z.ZodBoolean>;
|
|
6
|
+
force: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
force: boolean;
|
|
9
|
+
action: "status" | "create" | "list" | "complete";
|
|
10
|
+
name?: string | undefined;
|
|
11
|
+
worktree?: boolean | undefined;
|
|
12
|
+
}, {
|
|
13
|
+
action: "status" | "create" | "list" | "complete";
|
|
14
|
+
force?: boolean | undefined;
|
|
15
|
+
name?: string | undefined;
|
|
16
|
+
worktree?: boolean | undefined;
|
|
17
|
+
}>;
|
|
18
|
+
export type SessionInput = z.infer<typeof SessionInputSchema>;
|
|
19
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/tools/session/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;EAiB7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const SessionInputSchema = z.object({
|
|
3
|
+
action: z
|
|
4
|
+
.enum(["create", "list", "status", "complete"])
|
|
5
|
+
.describe("Session action"),
|
|
6
|
+
name: z
|
|
7
|
+
.string()
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Session name (for create, status, complete)"),
|
|
10
|
+
worktree: z
|
|
11
|
+
.boolean()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe("Create git worktree for this session (create only). Defaults to config.worktree.auto"),
|
|
14
|
+
force: z
|
|
15
|
+
.boolean()
|
|
16
|
+
.optional()
|
|
17
|
+
.default(false)
|
|
18
|
+
.describe("Force archive incomplete session (complete only)"),
|
|
19
|
+
});
|
|
20
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/tools/session/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,MAAM,EAAE,CAAC;SACN,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;SAC9C,QAAQ,CAAC,gBAAgB,CAAC;IAC7B,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,6CAA6C,CAAC;IAC1D,QAAQ,EAAE,CAAC;SACR,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CAAC,sFAAsF,CAAC;IACnG,KAAK,EAAE,CAAC;SACL,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,kDAAkD,CAAC;CAChE,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface WorktreeInfo {
|
|
2
|
+
path: string;
|
|
3
|
+
branch: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function createWorktree(sessionName: string): WorktreeInfo;
|
|
6
|
+
export declare function removeWorktree(sessionName: string): void;
|
|
7
|
+
export declare function getChangedFiles(sessionName: string): string[];
|
|
8
|
+
export declare function getGitDiffStat(sessionName?: string): string;
|
|
9
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/worktree/manager.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAcD,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CA2BhE;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAcxD;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAe7D;AAED,wBAAgB,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAoB3D"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { getConfig, getWorkspaceRoot, resolve } from "../context/workspace.js";
|
|
5
|
+
function isGitRepo() {
|
|
6
|
+
try {
|
|
7
|
+
execSync("git rev-parse --is-inside-work-tree", {
|
|
8
|
+
cwd: getWorkspaceRoot(),
|
|
9
|
+
stdio: "pipe",
|
|
10
|
+
});
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function createWorktree(sessionName) {
|
|
18
|
+
if (!isGitRepo()) {
|
|
19
|
+
throw new Error("Not a git repository. Worktree requires git.");
|
|
20
|
+
}
|
|
21
|
+
const config = getConfig();
|
|
22
|
+
const worktreesDir = resolve(config.worktree.path);
|
|
23
|
+
const worktreePath = join(worktreesDir, sessionName);
|
|
24
|
+
const branch = `${config.worktree.branch_prefix}${sessionName}`;
|
|
25
|
+
if (existsSync(worktreePath)) {
|
|
26
|
+
throw new Error(`Worktree already exists at ${worktreePath}`);
|
|
27
|
+
}
|
|
28
|
+
mkdirSync(worktreesDir, { recursive: true });
|
|
29
|
+
try {
|
|
30
|
+
execSync(`git worktree add -b "${branch}" "${worktreePath}"`, {
|
|
31
|
+
cwd: getWorkspaceRoot(),
|
|
32
|
+
stdio: "pipe",
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
37
|
+
throw new Error(`Failed to create worktree: ${msg}`);
|
|
38
|
+
}
|
|
39
|
+
return { path: worktreePath, branch };
|
|
40
|
+
}
|
|
41
|
+
export function removeWorktree(sessionName) {
|
|
42
|
+
const config = getConfig();
|
|
43
|
+
const worktreePath = join(resolve(config.worktree.path), sessionName);
|
|
44
|
+
if (!existsSync(worktreePath))
|
|
45
|
+
return;
|
|
46
|
+
try {
|
|
47
|
+
execSync(`git worktree remove "${worktreePath}" --force`, {
|
|
48
|
+
cwd: getWorkspaceRoot(),
|
|
49
|
+
stdio: "pipe",
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Ignore cleanup errors
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function getChangedFiles(sessionName) {
|
|
57
|
+
const config = getConfig();
|
|
58
|
+
const worktreePath = join(resolve(config.worktree.path), sessionName);
|
|
59
|
+
const cwd = existsSync(worktreePath) ? worktreePath : getWorkspaceRoot();
|
|
60
|
+
try {
|
|
61
|
+
const output = execSync("git diff --name-only HEAD", {
|
|
62
|
+
cwd,
|
|
63
|
+
stdio: "pipe",
|
|
64
|
+
encoding: "utf-8",
|
|
65
|
+
});
|
|
66
|
+
return output.trim().split("\n").filter(Boolean);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export function getGitDiffStat(sessionName) {
|
|
73
|
+
const config = getConfig();
|
|
74
|
+
let cwd = getWorkspaceRoot();
|
|
75
|
+
if (sessionName) {
|
|
76
|
+
const worktreePath = join(resolve(config.worktree.path), sessionName);
|
|
77
|
+
if (existsSync(worktreePath)) {
|
|
78
|
+
cwd = worktreePath;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
return execSync("git diff --stat HEAD", {
|
|
83
|
+
cwd,
|
|
84
|
+
stdio: "pipe",
|
|
85
|
+
encoding: "utf-8",
|
|
86
|
+
}).trim();
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return "";
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/worktree/manager.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aidflow",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Session-based development workflow MCP for Claude Code",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"aidflow": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/",
|
|
13
|
+
"templates/"
|
|
14
|
+
],
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/ghyeong/devpilot"
|
|
18
|
+
},
|
|
19
|
+
"author": "ghyeong",
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"dev": "tsc --watch",
|
|
23
|
+
"start": "node dist/index.js",
|
|
24
|
+
"lint": "tsc --noEmit",
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"test:watch": "vitest"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"mcp",
|
|
30
|
+
"claude-code",
|
|
31
|
+
"development",
|
|
32
|
+
"workflow",
|
|
33
|
+
"git-worktree",
|
|
34
|
+
"session"
|
|
35
|
+
],
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=22.0.0"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
42
|
+
"zod": "^3.24.4"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^22.0.0",
|
|
46
|
+
"typescript": "^5.7.0",
|
|
47
|
+
"vitest": "^4.0.18"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# devpilot
|
|
2
|
+
|
|
3
|
+
Session-based development workflow manager for Claude Code.
|
|
4
|
+
|
|
5
|
+
## Directory Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
.devpilot/
|
|
9
|
+
config.yaml # Configuration
|
|
10
|
+
sessions/ # Active sessions
|
|
11
|
+
{name}/
|
|
12
|
+
meta.json # Session metadata
|
|
13
|
+
plan.md # Work plan (optional)
|
|
14
|
+
history/ # Archived sessions
|
|
15
|
+
YYMMDD_{name}/
|
|
16
|
+
meta.json
|
|
17
|
+
plan.md
|
|
18
|
+
guides/ # Project-specific guides
|
|
19
|
+
*.md
|
|
20
|
+
worktrees/ # Git worktrees (gitignored)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## config.yaml
|
|
26
|
+
|
|
27
|
+
| Key | Type | Default | Description |
|
|
28
|
+
|-----|------|---------|-------------|
|
|
29
|
+
| `version` | number | `1` | Config version |
|
|
30
|
+
| `worktree.auto` | boolean | `false` | Auto-create worktree on session create |
|
|
31
|
+
| `worktree.path` | string | `".devpilot/worktrees"` | Worktree storage path |
|
|
32
|
+
| `worktree.branch_prefix` | string | `""` | Branch name prefix (e.g., `"feature/"`, `"fix/"`) |
|
|
33
|
+
| `session.history_path` | string | `".devpilot/history"` | Archive destination |
|
|
34
|
+
| `session.date_format` | string | `"YYMMDD"` | Date format for archive names (`YYMMDD` or `YYYYMMDD`) |
|
|
35
|
+
| `guides.path` | string | `".devpilot/guides"` | Guide documents path |
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## meta.json
|
|
40
|
+
|
|
41
|
+
Session metadata. Automatically managed by devpilot.
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"name": "fix-auth-bug",
|
|
46
|
+
"created_at": "2026-03-04T10:00:00.000Z",
|
|
47
|
+
"status": "active",
|
|
48
|
+
"worktree": {
|
|
49
|
+
"enabled": true,
|
|
50
|
+
"path": ".devpilot/worktrees/fix-auth-bug",
|
|
51
|
+
"branch": "fix-auth-bug"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
| Field | Type | Description |
|
|
57
|
+
|-------|------|-------------|
|
|
58
|
+
| `name` | string | Session name |
|
|
59
|
+
| `created_at` | string (ISO 8601) | Creation timestamp |
|
|
60
|
+
| `status` | `"active"` \| `"completed"` | Session state |
|
|
61
|
+
| `completed_at` | string (ISO 8601) | Completion timestamp (set on `session complete`) |
|
|
62
|
+
| `worktree.enabled` | boolean | Whether worktree is attached |
|
|
63
|
+
| `worktree.path` | string | Worktree directory path |
|
|
64
|
+
| `worktree.branch` | string | Git branch name |
|
|
65
|
+
| `changed_files` | string[] | Files changed during session (set on `session complete`) |
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## plan.md
|
|
70
|
+
|
|
71
|
+
Optional work plan. Created via `plan create`. Structure:
|
|
72
|
+
|
|
73
|
+
```markdown
|
|
74
|
+
# {Title}
|
|
75
|
+
|
|
76
|
+
## Background
|
|
77
|
+
{Context and motivation}
|
|
78
|
+
|
|
79
|
+
## Objective
|
|
80
|
+
{Clear, measurable goal}
|
|
81
|
+
|
|
82
|
+
## Requirements
|
|
83
|
+
|
|
84
|
+
### Functional Requirements
|
|
85
|
+
- FR-1: {requirement}
|
|
86
|
+
|
|
87
|
+
### Non-Functional Requirements
|
|
88
|
+
- NFR-1: {requirement}
|
|
89
|
+
|
|
90
|
+
## Out of Scope
|
|
91
|
+
- {Excluded items}
|
|
92
|
+
|
|
93
|
+
## Technical Approach
|
|
94
|
+
{Architecture, patterns, key decisions}
|
|
95
|
+
|
|
96
|
+
### Affected Files
|
|
97
|
+
- `path/to/file.ts` - {changes}
|
|
98
|
+
|
|
99
|
+
## Implementation Items
|
|
100
|
+
- [ ] Item 1
|
|
101
|
+
- [ ] Item 2
|
|
102
|
+
|
|
103
|
+
## Acceptance Criteria
|
|
104
|
+
- [ ] AC-1: {condition}
|
|
105
|
+
|
|
106
|
+
## Notes
|
|
107
|
+
{Constraints, assumptions, references}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Progress is tracked via checkboxes. `session status` reports completion rate.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Guides
|
|
115
|
+
|
|
116
|
+
Markdown files in `.devpilot/guides/`. Used for project-specific knowledge injection.
|
|
117
|
+
|
|
118
|
+
- First line = title, second line = description
|
|
119
|
+
- Use `guide list` to see available guides
|
|
120
|
+
- Use `guide read` to load a specific guide
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Skills
|
|
125
|
+
|
|
126
|
+
Claude Code skills installed to `.claude/commands/`:
|
|
127
|
+
|
|
128
|
+
| Skill | Description |
|
|
129
|
+
|-------|-------------|
|
|
130
|
+
| `/spec` | Create or update project SPEC.md |
|
|
131
|
+
| `/report` | Generate session completion report |
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Workflow
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
session create -> (plan create) -> work -> session complete -> /report
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
1. **session create**: Start a new session (optionally with worktree)
|
|
142
|
+
2. **plan create** (optional): Structured planning for medium/large tasks
|
|
143
|
+
3. **Work**: Implement using Claude Code's native tools
|
|
144
|
+
4. **session status**: Check progress anytime
|
|
145
|
+
5. **session complete**: Archive session to history
|
|
146
|
+
6. **/report**: Generate completion report
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# devpilot configuration
|
|
2
|
+
version: 1
|
|
3
|
+
|
|
4
|
+
worktree:
|
|
5
|
+
# Auto-create worktree for every new session
|
|
6
|
+
auto: false
|
|
7
|
+
# Worktree storage path
|
|
8
|
+
path: ".devpilot/worktrees"
|
|
9
|
+
# Branch name prefix for worktrees (e.g., "feature/", "fix/", or empty)
|
|
10
|
+
branch_prefix: ""
|
|
11
|
+
|
|
12
|
+
session:
|
|
13
|
+
# Archived session storage path
|
|
14
|
+
history_path: ".devpilot/history"
|
|
15
|
+
# Date format for archive names (YYMMDD or YYYYMMDD)
|
|
16
|
+
date_format: "YYMMDD"
|
|
17
|
+
|
|
18
|
+
guides:
|
|
19
|
+
# Guide documents path
|
|
20
|
+
path: ".devpilot/guides"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Getting Started
|
|
2
|
+
Quick guide to using devpilot in this project.
|
|
3
|
+
|
|
4
|
+
## Session Workflow
|
|
5
|
+
|
|
6
|
+
1. **Start**: `session create "task-name"` to begin a new task
|
|
7
|
+
2. **Plan** (optional): `plan create` for medium/large tasks
|
|
8
|
+
3. **Work**: Implement using Claude Code's native tools
|
|
9
|
+
4. **Check**: `session status` to see progress
|
|
10
|
+
5. **Done**: `session complete` to archive
|
|
11
|
+
|
|
12
|
+
## Worktrees
|
|
13
|
+
|
|
14
|
+
For isolated parallel work, create sessions with worktrees:
|
|
15
|
+
- Set `worktree: true` in `session create`
|
|
16
|
+
- Or set `worktree.auto: true` in config.yaml for all sessions
|
|
17
|
+
|
|
18
|
+
## Guides
|
|
19
|
+
|
|
20
|
+
Add project-specific guides to `.devpilot/guides/` as markdown files.
|
|
21
|
+
Use `guide list` to see available guides.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: report
|
|
3
|
+
description: Generate a session completion report. Call after session complete.
|
|
4
|
+
allowed-tools: Read, Write, Bash, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Generate a completion report for the most recently archived session.
|
|
8
|
+
|
|
9
|
+
## Steps
|
|
10
|
+
|
|
11
|
+
1. Find the latest directory in `.devpilot/history/` (sorted by name, newest first)
|
|
12
|
+
2. Read `meta.json` from that directory to get session metadata
|
|
13
|
+
3. Read `plan.md` from that directory (if exists)
|
|
14
|
+
4. Gather git commits for the session period:
|
|
15
|
+
- Use `created_at` and `completed_at` from meta.json as the time range
|
|
16
|
+
- Run: `git log --oneline --after="{created_at}" --before="{completed_at}"`
|
|
17
|
+
- If no completed_at, use current time as the end
|
|
18
|
+
5. Read the changed files listed in meta.json and briefly review each
|
|
19
|
+
6. Write `report.md` in the history directory
|
|
20
|
+
|
|
21
|
+
## report.md Format
|
|
22
|
+
|
|
23
|
+
```markdown
|
|
24
|
+
# {Session Name} - Report
|
|
25
|
+
|
|
26
|
+
## Summary
|
|
27
|
+
{1-2 line summary of what was accomplished}
|
|
28
|
+
|
|
29
|
+
## Plan Completion
|
|
30
|
+
{Plan items and their completion status, if plan existed}
|
|
31
|
+
|
|
32
|
+
## Changed Files
|
|
33
|
+
| File | Change Type | Description |
|
|
34
|
+
|------|-------------|-------------|
|
|
35
|
+
| path/to/file | modified/new/deleted | Brief description |
|
|
36
|
+
|
|
37
|
+
## Key Decisions
|
|
38
|
+
{Important technical decisions made during the work}
|
|
39
|
+
|
|
40
|
+
## Issues & Observations
|
|
41
|
+
{Any issues found, edge cases discovered, or observations for future reference}
|
|
42
|
+
|
|
43
|
+
## Duration
|
|
44
|
+
- Started: {created_at}
|
|
45
|
+
- Completed: {completed_at}
|
|
46
|
+
- Commits: {number of commits in range}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Notes
|
|
50
|
+
- If the history directory is empty, inform the user to run `session complete` first
|
|
51
|
+
- Focus on factual reporting, not speculation
|
|
52
|
+
- Keep descriptions concise but informative
|