harness-engineering-agent 0.1.2 → 0.1.4
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 +17 -6
- package/dist/mcp/cli.d.ts +3 -0
- package/dist/mcp/cli.d.ts.map +1 -0
- package/dist/mcp/cli.js +17 -0
- package/dist/mcp/cli.js.map +1 -0
- package/dist/mcp/server.d.ts +6 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +24 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/plugin/create-harness-plugin.d.ts +0 -9
- package/dist/plugin/create-harness-plugin.d.ts.map +1 -1
- package/dist/plugin/create-harness-plugin.js +1 -32
- package/dist/plugin/create-harness-plugin.js.map +1 -1
- package/dist/plugin/harness-agent-config.d.ts.map +1 -1
- package/dist/plugin/harness-agent-config.js +5 -4
- package/dist/plugin/harness-agent-config.js.map +1 -1
- package/dist/plugin/harness-chat-hook.d.ts +0 -3
- package/dist/plugin/harness-chat-hook.d.ts.map +1 -1
- package/dist/plugin/harness-chat-hook.js +20 -38
- package/dist/plugin/harness-chat-hook.js.map +1 -1
- package/dist/plugin/harness-chat-parts.d.ts +1 -1
- package/dist/plugin/harness-chat-parts.d.ts.map +1 -1
- package/dist/plugin/harness-chat-parts.js +6 -4
- package/dist/plugin/harness-chat-parts.js.map +1 -1
- package/dist/plugin/harness-chat-protocol.d.ts +0 -2
- package/dist/plugin/harness-chat-protocol.d.ts.map +1 -1
- package/dist/plugin/harness-chat-protocol.js +2 -7
- package/dist/plugin/harness-chat-protocol.js.map +1 -1
- package/dist/plugin/harness-request-router.d.ts +2 -0
- package/dist/plugin/harness-request-router.d.ts.map +1 -0
- package/dist/plugin/harness-request-router.js +49 -0
- package/dist/plugin/harness-request-router.js.map +1 -0
- package/dist/tools/harness-research-tools.d.ts +3 -13
- package/dist/tools/harness-research-tools.d.ts.map +1 -1
- package/dist/tools/harness-research-tools.js +75 -80
- package/dist/tools/harness-research-tools.js.map +1 -1
- package/package.json +9 -1
- package/dist/plugin/harness-parent-session-dispatcher.d.ts +0 -46
- package/dist/plugin/harness-parent-session-dispatcher.d.ts.map +0 -1
- package/dist/plugin/harness-parent-session-dispatcher.js +0 -33
- package/dist/plugin/harness-parent-session-dispatcher.js.map +0 -1
package/README.md
CHANGED
|
@@ -192,21 +192,21 @@ Luban / harness-worker:
|
|
|
192
192
|
|
|
193
193
|
`harness` primary 同样只读,不使用任何研究工具。
|
|
194
194
|
|
|
195
|
-
##
|
|
195
|
+
## Harness MCP 工具
|
|
196
196
|
|
|
197
|
-
Harness
|
|
197
|
+
Harness 通过本地 stdio MCP Server 提供以下只读工程工具:
|
|
198
198
|
|
|
199
199
|
- `harness_context7_resolve`、`harness_context7_query`:直连 Context7 官方 HTTP API。
|
|
200
200
|
- `harness_grep_app_search`:通过自研 Streamable HTTP MCP 客户端调用 grep.app 官方 `searchGitHub`。
|
|
201
201
|
- `harness_lsp_status`、`harness_lsp_diagnostics`、`harness_lsp_definition`、`harness_lsp_references`:通过自研 JSON-RPC stdio 客户端访问 JDT LS 和 TypeScript Language Server。
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
OpenCode 以 `harness` 作为 MCP Server 名称,因此最终工具名保持 `harness_*`。工具使用权限按角色分配:
|
|
204
204
|
|
|
205
205
|
- **全部研究工具**:Fuxi(Planner)、Luban(Worker)、Zhulong(Verifier)、Xingtian(Failure Analyzer)、Jingwei(Repair Worker)。
|
|
206
206
|
- **grep.app + LSP**:Yinglong(Acceptance)。
|
|
207
207
|
- **不使用研究工具**:Harness(primary)、Nuwa(Intake)。
|
|
208
208
|
|
|
209
|
-
LSP 只提供只读查询,不实现重命名或代码写入。JDT LS
|
|
209
|
+
LSP 只提供只读查询,不实现重命名或代码写入。JDT LS 数据目录位于系统临时目录,并在 MCP Server 退出时清理。
|
|
210
210
|
|
|
211
211
|
Context7 默认匿名访问,可通过环境变量 `CONTEXT7_API_KEY` 提升限额。JDT LS 命令可通过 `HARNESS_JDTLS_COMMAND` 覆盖。
|
|
212
212
|
|
|
@@ -373,18 +373,29 @@ pnpm publish:npm -- --token-auth
|
|
|
373
373
|
|
|
374
374
|
## OpenCode npm 引用
|
|
375
375
|
|
|
376
|
-
发布后在 `opencode.json`
|
|
376
|
+
发布后在 `opencode.json` 中加载插件并注册 Harness MCP Server:
|
|
377
377
|
|
|
378
378
|
```json
|
|
379
379
|
{
|
|
380
380
|
"$schema": "https://opencode.ai/config.json",
|
|
381
|
-
"plugin": ["harness-engineering-agent"]
|
|
381
|
+
"plugin": ["harness-engineering-agent"],
|
|
382
|
+
"mcp": {
|
|
383
|
+
"harness": {
|
|
384
|
+
"type": "local",
|
|
385
|
+
"command": ["npx", "-y", "harness-engineering-agent@latest"],
|
|
386
|
+
"enabled": true,
|
|
387
|
+
"timeout": 30000
|
|
388
|
+
}
|
|
389
|
+
}
|
|
382
390
|
}
|
|
383
391
|
```
|
|
384
392
|
|
|
385
393
|
OpenCode 会通过包的 `./server` 导出加载专用插件入口;根入口仍保留完整 SDK 导出,供其它
|
|
386
394
|
npm 调用方使用。
|
|
387
395
|
|
|
396
|
+
Harness 的内部 Agent 使用 `mode: "all"` 注册,会显示在 OpenCode Agent/Model 选择列表中,
|
|
397
|
+
同时仍可作为 Harness 内部会话角色调用。
|
|
398
|
+
|
|
388
399
|
## 项目配置
|
|
389
400
|
|
|
390
401
|
在目标项目创建 `.harness/config.yaml`:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/mcp/cli.ts"],"names":[],"mappings":""}
|
package/dist/mcp/cli.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { createHarnessMcpServer } from "./server.js";
|
|
4
|
+
const runtime = createHarnessMcpServer();
|
|
5
|
+
const transport = new StdioServerTransport();
|
|
6
|
+
const shutdown = async () => {
|
|
7
|
+
await runtime.close();
|
|
8
|
+
await runtime.server.close();
|
|
9
|
+
};
|
|
10
|
+
process.once("SIGINT", () => {
|
|
11
|
+
void shutdown();
|
|
12
|
+
});
|
|
13
|
+
process.once("SIGTERM", () => {
|
|
14
|
+
void shutdown();
|
|
15
|
+
});
|
|
16
|
+
await runtime.server.connect(transport);
|
|
17
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/mcp/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAEhF,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAEpD,MAAM,OAAO,GAAG,sBAAsB,EAAE,CAAA;AACxC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAA;AAE5C,MAAM,QAAQ,GAAG,KAAK,IAAmB,EAAE;IACzC,MAAM,OAAO,CAAC,KAAK,EAAE,CAAA;IACrB,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;AAC9B,CAAC,CAAA;AAED,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;IAC1B,KAAK,QAAQ,EAAE,CAAA;AACjB,CAAC,CAAC,CAAA;AACF,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;IAC3B,KAAK,QAAQ,EAAE,CAAA;AACjB,CAAC,CAAC,CAAA;AAEF,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA"}
|
|
@@ -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,CAAA;AASnE,eAAO,MAAM,sBAAsB,QAAO;IACxC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CA2BpC,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { createContext7Client } from "../tools/context7-client.js";
|
|
3
|
+
import { createGrepAppClient } from "../tools/grep-app-client.js";
|
|
4
|
+
import { registerHarnessResearchTools } from "../tools/harness-research-tools.js";
|
|
5
|
+
import { createLspClient } from "../tools/lsp-client.js";
|
|
6
|
+
const CONTEXT7_API_KEY = "CONTEXT7_API_KEY";
|
|
7
|
+
export const createHarnessMcpServer = () => {
|
|
8
|
+
const lsp = createLspClient();
|
|
9
|
+
const server = new McpServer({
|
|
10
|
+
name: "harness",
|
|
11
|
+
version: "1.0.0",
|
|
12
|
+
}, {
|
|
13
|
+
capabilities: { tools: {} },
|
|
14
|
+
instructions: "Harness research tools are read-only and intended for Harness internal agents.",
|
|
15
|
+
});
|
|
16
|
+
const context7ApiKey = process.env[CONTEXT7_API_KEY];
|
|
17
|
+
registerHarnessResearchTools(server, {
|
|
18
|
+
context7: createContext7Client(context7ApiKey === undefined ? {} : { apiKey: context7ApiKey }),
|
|
19
|
+
grepApp: createGrepAppClient(),
|
|
20
|
+
lsp,
|
|
21
|
+
}, process.cwd());
|
|
22
|
+
return { server, close: () => lsp.close() };
|
|
23
|
+
};
|
|
24
|
+
//# 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,CAAA;AAEnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAA;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,MAAM,gBAAgB,GAAG,kBAAkB,CAAA;AAE3C,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAGpC,EAAE;IACF,MAAM,GAAG,GAAG,eAAe,EAAE,CAAA;IAC7B,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,OAAO;KACjB,EACD;QACE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAC3B,YAAY,EACV,gFAAgF;KACnF,CACF,CAAA;IACD,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;IACpD,4BAA4B,CAC1B,MAAM,EACN;QACE,QAAQ,EAAE,oBAAoB,CAC5B,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAC/D;QACD,OAAO,EAAE,mBAAmB,EAAE;QAC9B,GAAG;KACJ,EACD,OAAO,CAAC,GAAG,EAAE,CACd,CAAA;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAA;AAC7C,CAAC,CAAA"}
|
|
@@ -6,7 +6,6 @@ import { type SessionAdapter } from "../session/index.js";
|
|
|
6
6
|
import { type RunStore } from "../store/index.js";
|
|
7
7
|
import { type ProcessRunner, type VerificationRunner } from "../verification/index.js";
|
|
8
8
|
import { type CreateHarnessCoordinatorOptions, type HarnessCoordinator } from "./harness-coordinator.js";
|
|
9
|
-
import { type ParentPromptAsyncRequest, type ParentSessionPromptDispatcher } from "./harness-parent-session-dispatcher.js";
|
|
10
9
|
export type HarnessPluginDependencies = {
|
|
11
10
|
readonly loadConfig?: (projectRoot: string) => Promise<HarnessConfig>;
|
|
12
11
|
readonly createStore?: (projectRoot: string, stateDirectory: string) => RunStore;
|
|
@@ -23,14 +22,6 @@ export type HarnessPluginDependencies = {
|
|
|
23
22
|
readonly ids: ControllerIdSource;
|
|
24
23
|
}) => RunController;
|
|
25
24
|
readonly createCoordinator?: (input: CreateHarnessCoordinatorOptions) => HarnessCoordinator;
|
|
26
|
-
readonly createParentSessionDispatcher?: (input: {
|
|
27
|
-
readonly config: HarnessConfig;
|
|
28
|
-
readonly client: {
|
|
29
|
-
readonly session: {
|
|
30
|
-
readonly promptAsync: (request: ParentPromptAsyncRequest) => Promise<unknown>;
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
}) => ParentSessionPromptDispatcher;
|
|
34
25
|
readonly clock?: ControllerClock;
|
|
35
26
|
readonly ids?: ControllerIdSource;
|
|
36
27
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-harness-plugin.d.ts","sourceRoot":"","sources":["../../src/plugin/create-harness-plugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEtD,OAAO,EAAE,KAAK,aAAa,EAAqB,MAAM,oBAAoB,CAAA;AAC1E,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,kBAAkB,EAEvB,KAAK,aAAa,EACnB,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAA4B,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"create-harness-plugin.d.ts","sourceRoot":"","sources":["../../src/plugin/create-harness-plugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEtD,OAAO,EAAE,KAAK,aAAa,EAAqB,MAAM,oBAAoB,CAAA;AAC1E,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,kBAAkB,EAEvB,KAAK,aAAa,EACnB,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAA4B,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC3E,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAA;AAGjC,OAAO,EACL,KAAK,+BAA+B,EAEpC,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAA;AAEjC,MAAM,MAAM,yBAAyB,GAAG;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,CAAA;IACrE,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,QAAQ,CAAA;IAChF,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,KAAK,cAAc,CAAA;IACjG,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,aAAa,CAAA;IAClD,QAAQ,CAAC,wBAAwB,CAAC,EAAE,CAAC,aAAa,EAAE,aAAa,KAAK,kBAAkB,CAAA;IACxF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE;QAClC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;QAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;QAC5B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAA;QACxB,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAA;QACvC,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAA;QAC/C,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;QAC/B,QAAQ,CAAC,GAAG,EAAE,kBAAkB,CAAA;KACjC,KAAK,aAAa,CAAA;IACnB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,+BAA+B,KAAK,kBAAkB,CAAA;IAC3F,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAA;IAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,kBAAkB,CAAA;CAClC,CAAA;AAUD,eAAO,MAAM,mBAAmB,GAAI,eAAc,yBAA8B,KAAG,MA+BlF,CAAA;AAED,eAAO,MAAM,aAAa,QAAwB,CAAA;AA4HlD,eAAO,MAAM,yBAAyB,GACpC,OAAO,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,UAAU,CAAC,KACjD,MAAoD,CAAA"}
|
|
@@ -5,36 +5,24 @@ import { createRunController, } from "../controller/index.js";
|
|
|
5
5
|
import { RunIdSchema } from "../domain/index.js";
|
|
6
6
|
import { createOpencodeSessionAdapter, createOpencodeSessionClient, } from "../session/index.js";
|
|
7
7
|
import { createFilesystemRunStore } from "../store/index.js";
|
|
8
|
-
import { createContext7Client } from "../tools/context7-client.js";
|
|
9
|
-
import { createGrepAppClient } from "../tools/grep-app-client.js";
|
|
10
|
-
import { createHarnessResearchTools } from "../tools/harness-research-tools.js";
|
|
11
|
-
import { createLspClient } from "../tools/lsp-client.js";
|
|
12
8
|
import { createNodeProcessRunner, createVerificationRunner, } from "../verification/index.js";
|
|
13
9
|
import { applyHarnessAgentConfig } from "./harness-agent-config.js";
|
|
14
10
|
import { handleHarnessChatMessage } from "./harness-chat-hook.js";
|
|
15
11
|
import { createHarnessCoordinator, } from "./harness-coordinator.js";
|
|
16
|
-
import { asParentSessionClient, createParentSessionPromptDispatcher, } from "./harness-parent-session-dispatcher.js";
|
|
17
12
|
export const createHarnessPlugin = (dependencies = {}) => {
|
|
18
13
|
return async (input) => {
|
|
19
14
|
const runtime = await createRuntime(input, dependencies);
|
|
20
15
|
if (runtime.config === undefined ||
|
|
21
16
|
runtime.controller === undefined ||
|
|
22
17
|
runtime.coordinator === undefined ||
|
|
23
|
-
runtime.parentSessionDispatcher === undefined ||
|
|
24
18
|
runtime.projectRoot === undefined ||
|
|
25
|
-
runtime.sessionGuards === undefined
|
|
26
|
-
runtime.researchClients === undefined) {
|
|
19
|
+
runtime.sessionGuards === undefined) {
|
|
27
20
|
return {};
|
|
28
21
|
}
|
|
29
22
|
const config = runtime.config;
|
|
30
23
|
const coordinator = runtime.coordinator;
|
|
31
|
-
const parentSessionDispatcher = runtime.parentSessionDispatcher;
|
|
32
|
-
const projectRoot = runtime.projectRoot;
|
|
33
24
|
const sessionGuards = runtime.sessionGuards;
|
|
34
|
-
const researchClients = runtime.researchClients;
|
|
35
25
|
return {
|
|
36
|
-
tool: createHarnessResearchTools(researchClients),
|
|
37
|
-
dispose: async () => researchClients.lsp.close(),
|
|
38
26
|
config: async (mutableConfig) => {
|
|
39
27
|
applyHarnessAgentConfig(mutableConfig, config);
|
|
40
28
|
},
|
|
@@ -42,11 +30,9 @@ export const createHarnessPlugin = (dependencies = {}) => {
|
|
|
42
30
|
await handleHarnessChatMessage({
|
|
43
31
|
config,
|
|
44
32
|
coordinator,
|
|
45
|
-
dispatcher: parentSessionDispatcher,
|
|
46
33
|
guards: sessionGuards,
|
|
47
34
|
messageInput,
|
|
48
35
|
output,
|
|
49
|
-
directory: projectRoot,
|
|
50
36
|
});
|
|
51
37
|
},
|
|
52
38
|
};
|
|
@@ -90,13 +76,6 @@ const createRuntime = async (input, dependencies) => {
|
|
|
90
76
|
inFlightSessions: new Map(),
|
|
91
77
|
internalSessionIds: new Set(),
|
|
92
78
|
};
|
|
93
|
-
const parentSessionClient = asParentSessionClient(input.client);
|
|
94
|
-
const context7ApiKey = process.env[String("CONTEXT7_API_KEY")];
|
|
95
|
-
const researchClients = {
|
|
96
|
-
context7: createContext7Client(context7ApiKey === undefined ? {} : { apiKey: context7ApiKey }),
|
|
97
|
-
grepApp: createGrepAppClient(),
|
|
98
|
-
lsp: createLspClient(),
|
|
99
|
-
};
|
|
100
79
|
const controller = (dependencies.createController ??
|
|
101
80
|
((options) => createRunController({
|
|
102
81
|
store: options.store,
|
|
@@ -135,22 +114,12 @@ const createRuntime = async (input, dependencies) => {
|
|
|
135
114
|
},
|
|
136
115
|
sessionAdapter,
|
|
137
116
|
});
|
|
138
|
-
const parentSessionDispatcher = (dependencies.createParentSessionDispatcher ??
|
|
139
|
-
((dispatcherInput) => createParentSessionPromptDispatcher({
|
|
140
|
-
client: dispatcherInput.client,
|
|
141
|
-
config: dispatcherInput.config,
|
|
142
|
-
})))({
|
|
143
|
-
config,
|
|
144
|
-
client: parentSessionClient,
|
|
145
|
-
});
|
|
146
117
|
return {
|
|
147
118
|
config,
|
|
148
119
|
controller,
|
|
149
120
|
coordinator,
|
|
150
|
-
parentSessionDispatcher,
|
|
151
121
|
projectRoot,
|
|
152
122
|
sessionGuards,
|
|
153
|
-
researchClients,
|
|
154
123
|
};
|
|
155
124
|
};
|
|
156
125
|
const createIdSource = () => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-harness-plugin.js","sourceRoot":"","sources":["../../src/plugin/create-harness-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAInC,OAAO,EAAsB,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC1E,OAAO,EAGL,mBAAmB,GAEpB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,GAE5B,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,wBAAwB,EAAiB,MAAM,mBAAmB,CAAA;AAC3E,OAAO,
|
|
1
|
+
{"version":3,"file":"create-harness-plugin.js","sourceRoot":"","sources":["../../src/plugin/create-harness-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-agent-config.d.ts","sourceRoot":"","sources":["../../src/plugin/harness-agent-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAEjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,EACL,6BAA6B,EAC7B,+BAA+B,EAC/B,mCAAmC,EACnC,qCAAqC,EACrC,yBAAyB,EACzB,2BAA2B,EAC3B,0BAA0B,EAC1B,4BAA4B,EAC5B,0BAA0B,EAC1B,gCAAgC,EAChC,kCAAkC,EAClC,2BAA2B,EAC3B,6BAA6B,EAC7B,yBAAyB,EACzB,2BAA2B,EAC5B,MAAM,mCAAmC,CAAA;
|
|
1
|
+
{"version":3,"file":"harness-agent-config.d.ts","sourceRoot":"","sources":["../../src/plugin/harness-agent-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAEjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,EACL,6BAA6B,EAC7B,+BAA+B,EAC/B,mCAAmC,EACnC,qCAAqC,EACrC,yBAAyB,EACzB,2BAA2B,EAC3B,0BAA0B,EAC1B,4BAA4B,EAC5B,0BAA0B,EAC1B,gCAAgC,EAChC,kCAAkC,EAClC,2BAA2B,EAC3B,6BAA6B,EAC7B,yBAAyB,EACzB,2BAA2B,EAC5B,MAAM,mCAAmC,CAAA;AA2D1C,eAAO,MAAM,uBAAuB,GAAI,QAAQ,MAAM,EAAE,eAAe,aAAa,KAAG,IA4FtF,CAAA;AAED,OAAO,EACL,6BAA6B,EAC7B,+BAA+B,EAC/B,mCAAmC,EACnC,qCAAqC,EACrC,yBAAyB,EACzB,2BAA2B,EAC3B,0BAA0B,EAC1B,4BAA4B,EAC5B,0BAA0B,EAC1B,gCAAgC,EAChC,kCAAkC,EAClC,2BAA2B,EAC3B,6BAA6B,EAC7B,yBAAyB,EACzB,2BAA2B,GAC5B,CAAA"}
|
|
@@ -2,8 +2,9 @@ import { HARNESS_ACCEPTANCE_AGENT_NAME, HARNESS_ACCEPTANCE_DISPLAY_NAME, HARNESS
|
|
|
2
2
|
const HARNESS_AGENT_DESCRIPTION = "Use for natural-language Harness lifecycle operations: start, status, resume, cancel, report.";
|
|
3
3
|
const HARNESS_AGENT_PROMPT = [
|
|
4
4
|
"你是 Harness Agent,只负责呈现 Harness 控制平面结果。",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
5
|
+
"关于可用模型、当前模型、MCP、智能体、配置、帮助或工具的普通能力查询,直接按 OpenCode 正常能力回答,不要进入 Harness 协调。",
|
|
6
|
+
"生命周期消息会在同一轮附带一个带有 <!-- HARNESS_INTERNAL_RESULT --> 标记的 synthetic result;该结果是唯一权威完成结果。",
|
|
7
|
+
"你只基于该 synthetic result 做总结,不要猜测、补造或改写运行状态。",
|
|
7
8
|
"不要直接编辑文件、执行 shell、调用 task 委派子 Agent 或声明未完成的任务已完成。",
|
|
8
9
|
"向用户清楚展示 runId、当前状态、阻塞原因和下一步操作。",
|
|
9
10
|
].join("\n");
|
|
@@ -17,7 +18,7 @@ const RESEARCH_TOOL_NAMES = [
|
|
|
17
18
|
"harness_lsp_references",
|
|
18
19
|
];
|
|
19
20
|
const createReadOnlyAgent = (input) => ({
|
|
20
|
-
mode: "
|
|
21
|
+
mode: "all",
|
|
21
22
|
model: input.model,
|
|
22
23
|
description: input.description,
|
|
23
24
|
prompt: input.prompt,
|
|
@@ -32,7 +33,7 @@ const createReadOnlyAgent = (input) => ({
|
|
|
32
33
|
permission: { edit: "deny", bash: "deny" },
|
|
33
34
|
});
|
|
34
35
|
const createWorkerAgent = (model) => ({
|
|
35
|
-
mode: "
|
|
36
|
+
mode: "all",
|
|
36
37
|
model,
|
|
37
38
|
description: "Internal Harness Worker executor; the only Harness role allowed to modify code.",
|
|
38
39
|
prompt: "你是 Harness Worker 子 Agent。仅在允许路径内实现任务,输出结构化结果,不要切换角色。",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-agent-config.js","sourceRoot":"","sources":["../../src/plugin/harness-agent-config.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,6BAA6B,EAC7B,+BAA+B,EAC/B,mCAAmC,EACnC,qCAAqC,EACrC,yBAAyB,EACzB,2BAA2B,EAC3B,0BAA0B,EAC1B,4BAA4B,EAC5B,0BAA0B,EAC1B,gCAAgC,EAChC,kCAAkC,EAClC,2BAA2B,EAC3B,6BAA6B,EAC7B,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,mCAAmC,CAAA;AAE1C,MAAM,yBAAyB,GAC7B,+FAA+F,CAAA;AACjG,MAAM,oBAAoB,GAAG;IAC3B,wCAAwC;IACxC,
|
|
1
|
+
{"version":3,"file":"harness-agent-config.js","sourceRoot":"","sources":["../../src/plugin/harness-agent-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Part } from "@opencode-ai/sdk";
|
|
2
2
|
import type { HarnessConfig } from "../config/index.js";
|
|
3
3
|
import type { HarnessCoordinator } from "./harness-coordinator.js";
|
|
4
|
-
import type { ParentSessionPromptDispatcher } from "./harness-parent-session-dispatcher.js";
|
|
5
4
|
export type SessionGuards = {
|
|
6
5
|
readonly inFlightSessions: Map<string, Promise<void>>;
|
|
7
6
|
readonly internalSessionIds: Set<string>;
|
|
@@ -9,9 +8,7 @@ export type SessionGuards = {
|
|
|
9
8
|
export declare const handleHarnessChatMessage: (input: {
|
|
10
9
|
readonly config: HarnessConfig;
|
|
11
10
|
readonly coordinator: HarnessCoordinator;
|
|
12
|
-
readonly dispatcher: ParentSessionPromptDispatcher;
|
|
13
11
|
readonly guards: SessionGuards;
|
|
14
|
-
readonly directory: string;
|
|
15
12
|
readonly messageInput: {
|
|
16
13
|
readonly sessionID: string;
|
|
17
14
|
readonly agent?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-chat-hook.d.ts","sourceRoot":"","sources":["../../src/plugin/harness-chat-hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAE5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"harness-chat-hook.d.ts","sourceRoot":"","sources":["../../src/plugin/harness-chat-hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAE5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAYvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAGlE,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;IACrD,QAAQ,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CACzC,CAAA;AAED,eAAO,MAAM,wBAAwB,GAAU,OAAO;IACpD,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAA;IACxC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,QAAQ,CAAC,YAAY,EAAE;QACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;QAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KACxB,CAAA;IACD,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,OAAO,EAAE;YAChB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;YACnB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;SAC3B,CAAA;QACD,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,CAAA;KACvB,CAAA;CACF,KAAG,OAAO,CAAC,IAAI,CAuCf,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { HARNESS_PRIMARY_AGENT_NAME } from "../session/index.js";
|
|
2
|
-
import { appendSyntheticTextPart,
|
|
3
|
-
import {
|
|
2
|
+
import { appendSyntheticTextPart, extractChatText, hasHarnessInternalResultPart, } from "./harness-chat-parts.js";
|
|
3
|
+
import { createBackgroundBusyInstruction, createInternalCompletionMessage, createInternalFailureMessage, } from "./harness-chat-protocol.js";
|
|
4
|
+
import { shouldBypassHarnessCoordination } from "./harness-request-router.js";
|
|
4
5
|
export const handleHarnessChatMessage = async (input) => {
|
|
5
6
|
if (!input.config.enabled || input.messageInput.agent !== HARNESS_PRIMARY_AGENT_NAME) {
|
|
6
7
|
return;
|
|
@@ -8,7 +9,11 @@ export const handleHarnessChatMessage = async (input) => {
|
|
|
8
9
|
if (input.guards.internalSessionIds.has(input.messageInput.sessionID)) {
|
|
9
10
|
return;
|
|
10
11
|
}
|
|
11
|
-
if (
|
|
12
|
+
if (hasHarnessInternalResultPart(input.output.parts)) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const inputText = extractChatText(input.output.parts);
|
|
16
|
+
if (shouldBypassHarnessCoordination(inputText)) {
|
|
12
17
|
return;
|
|
13
18
|
}
|
|
14
19
|
const existingJob = input.guards.inFlightSessions.get(input.messageInput.sessionID);
|
|
@@ -16,17 +21,21 @@ export const handleHarnessChatMessage = async (input) => {
|
|
|
16
21
|
appendProtocolPart(input.output, createBackgroundBusyInstruction());
|
|
17
22
|
return;
|
|
18
23
|
}
|
|
19
|
-
|
|
20
|
-
const job = runBackgroundConversation({
|
|
21
|
-
coordinator: input.coordinator,
|
|
22
|
-
dispatcher: input.dispatcher,
|
|
23
|
-
directory: input.directory,
|
|
24
|
-
inputText: extractChatText(input.output.parts),
|
|
24
|
+
const responsePromise = input.coordinator.handle({
|
|
25
25
|
sessionID: input.messageInput.sessionID,
|
|
26
|
-
|
|
27
|
-
input.guards.inFlightSessions.delete(input.messageInput.sessionID);
|
|
26
|
+
inputText,
|
|
28
27
|
});
|
|
28
|
+
const job = responsePromise.then(() => undefined, () => undefined);
|
|
29
29
|
input.guards.inFlightSessions.set(input.messageInput.sessionID, job);
|
|
30
|
+
try {
|
|
31
|
+
appendProtocolPart(input.output, createInternalCompletionMessage(await responsePromise));
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
appendProtocolPart(input.output, createInternalFailureMessage(createHookErrorMessage(error)));
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
input.guards.inFlightSessions.delete(input.messageInput.sessionID);
|
|
38
|
+
}
|
|
30
39
|
};
|
|
31
40
|
const appendProtocolPart = (output, text) => {
|
|
32
41
|
appendSyntheticTextPart({
|
|
@@ -36,33 +45,6 @@ const appendProtocolPart = (output, text) => {
|
|
|
36
45
|
text,
|
|
37
46
|
});
|
|
38
47
|
};
|
|
39
|
-
const runBackgroundConversation = (input) => {
|
|
40
|
-
return (async () => {
|
|
41
|
-
try {
|
|
42
|
-
const response = await input.coordinator.handle({
|
|
43
|
-
sessionID: input.sessionID,
|
|
44
|
-
inputText: input.inputText,
|
|
45
|
-
});
|
|
46
|
-
await input.dispatcher.dispatchInternalCompletion({
|
|
47
|
-
sessionID: input.sessionID,
|
|
48
|
-
directory: input.directory,
|
|
49
|
-
text: createInternalCompletionMessage(response),
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
try {
|
|
54
|
-
await input.dispatcher.dispatchInternalCompletion({
|
|
55
|
-
sessionID: input.sessionID,
|
|
56
|
-
directory: input.directory,
|
|
57
|
-
text: createInternalFailureMessage(createHookErrorMessage(error)),
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
catch (dispatchError) {
|
|
61
|
-
console.error("Harness background completion dispatch failed", dispatchError);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
})();
|
|
65
|
-
};
|
|
66
48
|
const createHookErrorMessage = (error) => {
|
|
67
49
|
if (error instanceof Error) {
|
|
68
50
|
return error.message;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-chat-hook.js","sourceRoot":"","sources":["../../src/plugin/harness-chat-hook.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,
|
|
1
|
+
{"version":3,"file":"harness-chat-hook.js","sourceRoot":"","sources":["../../src/plugin/harness-chat-hook.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,4BAA4B,GAC7B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,+BAA+B,EAC/B,+BAA+B,EAC/B,4BAA4B,GAC7B,MAAM,4BAA4B,CAAA;AAEnC,OAAO,EAAE,+BAA+B,EAAE,MAAM,6BAA6B,CAAA;AAO7E,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,EAAE,KAe9C,EAAiB,EAAE;IAClB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,KAAK,CAAC,YAAY,CAAC,KAAK,KAAK,0BAA0B,EAAE,CAAC;QACrF,OAAM;IACR,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;QACtE,OAAM;IACR,CAAC;IACD,IAAI,4BAA4B,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACrD,OAAM;IACR,CAAC;IAED,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACrD,IAAI,+BAA+B,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/C,OAAM;IACR,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA;IACnF,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,kBAAkB,CAAC,KAAK,CAAC,MAAM,EAAE,+BAA+B,EAAE,CAAC,CAAA;QACnE,OAAM;IACR,CAAC;IAED,MAAM,eAAe,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;QAC/C,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,SAAS;QACvC,SAAS;KACV,CAAC,CAAA;IACF,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAC9B,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAChB,CAAA;IACD,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;IAEpE,IAAI,CAAC;QACH,kBAAkB,CAAC,KAAK,CAAC,MAAM,EAAE,+BAA+B,CAAC,MAAM,eAAe,CAAC,CAAC,CAAA;IAC1F,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,kBAAkB,CAAC,KAAK,CAAC,MAAM,EAAE,4BAA4B,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC/F,CAAC;YAAS,CAAC;QACT,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA;IACpE,CAAC;AACH,CAAC,CAAA;AAED,MAAM,kBAAkB,GAAG,CACzB,MAMC,EACD,IAAY,EACN,EAAE;IACR,uBAAuB,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS;QACnC,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE;QAC5B,IAAI;KACL,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,sBAAsB,GAAG,CAAC,KAAc,EAAU,EAAE;IACxD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,OAAO,CAAA;IACtB,CAAC;IACD,OAAO,iBAAiB,CAAA;AAC1B,CAAC,CAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Part } from "@opencode-ai/sdk";
|
|
2
|
-
export declare const extractAllText: (parts: readonly Part[]) => string;
|
|
3
2
|
export declare const extractChatText: (parts: readonly Part[]) => string;
|
|
3
|
+
export declare const hasHarnessInternalResultPart: (parts: readonly Part[]) => boolean;
|
|
4
4
|
export declare const appendSyntheticTextPart: (input: {
|
|
5
5
|
readonly parts: Part[];
|
|
6
6
|
readonly sessionID: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-chat-parts.d.ts","sourceRoot":"","sources":["../../src/plugin/harness-chat-parts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"harness-chat-parts.d.ts","sourceRoot":"","sources":["../../src/plugin/harness-chat-parts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,kBAAkB,CAAA;AAItD,eAAO,MAAM,eAAe,GAAI,OAAO,SAAS,IAAI,EAAE,KAAG,MAQ9C,CAAA;AAEX,eAAO,MAAM,4BAA4B,GAAI,OAAO,SAAS,IAAI,EAAE,KAAG,OAQnE,CAAA;AAEH,eAAO,MAAM,uBAAuB,GAAI,OAAO;IAC7C,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB,KAAG,IAcH,CAAA"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
.filter((part) => part.type === "text")
|
|
3
|
-
.map((part) => part.text)
|
|
4
|
-
.join("");
|
|
1
|
+
import { HARNESS_INTERNAL_RESULT_MARKER } from "./harness-chat-protocol.js";
|
|
5
2
|
export const extractChatText = (parts) => parts
|
|
6
3
|
.filter((part) => part.type === "text" && part.synthetic !== true && part.ignored !== true)
|
|
7
4
|
.map((part) => part.text)
|
|
8
5
|
.join("")
|
|
9
6
|
.trim();
|
|
7
|
+
export const hasHarnessInternalResultPart = (parts) => parts.some((part) => part.type === "text" &&
|
|
8
|
+
part.synthetic === true &&
|
|
9
|
+
part.metadata !== undefined &&
|
|
10
|
+
Reflect.get(part.metadata, "source") === "harness" &&
|
|
11
|
+
part.text.includes(HARNESS_INTERNAL_RESULT_MARKER));
|
|
10
12
|
export const appendSyntheticTextPart = (input) => {
|
|
11
13
|
const part = {
|
|
12
14
|
id: createSyntheticPartId(input.parts, input.messageID),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-chat-parts.js","sourceRoot":"","sources":["../../src/plugin/harness-chat-parts.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"harness-chat-parts.js","sourceRoot":"","sources":["../../src/plugin/harness-chat-parts.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,8BAA8B,EAAE,MAAM,4BAA4B,CAAA;AAE3E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAsB,EAAU,EAAE,CAChE,KAAK;KACF,MAAM,CACL,CAAC,IAAI,EAAoD,EAAE,CACzD,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAC3E;KACA,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;KACxB,IAAI,CAAC,EAAE,CAAC;KACR,IAAI,EAAE,CAAA;AAEX,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,KAAsB,EAAW,EAAE,CAC9E,KAAK,CAAC,IAAI,CACR,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,IAAI,KAAK,MAAM;IACpB,IAAI,CAAC,SAAS,KAAK,IAAI;IACvB,IAAI,CAAC,QAAQ,KAAK,SAAS;IAC3B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,SAAS;IAClD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,8BAA8B,CAAC,CACrD,CAAA;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,KAKvC,EAAQ,EAAE;IACT,MAAM,IAAI,GAAa;QACrB,EAAE,EAAE,qBAAqB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;QACvD,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE;YACR,MAAM,EAAE,SAAS;SAClB;KACF,CAAA;IAED,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACxB,CAAC,CAAA;AAED,MAAM,qBAAqB,GAAG,CAAC,KAAsB,EAAE,SAAiB,EAAU,EAAE;IAClF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;IACzD,MAAM,IAAI,GAAG,OAAO,SAAS,mBAAmB,CAAA;IAChD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,QAAQ,GAAG,CAAC,CAAA;IAChB,OAAO,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,QAAQ,EAAE,CAAC,EAAE,CAAC;QAC9C,QAAQ,IAAI,CAAC,CAAA;IACf,CAAC;IACD,OAAO,GAAG,IAAI,IAAI,QAAQ,EAAE,CAAA;AAC9B,CAAC,CAAA"}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import type { HarnessCoordinatorResponse } from "./harness-coordinator.js";
|
|
2
2
|
export declare const HARNESS_BACKGROUND_ACK_MARKER = "<!-- HARNESS_BACKGROUND_ACK -->";
|
|
3
3
|
export declare const HARNESS_INTERNAL_RESULT_MARKER = "<!-- HARNESS_INTERNAL_RESULT -->";
|
|
4
|
-
export declare const createBackgroundAckInstruction: () => string;
|
|
5
4
|
export declare const createBackgroundBusyInstruction: () => string;
|
|
6
5
|
export declare const createInternalCompletionMessage: (response: HarnessCoordinatorResponse) => string;
|
|
7
6
|
export declare const createInternalFailureMessage: (message: string) => string;
|
|
8
|
-
export declare const hasHarnessInternalResultMarker: (text: string) => boolean;
|
|
9
7
|
//# sourceMappingURL=harness-chat-protocol.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-chat-protocol.d.ts","sourceRoot":"","sources":["../../src/plugin/harness-chat-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAA;AAE1E,eAAO,MAAM,6BAA6B,oCAAoC,CAAA;AAC9E,eAAO,MAAM,8BAA8B,qCAAqC,CAAA;
|
|
1
|
+
{"version":3,"file":"harness-chat-protocol.d.ts","sourceRoot":"","sources":["../../src/plugin/harness-chat-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAA;AAE1E,eAAO,MAAM,6BAA6B,oCAAoC,CAAA;AAC9E,eAAO,MAAM,8BAA8B,qCAAqC,CAAA;AAkBhF,eAAO,MAAM,+BAA+B,QAAO,MAI/C,CAAA;AAEJ,eAAO,MAAM,+BAA+B,GAAI,UAAU,0BAA0B,KAAG,MAKnF,CAAA;AAEJ,eAAO,MAAM,4BAA4B,GAAI,SAAS,MAAM,KAAG,MAK3D,CAAA"}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
export const HARNESS_BACKGROUND_ACK_MARKER = "<!-- HARNESS_BACKGROUND_ACK -->";
|
|
2
2
|
export const HARNESS_INTERNAL_RESULT_MARKER = "<!-- HARNESS_INTERNAL_RESULT -->";
|
|
3
|
-
export const
|
|
4
|
-
kind: "background-
|
|
5
|
-
status: "accepted",
|
|
6
|
-
});
|
|
7
|
-
export const createBackgroundBusyInstruction = () => createMarkedPayload(HARNESS_BACKGROUND_ACK_MARKER, {
|
|
8
|
-
kind: "background-busy",
|
|
3
|
+
export const createBackgroundBusyInstruction = () => createMarkedPayload(HARNESS_INTERNAL_RESULT_MARKER, {
|
|
4
|
+
kind: "background-result",
|
|
9
5
|
status: "busy",
|
|
10
6
|
});
|
|
11
7
|
export const createInternalCompletionMessage = (response) => createMarkedPayload(HARNESS_INTERNAL_RESULT_MARKER, {
|
|
@@ -18,6 +14,5 @@ export const createInternalFailureMessage = (message) => createMarkedPayload(HAR
|
|
|
18
14
|
status: "failed",
|
|
19
15
|
message,
|
|
20
16
|
});
|
|
21
|
-
export const hasHarnessInternalResultMarker = (text) => text.includes(HARNESS_INTERNAL_RESULT_MARKER);
|
|
22
17
|
const createMarkedPayload = (marker, payload) => `${marker}\n${JSON.stringify(payload)}`;
|
|
23
18
|
//# sourceMappingURL=harness-chat-protocol.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-chat-protocol.js","sourceRoot":"","sources":["../../src/plugin/harness-chat-protocol.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,6BAA6B,GAAG,iCAAiC,CAAA;AAC9E,MAAM,CAAC,MAAM,8BAA8B,GAAG,kCAAkC,CAAA;
|
|
1
|
+
{"version":3,"file":"harness-chat-protocol.js","sourceRoot":"","sources":["../../src/plugin/harness-chat-protocol.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,6BAA6B,GAAG,iCAAiC,CAAA;AAC9E,MAAM,CAAC,MAAM,8BAA8B,GAAG,kCAAkC,CAAA;AAkBhF,MAAM,CAAC,MAAM,+BAA+B,GAAG,GAAW,EAAE,CAC1D,mBAAmB,CAAC,8BAA8B,EAAE;IAClD,IAAI,EAAE,mBAAmB;IACzB,MAAM,EAAE,MAAM;CACf,CAAC,CAAA;AAEJ,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,QAAoC,EAAU,EAAE,CAC9F,mBAAmB,CAAC,8BAA8B,EAAE;IAClD,IAAI,EAAE,mBAAmB;IACzB,MAAM,EAAE,WAAW;IACnB,QAAQ;CACT,CAAC,CAAA;AAEJ,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,OAAe,EAAU,EAAE,CACtE,mBAAmB,CAAC,8BAA8B,EAAE;IAClD,IAAI,EAAE,mBAAmB;IACzB,MAAM,EAAE,QAAQ;IAChB,OAAO;CACR,CAAC,CAAA;AAEJ,MAAM,mBAAmB,GAAG,CAAC,MAAc,EAAE,OAAiC,EAAU,EAAE,CACxF,GAAG,MAAM,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-request-router.d.ts","sourceRoot":"","sources":["../../src/plugin/harness-request-router.ts"],"names":[],"mappings":"AAmCA,eAAO,MAAM,+BAA+B,GAAI,WAAW,MAAM,KAAG,OAiBnE,CAAA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const LIFECYCLE_COMMAND_HEADS = [
|
|
2
|
+
"start",
|
|
3
|
+
"run",
|
|
4
|
+
"status",
|
|
5
|
+
"pause",
|
|
6
|
+
"answer",
|
|
7
|
+
"resume",
|
|
8
|
+
"cancel",
|
|
9
|
+
"waive",
|
|
10
|
+
"report",
|
|
11
|
+
];
|
|
12
|
+
const ADMIN_NOUN_PATTERNS = [
|
|
13
|
+
/\bmodels?\b/iu,
|
|
14
|
+
/模型/u,
|
|
15
|
+
/\bmcp\b/iu,
|
|
16
|
+
/\bagents?\b/iu,
|
|
17
|
+
/智能体/u,
|
|
18
|
+
/\bconfig(?:uration)?\b/iu,
|
|
19
|
+
/配置/u,
|
|
20
|
+
/\bhelp\b/iu,
|
|
21
|
+
/帮助/u,
|
|
22
|
+
/\btools?\b/iu,
|
|
23
|
+
/工具/u,
|
|
24
|
+
];
|
|
25
|
+
const QUERY_VERB_PATTERNS = [
|
|
26
|
+
/\b(?:list|show|available|current|what(?:'s| is)?|which)\b/iu,
|
|
27
|
+
/\b(?:how many|display)\b/iu,
|
|
28
|
+
/\b(?:supports|supported)\b/iu,
|
|
29
|
+
/\b(?:configured|enabled)\b/iu,
|
|
30
|
+
/\b(?:tell me|can you show)\b/iu,
|
|
31
|
+
/(?:有哪些|哪些|那些|什么|列出|列一下|查看|查询|查一下|显示|当前|可用|启用|配置了什么)/u,
|
|
32
|
+
];
|
|
33
|
+
export const shouldBypassHarnessCoordination = (inputText) => {
|
|
34
|
+
const normalizedText = inputText.trim();
|
|
35
|
+
if (normalizedText.length === 0) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const commandHead = normalizedText.split(/\s+/u)[0]?.toLowerCase();
|
|
39
|
+
if (commandHead !== undefined && isLifecycleCommandHead(commandHead)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const hasAdminNoun = ADMIN_NOUN_PATTERNS.some((pattern) => pattern.test(normalizedText));
|
|
43
|
+
if (!hasAdminNoun) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return QUERY_VERB_PATTERNS.some((pattern) => pattern.test(normalizedText));
|
|
47
|
+
};
|
|
48
|
+
const isLifecycleCommandHead = (value) => LIFECYCLE_COMMAND_HEADS.some((commandHead) => commandHead === value);
|
|
49
|
+
//# sourceMappingURL=harness-request-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-request-router.js","sourceRoot":"","sources":["../../src/plugin/harness-request-router.ts"],"names":[],"mappings":"AAAA,MAAM,uBAAuB,GAAG;IAC9B,OAAO;IACP,KAAK;IACL,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,QAAQ;CACA,CAAA;AAEV,MAAM,mBAAmB,GAAG;IAC1B,eAAe;IACf,KAAK;IACL,WAAW;IACX,eAAe;IACf,MAAM;IACN,0BAA0B;IAC1B,KAAK;IACL,YAAY;IACZ,KAAK;IACL,cAAc;IACd,KAAK;CACG,CAAA;AAEV,MAAM,mBAAmB,GAAG;IAC1B,6DAA6D;IAC7D,4BAA4B;IAC5B,8BAA8B;IAC9B,8BAA8B;IAC9B,gCAAgC;IAChC,sDAAsD;CAC9C,CAAA;AAEV,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,SAAiB,EAAW,EAAE;IAC5E,MAAM,cAAc,GAAG,SAAS,CAAC,IAAI,EAAE,CAAA;IACvC,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAA;IAClE,IAAI,WAAW,KAAK,SAAS,IAAI,sBAAsB,CAAC,WAAW,CAAC,EAAE,CAAC;QACrE,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,YAAY,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAA;IACxF,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAA;AAC5E,CAAC,CAAA;AAED,MAAM,sBAAsB,GAAG,CAAC,KAAa,EAAqD,EAAE,CAClG,uBAAuB,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,KAAK,KAAK,CAAC,CAAA"}
|
|
@@ -1,21 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import type { Context7Client } from "./context7-client.js";
|
|
3
3
|
import type { GrepAppClient } from "./grep-app-client.js";
|
|
4
4
|
import type { LspClient } from "./lsp-client.js";
|
|
5
|
-
type ResearchClients = {
|
|
5
|
+
export type ResearchClients = {
|
|
6
6
|
readonly context7: Context7Client;
|
|
7
7
|
readonly grepApp: GrepAppClient;
|
|
8
8
|
readonly lsp: LspClient;
|
|
9
9
|
};
|
|
10
|
-
export
|
|
11
|
-
readonly harness_context7_resolve: ToolDefinition;
|
|
12
|
-
readonly harness_context7_query: ToolDefinition;
|
|
13
|
-
readonly harness_grep_app_search: ToolDefinition;
|
|
14
|
-
readonly harness_lsp_status: ToolDefinition;
|
|
15
|
-
readonly harness_lsp_diagnostics: ToolDefinition;
|
|
16
|
-
readonly harness_lsp_definition: ToolDefinition;
|
|
17
|
-
readonly harness_lsp_references: ToolDefinition;
|
|
18
|
-
};
|
|
19
|
-
export declare const createHarnessResearchTools: (clients: ResearchClients) => HarnessResearchTools;
|
|
20
|
-
export {};
|
|
10
|
+
export declare const registerHarnessResearchTools: (server: McpServer, clients: ResearchClients, workspaceRoot: string) => void;
|
|
21
11
|
//# sourceMappingURL=harness-research-tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-research-tools.d.ts","sourceRoot":"","sources":["../../src/tools/harness-research-tools.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"harness-research-tools.d.ts","sourceRoot":"","sources":["../../src/tools/harness-research-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAIxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;IAC/B,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAA;CACxB,CAAA;AAED,eAAO,MAAM,4BAA4B,GACvC,QAAQ,SAAS,EACjB,SAAS,eAAe,EACxB,eAAe,MAAM,KACpB,IA8FF,CAAA"}
|
|
@@ -1,101 +1,96 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { z } from "zod";
|
|
2
2
|
import { sanitizeResearchToolOutput } from "../verification/command-policy.js";
|
|
3
|
-
const
|
|
4
|
-
"
|
|
5
|
-
"harness-worker",
|
|
6
|
-
"harness-verifier",
|
|
7
|
-
"harness-failure-analyzer",
|
|
8
|
-
]);
|
|
9
|
-
const GREP_ROLES = new Set([...RESEARCH_ROLES, "harness-acceptance"]);
|
|
10
|
-
const LSP_ROLES = new Set([...RESEARCH_ROLES, "harness-acceptance"]);
|
|
11
|
-
export const createHarnessResearchTools = (clients) => ({
|
|
12
|
-
harness_context7_resolve: tool({
|
|
3
|
+
export const registerHarnessResearchTools = (server, clients, workspaceRoot) => {
|
|
4
|
+
server.registerTool("context7_resolve", {
|
|
13
5
|
description: "Search Context7 for a library documentation source.",
|
|
14
|
-
|
|
15
|
-
libraryName:
|
|
16
|
-
query:
|
|
6
|
+
inputSchema: {
|
|
7
|
+
libraryName: z.string().trim().min(1),
|
|
8
|
+
query: z.string().trim().min(1),
|
|
17
9
|
},
|
|
18
|
-
|
|
19
|
-
}),
|
|
20
|
-
|
|
10
|
+
annotations: { readOnlyHint: true },
|
|
11
|
+
}, async ({ libraryName, query }) => researchResult(clients.context7.resolveLibrary({ libraryName, query })));
|
|
12
|
+
server.registerTool("context7_query", {
|
|
21
13
|
description: "Query official Context7 documentation snippets.",
|
|
22
|
-
|
|
23
|
-
libraryId:
|
|
14
|
+
inputSchema: {
|
|
15
|
+
libraryId: z
|
|
24
16
|
.string()
|
|
25
17
|
.trim()
|
|
26
18
|
.regex(/^\/[^/]+\/[^/]+/),
|
|
27
|
-
query:
|
|
19
|
+
query: z.string().trim().min(1),
|
|
28
20
|
},
|
|
29
|
-
|
|
30
|
-
}),
|
|
31
|
-
|
|
21
|
+
annotations: { readOnlyHint: true },
|
|
22
|
+
}, async ({ libraryId, query }) => researchResult(clients.context7.queryDocs({ libraryId, query })));
|
|
23
|
+
server.registerTool("grep_app_search", {
|
|
32
24
|
description: "Search public GitHub code through the official grep.app MCP service.",
|
|
33
|
-
|
|
34
|
-
query:
|
|
35
|
-
language:
|
|
36
|
-
repo:
|
|
37
|
-
path:
|
|
38
|
-
useRegexp:
|
|
39
|
-
matchCase:
|
|
40
|
-
matchWholeWords:
|
|
25
|
+
inputSchema: {
|
|
26
|
+
query: z.string().trim().min(1),
|
|
27
|
+
language: z.array(z.string().trim().min(1)).optional(),
|
|
28
|
+
repo: z.string().trim().min(1).optional(),
|
|
29
|
+
path: z.string().trim().min(1).optional(),
|
|
30
|
+
useRegexp: z.boolean().optional(),
|
|
31
|
+
matchCase: z.boolean().optional(),
|
|
32
|
+
matchWholeWords: z.boolean().optional(),
|
|
41
33
|
},
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
})
|
|
51
|
-
})
|
|
52
|
-
|
|
34
|
+
annotations: { readOnlyHint: true },
|
|
35
|
+
}, async (args) => researchResult(clients.grepApp.search({
|
|
36
|
+
query: args.query,
|
|
37
|
+
...(args.language === undefined ? {} : { language: args.language }),
|
|
38
|
+
...(args.repo === undefined ? {} : { repo: args.repo }),
|
|
39
|
+
...(args.path === undefined ? {} : { path: args.path }),
|
|
40
|
+
...(args.useRegexp === undefined ? {} : { useRegexp: args.useRegexp }),
|
|
41
|
+
...(args.matchCase === undefined ? {} : { matchCase: args.matchCase }),
|
|
42
|
+
...(args.matchWholeWords === undefined ? {} : { matchWholeWords: args.matchWholeWords }),
|
|
43
|
+
})));
|
|
44
|
+
server.registerTool("lsp_status", {
|
|
53
45
|
description: "Report available Harness LSP servers.",
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
})
|
|
57
|
-
|
|
46
|
+
inputSchema: {},
|
|
47
|
+
annotations: { readOnlyHint: true },
|
|
48
|
+
}, async () => researchResult(clients.lsp.status()));
|
|
49
|
+
server.registerTool("lsp_diagnostics", {
|
|
58
50
|
description: "Read diagnostics for a JavaScript, TypeScript, or Java file.",
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}),
|
|
62
|
-
|
|
51
|
+
inputSchema: lspInputSchema(),
|
|
52
|
+
annotations: { readOnlyHint: true },
|
|
53
|
+
}, async (args) => researchResult(clients.lsp.diagnostics({ ...args, workspaceRoot })));
|
|
54
|
+
server.registerTool("lsp_definition", {
|
|
63
55
|
description: "Resolve the definition at a source position.",
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}),
|
|
67
|
-
|
|
56
|
+
inputSchema: lspInputSchema(),
|
|
57
|
+
annotations: { readOnlyHint: true },
|
|
58
|
+
}, async (args) => researchResult(clients.lsp.definition({ ...args, workspaceRoot })));
|
|
59
|
+
server.registerTool("lsp_references", {
|
|
68
60
|
description: "Find references at a source position.",
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}),
|
|
72
|
-
}
|
|
73
|
-
const
|
|
74
|
-
filePath:
|
|
75
|
-
line:
|
|
76
|
-
column:
|
|
61
|
+
inputSchema: lspInputSchema(),
|
|
62
|
+
annotations: { readOnlyHint: true },
|
|
63
|
+
}, async (args) => researchResult(clients.lsp.references({ ...args, workspaceRoot })));
|
|
64
|
+
};
|
|
65
|
+
const lspInputSchema = () => ({
|
|
66
|
+
filePath: z.string().trim().min(1),
|
|
67
|
+
line: z.number().int().positive(),
|
|
68
|
+
column: z.number().int().positive(),
|
|
77
69
|
});
|
|
78
|
-
const
|
|
79
|
-
if (!context.agent.startsWith("harness-")) {
|
|
80
|
-
return JSON.stringify({
|
|
81
|
-
status: "denied",
|
|
82
|
-
reason: "tool is restricted to Harness internal agents",
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
if (!allowedRoles.has(context.agent)) {
|
|
86
|
-
return JSON.stringify({
|
|
87
|
-
status: "denied",
|
|
88
|
-
reason: "tool is restricted to Harness internal agents",
|
|
89
|
-
});
|
|
90
|
-
}
|
|
70
|
+
const researchResult = async (operation) => {
|
|
91
71
|
try {
|
|
92
|
-
return
|
|
72
|
+
return {
|
|
73
|
+
content: [
|
|
74
|
+
{
|
|
75
|
+
type: "text",
|
|
76
|
+
text: JSON.stringify({ status: "ok", data: sanitizeResearchToolOutput(await operation) }),
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
};
|
|
93
80
|
}
|
|
94
81
|
catch (error) {
|
|
95
|
-
return
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
82
|
+
return {
|
|
83
|
+
content: [
|
|
84
|
+
{
|
|
85
|
+
type: "text",
|
|
86
|
+
text: JSON.stringify({
|
|
87
|
+
status: "error",
|
|
88
|
+
error: error instanceof Error ? error.message : "Harness research tool failed",
|
|
89
|
+
}),
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
isError: true,
|
|
93
|
+
};
|
|
99
94
|
}
|
|
100
95
|
};
|
|
101
96
|
//# sourceMappingURL=harness-research-tools.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-research-tools.js","sourceRoot":"","sources":["../../src/tools/harness-research-tools.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"harness-research-tools.js","sourceRoot":"","sources":["../../src/tools/harness-research-tools.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "harness-engineering-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Minimal OpenCode harness plugin package.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -14,8 +14,15 @@
|
|
|
14
14
|
"./server": {
|
|
15
15
|
"types": "./dist/server.d.ts",
|
|
16
16
|
"import": "./dist/server.js"
|
|
17
|
+
},
|
|
18
|
+
"./mcp": {
|
|
19
|
+
"types": "./dist/mcp/server.d.ts",
|
|
20
|
+
"import": "./dist/mcp/server.js"
|
|
17
21
|
}
|
|
18
22
|
},
|
|
23
|
+
"bin": {
|
|
24
|
+
"harness-engineering-agent-mcp": "./dist/mcp/cli.js"
|
|
25
|
+
},
|
|
19
26
|
"files": [
|
|
20
27
|
"dist"
|
|
21
28
|
],
|
|
@@ -33,6 +40,7 @@
|
|
|
33
40
|
"typecheck": "tsc --noEmit"
|
|
34
41
|
},
|
|
35
42
|
"dependencies": {
|
|
43
|
+
"@modelcontextprotocol/sdk": "1.29.0",
|
|
36
44
|
"@opencode-ai/plugin": "1.17.11",
|
|
37
45
|
"@opencode-ai/sdk": "1.17.11",
|
|
38
46
|
"typescript-language-server": "5.3.0",
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import type { OpencodeClient } from "@opencode-ai/sdk";
|
|
2
|
-
import type { HarnessConfig } from "../config/index.js";
|
|
3
|
-
export type ParentPromptAsyncRequest = {
|
|
4
|
-
readonly path: {
|
|
5
|
-
readonly id: string;
|
|
6
|
-
};
|
|
7
|
-
readonly query: {
|
|
8
|
-
readonly directory: string;
|
|
9
|
-
};
|
|
10
|
-
readonly body: {
|
|
11
|
-
readonly agent: "harness";
|
|
12
|
-
readonly model: {
|
|
13
|
-
readonly providerID: string;
|
|
14
|
-
readonly modelID: string;
|
|
15
|
-
};
|
|
16
|
-
readonly parts: ParentTextPartInput[];
|
|
17
|
-
};
|
|
18
|
-
readonly throwOnError: true;
|
|
19
|
-
};
|
|
20
|
-
type ParentTextPartInput = {
|
|
21
|
-
readonly type: "text";
|
|
22
|
-
readonly text: string;
|
|
23
|
-
readonly synthetic: true;
|
|
24
|
-
readonly metadata: {
|
|
25
|
-
readonly source: "harness";
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
export type ParentSessionPromptDispatcher = {
|
|
29
|
-
readonly dispatchInternalCompletion: (input: {
|
|
30
|
-
readonly sessionID: string;
|
|
31
|
-
readonly directory: string;
|
|
32
|
-
readonly text: string;
|
|
33
|
-
}) => Promise<void>;
|
|
34
|
-
};
|
|
35
|
-
type ParentSessionClient = {
|
|
36
|
-
readonly session: {
|
|
37
|
-
readonly promptAsync: (input: ParentPromptAsyncRequest) => Promise<unknown>;
|
|
38
|
-
};
|
|
39
|
-
};
|
|
40
|
-
export declare const createParentSessionPromptDispatcher: (input: {
|
|
41
|
-
readonly client: ParentSessionClient;
|
|
42
|
-
readonly config: HarnessConfig;
|
|
43
|
-
}) => ParentSessionPromptDispatcher;
|
|
44
|
-
export declare const asParentSessionClient: (client: OpencodeClient) => ParentSessionClient;
|
|
45
|
-
export {};
|
|
46
|
-
//# sourceMappingURL=harness-parent-session-dispatcher.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"harness-parent-session-dispatcher.d.ts","sourceRoot":"","sources":["../../src/plugin/harness-parent-session-dispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IACtC,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9C,QAAQ,CAAC,IAAI,EAAE;QACb,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;QACzB,QAAQ,CAAC,KAAK,EAAE;YACd,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;YAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SACzB,CAAA;QACD,QAAQ,CAAC,KAAK,EAAE,mBAAmB,EAAE,CAAA;KACtC,CAAA;IACD,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAA;CAC5B,CAAA;AAED,KAAK,mBAAmB,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;KAC3B,CAAA;CACF,CAAA;AAED,MAAM,MAAM,6BAA6B,GAAG;IAC1C,QAAQ,CAAC,0BAA0B,EAAE,CAAC,KAAK,EAAE;QAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;QAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;QAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KACtB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACpB,CAAA;AAED,KAAK,mBAAmB,GAAG;IACzB,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;KAC5E,CAAA;CACF,CAAA;AAED,eAAO,MAAM,mCAAmC,GAAI,OAAO;IACzD,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAA;IACpC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;CAC/B,KAAG,6BAkBH,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,QAAQ,cAAc,KAAG,mBAI7D,CAAA"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
export const createParentSessionPromptDispatcher = (input) => {
|
|
2
|
-
return {
|
|
3
|
-
dispatchInternalCompletion: async ({ directory, sessionID, text }) => {
|
|
4
|
-
await input.client.session.promptAsync({
|
|
5
|
-
path: { id: sessionID },
|
|
6
|
-
query: { directory },
|
|
7
|
-
body: {
|
|
8
|
-
agent: "harness",
|
|
9
|
-
model: {
|
|
10
|
-
providerID: input.config.harness.provider,
|
|
11
|
-
modelID: input.config.harness.model,
|
|
12
|
-
},
|
|
13
|
-
parts: [createSyntheticTextPart(text)],
|
|
14
|
-
},
|
|
15
|
-
throwOnError: true,
|
|
16
|
-
});
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
|
-
export const asParentSessionClient = (client) => ({
|
|
21
|
-
session: {
|
|
22
|
-
promptAsync: (request) => client.session.promptAsync(request),
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
const createSyntheticTextPart = (text) => ({
|
|
26
|
-
type: "text",
|
|
27
|
-
text,
|
|
28
|
-
synthetic: true,
|
|
29
|
-
metadata: {
|
|
30
|
-
source: "harness",
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
//# sourceMappingURL=harness-parent-session-dispatcher.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"harness-parent-session-dispatcher.js","sourceRoot":"","sources":["../../src/plugin/harness-parent-session-dispatcher.ts"],"names":[],"mappings":"AAyCA,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,KAGnD,EAAiC,EAAE;IAClC,OAAO;QACL,0BAA0B,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE;YACnE,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;gBACrC,IAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE;gBACvB,KAAK,EAAE,EAAE,SAAS,EAAE;gBACpB,IAAI,EAAE;oBACJ,KAAK,EAAE,SAAS;oBAChB,KAAK,EAAE;wBACL,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ;wBACzC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK;qBACpC;oBACD,KAAK,EAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;iBACvC;gBACD,YAAY,EAAE,IAAI;aACnB,CAAC,CAAA;QACJ,CAAC;KACF,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAAsB,EAAuB,EAAE,CAAC,CAAC;IACrF,OAAO,EAAE;QACP,WAAW,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC;KAC9D;CACF,CAAC,CAAA;AAEF,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAuB,EAAE,CAAC,CAAC;IACtE,IAAI,EAAE,MAAM;IACZ,IAAI;IACJ,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE;QACR,MAAM,EAAE,SAAS;KAClB;CACF,CAAC,CAAA"}
|