@anyforge/mcp-server 2.5.0 → 3.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/README.md +186 -13
- package/dist/index.js +258 -95
- package/package.json +7 -6
- package/dist/index.d.ts +0 -20
- package/dist/index.js.map +0 -1
- package/dist/lib/apiClient.d.ts +0 -20
- package/dist/lib/apiClient.js +0 -64
- package/dist/lib/apiClient.js.map +0 -1
- package/dist/lib/credentials.d.ts +0 -20
- package/dist/lib/credentials.js +0 -33
- package/dist/lib/credentials.js.map +0 -1
- package/dist/prompts/genesis.d.ts +0 -3
- package/dist/prompts/genesis.js +0 -68
- package/dist/prompts/genesis.js.map +0 -1
- package/dist/tools/coverage.d.ts +0 -12
- package/dist/tools/coverage.js +0 -62
- package/dist/tools/coverage.js.map +0 -1
- package/dist/tools/crews.d.ts +0 -6
- package/dist/tools/crews.js +0 -82
- package/dist/tools/crews.js.map +0 -1
- package/dist/tools/hil.d.ts +0 -7
- package/dist/tools/hil.js +0 -56
- package/dist/tools/hil.js.map +0 -1
- package/dist/tools/initiatives.d.ts +0 -7
- package/dist/tools/initiatives.js +0 -115
- package/dist/tools/initiatives.js.map +0 -1
- package/dist/tools/programs.d.ts +0 -5
- package/dist/tools/programs.js +0 -82
- package/dist/tools/programs.js.map +0 -1
- package/dist/tools/repos.d.ts +0 -11
- package/dist/tools/repos.js +0 -120
- package/dist/tools/repos.js.map +0 -1
- package/dist/tools/types.d.ts +0 -39
- package/dist/tools/types.js +0 -9
- package/dist/tools/types.js.map +0 -1
- package/dist/tools/work.d.ts +0 -5
- package/dist/tools/work.js +0 -104
- package/dist/tools/work.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anyforge/mcp-server",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "AnyForge MCP Server — drive AnyForge (HIL approvals, initiatives, work items, crews) from Claude CLI, Cursor, and other MCP clients",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
"README.md"
|
|
13
13
|
],
|
|
14
14
|
"engines": {
|
|
15
|
-
"node": ">=
|
|
15
|
+
"node": ">=22"
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
|
-
"build": "
|
|
18
|
+
"build": "esbuild index.ts --bundle --minify --platform=node --format=esm --outfile=dist/index.js --packages=external",
|
|
19
19
|
"type-check": "tsc --noEmit",
|
|
20
20
|
"prepublishOnly": "npm run build",
|
|
21
21
|
"start": "npx tsx index.ts",
|
|
@@ -33,10 +33,11 @@
|
|
|
33
33
|
],
|
|
34
34
|
"license": "UNLICENSED",
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
36
|
+
"@modelcontextprotocol/sdk": "^1.30.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@types/node": "^20.
|
|
40
|
-
"
|
|
39
|
+
"@types/node": "^22.20.0",
|
|
40
|
+
"esbuild": "^0.25.0",
|
|
41
|
+
"typescript": "^7.0.2"
|
|
41
42
|
}
|
|
42
43
|
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* AnyForge MCP Server
|
|
4
|
-
*
|
|
5
|
-
* Exposes AnyForge platform control as MCP tools so Claude CLI (Claude
|
|
6
|
-
* Code), Cursor, and other MCP clients can drive the platform: view and
|
|
7
|
-
* approve HIL notifications, read programs / initiatives / work items,
|
|
8
|
-
* add and modify work items, see crew outputs, and interact with crews.
|
|
9
|
-
*
|
|
10
|
-
* This process holds ZERO business logic — every tool is a thin call to
|
|
11
|
-
* the key-authenticated control API (/api/v1/control/*). Auth is the
|
|
12
|
-
* long-lived `sk_anyforge_` key from `~/.anyforge/credentials` (written
|
|
13
|
-
* by `npx @anyforge/control init`) or the ANYFORGE_API_TOKEN env var.
|
|
14
|
-
*
|
|
15
|
-
* Register with Claude CLI:
|
|
16
|
-
* claude mcp add anyforge -- npx tsx <abs path>/index.ts
|
|
17
|
-
*
|
|
18
|
-
* See README.md for full setup.
|
|
19
|
-
*/
|
|
20
|
-
export {};
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/apiClient.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Thin typed client over the AnyForge control API (/api/v1/control/*).
|
|
3
|
-
*
|
|
4
|
-
* The MCP server holds zero business logic — every tool handler calls
|
|
5
|
-
* callControl() and forwards the JSON. Auth is the long-lived
|
|
6
|
-
* sk_anyforge_ key resolved once and cached for the process lifetime.
|
|
7
|
-
*
|
|
8
|
-
* The control API speaks a `{ ok, data | error }` envelope. We unwrap
|
|
9
|
-
* it: on `ok` return `data`; otherwise throw a ControlApiError carrying
|
|
10
|
-
* the stable error code so the MCP layer surfaces an actionable message
|
|
11
|
-
* to Claude instead of a raw HTTP failure.
|
|
12
|
-
*/
|
|
13
|
-
export declare class ControlApiError extends Error {
|
|
14
|
-
readonly code: string;
|
|
15
|
-
readonly status: number;
|
|
16
|
-
constructor(code: string, status: number, detail?: string);
|
|
17
|
-
}
|
|
18
|
-
export declare function callControl<T = unknown>(method: 'GET' | 'POST' | 'PATCH' | 'DELETE', path: string, body?: unknown): Promise<T>;
|
|
19
|
-
/** Build a `?a=b&c=d` query string from defined values only. */
|
|
20
|
-
export declare function qs(params: Record<string, string | number | boolean | undefined>): string;
|
package/dist/lib/apiClient.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { resolveCredentials } from './credentials.js';
|
|
2
|
-
/**
|
|
3
|
-
* Thin typed client over the AnyForge control API (/api/v1/control/*).
|
|
4
|
-
*
|
|
5
|
-
* The MCP server holds zero business logic — every tool handler calls
|
|
6
|
-
* callControl() and forwards the JSON. Auth is the long-lived
|
|
7
|
-
* sk_anyforge_ key resolved once and cached for the process lifetime.
|
|
8
|
-
*
|
|
9
|
-
* The control API speaks a `{ ok, data | error }` envelope. We unwrap
|
|
10
|
-
* it: on `ok` return `data`; otherwise throw a ControlApiError carrying
|
|
11
|
-
* the stable error code so the MCP layer surfaces an actionable message
|
|
12
|
-
* to Claude instead of a raw HTTP failure.
|
|
13
|
-
*/
|
|
14
|
-
export class ControlApiError extends Error {
|
|
15
|
-
code;
|
|
16
|
-
status;
|
|
17
|
-
constructor(code, status, detail) {
|
|
18
|
-
super(detail ? `${code}: ${detail}` : code);
|
|
19
|
-
this.name = 'ControlApiError';
|
|
20
|
-
this.code = code;
|
|
21
|
-
this.status = status;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
let cached = null;
|
|
25
|
-
async function creds() {
|
|
26
|
-
if (!cached)
|
|
27
|
-
cached = await resolveCredentials();
|
|
28
|
-
return cached;
|
|
29
|
-
}
|
|
30
|
-
export async function callControl(method, path, body) {
|
|
31
|
-
const { apiKey, endpoint } = await creds();
|
|
32
|
-
const url = `${endpoint.replace(/\/$/, '')}/api/v1/control${path}`;
|
|
33
|
-
const res = await fetch(url, {
|
|
34
|
-
method,
|
|
35
|
-
headers: {
|
|
36
|
-
'Content-Type': 'application/json',
|
|
37
|
-
Authorization: `Bearer ${apiKey}`,
|
|
38
|
-
},
|
|
39
|
-
...(body !== undefined ? { body: JSON.stringify(body) } : {}),
|
|
40
|
-
});
|
|
41
|
-
let json;
|
|
42
|
-
try {
|
|
43
|
-
json = await res.json();
|
|
44
|
-
}
|
|
45
|
-
catch {
|
|
46
|
-
throw new ControlApiError('invalid_response', res.status, `non-JSON response from ${url}`);
|
|
47
|
-
}
|
|
48
|
-
if (!res.ok || json.ok === false) {
|
|
49
|
-
const code = typeof json.error === 'string' ? json.error : `http_${res.status}`;
|
|
50
|
-
const detail = typeof json.message === 'string' ? json.message
|
|
51
|
-
: typeof json.detail === 'string' ? json.detail
|
|
52
|
-
: undefined;
|
|
53
|
-
throw new ControlApiError(code, res.status, detail);
|
|
54
|
-
}
|
|
55
|
-
return json.data;
|
|
56
|
-
}
|
|
57
|
-
/** Build a `?a=b&c=d` query string from defined values only. */
|
|
58
|
-
export function qs(params) {
|
|
59
|
-
const pairs = Object.entries(params)
|
|
60
|
-
.filter(([, v]) => v !== undefined && v !== '')
|
|
61
|
-
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);
|
|
62
|
-
return pairs.length ? `?${pairs.join('&')}` : '';
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=apiClient.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiClient.js","sourceRoot":"","sources":["../../lib/apiClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Resolve the AnyForge control credentials the MCP server uses to talk
|
|
3
|
-
* to /api/v1/control/*.
|
|
4
|
-
*
|
|
5
|
-
* Precedence:
|
|
6
|
-
* 1. Env vars (ANYFORGE_API_TOKEN + ANYFORGE_API_URL) — lets an MCP
|
|
7
|
-
* config inline a key explicitly if desired.
|
|
8
|
-
* 2. ~/.anyforge/credentials — the file written by
|
|
9
|
-
* `npx @anyforge/control init`. This is the default path, so a
|
|
10
|
-
* user who has already run init needs zero secrets in their MCP
|
|
11
|
-
* config: `claude mcp add anyforge -- npx tsx <path>/index.ts`.
|
|
12
|
-
*
|
|
13
|
-
* The key is a long-lived `sk_anyforge_…` token, so there's no
|
|
14
|
-
* expiry/refresh dance — unlike a Firebase ID token.
|
|
15
|
-
*/
|
|
16
|
-
export interface ResolvedCredentials {
|
|
17
|
-
apiKey: string;
|
|
18
|
-
endpoint: string;
|
|
19
|
-
}
|
|
20
|
-
export declare function resolveCredentials(): Promise<ResolvedCredentials>;
|
package/dist/lib/credentials.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { promises as fs } from 'fs';
|
|
2
|
-
import { homedir } from 'os';
|
|
3
|
-
import { join } from 'path';
|
|
4
|
-
const DEFAULT_ENDPOINT = 'https://anyforge.ai';
|
|
5
|
-
const FILE = join(homedir(), '.anyforge', 'credentials');
|
|
6
|
-
export async function resolveCredentials() {
|
|
7
|
-
const envKey = process.env.ANYFORGE_API_TOKEN;
|
|
8
|
-
const envUrl = process.env.ANYFORGE_API_URL;
|
|
9
|
-
if (envKey) {
|
|
10
|
-
return { apiKey: envKey, endpoint: envUrl || DEFAULT_ENDPOINT };
|
|
11
|
-
}
|
|
12
|
-
const fromFile = await readCredentialsFile();
|
|
13
|
-
if (fromFile?.apiKey) {
|
|
14
|
-
return {
|
|
15
|
-
apiKey: fromFile.apiKey,
|
|
16
|
-
endpoint: envUrl || fromFile.endpoint || DEFAULT_ENDPOINT,
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
throw new Error('No AnyForge credentials found. Run `npx @anyforge/control init` to authorise this machine, ' +
|
|
20
|
-
'or set ANYFORGE_API_TOKEN (and optionally ANYFORGE_API_URL) in the MCP server env.');
|
|
21
|
-
}
|
|
22
|
-
async function readCredentialsFile() {
|
|
23
|
-
try {
|
|
24
|
-
const text = await fs.readFile(FILE, 'utf8');
|
|
25
|
-
return JSON.parse(text);
|
|
26
|
-
}
|
|
27
|
-
catch (err) {
|
|
28
|
-
if (err.code === 'ENOENT')
|
|
29
|
-
return null;
|
|
30
|
-
throw err;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
//# sourceMappingURL=credentials.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../lib/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAA;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AA6B3B,MAAM,gBAAgB,GAAG,qBAAqB,CAAA;AAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,aAAa,CAAC,CAAA;AAExD,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAA;IAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAA;IAE3C,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,gBAAgB,EAAE,CAAA;IACjE,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,mBAAmB,EAAE,CAAA;IAC5C,IAAI,QAAQ,EAAE,MAAM,EAAE,CAAC;QACrB,OAAO;YACL,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,QAAQ,EAAE,MAAM,IAAI,QAAQ,CAAC,QAAQ,IAAI,gBAAgB;SAC1D,CAAA;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CACb,6FAA6F;QAC7F,oFAAoF,CACrF,CAAA;AACH,CAAC;AAED,KAAK,UAAU,mBAAmB;IAChC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAoB,CAAA;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAA;QACjE,MAAM,GAAG,CAAA;IACX,CAAC;AACH,CAAC"}
|
package/dist/prompts/genesis.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The `genesis` prompt — the discoverable entry point that turns the MCP
|
|
3
|
-
* client (Claude Code, Cursor, …) INTO the AnyForge Program Genesis agent.
|
|
4
|
-
*
|
|
5
|
-
* We deliberately do NOT pipe a server-side agent through a chat-in-a-tool:
|
|
6
|
-
* the user already has a capable conversational agent (the MCP client), so
|
|
7
|
-
* we give it the Genesis persona + the interview script and let it drive the
|
|
8
|
-
* conversation, calling the AnyForge control tools as it goes. This reads as
|
|
9
|
-
* a natural chat — "talk to Genesis" — and works in any MCP client.
|
|
10
|
-
*
|
|
11
|
-
* Flow it encodes: gather objective → scope codebases (list_repo_index) →
|
|
12
|
-
* gather per-codebase functionality/details (get_repo_analysis to ground) →
|
|
13
|
-
* persist the program brief → propose + confirm one initiative per codebase →
|
|
14
|
-
* create them (create_initiative w/ programId) → dispatch the architect per
|
|
15
|
-
* initiative (dispatch_architect → backlog → approve_backlog).
|
|
16
|
-
*/
|
|
17
|
-
function header(args) {
|
|
18
|
-
const lines = ['You are the **AnyForge Program Genesis agent**, running inside the user\'s terminal via the AnyForge MCP server.'];
|
|
19
|
-
if (args.programId)
|
|
20
|
-
lines.push(`\nYou are scoping the existing program \`${args.programId}\`. Call \`anyforge_get_program\` on it first to load its current name, status, and brief.`);
|
|
21
|
-
else
|
|
22
|
-
lines.push('\nNo program exists yet. Once you understand the objective, create one with `anyforge_create_program` and use its id for everything below.');
|
|
23
|
-
if (args.goal)
|
|
24
|
-
lines.push(`\nThe user's stated goal to start from: "${args.goal}"`);
|
|
25
|
-
return lines.join('\n');
|
|
26
|
-
}
|
|
27
|
-
export const genesisPrompt = {
|
|
28
|
-
name: 'genesis',
|
|
29
|
-
description: 'Start a Program Genesis session: chat with the AnyForge Genesis agent to scope a program ' +
|
|
30
|
-
'across your codebases and create one initiative per codebase, then dispatch the architect on each.',
|
|
31
|
-
arguments: [
|
|
32
|
-
{ name: 'programId', description: 'Existing program to scope (omit to create a new one during the chat).', required: false },
|
|
33
|
-
{ name: 'goal', description: 'One-line program goal to seed the conversation (optional).', required: false },
|
|
34
|
-
],
|
|
35
|
-
render: (args) => `${header(args)}
|
|
36
|
-
|
|
37
|
-
Your job is to interview the user until you have enough to define **proper, codebase-scoped initiatives** under this program, then create them and (on the user's go-ahead) dispatch the architect on each. Initiatives are always scoped to a single codebase — one program fans out into one initiative per in-scope codebase.
|
|
38
|
-
|
|
39
|
-
## How to run the conversation
|
|
40
|
-
Ask questions in small clusters — never dump the whole questionnaire at once. Listen, then go deeper where the answer is thin. Use the tools to ground every step in real data rather than guessing.
|
|
41
|
-
|
|
42
|
-
**1. Objective & outcome.** What is this program trying to achieve, and what's the business outcome / definition of done? (e.g. "raise test coverage above 90% across the payments services", "migrate the Go services off the deprecated auth SDK".)
|
|
43
|
-
|
|
44
|
-
**2. Scope the codebases.** Call \`anyforge_list_repo_index\` to show real candidates (default = active repos; for a coverage/quality program pass \`belowCoverage\` to get the repos below the target, worst-first). Present them and ask the user which are in scope. For the handful you or the user are unsure about, call \`anyforge_get_repo_analysis\` to see coverage, architecture health, gap count, and languages — that tells you how far each repo is from the goal. Confirm the final in-scope set explicitly.
|
|
45
|
-
|
|
46
|
-
**3. Per-codebase detail.** For each in-scope codebase, gather what the program actually means *there*: which functionality/areas, the specific work expected, constraints, and any nuances. Pull \`anyforge_get_repo_analysis\` to anchor this in the repo's real state. Keep asking until each codebase has enough for an architect to decompose it into real work — not a vague one-liner.
|
|
47
|
-
|
|
48
|
-
**4. Success criteria & guardrails.** Coverage target, deadlines, priorities/ordering across codebases, anything explicitly out of scope.
|
|
49
|
-
|
|
50
|
-
## When scope is clear
|
|
51
|
-
**5. Persist the brief.** Call \`anyforge_write_program_brief\` with a markdown charter (Purpose, Goals, Rationale, Scope in/out, Success metrics, Key context & sources). This grounds the program and seeds every initiative's architect context — so write it well.
|
|
52
|
-
|
|
53
|
-
**6. Propose initiatives — then STOP for confirmation.** Present a table: one initiative per in-scope codebase, each with a name, the repo, and a 1–2 sentence intent derived from the objective + that repo's analysis. Do **not** create anything yet. Ask the user to confirm, edit names/intents, drop or add codebases.
|
|
54
|
-
|
|
55
|
-
**7. Create them.** On confirmation, call \`anyforge_create_initiative\` once per codebase with: \`programId\`, \`name\`, \`description\`, \`defaultGithubRepo\` (the repo), \`defaultGithubBranch\` (its default branch from the index), and a \`brdContent\` that captures that codebase's slice of the program (objective + specific functionality/details + success criteria). It's idempotent — it de-dupes on name within the program/repo. Report the created initiative ids/codes.
|
|
56
|
-
|
|
57
|
-
**8. Dispatch the architect.** Tell the user each initiative starts in DRAFT and the architect decomposes it into a backlog that lands at HIL #1 for approval. Offer to dispatch — call \`anyforge_dispatch_architect\` per initiative (one at a time, or all of them, the user's choice). After review, \`anyforge_approve_backlog\` moves an initiative to IN_PROGRESS and crews pick it up.
|
|
58
|
-
|
|
59
|
-
## Rules
|
|
60
|
-
- Ground every claim in tool output — never invent repos, coverage numbers, or codebase facts.
|
|
61
|
-
- Never write (create program/initiative, write brief) before the user has confirmed the relevant step.
|
|
62
|
-
- One initiative per codebase; reflect the program brief into each initiative's \`brdContent\`.
|
|
63
|
-
- If the user gives you everything up front, still confirm the proposed initiative list before creating.
|
|
64
|
-
|
|
65
|
-
Begin by ${args.programId ? 'loading the program, then confirming the objective' : 'asking for the program objective'}.`,
|
|
66
|
-
};
|
|
67
|
-
export const prompts = [genesisPrompt];
|
|
68
|
-
//# sourceMappingURL=genesis.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"genesis.js","sourceRoot":"","sources":["../../prompts/genesis.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,SAAS,MAAM,CAAC,IAA4B;IAC1C,MAAM,KAAK,GAAG,CAAC,kHAAkH,CAAC,CAAA;IAClI,IAAI,IAAI,CAAC,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,4CAA4C,IAAI,CAAC,SAAS,4FAA4F,CAAC,CAAA;;QACjL,KAAK,CAAC,IAAI,CAAC,4IAA4I,CAAC,CAAA;IAC7J,IAAI,IAAI,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,4CAA4C,IAAI,CAAC,IAAI,GAAG,CAAC,CAAA;IACnF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAc;IACtC,IAAI,EAAE,SAAS;IACf,WAAW,EACT,2FAA2F;QAC3F,oGAAoG;IACtG,SAAS,EAAE;QACT,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,uEAAuE,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC5H,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,4DAA4D,EAAE,QAAQ,EAAE,KAAK,EAAE;KAC7G;IACD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA8BxB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,oDAAoD,CAAC,CAAC,CAAC,kCAAkC,GAAG;CACvH,CAAA;AAED,MAAM,CAAC,MAAM,OAAO,GAAgB,CAAC,aAAa,CAAC,CAAA"}
|
package/dist/tools/coverage.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { ToolModule } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Coverage tools — push test-coverage measurements into AnyForge so
|
|
4
|
-
* Program Genesis can scope quality programs by real coverage.
|
|
5
|
-
*
|
|
6
|
-
* The intended flow is the SonarQube → AnyForge bridge: a user on the
|
|
7
|
-
* VPN runs Claude with both the SonarQube MCP and the AnyForge MCP,
|
|
8
|
-
* reads coverage per project from SonarQube, maps each to its
|
|
9
|
-
* owner/repo, and pushes them here in one batched call. AnyForge's
|
|
10
|
-
* cloud never needs VPN access — Claude on the VPN is the bridge.
|
|
11
|
-
*/
|
|
12
|
-
export declare const coverageTools: ToolModule;
|
package/dist/tools/coverage.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { callControl } from '../lib/apiClient.js';
|
|
2
|
-
/**
|
|
3
|
-
* Coverage tools — push test-coverage measurements into AnyForge so
|
|
4
|
-
* Program Genesis can scope quality programs by real coverage.
|
|
5
|
-
*
|
|
6
|
-
* The intended flow is the SonarQube → AnyForge bridge: a user on the
|
|
7
|
-
* VPN runs Claude with both the SonarQube MCP and the AnyForge MCP,
|
|
8
|
-
* reads coverage per project from SonarQube, maps each to its
|
|
9
|
-
* owner/repo, and pushes them here in one batched call. AnyForge's
|
|
10
|
-
* cloud never needs VPN access — Claude on the VPN is the bridge.
|
|
11
|
-
*/
|
|
12
|
-
export const coverageTools = {
|
|
13
|
-
tools: [
|
|
14
|
-
{
|
|
15
|
-
name: 'anyforge_upload_coverage',
|
|
16
|
-
description: 'Upload test-coverage measurements for one or many repos (e.g. synced from SonarQube). ' +
|
|
17
|
-
'Requires `write` scope. Each item needs repo ("owner/name") and either percent (0–100) or ' +
|
|
18
|
-
'a raw lcov report. Writes coverage to the matching codebase + the org repo index, so a ' +
|
|
19
|
-
'Program Genesis quality program can scope "repos below X%". Batch up to 200 items per call ' +
|
|
20
|
-
'— chunk larger syncs. Map SonarQube projects to owner/repo via their GitHub binding before ' +
|
|
21
|
-
'calling; ask the operator about any you can\'t map.',
|
|
22
|
-
inputSchema: {
|
|
23
|
-
type: 'object',
|
|
24
|
-
properties: {
|
|
25
|
-
items: {
|
|
26
|
-
type: 'array',
|
|
27
|
-
description: 'Coverage measurements (up to 200). Use this for batch sync.',
|
|
28
|
-
items: {
|
|
29
|
-
type: 'object',
|
|
30
|
-
properties: {
|
|
31
|
-
repo: { type: 'string', description: '"owner/name".' },
|
|
32
|
-
percent: { type: 'number', description: 'Line coverage % (0–100).' },
|
|
33
|
-
lcov: { type: 'string', description: 'Alternative to percent: a raw lcov report; coverage is computed from it.' },
|
|
34
|
-
commitSha: { type: 'string', description: 'Optional commit the measurement was taken at.' },
|
|
35
|
-
},
|
|
36
|
-
required: ['repo'],
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
repo: { type: 'string', description: 'Single-repo shortcut (use instead of items): "owner/name".' },
|
|
40
|
-
percent: { type: 'number', description: 'Single-repo coverage % (with `repo`).' },
|
|
41
|
-
lcov: { type: 'string', description: 'Single-repo lcov report (with `repo`).' },
|
|
42
|
-
commitSha: { type: 'string', description: 'Single-repo commit sha (with `repo`).' },
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
],
|
|
47
|
-
handlers: {
|
|
48
|
-
anyforge_upload_coverage: args => {
|
|
49
|
-
// Pass through either {items:[…]} (batch) or the single-repo shortcut.
|
|
50
|
-
const payload = Array.isArray(args.items)
|
|
51
|
-
? { items: args.items }
|
|
52
|
-
: {
|
|
53
|
-
repo: args.repo,
|
|
54
|
-
...(typeof args.percent === 'number' ? { percent: args.percent } : {}),
|
|
55
|
-
...(typeof args.lcov === 'string' ? { lcov: args.lcov } : {}),
|
|
56
|
-
...(typeof args.commitSha === 'string' ? { commitSha: args.commitSha } : {}),
|
|
57
|
-
};
|
|
58
|
-
return callControl('POST', '/coverage', payload);
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
//# sourceMappingURL=coverage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../../tools/coverage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAGjD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAe;IACvC,KAAK,EAAE;QACL;YACE,IAAI,EAAE,0BAA0B;YAChC,WAAW,EACT,wFAAwF;gBACxF,4FAA4F;gBAC5F,yFAAyF;gBACzF,6FAA6F;gBAC7F,6FAA6F;gBAC7F,qDAAqD;YACvD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,KAAK,EAAE;wBACL,IAAI,EAAE,OAAO;wBACb,WAAW,EAAE,6DAA6D;wBAC1E,KAAK,EAAE;4BACL,IAAI,EAAE,QAAQ;4BACd,UAAU,EAAE;gCACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE;gCACtD,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0BAA0B,EAAE;gCACpE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0EAA0E,EAAE;gCACjH,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+CAA+C,EAAE;6BAC5F;4BACD,QAAQ,EAAE,CAAC,MAAM,CAAC;yBACnB;qBACF;oBACD,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,4DAA4D,EAAE;oBACnG,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uCAAuC,EAAE;oBACjF,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wCAAwC,EAAE;oBAC/E,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uCAAuC,EAAE;iBACpF;aACF;SACF;KACF;IACD,QAAQ,EAAE;QACR,wBAAwB,EAAE,IAAI,CAAC,EAAE;YAC/B,uEAAuE;YACvE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;gBACvC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;gBACvB,CAAC,CAAC;oBACE,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,GAAG,CAAC,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACtE,GAAG,CAAC,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC7D,GAAG,CAAC,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC7E,CAAA;YACL,OAAO,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,CAAA;QAClD,CAAC;KACF;CACF,CAAA"}
|
package/dist/tools/crews.d.ts
DELETED
package/dist/tools/crews.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { callControl, qs } from '../lib/apiClient.js';
|
|
2
|
-
/**
|
|
3
|
-
* Crew tools — see crew outputs and interact (operator comments,
|
|
4
|
-
* resume, halt).
|
|
5
|
-
*/
|
|
6
|
-
export const crewTools = {
|
|
7
|
-
tools: [
|
|
8
|
-
{
|
|
9
|
-
name: 'anyforge_get_crew',
|
|
10
|
-
description: 'Get a crew with its recent chat messages (the crew output) and operator comments. ' +
|
|
11
|
-
'Use this to see what a crew produced and where it stands.',
|
|
12
|
-
inputSchema: {
|
|
13
|
-
type: 'object',
|
|
14
|
-
properties: {
|
|
15
|
-
crewId: { type: 'string', description: 'The crew id.' },
|
|
16
|
-
messages: { type: 'number', description: 'How many recent chat/comment entries (default 50, max 200).' },
|
|
17
|
-
},
|
|
18
|
-
required: ['crewId'],
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
name: 'anyforge_post_crew_comment',
|
|
23
|
-
description: 'Post an operator comment on a crew (optionally @-mentioning teammates by uid). ' +
|
|
24
|
-
'Requires `write` scope.',
|
|
25
|
-
inputSchema: {
|
|
26
|
-
type: 'object',
|
|
27
|
-
properties: {
|
|
28
|
-
crewId: { type: 'string', description: 'The crew id.' },
|
|
29
|
-
body: { type: 'string', description: 'Comment text (max 4000 chars).' },
|
|
30
|
-
messageId: { type: 'string', description: 'Optional crewChat message id to anchor the comment to.' },
|
|
31
|
-
mentionedUids: { type: 'array', items: { type: 'string' }, description: 'Optional uids to mention.' },
|
|
32
|
-
},
|
|
33
|
-
required: ['crewId', 'body'],
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
name: 'anyforge_resume_crew',
|
|
38
|
-
description: 'Resume a PAUSED or HALTED crew from its last checkpoint. Requires `approve` scope.',
|
|
39
|
-
inputSchema: {
|
|
40
|
-
type: 'object',
|
|
41
|
-
properties: { crewId: { type: 'string', description: 'The crew id.' } },
|
|
42
|
-
required: ['crewId'],
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
name: 'anyforge_halt_crew',
|
|
47
|
-
description: 'Halt a crew (terminal stop). Idempotent on already-finished crews. Requires `approve` scope.',
|
|
48
|
-
inputSchema: {
|
|
49
|
-
type: 'object',
|
|
50
|
-
properties: { crewId: { type: 'string', description: 'The crew id.' } },
|
|
51
|
-
required: ['crewId'],
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: 'anyforge_amend_crew',
|
|
56
|
-
description: 'Continue & finish: send a crew waiting at its HIL gate back to the engineer with guidance — it ' +
|
|
57
|
-
'resumes work on the SAME PR (capped at the amend limit). This is the "Continue" option alongside ' +
|
|
58
|
-
'submit_approval APPROVE (ship) / REJECT (stop). Requires `approve` scope. Only call when the operator ' +
|
|
59
|
-
'explicitly asks to amend/continue — never on your own judgement of the reviews.',
|
|
60
|
-
inputSchema: {
|
|
61
|
-
type: 'object',
|
|
62
|
-
properties: {
|
|
63
|
-
crewId: { type: 'string', description: 'The crew id (the crew must be at a pending approval gate).' },
|
|
64
|
-
notes: { type: 'string', description: 'What the engineer should finish/change — becomes the amend instruction.' },
|
|
65
|
-
},
|
|
66
|
-
required: ['crewId', 'notes'],
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
],
|
|
70
|
-
handlers: {
|
|
71
|
-
anyforge_get_crew: args => callControl('GET', `/crews/${encodeURIComponent(String(args.crewId))}${qs({ messages: args.messages })}`),
|
|
72
|
-
anyforge_post_crew_comment: args => callControl('POST', `/crews/${encodeURIComponent(String(args.crewId))}/comments`, {
|
|
73
|
-
body: args.body,
|
|
74
|
-
...(args.messageId ? { messageId: args.messageId } : {}),
|
|
75
|
-
...(Array.isArray(args.mentionedUids) ? { mentionedUids: args.mentionedUids } : {}),
|
|
76
|
-
}),
|
|
77
|
-
anyforge_resume_crew: args => callControl('POST', `/crews/${encodeURIComponent(String(args.crewId))}/resume`),
|
|
78
|
-
anyforge_halt_crew: args => callControl('POST', `/crews/${encodeURIComponent(String(args.crewId))}/halt`),
|
|
79
|
-
anyforge_amend_crew: args => callControl('POST', `/crews/${encodeURIComponent(String(args.crewId))}/amend`, { notes: args.notes }),
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
//# sourceMappingURL=crews.js.map
|
package/dist/tools/crews.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crews.js","sourceRoot":"","sources":["../../tools/crews.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/hil.d.ts
DELETED
package/dist/tools/hil.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { callControl, qs } from '../lib/apiClient.js';
|
|
2
|
-
/**
|
|
3
|
-
* HIL (human-in-the-loop) approval tools — the headline capability:
|
|
4
|
-
* list what's awaiting the operator, read its context, and approve /
|
|
5
|
-
* reject from the CLI.
|
|
6
|
-
*/
|
|
7
|
-
export const hilTools = {
|
|
8
|
-
tools: [
|
|
9
|
-
{
|
|
10
|
-
name: 'anyforge_list_pending_approvals',
|
|
11
|
-
description: 'List HIL approvals awaiting an operator decision for your company. Returns each ' +
|
|
12
|
-
'approval id, the crew it belongs to, plan summary, and the architecture / security ' +
|
|
13
|
-
'context. Use this to see what needs your sign-off.',
|
|
14
|
-
inputSchema: {
|
|
15
|
-
type: 'object',
|
|
16
|
-
properties: {
|
|
17
|
-
limit: { type: 'number', description: 'Max approvals to return (default 50, max 200).' },
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
name: 'anyforge_get_approval_detail',
|
|
23
|
-
description: 'Get the full detail of a single HIL approval by id (plan, ADR, security audit).',
|
|
24
|
-
inputSchema: {
|
|
25
|
-
type: 'object',
|
|
26
|
-
properties: {
|
|
27
|
-
approvalId: { type: 'string', description: 'The HIL approval id.' },
|
|
28
|
-
},
|
|
29
|
-
required: ['approvalId'],
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
name: 'anyforge_submit_approval',
|
|
34
|
-
description: 'Submit a decision on a HIL approval. APPROVED resumes the crew past the gate; ' +
|
|
35
|
-
'REJECTED sends it back. Requires a key with the `approve` scope.',
|
|
36
|
-
inputSchema: {
|
|
37
|
-
type: 'object',
|
|
38
|
-
properties: {
|
|
39
|
-
approvalId: { type: 'string', description: 'The HIL approval id.' },
|
|
40
|
-
decision: { type: 'string', description: "'APPROVED' or 'REJECTED'." },
|
|
41
|
-
notes: { type: 'string', description: 'Optional reviewer notes (shown in the audit trail).' },
|
|
42
|
-
},
|
|
43
|
-
required: ['approvalId', 'decision'],
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
],
|
|
47
|
-
handlers: {
|
|
48
|
-
anyforge_list_pending_approvals: args => callControl('GET', `/hil${qs({ limit: args.limit })}`),
|
|
49
|
-
anyforge_get_approval_detail: args => callControl('GET', `/hil/${encodeURIComponent(String(args.approvalId))}`),
|
|
50
|
-
anyforge_submit_approval: args => callControl('POST', `/hil/${encodeURIComponent(String(args.approvalId))}`, {
|
|
51
|
-
decision: args.decision,
|
|
52
|
-
...(args.notes ? { notes: args.notes } : {}),
|
|
53
|
-
}),
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
//# sourceMappingURL=hil.js.map
|
package/dist/tools/hil.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hil.js","sourceRoot":"","sources":["../../tools/hil.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAA;AAGrD;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAe;IAClC,KAAK,EAAE;QACL;YACE,IAAI,EAAE,iCAAiC;YACvC,WAAW,EACT,kFAAkF;gBAClF,qFAAqF;gBACrF,oDAAoD;YACtD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gDAAgD,EAAE;iBACzF;aACF;SACF;QACD;YACE,IAAI,EAAE,8BAA8B;YACpC,WAAW,EAAE,iFAAiF;YAC9F,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE;iBACpE;gBACD,QAAQ,EAAE,CAAC,YAAY,CAAC;aACzB;SACF;QACD;YACE,IAAI,EAAE,0BAA0B;YAChC,WAAW,EACT,gFAAgF;gBAChF,kEAAkE;YACpE,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE;oBACnE,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2BAA2B,EAAE;oBACtE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qDAAqD,EAAE;iBAC9F;gBACD,QAAQ,EAAE,CAAC,YAAY,EAAE,UAAU,CAAC;aACrC;SACF;KACF;IACD,QAAQ,EAAE;QACR,+BAA+B,EAAE,IAAI,CAAC,EAAE,CACtC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAA2B,EAAE,CAAC,EAAE,CAAC;QAC9E,4BAA4B,EAAE,IAAI,CAAC,EAAE,CACnC,WAAW,CAAC,KAAK,EAAE,QAAQ,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QAC3E,wBAAwB,EAAE,IAAI,CAAC,EAAE,CAC/B,WAAW,CAAC,MAAM,EAAE,QAAQ,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE;YACzE,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7C,CAAC;KACL;CACF,CAAA"}
|