forgepm 0.7.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/dist/bin/forgepm.d.ts +2 -0
- package/dist/bin/forgepm.js +4 -0
- package/dist/bin/forgepm.js.map +1 -0
- package/dist/src/backends/base.d.ts +23 -0
- package/dist/src/backends/base.js +2 -0
- package/dist/src/backends/base.js.map +1 -0
- package/dist/src/backends/http-utils.d.ts +6 -0
- package/dist/src/backends/http-utils.js +36 -0
- package/dist/src/backends/http-utils.js.map +1 -0
- package/dist/src/backends/jira.d.ts +16 -0
- package/dist/src/backends/jira.js +117 -0
- package/dist/src/backends/jira.js.map +1 -0
- package/dist/src/backends/linear.d.ts +11 -0
- package/dist/src/backends/linear.js +85 -0
- package/dist/src/backends/linear.js.map +1 -0
- package/dist/src/cli/archaeology.d.ts +38 -0
- package/dist/src/cli/archaeology.js +182 -0
- package/dist/src/cli/archaeology.js.map +1 -0
- package/dist/src/cli/index.d.ts +1 -0
- package/dist/src/cli/index.js +351 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/core/event-bus.d.ts +17 -0
- package/dist/src/core/event-bus.js +33 -0
- package/dist/src/core/event-bus.js.map +1 -0
- package/dist/src/core/event-plugins.d.ts +6 -0
- package/dist/src/core/event-plugins.js +2 -0
- package/dist/src/core/event-plugins.js.map +1 -0
- package/dist/src/core/forge-ops.d.ts +42 -0
- package/dist/src/core/forge-ops.js +101 -0
- package/dist/src/core/forge-ops.js.map +1 -0
- package/dist/src/core/forge.d.ts +44 -0
- package/dist/src/core/forge.js +86 -0
- package/dist/src/core/forge.js.map +1 -0
- package/dist/src/core/schema.d.ts +8 -0
- package/dist/src/core/schema.js +139 -0
- package/dist/src/core/schema.js.map +1 -0
- package/dist/src/core/store.d.ts +24 -0
- package/dist/src/core/store.js +155 -0
- package/dist/src/core/store.js.map +1 -0
- package/dist/src/core/types.d.ts +91 -0
- package/dist/src/core/types.js +19 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/core/version.d.ts +1 -0
- package/dist/src/core/version.js +20 -0
- package/dist/src/core/version.js.map +1 -0
- package/dist/src/github/pull.d.ts +13 -0
- package/dist/src/github/pull.js +51 -0
- package/dist/src/github/pull.js.map +1 -0
- package/dist/src/github/push.d.ts +20 -0
- package/dist/src/github/push.js +118 -0
- package/dist/src/github/push.js.map +1 -0
- package/dist/src/github/setup.d.ts +10 -0
- package/dist/src/github/setup.js +112 -0
- package/dist/src/github/setup.js.map +1 -0
- package/dist/src/github/slack.d.ts +12 -0
- package/dist/src/github/slack.js +33 -0
- package/dist/src/github/slack.js.map +1 -0
- package/dist/src/index.d.ts +14 -0
- package/dist/src/index.js +9 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mcp/server.d.ts +5 -0
- package/dist/src/mcp/server.js +69 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/mcp/tool-handlers.d.ts +19 -0
- package/dist/src/mcp/tool-handlers.js +123 -0
- package/dist/src/mcp/tool-handlers.js.map +1 -0
- package/dist/src/pm/calibration.d.ts +13 -0
- package/dist/src/pm/calibration.js +56 -0
- package/dist/src/pm/calibration.js.map +1 -0
- package/dist/src/pm/callsheet.d.ts +66 -0
- package/dist/src/pm/callsheet.js +91 -0
- package/dist/src/pm/callsheet.js.map +1 -0
- package/dist/src/pm/drift-detector.d.ts +38 -0
- package/dist/src/pm/drift-detector.js +111 -0
- package/dist/src/pm/drift-detector.js.map +1 -0
- package/dist/src/pm/evm.d.ts +31 -0
- package/dist/src/pm/evm.js +58 -0
- package/dist/src/pm/evm.js.map +1 -0
- package/dist/src/pm/pdca.d.ts +27 -0
- package/dist/src/pm/pdca.js +83 -0
- package/dist/src/pm/pdca.js.map +1 -0
- package/dist/src/pm/recall.d.ts +23 -0
- package/dist/src/pm/recall.js +126 -0
- package/dist/src/pm/recall.js.map +1 -0
- package/dist/src/pm/retrospective.d.ts +35 -0
- package/dist/src/pm/retrospective.js +104 -0
- package/dist/src/pm/retrospective.js.map +1 -0
- package/dist/src/pm/sessions.d.ts +36 -0
- package/dist/src/pm/sessions.js +91 -0
- package/dist/src/pm/sessions.js.map +1 -0
- package/dist/src/pm/tolerances.d.ts +21 -0
- package/dist/src/pm/tolerances.js +54 -0
- package/dist/src/pm/tolerances.js.map +1 -0
- package/dist/src/utils/validation.d.ts +2 -0
- package/dist/src/utils/validation.js +8 -0
- package/dist/src/utils/validation.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
const execFileAsync = promisify(execFile);
|
|
4
|
+
import { validateGitHubName } from '../utils/validation.js';
|
|
5
|
+
export class GitHubPullSync {
|
|
6
|
+
owner;
|
|
7
|
+
repo;
|
|
8
|
+
constructor(owner, repo) {
|
|
9
|
+
this.owner = owner;
|
|
10
|
+
this.repo = repo;
|
|
11
|
+
validateGitHubName(owner, repo);
|
|
12
|
+
}
|
|
13
|
+
async pull(store, bus) {
|
|
14
|
+
const result = { totalFetched: 0, tasksClosed: 0, errors: [] };
|
|
15
|
+
let issues;
|
|
16
|
+
try {
|
|
17
|
+
const { stdout } = await execFileAsync('gh', [
|
|
18
|
+
'issue', 'list',
|
|
19
|
+
'--repo', `${this.owner}/${this.repo}`,
|
|
20
|
+
'--label', 'forge:tracked',
|
|
21
|
+
'--state', 'all',
|
|
22
|
+
'--json', 'number,state,labels,title',
|
|
23
|
+
'--limit', '200',
|
|
24
|
+
]);
|
|
25
|
+
issues = JSON.parse(stdout);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
result.errors.push(`Failed to fetch issues: ${err instanceof Error ? err.message : String(err)}`);
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
result.totalFetched = issues.length;
|
|
32
|
+
// Get all local tasks with github_issue_number
|
|
33
|
+
const localTasks = store.query('SELECT id, status, github_issue_number FROM tasks WHERE github_issue_number IS NOT NULL AND github_issue_number > 0');
|
|
34
|
+
const localByIssue = new Map(localTasks.map(t => [t.github_issue_number, t]));
|
|
35
|
+
for (const issue of issues) {
|
|
36
|
+
const localTask = localByIssue.get(issue.number);
|
|
37
|
+
if (!localTask)
|
|
38
|
+
continue; // Issue not tracked locally
|
|
39
|
+
// Conflict policy: SQLite wins — only process unidirectional events
|
|
40
|
+
// If GitHub issue is closed but local task is not done/blocked, mark it done
|
|
41
|
+
if (issue.state === 'closed' && localTask.status !== 'done' && localTask.status !== 'blocked') {
|
|
42
|
+
store.run('UPDATE tasks SET status = ?, updated_at = datetime("now") WHERE id = ?', ['done', localTask.id]);
|
|
43
|
+
bus.publish({ type: 'pull.task_closed', taskId: localTask.id, issueNumber: issue.number });
|
|
44
|
+
result.tasksClosed++;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
bus.publish({ type: 'pull.completed', synced: result.tasksClosed });
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=pull.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.js","sourceRoot":"","sources":["../../../src/github/pull.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAItC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAe1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,OAAO,cAAc;IAEf;IACA;IAFV,YACU,KAAa,EACb,IAAY;QADZ,UAAK,GAAL,KAAK,CAAQ;QACb,SAAI,GAAJ,IAAI,CAAQ;QAEpB,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAmB,EAAE,GAAa;QAC3C,MAAM,MAAM,GAAe,EAAE,YAAY,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAE3E,IAAI,MAAqB,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE;gBAC3C,OAAO,EAAE,MAAM;gBACf,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE;gBACtC,SAAS,EAAE,eAAe;gBAC1B,SAAS,EAAE,KAAK;gBAChB,QAAQ,EAAE,2BAA2B;gBACrC,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAkB,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAClG,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;QAEpC,+CAA+C;QAC/C,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAC5B,qHAAqH,CACtH,CAAC;QAEF,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAE9E,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACjD,IAAI,CAAC,SAAS;gBAAE,SAAS,CAAC,4BAA4B;YAEtD,oEAAoE;YACpE,6EAA6E;YAC7E,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,KAAK,MAAM,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC9F,KAAK,CAAC,GAAG,CAAC,wEAAwE,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC5G,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC3F,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,CAAC;QACH,CAAC;QAED,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QACpE,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { OverlayStore } from '../core/store.js';
|
|
2
|
+
interface PushTask {
|
|
3
|
+
id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
status: string;
|
|
6
|
+
complexity: number;
|
|
7
|
+
github_issue_number?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare class GitHubPushSync {
|
|
10
|
+
private owner;
|
|
11
|
+
private repo;
|
|
12
|
+
private projectNumber;
|
|
13
|
+
constructor(owner: string, repo: string, projectNumber: number);
|
|
14
|
+
pushTask(task: PushTask): Promise<number>;
|
|
15
|
+
closeTask(issueNumber: number): Promise<void>;
|
|
16
|
+
updateProjectField(_itemId: string, _fieldId: string, _value: string | number): Promise<void>;
|
|
17
|
+
processSyncOutbox(store: OverlayStore): Promise<number>;
|
|
18
|
+
private statusToLabel;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
const execFileAsync = promisify(execFile);
|
|
4
|
+
import { validateGitHubName } from '../utils/validation.js';
|
|
5
|
+
export class GitHubPushSync {
|
|
6
|
+
owner;
|
|
7
|
+
repo;
|
|
8
|
+
projectNumber;
|
|
9
|
+
constructor(owner, repo, projectNumber) {
|
|
10
|
+
this.owner = owner;
|
|
11
|
+
this.repo = repo;
|
|
12
|
+
this.projectNumber = projectNumber;
|
|
13
|
+
validateGitHubName(owner, repo);
|
|
14
|
+
}
|
|
15
|
+
async pushTask(task) {
|
|
16
|
+
const repoFlag = `${this.owner}/${this.repo}`;
|
|
17
|
+
if (!task.github_issue_number) {
|
|
18
|
+
// Create new issue
|
|
19
|
+
const { stdout } = await execFileAsync('gh', [
|
|
20
|
+
'issue',
|
|
21
|
+
'create',
|
|
22
|
+
'--repo',
|
|
23
|
+
repoFlag,
|
|
24
|
+
'--title',
|
|
25
|
+
task.title,
|
|
26
|
+
'--body',
|
|
27
|
+
`ForgePM task \`${task.id}\`\nStatus: ${task.status}\nComplexity: ${task.complexity}`,
|
|
28
|
+
'--label',
|
|
29
|
+
'forge:tracked',
|
|
30
|
+
]);
|
|
31
|
+
// gh issue create outputs the issue URL on stdout
|
|
32
|
+
const match = stdout.trim().match(/\/issues\/(\d+)/);
|
|
33
|
+
if (!match)
|
|
34
|
+
throw new Error(`Failed to parse issue URL from gh output: ${stdout.trim()}`);
|
|
35
|
+
return parseInt(match[1], 10);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
// Update existing issue — update title and labels via gh issue edit
|
|
39
|
+
const statusLabel = this.statusToLabel(task.status);
|
|
40
|
+
const editArgs = [
|
|
41
|
+
'issue',
|
|
42
|
+
'edit',
|
|
43
|
+
String(task.github_issue_number),
|
|
44
|
+
'--repo',
|
|
45
|
+
repoFlag,
|
|
46
|
+
'--title',
|
|
47
|
+
task.title,
|
|
48
|
+
'--body',
|
|
49
|
+
`ForgePM task \`${task.id}\`\nStatus: ${task.status}\nComplexity: ${task.complexity}`,
|
|
50
|
+
];
|
|
51
|
+
if (statusLabel) {
|
|
52
|
+
editArgs.push('--add-label', statusLabel);
|
|
53
|
+
}
|
|
54
|
+
await execFileAsync('gh', editArgs);
|
|
55
|
+
return task.github_issue_number;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async closeTask(issueNumber) {
|
|
59
|
+
await execFileAsync('gh', [
|
|
60
|
+
'issue',
|
|
61
|
+
'close',
|
|
62
|
+
String(issueNumber),
|
|
63
|
+
'--repo',
|
|
64
|
+
`${this.owner}/${this.repo}`,
|
|
65
|
+
]);
|
|
66
|
+
}
|
|
67
|
+
// TODO v0.2: implement full Projects V2 field updates using item IDs + field IDs
|
|
68
|
+
// For MVP, label-based updates are used in pushTask instead.
|
|
69
|
+
async updateProjectField(_itemId, _fieldId, _value) {
|
|
70
|
+
// Placeholder — Projects V2 field updates require resolving item node IDs
|
|
71
|
+
// and field node IDs via GraphQL, which is out of scope for MVP.
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
async processSyncOutbox(store) {
|
|
75
|
+
const pending = store.query(`SELECT id, entity_type, entity_id, operation, payload
|
|
76
|
+
FROM sync_outbox
|
|
77
|
+
WHERE synced_at IS NULL
|
|
78
|
+
ORDER BY id ASC`);
|
|
79
|
+
let synced = 0;
|
|
80
|
+
for (const row of pending) {
|
|
81
|
+
try {
|
|
82
|
+
const payload = JSON.parse(row.payload);
|
|
83
|
+
if (row.entity_type === 'task') {
|
|
84
|
+
if (row.operation === 'upsert') {
|
|
85
|
+
await this.pushTask({
|
|
86
|
+
id: row.entity_id,
|
|
87
|
+
title: payload['title'] ?? row.entity_id,
|
|
88
|
+
status: payload['status'] ?? 'backlog',
|
|
89
|
+
complexity: payload['complexity'] ?? 1,
|
|
90
|
+
github_issue_number: payload['github_issue_number'],
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
else if (row.operation === 'close') {
|
|
94
|
+
const issueNumber = payload['github_issue_number'];
|
|
95
|
+
if (issueNumber) {
|
|
96
|
+
await this.closeTask(issueNumber);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
store.run(`UPDATE sync_outbox SET synced_at = datetime('now') WHERE id = ?`, [row.id]);
|
|
101
|
+
synced++;
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
console.error(`[push] Failed to sync outbox item ${row.id}:`, err);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return synced;
|
|
108
|
+
}
|
|
109
|
+
statusToLabel(status) {
|
|
110
|
+
const map = {
|
|
111
|
+
in_progress: 'forge:tracked',
|
|
112
|
+
done: 'forge:tracked',
|
|
113
|
+
blocked: 'forge:breach',
|
|
114
|
+
};
|
|
115
|
+
return map[status] ?? null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../../src/github/push.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface GitHubSetupResult {
|
|
2
|
+
projectNumber: number;
|
|
3
|
+
fieldsCreated: string[];
|
|
4
|
+
labelsCreated: string[];
|
|
5
|
+
}
|
|
6
|
+
export declare function setupGitHubProject(owner: string, repo: string): Promise<GitHubSetupResult>;
|
|
7
|
+
export declare function detectGitHubRemote(): Promise<{
|
|
8
|
+
owner: string;
|
|
9
|
+
repo: string;
|
|
10
|
+
} | null>;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
const execFileAsync = promisify(execFile);
|
|
4
|
+
const CUSTOM_FIELDS = [
|
|
5
|
+
{ name: 'Agent', type: 'SINGLE_SELECT', options: ['pm', 'dev-1', 'dev-2', 'qa'] },
|
|
6
|
+
{ name: 'Complexity', type: 'NUMBER' },
|
|
7
|
+
{ name: 'SPI', type: 'NUMBER' },
|
|
8
|
+
{ name: 'CPI', type: 'NUMBER' },
|
|
9
|
+
{ name: 'TokenBudget', type: 'NUMBER' },
|
|
10
|
+
{ name: 'TokensSpent', type: 'NUMBER' },
|
|
11
|
+
{
|
|
12
|
+
name: 'PDCAPhase',
|
|
13
|
+
type: 'SINGLE_SELECT',
|
|
14
|
+
options: ['plan', 'do', 'check', 'act', 'done'],
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
const LABELS = [
|
|
18
|
+
{ name: 'agent:pm', color: '0075ca' },
|
|
19
|
+
{ name: 'agent:dev-1', color: '00b4d8' },
|
|
20
|
+
{ name: 'agent:dev-2', color: '48cae4' },
|
|
21
|
+
{ name: 'agent:qa', color: '90e0ef' },
|
|
22
|
+
{ name: 'forge:tracked', color: '2ea44f' },
|
|
23
|
+
{ name: 'forge:breach', color: 'd93f0b' },
|
|
24
|
+
{ name: 'forge:escalated', color: 'e4e669' },
|
|
25
|
+
{ name: 'priority:high', color: 'b60205' },
|
|
26
|
+
{ name: 'priority:medium', color: 'fbca04' },
|
|
27
|
+
{ name: 'priority:low', color: '0e8a16' },
|
|
28
|
+
];
|
|
29
|
+
import { validateGitHubName } from '../utils/validation.js';
|
|
30
|
+
export async function setupGitHubProject(owner, repo) {
|
|
31
|
+
validateGitHubName(owner, repo);
|
|
32
|
+
// 1. Create GitHub Project V2
|
|
33
|
+
const { stdout: createOut } = await execFileAsync('gh', [
|
|
34
|
+
'project',
|
|
35
|
+
'create',
|
|
36
|
+
'--owner',
|
|
37
|
+
owner,
|
|
38
|
+
'--title',
|
|
39
|
+
`ForgePM: ${repo}`,
|
|
40
|
+
'--format',
|
|
41
|
+
'json',
|
|
42
|
+
]);
|
|
43
|
+
const projectData = JSON.parse(createOut);
|
|
44
|
+
const projectNumber = projectData.number;
|
|
45
|
+
// 2. Create custom fields
|
|
46
|
+
const fieldsCreated = [];
|
|
47
|
+
for (const field of CUSTOM_FIELDS) {
|
|
48
|
+
try {
|
|
49
|
+
const args = [
|
|
50
|
+
'project',
|
|
51
|
+
'field-create',
|
|
52
|
+
String(projectNumber),
|
|
53
|
+
'--owner',
|
|
54
|
+
owner,
|
|
55
|
+
'--name',
|
|
56
|
+
field.name,
|
|
57
|
+
'--data-type',
|
|
58
|
+
field.type,
|
|
59
|
+
];
|
|
60
|
+
if (field.options && field.options.length > 0) {
|
|
61
|
+
args.push('--single-select-options', field.options.join(','));
|
|
62
|
+
}
|
|
63
|
+
await execFileAsync('gh', args);
|
|
64
|
+
fieldsCreated.push(field.name);
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
console.error(`[setup] Failed to create field ${field.name}:`, err);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// 3. Create labels
|
|
71
|
+
const labelsCreated = [];
|
|
72
|
+
for (const label of LABELS) {
|
|
73
|
+
try {
|
|
74
|
+
await execFileAsync('gh', [
|
|
75
|
+
'label',
|
|
76
|
+
'create',
|
|
77
|
+
label.name,
|
|
78
|
+
'--repo',
|
|
79
|
+
`${owner}/${repo}`,
|
|
80
|
+
'--color',
|
|
81
|
+
label.color,
|
|
82
|
+
'--force',
|
|
83
|
+
]);
|
|
84
|
+
labelsCreated.push(label.name);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
console.error(`[setup] Failed to create label ${label.name}:`, err);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return { projectNumber, fieldsCreated, labelsCreated };
|
|
91
|
+
}
|
|
92
|
+
export async function detectGitHubRemote() {
|
|
93
|
+
try {
|
|
94
|
+
const { stdout } = await execFileAsync('git', ['remote', 'get-url', 'origin']);
|
|
95
|
+
const url = stdout.trim();
|
|
96
|
+
// SSH: git@github.com:owner/repo.git
|
|
97
|
+
const sshMatch = url.match(/^git@github\.com:([^/]+)\/([^.]+?)(?:\.git)?$/);
|
|
98
|
+
if (sshMatch) {
|
|
99
|
+
return { owner: sshMatch[1], repo: sshMatch[2] };
|
|
100
|
+
}
|
|
101
|
+
// HTTPS: https://github.com/owner/repo.git
|
|
102
|
+
const httpsMatch = url.match(/^https:\/\/github\.com\/([^/]+)\/([^.]+?)(?:\.git)?$/);
|
|
103
|
+
if (httpsMatch) {
|
|
104
|
+
return { owner: httpsMatch[1], repo: httpsMatch[2] };
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/github/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAQ1C,MAAM,aAAa,GAAkF;IACnG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;IACjF,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE;IACtC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC/B,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC/B,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE;IACvC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE;IACvC;QACE,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC;KAChD;CACF,CAAC;AAEF,MAAM,MAAM,GAA2C;IACrD,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE;IACrC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE;IACxC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE;IACxC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE;IACrC,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,QAAQ,EAAE;IAC1C,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE;IACzC,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,QAAQ,EAAE;IAC5C,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,QAAQ,EAAE;IAC1C,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,QAAQ,EAAE;IAC5C,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE;CAC1C,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAa,EACb,IAAY;IAEZ,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAChC,8BAA8B;IAC9B,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE;QACtD,SAAS;QACT,QAAQ;QACR,SAAS;QACT,KAAK;QACL,SAAS;QACT,YAAY,IAAI,EAAE;QAClB,UAAU;QACV,MAAM;KACP,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAuB,CAAC;IAChE,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,CAAC;IAEzC,0BAA0B;IAC1B,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG;gBACX,SAAS;gBACT,cAAc;gBACd,MAAM,CAAC,aAAa,CAAC;gBACrB,SAAS;gBACT,KAAK;gBACL,QAAQ;gBACR,KAAK,CAAC,IAAI;gBACV,aAAa;gBACb,KAAK,CAAC,IAAI;aACX,CAAC;YACF,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9C,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAChE,CAAC;YACD,MAAM,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAChC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,kCAAkC,KAAK,CAAC,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,IAAI,EAAE;gBACxB,OAAO;gBACP,QAAQ;gBACR,KAAK,CAAC,IAAI;gBACV,QAAQ;gBACR,GAAG,KAAK,IAAI,IAAI,EAAE;gBAClB,SAAS;gBACT,KAAK,CAAC,KAAK;gBACX,SAAS;aACV,CAAC,CAAC;YACH,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,kCAAkC,KAAK,CAAC,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;AACzD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC/E,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAE1B,qCAAqC;QACrC,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;QAC5E,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAE,EAAE,CAAC;QACrD,CAAC;QAED,2CAA2C;QAC3C,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;QACrF,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAE,EAAE,CAAC;QACzD,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface SlackMessage {
|
|
2
|
+
text: string;
|
|
3
|
+
blocks?: unknown[];
|
|
4
|
+
}
|
|
5
|
+
export declare function postToSlack(webhookUrl: string, message: SlackMessage): Promise<boolean>;
|
|
6
|
+
export declare function formatBreachAlert(taskId: string, dimension: string, actual: number, limit: number): SlackMessage;
|
|
7
|
+
export declare function formatSessionSummary(summary: {
|
|
8
|
+
goal: string;
|
|
9
|
+
tasksCompleted: number;
|
|
10
|
+
tokensSpent: number;
|
|
11
|
+
velocityPoints: number;
|
|
12
|
+
}): SlackMessage;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export async function postToSlack(webhookUrl, message) {
|
|
2
|
+
try {
|
|
3
|
+
const response = await fetch(webhookUrl, {
|
|
4
|
+
method: 'POST',
|
|
5
|
+
headers: { 'Content-Type': 'application/json' },
|
|
6
|
+
body: JSON.stringify(message),
|
|
7
|
+
});
|
|
8
|
+
if (!response.ok) {
|
|
9
|
+
console.error(`[slack] POST failed: ${response.status} ${response.statusText}`);
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
console.error('[slack] POST error:', err);
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function formatBreachAlert(taskId, dimension, actual, limit) {
|
|
20
|
+
const text = `🚨 *Tolerance Breach* — task \`${taskId}\`\n` +
|
|
21
|
+
` Dimension: *${dimension}*\n` +
|
|
22
|
+
` Actual: ${actual} | Limit: ${limit}`;
|
|
23
|
+
return { text };
|
|
24
|
+
}
|
|
25
|
+
export function formatSessionSummary(summary) {
|
|
26
|
+
const text = `✅ *Session Complete*\n` +
|
|
27
|
+
` Goal: ${summary.goal}\n` +
|
|
28
|
+
` Tasks completed: ${summary.tasksCompleted}\n` +
|
|
29
|
+
` Tokens spent: ${summary.tokensSpent}\n` +
|
|
30
|
+
` Velocity points: ${summary.velocityPoints}`;
|
|
31
|
+
return { text };
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=slack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../../../src/github/slack.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAAkB,EAAE,OAAqB;IACzE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE;YACvC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,wBAAwB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YAChF,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,MAAc,EACd,SAAiB,EACjB,MAAc,EACd,KAAa;IAEb,MAAM,IAAI,GACR,kCAAkC,MAAM,MAAM;QAC9C,iBAAiB,SAAS,KAAK;QAC/B,aAAa,MAAM,eAAe,KAAK,EAAE,CAAC;IAC5C,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAKpC;IACC,MAAM,IAAI,GACR,wBAAwB;QACxB,WAAW,OAAO,CAAC,IAAI,IAAI;QAC3B,sBAAsB,OAAO,CAAC,cAAc,IAAI;QAChD,mBAAmB,OAAO,CAAC,WAAW,IAAI;QAC1C,sBAAsB,OAAO,CAAC,cAAc,EAAE,CAAC;IACjD,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { createForge } from './core/forge.js';
|
|
2
|
+
export type { ForgeInstance } from './core/forge.js';
|
|
3
|
+
export { startMcpServer, createMcpServer } from './mcp/server.js';
|
|
4
|
+
export type { ForgeConfig, DomainEvent, Result, ModelTier, TaskStatus, PdcaPhase, ToleranceStatus, EvmHealth, TolerancePreset, } from './core/types.js';
|
|
5
|
+
export { DEFAULT_CONFIG, getModelTier } from './core/types.js';
|
|
6
|
+
export type { CallSheet, InternalMetrics } from './pm/callsheet.js';
|
|
7
|
+
export type { Session, SessionSummary } from './pm/sessions.js';
|
|
8
|
+
export { RecallEngine } from './pm/recall.js';
|
|
9
|
+
export type { RecallResult, RecallParams } from './pm/recall.js';
|
|
10
|
+
export type { EventPlugin } from './core/event-plugins.js';
|
|
11
|
+
export { fetchWithRetry, HttpError } from './backends/http-utils.js';
|
|
12
|
+
export type { BackendAdapter, TaskData, ExternalUpdate } from './backends/base.js';
|
|
13
|
+
export { LinearBackend } from './backends/linear.js';
|
|
14
|
+
export { JiraBackend } from './backends/jira.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Public API — re-exports for consumers of the forgepm package
|
|
2
|
+
export { createForge } from './core/forge.js';
|
|
3
|
+
export { startMcpServer, createMcpServer } from './mcp/server.js';
|
|
4
|
+
export { DEFAULT_CONFIG, getModelTier } from './core/types.js';
|
|
5
|
+
export { RecallEngine } from './pm/recall.js';
|
|
6
|
+
export { fetchWithRetry, HttpError } from './backends/http-utils.js';
|
|
7
|
+
export { LinearBackend } from './backends/linear.js';
|
|
8
|
+
export { JiraBackend } from './backends/jira.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAclE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAK/D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { type ForgeInstance } from '../core/forge.js';
|
|
3
|
+
import type { ForgeConfig } from '../core/types.js';
|
|
4
|
+
export declare function createMcpServer(forge: ForgeInstance): McpServer;
|
|
5
|
+
export declare function startMcpServer(dbPath: string, config?: Partial<ForgeConfig>): Promise<McpServer>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { createForge } from '../core/forge.js';
|
|
5
|
+
import { VERSION } from '../core/version.js';
|
|
6
|
+
import { handleStatus, handleStart, handleDone, handleSession, handleEscalate, handleCreate, handleDecompose, handleRecall, handleRetro } from './tool-handlers.js';
|
|
7
|
+
function registerTools(server, forge) {
|
|
8
|
+
server.tool('forge_status', 'Get project status, progress, and next recommended action', {
|
|
9
|
+
include_internal: z.boolean().optional().describe('Include SPI/CPI metrics for agent use'),
|
|
10
|
+
}, async ({ include_internal }) => handleStatus(forge, include_internal));
|
|
11
|
+
server.tool('forge_start', 'Start a PDCA cycle on a task, initialising EVM baseline and model-tier selection', {
|
|
12
|
+
task_id: z.string().describe('The task ID to start (e.g. TASK-001)'),
|
|
13
|
+
complexity: z.number().int().min(1).max(10).optional().describe('Override complexity score 1-10'),
|
|
14
|
+
}, async ({ task_id, complexity }) => handleStart(forge, task_id, complexity));
|
|
15
|
+
server.tool('forge_done', 'Mark a task complete, record actual tokens, update EVM metrics', {
|
|
16
|
+
task_id: z.string().describe('The task ID to complete'),
|
|
17
|
+
actual_tokens: z.number().int().positive().optional().describe('Total tokens used (legacy). Prefer input_tokens + output_tokens.'),
|
|
18
|
+
input_tokens: z.number().int().nonnegative().optional().describe('Input tokens from LLM response usage field'),
|
|
19
|
+
output_tokens: z.number().int().nonnegative().optional().describe('Output tokens from LLM response usage field'),
|
|
20
|
+
notes: z.string().optional().describe('Optional completion notes'),
|
|
21
|
+
}, async ({ task_id, actual_tokens, input_tokens, output_tokens, notes }) => handleDone(forge, task_id, actual_tokens, input_tokens, output_tokens, notes));
|
|
22
|
+
server.tool('forge_session', 'Manage work sessions: start, end, or get current status', {
|
|
23
|
+
action: z.enum(['start', 'end', 'status']).describe('"start" | "end" | "status"'),
|
|
24
|
+
goal: z.string().optional().describe('Session goal (required for action=start)'),
|
|
25
|
+
token_budget: z.number().int().positive().optional().describe('Token budget for this session'),
|
|
26
|
+
}, async ({ action, goal, token_budget }) => handleSession(forge, action, goal, token_budget));
|
|
27
|
+
server.tool('forge_escalate', 'Report a tolerance breach or blocking issue, get exception report with options', {
|
|
28
|
+
task_id: z.string().describe('The task ID that encountered the issue'),
|
|
29
|
+
reason: z.string().describe('Description of what went wrong'),
|
|
30
|
+
failure_type: z.enum(['reasoning', 'prompt', 'task_definition', 'unknown']).optional().describe('Type of failure for PDCA routing'),
|
|
31
|
+
}, async ({ task_id, reason, failure_type }) => handleEscalate(forge, task_id, reason, failure_type));
|
|
32
|
+
server.tool('forge_create', 'Create a task, story, or epic in the project backlog', {
|
|
33
|
+
type: z.enum(['task', 'story', 'epic']).describe('"task" | "story" | "epic"'),
|
|
34
|
+
title: z.string().describe('Title of the item'),
|
|
35
|
+
complexity: z.number().int().min(1).max(10).optional().describe('Complexity 1-10 (tasks only, default 3)'),
|
|
36
|
+
why: z.string().optional().describe('Rationale / user value'),
|
|
37
|
+
story_id: z.string().optional().describe('Parent story ID for tasks'),
|
|
38
|
+
depends_on: z.array(z.string()).optional().describe('List of dependency task IDs'),
|
|
39
|
+
}, async ({ type, title, complexity, why, story_id, depends_on }) => handleCreate(forge, type, title, complexity, why, story_id, depends_on));
|
|
40
|
+
server.tool('forge_recall', 'Search project knowledge: tasks, sessions, failure patterns, lessons learned', {
|
|
41
|
+
query: z.string().min(1).describe('Free-text search query'),
|
|
42
|
+
entity_types: z.array(z.enum(['task', 'story', 'epic', 'session', 'pdca', 'lesson'])).optional().describe('Filter by entity type. Default: all'),
|
|
43
|
+
status_filter: z.string().optional().describe('Filter by task status (e.g. "done", "blocked"). Applies to tasks only.'),
|
|
44
|
+
limit: z.number().int().min(1).max(50).optional().describe('Max results (default 10)'),
|
|
45
|
+
include_failures: z.boolean().optional().describe('Include PDCA failure patterns'),
|
|
46
|
+
}, async ({ query, entity_types, status_filter, limit, include_failures }) => handleRecall(forge, query, entity_types, status_filter, limit, include_failures));
|
|
47
|
+
server.tool('forge_retro', 'Generate a retrospective report for a session: progress, EVM, lessons, recommendations', {
|
|
48
|
+
session_id: z.string().optional().describe('Session ID. Omit for most recent session.'),
|
|
49
|
+
format: z.enum(['json', 'markdown']).optional().describe('Output format (default: json)'),
|
|
50
|
+
}, async ({ session_id, format }) => handleRetro(forge, session_id, format));
|
|
51
|
+
server.tool('forge_decompose', 'Decompose a feature description into tasks — returns hints for agent to create sub-tasks', {
|
|
52
|
+
description: z.string().describe('Feature or work item description'),
|
|
53
|
+
max_complexity: z.number().int().min(1).max(10).optional().describe('Max complexity per task (default 5)'),
|
|
54
|
+
max_tasks: z.number().int().positive().optional().describe('Maximum number of tasks to create (default 5)'),
|
|
55
|
+
}, async ({ description, max_complexity, max_tasks }) => handleDecompose(forge, description, max_complexity, max_tasks));
|
|
56
|
+
}
|
|
57
|
+
export function createMcpServer(forge) {
|
|
58
|
+
const server = new McpServer({ name: 'forgepm', version: VERSION });
|
|
59
|
+
registerTools(server, forge);
|
|
60
|
+
return server;
|
|
61
|
+
}
|
|
62
|
+
export async function startMcpServer(dbPath, config) {
|
|
63
|
+
const forge = await createForge(dbPath, config);
|
|
64
|
+
const server = createMcpServer(forge);
|
|
65
|
+
const transport = new StdioServerTransport();
|
|
66
|
+
await server.connect(transport);
|
|
67
|
+
return server;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ForgeInstance } from '../core/forge.js';
|
|
2
|
+
import type { FailureType } from '../pm/pdca.js';
|
|
3
|
+
export interface ToolResult {
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
content: Array<{
|
|
6
|
+
type: 'text';
|
|
7
|
+
text: string;
|
|
8
|
+
}>;
|
|
9
|
+
isError?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function handleStatus(forge: ForgeInstance, includeInternal?: boolean): ToolResult;
|
|
12
|
+
export declare function handleStart(forge: ForgeInstance, taskId: string, complexity?: number): ToolResult;
|
|
13
|
+
export declare function handleDone(forge: ForgeInstance, taskId: string, actualTokens?: number, inputTokens?: number, outputTokens?: number, notes?: string): ToolResult;
|
|
14
|
+
export declare function handleSession(forge: ForgeInstance, action: string, goal?: string, tokenBudget?: number): ToolResult;
|
|
15
|
+
export declare function handleEscalate(forge: ForgeInstance, taskId: string, reason: string, failureType?: FailureType): ToolResult;
|
|
16
|
+
export declare function handleCreate(forge: ForgeInstance, type: string, title: string, complexity?: number, why?: string, storyId?: string, dependsOn?: string[]): ToolResult;
|
|
17
|
+
export declare function handleRecall(forge: ForgeInstance, query: string, entityTypes?: string[], statusFilter?: string, limit?: number, includeFailures?: boolean): ToolResult;
|
|
18
|
+
export declare function handleRetro(forge: ForgeInstance, sessionId?: string, format?: string): ToolResult;
|
|
19
|
+
export declare function handleDecompose(_forge: ForgeInstance, description: string, maxComplexity?: number, _maxTasks?: number): ToolResult;
|