workplanr 0.1.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/README.md +1 -0
- package/dist/cli/commands/add.d.ts +6 -0
- package/dist/cli/commands/add.d.ts.map +1 -0
- package/dist/cli/commands/add.js +37 -0
- package/dist/cli/commands/add.js.map +1 -0
- package/dist/cli/commands/done.d.ts +2 -0
- package/dist/cli/commands/done.d.ts.map +1 -0
- package/dist/cli/commands/done.js +43 -0
- package/dist/cli/commands/done.js.map +1 -0
- package/dist/cli/commands/init.d.ts +5 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +57 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/list.d.ts +4 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +23 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/propose.d.ts +3 -0
- package/dist/cli/commands/propose.d.ts.map +1 -0
- package/dist/cli/commands/propose.js +80 -0
- package/dist/cli/commands/propose.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +4 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +6 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/status.d.ts +2 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +24 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/tui.d.ts +2 -0
- package/dist/cli/commands/tui.d.ts.map +1 -0
- package/dist/cli/commands/tui.js +8 -0
- package/dist/cli/commands/tui.js.map +1 -0
- package/dist/cli/utils.d.ts +6 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +37 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/core/dod.d.ts +15 -0
- package/dist/core/dod.d.ts.map +1 -0
- package/dist/core/dod.js +103 -0
- package/dist/core/dod.js.map +1 -0
- package/dist/core/git.d.ts +2 -0
- package/dist/core/git.d.ts.map +1 -0
- package/dist/core/git.js +13 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/plan.d.ts +9 -0
- package/dist/core/plan.d.ts.map +1 -0
- package/dist/core/plan.js +64 -0
- package/dist/core/plan.js.map +1 -0
- package/dist/core/uuid.d.ts +8 -0
- package/dist/core/uuid.d.ts.map +1 -0
- package/dist/core/uuid.js +33 -0
- package/dist/core/uuid.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +4 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +28 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/complete-task.d.ts +3 -0
- package/dist/mcp/tools/complete-task.d.ts.map +1 -0
- package/dist/mcp/tools/complete-task.js +87 -0
- package/dist/mcp/tools/complete-task.js.map +1 -0
- package/dist/mcp/tools/get-next-task.d.ts +3 -0
- package/dist/mcp/tools/get-next-task.d.ts.map +1 -0
- package/dist/mcp/tools/get-next-task.js +41 -0
- package/dist/mcp/tools/get-next-task.js.map +1 -0
- package/dist/mcp/tools/get-plan.d.ts +3 -0
- package/dist/mcp/tools/get-plan.d.ts.map +1 -0
- package/dist/mcp/tools/get-plan.js +50 -0
- package/dist/mcp/tools/get-plan.js.map +1 -0
- package/dist/mcp/tools/propose-subtasks.d.ts +3 -0
- package/dist/mcp/tools/propose-subtasks.d.ts.map +1 -0
- package/dist/mcp/tools/propose-subtasks.js +80 -0
- package/dist/mcp/tools/propose-subtasks.js.map +1 -0
- package/dist/mcp/tools/update-progress.d.ts +3 -0
- package/dist/mcp/tools/update-progress.d.ts.map +1 -0
- package/dist/mcp/tools/update-progress.js +93 -0
- package/dist/mcp/tools/update-progress.js.map +1 -0
- package/dist/mcp/tools/validate-dod.d.ts +3 -0
- package/dist/mcp/tools/validate-dod.d.ts.map +1 -0
- package/dist/mcp/tools/validate-dod.js +34 -0
- package/dist/mcp/tools/validate-dod.js.map +1 -0
- package/dist/tui/App.d.ts +2 -0
- package/dist/tui/App.d.ts.map +1 -0
- package/dist/tui/App.js +31 -0
- package/dist/tui/App.js.map +1 -0
- package/dist/tui/components/ProposalPanel.d.ts +7 -0
- package/dist/tui/components/ProposalPanel.d.ts.map +1 -0
- package/dist/tui/components/ProposalPanel.js +9 -0
- package/dist/tui/components/ProposalPanel.js.map +1 -0
- package/dist/tui/components/StatusBar.d.ts +7 -0
- package/dist/tui/components/StatusBar.d.ts.map +1 -0
- package/dist/tui/components/StatusBar.js +10 -0
- package/dist/tui/components/StatusBar.js.map +1 -0
- package/dist/tui/components/TaskList.d.ts +8 -0
- package/dist/tui/components/TaskList.d.ts.map +1 -0
- package/dist/tui/components/TaskList.js +10 -0
- package/dist/tui/components/TaskList.js.map +1 -0
- package/dist/tui/components/TaskRow.d.ts +8 -0
- package/dist/tui/components/TaskRow.d.ts.map +1 -0
- package/dist/tui/components/TaskRow.js +28 -0
- package/dist/tui/components/TaskRow.js.map +1 -0
- package/dist/tui/hooks/usePlan.d.ts +3 -0
- package/dist/tui/hooks/usePlan.d.ts.map +1 -0
- package/dist/tui/hooks/usePlan.js +25 -0
- package/dist/tui/hooks/usePlan.js.map +1 -0
- package/dist/types/plan.d.ts +260 -0
- package/dist/types/plan.d.ts.map +1 -0
- package/dist/types/plan.js +76 -0
- package/dist/types/plan.js.map +1 -0
- package/package.json +59 -0
- package/schema/plan.schema.json +89 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Plan } from "../types/plan.js";
|
|
2
|
+
export declare function getPlanrDir(cwd?: string): string;
|
|
3
|
+
export declare function getPlanPath(cwd?: string): string;
|
|
4
|
+
export declare function planExists(cwd?: string): Promise<boolean>;
|
|
5
|
+
export declare function readPlan(cwd?: string): Promise<Plan>;
|
|
6
|
+
export declare function writePlan(plan: Plan, cwd?: string): Promise<void>;
|
|
7
|
+
export declare function createEmptyPlan(projectName: string, goal: string, projectId: string): Plan;
|
|
8
|
+
export declare function nowISO(): string;
|
|
9
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/core/plan.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAMzD,wBAAgB,WAAW,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAE/D;AAED,wBAAgB,WAAW,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAI/D;AAED,wBAAsB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAED,wBAAsB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK1D;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvE;AAED,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,IAAI,CAiBN;AAED,wBAAgB,MAAM,IAAI,MAAM,CAE/B"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { PlanSchema } from "../types/plan.js";
|
|
4
|
+
import { currentBranch } from "./git.js";
|
|
5
|
+
const PLANR_DIR = ".planr";
|
|
6
|
+
const PLAN_FILE = "plan.json";
|
|
7
|
+
export function getPlanrDir(cwd = process.cwd()) {
|
|
8
|
+
return path.join(cwd, PLANR_DIR);
|
|
9
|
+
}
|
|
10
|
+
export function getPlanPath(cwd = process.cwd()) {
|
|
11
|
+
const envPath = process.env.WORKPLANR_PLAN;
|
|
12
|
+
if (envPath)
|
|
13
|
+
return path.resolve(envPath);
|
|
14
|
+
return path.join(cwd, PLANR_DIR, PLAN_FILE);
|
|
15
|
+
}
|
|
16
|
+
export async function planExists(cwd) {
|
|
17
|
+
try {
|
|
18
|
+
await fs.access(getPlanPath(cwd));
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export async function readPlan(cwd) {
|
|
26
|
+
const planPath = getPlanPath(cwd);
|
|
27
|
+
const raw = await fs.readFile(planPath, "utf8");
|
|
28
|
+
const data = JSON.parse(raw);
|
|
29
|
+
return PlanSchema.parse(data);
|
|
30
|
+
}
|
|
31
|
+
export async function writePlan(plan, cwd) {
|
|
32
|
+
const planPath = getPlanPath(cwd);
|
|
33
|
+
// Update meta
|
|
34
|
+
plan.meta.branch = currentBranch();
|
|
35
|
+
plan.meta.updated_at = new Date().toISOString();
|
|
36
|
+
// Validate before writing
|
|
37
|
+
PlanSchema.parse(plan);
|
|
38
|
+
// Atomic write: write to temp, then rename
|
|
39
|
+
const tmpPath = planPath + ".tmp";
|
|
40
|
+
await fs.writeFile(tmpPath, JSON.stringify(plan, null, 2) + "\n", "utf8");
|
|
41
|
+
await fs.rename(tmpPath, planPath);
|
|
42
|
+
}
|
|
43
|
+
export function createEmptyPlan(projectName, goal, projectId) {
|
|
44
|
+
const now = new Date().toISOString();
|
|
45
|
+
return {
|
|
46
|
+
schema_version: "1.0.0",
|
|
47
|
+
project: {
|
|
48
|
+
id: projectId,
|
|
49
|
+
name: projectName,
|
|
50
|
+
goal,
|
|
51
|
+
},
|
|
52
|
+
tasks: [],
|
|
53
|
+
proposals: [],
|
|
54
|
+
meta: {
|
|
55
|
+
branch: currentBranch(),
|
|
56
|
+
created_by: "human",
|
|
57
|
+
updated_at: now,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function nowISO() {
|
|
62
|
+
return new Date().toISOString();
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/core/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAa,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,QAAQ,CAAC;AAC3B,MAAM,SAAS,GAAG,WAAW,CAAC;AAE9B,MAAM,UAAU,WAAW,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACrD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC3C,IAAI,OAAO;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAY;IAC3C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAY;IACzC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAU,EAAE,GAAY;IACtD,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAElC,cAAc;IACd,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,aAAa,EAAE,CAAC;IACnC,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAEhD,0BAA0B;IAC1B,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEvB,2CAA2C;IAC3C,MAAM,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IAClC,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1E,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,WAAmB,EACnB,IAAY,EACZ,SAAiB;IAEjB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO;QACL,cAAc,EAAE,OAAO;QACvB,OAAO,EAAE;YACP,EAAE,EAAE,SAAS;YACb,IAAI,EAAE,WAAW;YACjB,IAAI;SACL;QACD,KAAK,EAAE,EAAE;QACT,SAAS,EAAE,EAAE;QACb,IAAI,EAAE;YACJ,MAAM,EAAE,aAAa,EAAE;YACvB,UAAU,EAAE,OAAO;YACnB,UAAU,EAAE,GAAG;SAChB;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,MAAM;IACpB,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function generateId(): string;
|
|
2
|
+
export declare function generateTaskId(existingTasks: {
|
|
3
|
+
id: string;
|
|
4
|
+
}[]): string;
|
|
5
|
+
export declare function generateProposalId(existingProposals: {
|
|
6
|
+
id: string;
|
|
7
|
+
}[]): string;
|
|
8
|
+
//# sourceMappingURL=uuid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uuid.d.ts","sourceRoot":"","sources":["../../src/core/uuid.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAID,wBAAgB,cAAc,CAAC,aAAa,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,MAAM,CAYtE;AAED,wBAAgB,kBAAkB,CAChC,iBAAiB,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,GAClC,MAAM,CAWR"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
export function generateId() {
|
|
3
|
+
return randomUUID();
|
|
4
|
+
}
|
|
5
|
+
let taskCounter = 0;
|
|
6
|
+
export function generateTaskId(existingTasks) {
|
|
7
|
+
// Find the highest existing task number
|
|
8
|
+
let max = 0;
|
|
9
|
+
for (const task of existingTasks) {
|
|
10
|
+
const match = task.id.match(/^task-(\d+)$/);
|
|
11
|
+
if (match) {
|
|
12
|
+
const num = parseInt(match[1], 10);
|
|
13
|
+
if (num > max)
|
|
14
|
+
max = num;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const next = max + 1;
|
|
18
|
+
return `task-${String(next).padStart(3, "0")}`;
|
|
19
|
+
}
|
|
20
|
+
export function generateProposalId(existingProposals) {
|
|
21
|
+
let max = 0;
|
|
22
|
+
for (const p of existingProposals) {
|
|
23
|
+
const match = p.id.match(/^prop-(\d+)$/);
|
|
24
|
+
if (match) {
|
|
25
|
+
const num = parseInt(match[1], 10);
|
|
26
|
+
if (num > max)
|
|
27
|
+
max = num;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const next = max + 1;
|
|
31
|
+
return `prop-${String(next).padStart(3, "0")}`;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=uuid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uuid.js","sourceRoot":"","sources":["../../src/core/uuid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,UAAU;IACxB,OAAO,UAAU,EAAE,CAAC;AACtB,CAAC;AAED,IAAI,WAAW,GAAG,CAAC,CAAC;AAEpB,MAAM,UAAU,cAAc,CAAC,aAA+B;IAC5D,wCAAwC;IACxC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC5C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnC,IAAI,GAAG,GAAG,GAAG;gBAAE,GAAG,GAAG,GAAG,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;IACrB,OAAO,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,iBAAmC;IAEnC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,CAAC,IAAI,iBAAiB,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACzC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnC,IAAI,GAAG,GAAG,GAAG;gBAAE,GAAG,GAAG,GAAG,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;IACrB,OAAO,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AACjD,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,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { initCommand } from "./cli/commands/init.js";
|
|
4
|
+
import { addCommand } from "./cli/commands/add.js";
|
|
5
|
+
import { listCommand } from "./cli/commands/list.js";
|
|
6
|
+
import { doneCommand } from "./cli/commands/done.js";
|
|
7
|
+
import { statusCommand } from "./cli/commands/status.js";
|
|
8
|
+
import { serveCommand } from "./cli/commands/serve.js";
|
|
9
|
+
import { tuiCommand } from "./cli/commands/tui.js";
|
|
10
|
+
import { approveProposalCommand, rejectProposalCommand, } from "./cli/commands/propose.js";
|
|
11
|
+
const program = new Command();
|
|
12
|
+
program
|
|
13
|
+
.name("wp")
|
|
14
|
+
.description("Workplanr — planning as code, for humans and agents")
|
|
15
|
+
.version("0.1.0");
|
|
16
|
+
program
|
|
17
|
+
.command("init")
|
|
18
|
+
.description("Initialize .planr/ in current directory")
|
|
19
|
+
.option("--name <name>", "Project name")
|
|
20
|
+
.option("--goal <goal>", "Project goal")
|
|
21
|
+
.action(initCommand);
|
|
22
|
+
program
|
|
23
|
+
.command("add <title>")
|
|
24
|
+
.description("Add a new task")
|
|
25
|
+
.option("--priority <priority>", "low | medium | high | critical", "medium")
|
|
26
|
+
.option("--depends-on <ids>", "Comma-separated task IDs")
|
|
27
|
+
.option("--dod <path>", "Path to custom DoD template")
|
|
28
|
+
.action(addCommand);
|
|
29
|
+
program
|
|
30
|
+
.command("list")
|
|
31
|
+
.description("List tasks")
|
|
32
|
+
.option("--status <status>", "Filter by status (comma-separated)")
|
|
33
|
+
.action(listCommand);
|
|
34
|
+
program
|
|
35
|
+
.command("done <id>")
|
|
36
|
+
.description("Mark task as done (runs DoD validation)")
|
|
37
|
+
.action(doneCommand);
|
|
38
|
+
program.command("status").description("Print plan summary").action(statusCommand);
|
|
39
|
+
const propose = program
|
|
40
|
+
.command("propose")
|
|
41
|
+
.description("Manage subtask proposals");
|
|
42
|
+
propose
|
|
43
|
+
.command("approve <id>")
|
|
44
|
+
.description("Approve a subtask proposal")
|
|
45
|
+
.action(approveProposalCommand);
|
|
46
|
+
propose
|
|
47
|
+
.command("reject <id>")
|
|
48
|
+
.description("Reject a subtask proposal")
|
|
49
|
+
.action(rejectProposalCommand);
|
|
50
|
+
program
|
|
51
|
+
.command("serve")
|
|
52
|
+
.description("Start MCP server")
|
|
53
|
+
.option("--port <port>", "TCP port (default: stdio)")
|
|
54
|
+
.action(serveCommand);
|
|
55
|
+
program
|
|
56
|
+
.command("tui")
|
|
57
|
+
.description("Open TUI dashboard")
|
|
58
|
+
.action(tuiCommand);
|
|
59
|
+
program.parse();
|
|
60
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,IAAI,CAAC;KACV,WAAW,CAAC,qDAAqD,CAAC;KAClE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,yCAAyC,CAAC;KACtD,MAAM,CAAC,eAAe,EAAE,cAAc,CAAC;KACvC,MAAM,CAAC,eAAe,EAAE,cAAc,CAAC;KACvC,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,gBAAgB,CAAC;KAC7B,MAAM,CAAC,uBAAuB,EAAE,gCAAgC,EAAE,QAAQ,CAAC;KAC3E,MAAM,CAAC,oBAAoB,EAAE,0BAA0B,CAAC;KACxD,MAAM,CAAC,cAAc,EAAE,6BAA6B,CAAC;KACrD,MAAM,CAAC,UAAU,CAAC,CAAC;AAEtB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,YAAY,CAAC;KACzB,MAAM,CAAC,mBAAmB,EAAE,oCAAoC,CAAC;KACjE,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,WAAW,CAAC;KACpB,WAAW,CAAC,yCAAyC,CAAC;KACtD,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;AAElF,MAAM,OAAO,GAAG,OAAO;KACpB,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,0BAA0B,CAAC,CAAC;AAE3C,OAAO;KACJ,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CAAC,4BAA4B,CAAC;KACzC,MAAM,CAAC,sBAAsB,CAAC,CAAC;AAElC,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,2BAA2B,CAAC;KACxC,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjC,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,kBAAkB,CAAC;KAC/B,MAAM,CAAC,eAAe,EAAE,2BAA2B,CAAC;KACpD,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,oBAAoB,CAAC;KACjC,MAAM,CAAC,UAAU,CAAC,CAAC;AAEtB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASpE,wBAAgB,YAAY,IAAI,SAAS,CAcxC;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAStD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { registerGetPlan } from "./tools/get-plan.js";
|
|
4
|
+
import { registerGetNextTask } from "./tools/get-next-task.js";
|
|
5
|
+
import { registerUpdateProgress } from "./tools/update-progress.js";
|
|
6
|
+
import { registerValidateDod } from "./tools/validate-dod.js";
|
|
7
|
+
import { registerCompleteTask } from "./tools/complete-task.js";
|
|
8
|
+
import { registerProposeSubtasks } from "./tools/propose-subtasks.js";
|
|
9
|
+
export function createServer() {
|
|
10
|
+
const server = new McpServer({
|
|
11
|
+
name: "workplanr",
|
|
12
|
+
version: "0.1.0",
|
|
13
|
+
});
|
|
14
|
+
registerGetPlan(server);
|
|
15
|
+
registerGetNextTask(server);
|
|
16
|
+
registerUpdateProgress(server);
|
|
17
|
+
registerValidateDod(server);
|
|
18
|
+
registerCompleteTask(server);
|
|
19
|
+
registerProposeSubtasks(server);
|
|
20
|
+
return server;
|
|
21
|
+
}
|
|
22
|
+
export async function startStdioServer() {
|
|
23
|
+
const server = createServer();
|
|
24
|
+
const transport = new StdioServerTransport();
|
|
25
|
+
process.stderr.write(`workplanr MCP server started\nplan: ${process.cwd()}/.planr/plan.json\ntransport: stdio\n`);
|
|
26
|
+
await server.connect(transport);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,eAAe,CAAC,MAAM,CAAC,CAAC;IACxB,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAEhC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,uCAAuC,OAAO,CAAC,GAAG,EAAE,uCAAuC,CAC5F,CAAC;IAEF,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete-task.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/complete-task.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4F5D"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { readPlan, writePlan, nowISO } from "../../core/plan.js";
|
|
3
|
+
import { validateDod } from "../../core/dod.js";
|
|
4
|
+
export function registerCompleteTask(server) {
|
|
5
|
+
server.tool("complete_task", "Marks a task as done. Blocked if DoD has unfulfilled Required items.", {
|
|
6
|
+
task_id: z.string().describe("The task ID to complete"),
|
|
7
|
+
summary: z.string().describe("One sentence: what was done"),
|
|
8
|
+
}, async ({ task_id, summary }) => {
|
|
9
|
+
try {
|
|
10
|
+
const plan = await readPlan();
|
|
11
|
+
const task = plan.tasks.find((t) => t.id === task_id);
|
|
12
|
+
if (!task) {
|
|
13
|
+
return {
|
|
14
|
+
content: [
|
|
15
|
+
{
|
|
16
|
+
type: "text",
|
|
17
|
+
text: JSON.stringify({ ok: false, error: "task_not_found" }),
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
isError: true,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
if (task.status === "done") {
|
|
24
|
+
return {
|
|
25
|
+
content: [
|
|
26
|
+
{
|
|
27
|
+
type: "text",
|
|
28
|
+
text: JSON.stringify({ ok: false, error: "already_done" }),
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
isError: true,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
// Run DoD validation
|
|
35
|
+
const dodResult = await validateDod(task_id);
|
|
36
|
+
if (!dodResult.passed) {
|
|
37
|
+
return {
|
|
38
|
+
content: [
|
|
39
|
+
{
|
|
40
|
+
type: "text",
|
|
41
|
+
text: JSON.stringify({
|
|
42
|
+
ok: false,
|
|
43
|
+
error: "dod_not_passed",
|
|
44
|
+
dod_result: dodResult,
|
|
45
|
+
}),
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
isError: true,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// Mark as done
|
|
52
|
+
task.status = "done";
|
|
53
|
+
task.progress = 100;
|
|
54
|
+
task.updated_at = nowISO();
|
|
55
|
+
task.log.push({
|
|
56
|
+
ts: nowISO(),
|
|
57
|
+
actor: task.agent_assignee || "agent",
|
|
58
|
+
event: "completed",
|
|
59
|
+
payload: { summary },
|
|
60
|
+
});
|
|
61
|
+
await writePlan(plan);
|
|
62
|
+
return {
|
|
63
|
+
content: [
|
|
64
|
+
{
|
|
65
|
+
type: "text",
|
|
66
|
+
text: JSON.stringify({ ok: true }),
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
return {
|
|
73
|
+
content: [
|
|
74
|
+
{
|
|
75
|
+
type: "text",
|
|
76
|
+
text: JSON.stringify({
|
|
77
|
+
ok: false,
|
|
78
|
+
error: error instanceof Error ? error.message : String(error),
|
|
79
|
+
}),
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
isError: true,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=complete-task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete-task.js","sourceRoot":"","sources":["../../../src/mcp/tools/complete-task.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-next-task.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/get-next-task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwD3D"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { readPlan } from "../../core/plan.js";
|
|
2
|
+
import { PRIORITY_ORDER } from "../../types/plan.js";
|
|
3
|
+
export function registerGetNextTask(server) {
|
|
4
|
+
server.tool("get_next_task", "Returns the highest-priority task that is ready to work on (all dependencies satisfied, status is pending)", {}, async () => {
|
|
5
|
+
try {
|
|
6
|
+
const plan = await readPlan();
|
|
7
|
+
const doneIds = new Set(plan.tasks.filter((t) => t.status === "done").map((t) => t.id));
|
|
8
|
+
const available = plan.tasks
|
|
9
|
+
.filter((t) => t.status === "pending" &&
|
|
10
|
+
t.depends_on.every((dep) => doneIds.has(dep)))
|
|
11
|
+
.sort((a, b) => PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority]);
|
|
12
|
+
const task = available.length > 0 ? available[0] : null;
|
|
13
|
+
return {
|
|
14
|
+
content: [
|
|
15
|
+
{
|
|
16
|
+
type: "text",
|
|
17
|
+
text: JSON.stringify({
|
|
18
|
+
task,
|
|
19
|
+
context: plan.project.goal,
|
|
20
|
+
}, null, 2),
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
return {
|
|
27
|
+
content: [
|
|
28
|
+
{
|
|
29
|
+
type: "text",
|
|
30
|
+
text: JSON.stringify({
|
|
31
|
+
error: "Failed to get next task",
|
|
32
|
+
details: error instanceof Error ? error.message : String(error),
|
|
33
|
+
}),
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
isError: true,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=get-next-task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-next-task.js","sourceRoot":"","sources":["../../../src/mcp/tools/get-next-task.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,IAAI,CACT,eAAe,EACf,4GAA4G,EAC5G,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAC/D,CAAC;YAEF,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK;iBACzB,MAAM,CACL,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,MAAM,KAAK,SAAS;gBACtB,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAChD;iBACA,IAAI,CACH,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAClE,CAAC;YAEJ,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAExD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;4BACE,IAAI;4BACJ,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;yBAC3B,EACD,IAAI,EACJ,CAAC,CACF;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACnB,KAAK,EAAE,yBAAyB;4BAChC,OAAO,EACL,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;yBACzD,CAAC;qBACH;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-plan.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/get-plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoDvD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { readPlan } from "../../core/plan.js";
|
|
2
|
+
export function registerGetPlan(server) {
|
|
3
|
+
server.tool("get_plan", "Returns the full current plan with summary statistics", {}, async () => {
|
|
4
|
+
try {
|
|
5
|
+
const plan = await readPlan();
|
|
6
|
+
const summary = {
|
|
7
|
+
total: plan.tasks.length,
|
|
8
|
+
done: 0,
|
|
9
|
+
in_progress: 0,
|
|
10
|
+
blocked: 0,
|
|
11
|
+
pending: 0,
|
|
12
|
+
};
|
|
13
|
+
for (const task of plan.tasks) {
|
|
14
|
+
const key = task.status;
|
|
15
|
+
if (key in summary) {
|
|
16
|
+
summary[key]++;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
content: [
|
|
21
|
+
{
|
|
22
|
+
type: "text",
|
|
23
|
+
text: JSON.stringify({
|
|
24
|
+
project: plan.project,
|
|
25
|
+
tasks: plan.tasks,
|
|
26
|
+
proposals: plan.proposals,
|
|
27
|
+
branch: plan.meta.branch,
|
|
28
|
+
summary,
|
|
29
|
+
}, null, 2),
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
return {
|
|
36
|
+
content: [
|
|
37
|
+
{
|
|
38
|
+
type: "text",
|
|
39
|
+
text: JSON.stringify({
|
|
40
|
+
error: "Failed to read plan",
|
|
41
|
+
details: error instanceof Error ? error.message : String(error),
|
|
42
|
+
}),
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
isError: true,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=get-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-plan.js","sourceRoot":"","sources":["../../../src/mcp/tools/get-plan.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,uDAAuD,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE;QAC9F,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG;gBACd,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;gBACxB,IAAI,EAAE,CAAC;gBACP,WAAW,EAAE,CAAC;gBACd,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,CAAC;aACX,CAAC;YAEF,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAoB,CAAC;gBACtC,IAAI,GAAG,IAAI,OAAO,EAAE,CAAC;oBAClB,OAAkC,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7C,CAAC;YACH,CAAC;YAED,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;4BACE,OAAO,EAAE,IAAI,CAAC,OAAO;4BACrB,KAAK,EAAE,IAAI,CAAC,KAAK;4BACjB,SAAS,EAAE,IAAI,CAAC,SAAS;4BACzB,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;4BACxB,OAAO;yBACR,EACD,IAAI,EACJ,CAAC,CACF;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACnB,KAAK,EAAE,qBAAqB;4BAC5B,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;yBAChE,CAAC;qBACH;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"propose-subtasks.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/propose-subtasks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAuF/D"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { readPlan, writePlan, nowISO } from "../../core/plan.js";
|
|
3
|
+
import { generateProposalId } from "../../core/uuid.js";
|
|
4
|
+
export function registerProposeSubtasks(server) {
|
|
5
|
+
server.tool("propose_subtasks", "Agent suggests breaking a task into subtasks. Sets parent task to blocked and creates a proposal awaiting human approval.", {
|
|
6
|
+
task_id: z.string().describe("The parent task ID"),
|
|
7
|
+
reason: z.string().describe("Why decomposition is needed"),
|
|
8
|
+
subtasks: z
|
|
9
|
+
.array(z.object({
|
|
10
|
+
title: z.string(),
|
|
11
|
+
description: z.string(),
|
|
12
|
+
estimated_complexity: z.enum(["s", "m", "l"]),
|
|
13
|
+
}))
|
|
14
|
+
.describe("Proposed subtasks"),
|
|
15
|
+
}, async ({ task_id, reason, subtasks }) => {
|
|
16
|
+
try {
|
|
17
|
+
const plan = await readPlan();
|
|
18
|
+
const task = plan.tasks.find((t) => t.id === task_id);
|
|
19
|
+
if (!task) {
|
|
20
|
+
return {
|
|
21
|
+
content: [
|
|
22
|
+
{
|
|
23
|
+
type: "text",
|
|
24
|
+
text: JSON.stringify({
|
|
25
|
+
error: "task_not_found",
|
|
26
|
+
}),
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
isError: true,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const proposalId = generateProposalId(plan.proposals);
|
|
33
|
+
// Block parent task
|
|
34
|
+
task.status = "blocked";
|
|
35
|
+
task.updated_at = nowISO();
|
|
36
|
+
task.log.push({
|
|
37
|
+
ts: nowISO(),
|
|
38
|
+
actor: task.agent_assignee || "agent",
|
|
39
|
+
event: "proposal_created",
|
|
40
|
+
payload: { proposal_id: proposalId, reason },
|
|
41
|
+
});
|
|
42
|
+
// Create proposal
|
|
43
|
+
plan.proposals.push({
|
|
44
|
+
id: proposalId,
|
|
45
|
+
task_id,
|
|
46
|
+
status: "pending",
|
|
47
|
+
proposed_by: task.agent_assignee || "agent",
|
|
48
|
+
proposed_at: nowISO(),
|
|
49
|
+
subtasks,
|
|
50
|
+
});
|
|
51
|
+
await writePlan(plan);
|
|
52
|
+
return {
|
|
53
|
+
content: [
|
|
54
|
+
{
|
|
55
|
+
type: "text",
|
|
56
|
+
text: JSON.stringify({
|
|
57
|
+
proposal_id: proposalId,
|
|
58
|
+
status: "pending_approval",
|
|
59
|
+
message: `Proposal ${proposalId} created with ${subtasks.length} subtasks. Awaiting human approval via 'wp propose approve ${proposalId}' or TUI.`,
|
|
60
|
+
}),
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
return {
|
|
67
|
+
content: [
|
|
68
|
+
{
|
|
69
|
+
type: "text",
|
|
70
|
+
text: JSON.stringify({
|
|
71
|
+
error: error instanceof Error ? error.message : String(error),
|
|
72
|
+
}),
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
isError: true,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=propose-subtasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"propose-subtasks.js","sourceRoot":"","sources":["../../../src/mcp/tools/propose-subtasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-progress.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/update-progress.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkG9D"}
|