@ddtcorex/dsh-maestro-review 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -0
- package/client/settings-card.tsx +4 -0
- package/lib/config-store.d.ts +53 -0
- package/lib/config-store.d.ts.map +1 -0
- package/lib/config-store.js +60 -0
- package/lib/config-store.js.map +1 -0
- package/lib/events.d.ts +27 -0
- package/lib/events.d.ts.map +1 -0
- package/lib/events.js +2 -0
- package/lib/events.js.map +1 -0
- package/lib/gitlab-client.d.ts +14 -0
- package/lib/gitlab-client.d.ts.map +1 -0
- package/lib/gitlab-client.js +146 -0
- package/lib/gitlab-client.js.map +1 -0
- package/lib/gitlab-webhook.d.ts +17 -0
- package/lib/gitlab-webhook.d.ts.map +1 -0
- package/lib/gitlab-webhook.js +144 -0
- package/lib/gitlab-webhook.js.map +1 -0
- package/lib/govard-tool.d.ts +11 -0
- package/lib/govard-tool.d.ts.map +1 -0
- package/lib/govard-tool.js +95 -0
- package/lib/govard-tool.js.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +15 -0
- package/lib/index.js.map +1 -0
- package/lib/notify.d.ts +23 -0
- package/lib/notify.d.ts.map +1 -0
- package/lib/notify.js +10 -0
- package/lib/notify.js.map +1 -0
- package/lib/orchestrator.d.ts +144 -0
- package/lib/orchestrator.d.ts.map +1 -0
- package/lib/orchestrator.js +655 -0
- package/lib/orchestrator.js.map +1 -0
- package/lib/pin-store.d.ts +5 -0
- package/lib/pin-store.d.ts.map +1 -0
- package/lib/pin-store.js +5 -0
- package/lib/pin-store.js.map +1 -0
- package/lib/providers/github.stub.d.ts +3 -0
- package/lib/providers/github.stub.d.ts.map +1 -0
- package/lib/providers/github.stub.js +10 -0
- package/lib/providers/github.stub.js.map +1 -0
- package/lib/providers/gitlab.d.ts +13 -0
- package/lib/providers/gitlab.d.ts.map +1 -0
- package/lib/providers/gitlab.js +173 -0
- package/lib/providers/gitlab.js.map +1 -0
- package/lib/providers/interface.d.ts +12 -0
- package/lib/providers/interface.d.ts.map +1 -0
- package/lib/providers/interface.js +2 -0
- package/lib/providers/interface.js.map +1 -0
- package/lib/review-findings-tool.d.ts +15 -0
- package/lib/review-findings-tool.d.ts.map +1 -0
- package/lib/review-findings-tool.js +37 -0
- package/lib/review-findings-tool.js.map +1 -0
- package/lib/review-history.d.ts +35 -0
- package/lib/review-history.d.ts.map +1 -0
- package/lib/review-history.js +87 -0
- package/lib/review-history.js.map +1 -0
- package/lib/review-intake.d.ts +7 -0
- package/lib/review-intake.d.ts.map +1 -0
- package/lib/review-intake.js +80 -0
- package/lib/review-intake.js.map +1 -0
- package/lib/review-signals.d.ts +17 -0
- package/lib/review-signals.d.ts.map +1 -0
- package/lib/review-signals.js +49 -0
- package/lib/review-signals.js.map +1 -0
- package/lib/secure-compare.d.ts +7 -0
- package/lib/secure-compare.d.ts.map +1 -0
- package/lib/secure-compare.js +14 -0
- package/lib/secure-compare.js.map +1 -0
- package/lib/settings-rpc.d.ts +22 -0
- package/lib/settings-rpc.d.ts.map +1 -0
- package/lib/settings-rpc.js +252 -0
- package/lib/settings-rpc.js.map +1 -0
- package/lib/skills-tool.d.ts +29 -0
- package/lib/skills-tool.d.ts.map +1 -0
- package/lib/skills-tool.js +160 -0
- package/lib/skills-tool.js.map +1 -0
- package/lib/workspace-tool.d.ts +10 -0
- package/lib/workspace-tool.d.ts.map +1 -0
- package/lib/workspace-tool.js +86 -0
- package/lib/workspace-tool.js.map +1 -0
- package/package.json +53 -0
- package/presets/maestro-auditor/agent.cordis.yml +10 -0
- package/presets/maestro-auditor/preset.yml +2 -0
- package/presets/maestro-coder/agent.cordis.yml +223 -0
- package/presets/maestro-coder/preset.yml +2 -0
- package/presets/maestro-reviewer/agent.cordis.yml +14 -0
- package/presets/maestro-reviewer/preset.yml +2 -0
- package/src/augment.d.ts +47 -0
- package/src/config-store.ts +109 -0
- package/src/events.ts +25 -0
- package/src/gitlab-client.ts +186 -0
- package/src/gitlab-webhook.ts +166 -0
- package/src/govard-tool.ts +114 -0
- package/src/index.ts +15 -0
- package/src/notify.ts +30 -0
- package/src/orchestrator.ts +740 -0
- package/src/pin-store.ts +4 -0
- package/src/providers/github.stub.ts +11 -0
- package/src/providers/gitlab.ts +190 -0
- package/src/providers/interface.ts +2 -0
- package/src/review-findings-tool.ts +51 -0
- package/src/review-history.ts +112 -0
- package/src/review-intake.ts +86 -0
- package/src/review-signals.ts +52 -0
- package/src/secure-compare.ts +13 -0
- package/src/settings-rpc.ts +249 -0
- package/src/skills-tool.ts +193 -0
- package/src/workspace-tool.ts +90 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-tool.d.ts","sourceRoot":"","sources":["../src/workspace-tool.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAGxC,eAAO,MAAM,IAAI,2BAA2B,CAAA;AAC5C,eAAO,MAAM,MAAM,UAAY,CAAA;AAE/B,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,eAAO,MAAM,MAAM,EAAE,CAAC,CAAC,MAAM,CAE3B,CAAA;AAkCF,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,MAAW,GAAG,IAAI,CAwC7D"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { basename, dirname, resolve, sep } from 'node:path';
|
|
2
|
+
import { mkdir, readFile, realpath, writeFile } from 'node:fs/promises';
|
|
3
|
+
import z from '@deepseek-ai/schemastery';
|
|
4
|
+
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
5
|
+
export const name = 'maestro-workspace-tool';
|
|
6
|
+
export const inject = ['tools'];
|
|
7
|
+
export const Config = z.object({
|
|
8
|
+
rootPath: z.string(),
|
|
9
|
+
});
|
|
10
|
+
async function resolveInRoot(rootPath, requestedPath) {
|
|
11
|
+
const absoluteRoot = resolve(rootPath);
|
|
12
|
+
const target = resolve(absoluteRoot, requestedPath);
|
|
13
|
+
if (target !== absoluteRoot && !target.startsWith(absoluteRoot + sep))
|
|
14
|
+
return undefined;
|
|
15
|
+
let realRoot;
|
|
16
|
+
try {
|
|
17
|
+
realRoot = await realpath(absoluteRoot);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
let existing = target;
|
|
23
|
+
const pending = [];
|
|
24
|
+
while (true) {
|
|
25
|
+
let real;
|
|
26
|
+
try {
|
|
27
|
+
real = await realpath(existing);
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
if (err.code !== 'ENOENT')
|
|
31
|
+
return undefined;
|
|
32
|
+
const parent = dirname(existing);
|
|
33
|
+
if (parent === existing)
|
|
34
|
+
return undefined;
|
|
35
|
+
pending.unshift(basename(existing));
|
|
36
|
+
existing = parent;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const realTarget = pending.length > 0 ? resolve(real, ...pending) : real;
|
|
40
|
+
if (realTarget !== realRoot && !realTarget.startsWith(realRoot + sep))
|
|
41
|
+
return undefined;
|
|
42
|
+
return target;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export function apply(ctx, config = {}) {
|
|
46
|
+
const rootPath = config.rootPath ?? process.cwd();
|
|
47
|
+
ctx.tools.register(defineTool({
|
|
48
|
+
name: 'maestro_read_file',
|
|
49
|
+
description: 'Read a text file relative to the current workspace root.',
|
|
50
|
+
parameters: {
|
|
51
|
+
path: { type: 'string', required: true, description: 'Path relative to the workspace root.' },
|
|
52
|
+
},
|
|
53
|
+
output: {
|
|
54
|
+
schema: { type: 'object', additionalProperties: false, properties: { text: { type: 'string', required: true } } },
|
|
55
|
+
render: (_args, value) => [{ type: 'text', text: value.text }],
|
|
56
|
+
},
|
|
57
|
+
async execute(args) {
|
|
58
|
+
const target = await resolveInRoot(rootPath, args.path);
|
|
59
|
+
if (target === undefined)
|
|
60
|
+
return { isError: true, text: `Path "${args.path}" escapes the workspace root.` };
|
|
61
|
+
const text = await readFile(target, 'utf-8');
|
|
62
|
+
return { text };
|
|
63
|
+
},
|
|
64
|
+
}));
|
|
65
|
+
ctx.tools.register(defineTool({
|
|
66
|
+
name: 'maestro_write_file',
|
|
67
|
+
description: 'Write a text file relative to the current workspace root, creating parent directories as needed.',
|
|
68
|
+
parameters: {
|
|
69
|
+
path: { type: 'string', required: true, description: 'Path relative to the workspace root.' },
|
|
70
|
+
content: { type: 'string', required: true, description: 'File content to write.' },
|
|
71
|
+
},
|
|
72
|
+
output: {
|
|
73
|
+
schema: { type: 'object', additionalProperties: false, properties: { written: { type: 'boolean', required: true } } },
|
|
74
|
+
render: (args) => [{ type: 'text', text: `Wrote ${args.path}` }],
|
|
75
|
+
},
|
|
76
|
+
async execute(args) {
|
|
77
|
+
const target = await resolveInRoot(rootPath, args.path);
|
|
78
|
+
if (target === undefined)
|
|
79
|
+
return { isError: true, text: `Path "${args.path}" escapes the workspace root.` };
|
|
80
|
+
await mkdir(dirname(target), { recursive: true });
|
|
81
|
+
await writeFile(target, args.content, 'utf-8');
|
|
82
|
+
return { written: true };
|
|
83
|
+
},
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=workspace-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-tool.js","sourceRoot":"","sources":["../src/workspace-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAC3D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEvE,OAAO,CAAC,MAAM,0BAA0B,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAEnD,MAAM,CAAC,MAAM,IAAI,GAAG,wBAAwB,CAAA;AAC5C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,CAAA;AAM/B,MAAM,CAAC,MAAM,MAAM,GAAc,CAAC,CAAC,MAAM,CAAC;IACxC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;CACrB,CAAC,CAAA;AAEF,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,aAAqB;IAClE,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IACtC,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,aAAa,CAAC,CAAA;IACnD,IAAI,MAAM,KAAK,YAAY,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,GAAG,GAAG,CAAC;QAAE,OAAO,SAAS,CAAA;IAEvF,IAAI,QAAgB,CAAA;IACpB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAA;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,IAAI,QAAQ,GAAG,MAAM,CAAA;IACrB,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,IAAY,CAAA;QAChB,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAA;QACjC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,SAAS,CAAA;YACtE,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;YAChC,IAAI,MAAM,KAAK,QAAQ;gBAAE,OAAO,SAAS,CAAA;YACzC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAA;YACnC,QAAQ,GAAG,MAAM,CAAA;YACjB,SAAQ;QACV,CAAC;QACD,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACxE,IAAI,UAAU,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,QAAQ,GAAG,GAAG,CAAC;YAAE,OAAO,SAAS,CAAA;QACvF,OAAO,MAAM,CAAA;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAY,EAAE,SAAiB,EAAE;IACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IAEjD,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC5B,IAAI,EAAE,mBAAmB;QACzB,WAAW,EAAE,0DAA0D;QACvE,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,sCAAsC,EAAE;SAC9F;QACD,MAAM,EAAE;YACN,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE;YACjH,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;SAC/D;QACD,KAAK,CAAC,OAAO,CAAC,IAAI;YAChB,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;YACvD,IAAI,MAAM,KAAK,SAAS;gBAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,IAAI,CAAC,IAAI,+BAA+B,EAAW,CAAA;YACpH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;YAC5C,OAAO,EAAE,IAAI,EAAE,CAAA;QACjB,CAAC;KACF,CAAC,CAAC,CAAA;IAEH,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC5B,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,kGAAkG;QAC/G,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,sCAAsC,EAAE;YAC7F,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,wBAAwB,EAAE;SACnF;QACD,MAAM,EAAE;YACN,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE;YACrH,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;SACjE;QACD,KAAK,CAAC,OAAO,CAAC,IAAI;YAChB,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;YACvD,IAAI,MAAM,KAAK,SAAS;gBAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,IAAI,CAAC,IAAI,+BAA+B,EAAW,CAAA;YACpH,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YACjD,MAAM,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC9C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;QAC1B,CAAC;KACF,CAAC,CAAC,CAAA;AACL,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ddtcorex/dsh-maestro-review",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Maestro Review — pluggable ReviewProvider (GitLab/GitHub) + orchestrator for automated MR review",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./lib/index.js",
|
|
7
|
+
"types": "./lib/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./lib/index.js",
|
|
10
|
+
"./lib/*": "./lib/*",
|
|
11
|
+
"./package.json": "./package.json"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"README.md",
|
|
15
|
+
"lib",
|
|
16
|
+
"src",
|
|
17
|
+
"presets",
|
|
18
|
+
"client"
|
|
19
|
+
],
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
22
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.1-rc.2"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@deepseek-ai/schemastery": "^3.0.0",
|
|
26
|
+
"@ddtcorex/dsh-maestro-config-lib": "^0.1.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
30
|
+
"typescript": "^5.8.0",
|
|
31
|
+
"vitest": "^2.0.0",
|
|
32
|
+
"@types/node": "^22.0.0",
|
|
33
|
+
"@deepseek-ai/dsh-agent": "0.1.0-rc.8",
|
|
34
|
+
"@deepseek-ai/dsh-agent-default-model": "0.1.0-rc.8",
|
|
35
|
+
"@deepseek-ai/dsh-agent-presets": "0.1.0-rc.8",
|
|
36
|
+
"@deepseek-ai/dsh-host-apiproxy": "0.1.0-rc.8",
|
|
37
|
+
"@deepseek-ai/dsh-llm": "0.1.0-rc.8",
|
|
38
|
+
"@deepseek-ai/dsh-session": "0.1.0-rc.8",
|
|
39
|
+
"@deepseek-ai/dsh-session-title": "0.1.0-rc.8",
|
|
40
|
+
"@deepseek-ai/dsh-subagent": "0.1.0-rc.8",
|
|
41
|
+
"@deepseek-ai/dsh-tools": "0.1.0-rc.8"
|
|
42
|
+
},
|
|
43
|
+
"dsh": {
|
|
44
|
+
"bundle": {
|
|
45
|
+
"patch": "./cordis.patch.yml"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsc",
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"verify": "tsc --noEmit"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
- id: persona
|
|
2
|
+
name: '@deepseek-ai/dsh-persona'
|
|
3
|
+
config:
|
|
4
|
+
text: |
|
|
5
|
+
You are Maestro Auditor, a Performance Architect. Workflow:
|
|
6
|
+
1. Call govard_env_up to bring up the merge request's Magento 2 environment.
|
|
7
|
+
2. Call govard_shell to run the test suite (e.g. "vendor/bin/phpunit") and any profiling commands.
|
|
8
|
+
3. Analyze the output for regressions, N+1 queries, or memory issues.
|
|
9
|
+
4. Call govard_env_down to tear the environment down.
|
|
10
|
+
5. Output a Markdown report. Do not call gitlab_post_mr_comment yourself — the orchestrator posts the combined report.
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# Non-persona rows below are copied from maestro-skills/.dsh-plugin/agent.cordis.yml
|
|
2
|
+
# (formerly agent-dev-skills), which is itself derived from DeepSeek Harness's
|
|
3
|
+
# `standard` preset (MIT License, Copyright (c) 2026 DeepSeek). Attribution
|
|
4
|
+
# retained per MIT license requirements.
|
|
5
|
+
|
|
6
|
+
- id: agent-instructions
|
|
7
|
+
name: '@deepseek-ai/dsh-agent-instructions'
|
|
8
|
+
config:
|
|
9
|
+
maxBytes: 65536
|
|
10
|
+
|
|
11
|
+
# ── shell ───────────────────────────────────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
# `shell-env` stays in the HOST composition: it publishes host-level env vars
|
|
14
|
+
# before any session exists, so there is no agent to key it by. Both shell
|
|
15
|
+
# tools here consume the host registry; their executors (`bash-sandbox`/
|
|
16
|
+
# `pwsh-sandbox`) are host-plane too.
|
|
17
|
+
- id: tool-bash
|
|
18
|
+
name: '@deepseek-ai/dsh-tool-bash'
|
|
19
|
+
disabled: !!js process.platform === 'win32'
|
|
20
|
+
|
|
21
|
+
- id: tool-pwsh
|
|
22
|
+
name: '@deepseek-ai/dsh-tool-pwsh'
|
|
23
|
+
disabled: !!js process.platform !== 'win32'
|
|
24
|
+
|
|
25
|
+
# ── filesystem ──────────────────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
# Both register into the host `tools` registry and provide nothing, so
|
|
28
|
+
# they need no realm. The `fs` service and its policy stay in the host.
|
|
29
|
+
- id: tool-fs
|
|
30
|
+
name: '@deepseek-ai/dsh-tool-fs'
|
|
31
|
+
|
|
32
|
+
- id: tool-fs-search
|
|
33
|
+
name: '@deepseek-ai/dsh-tool-fs-search'
|
|
34
|
+
config:
|
|
35
|
+
sampleOverCapGlobResults: false
|
|
36
|
+
|
|
37
|
+
# ── background jobs ────────────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
# Only the model-facing controls. The task registry stays on the host plane
|
|
40
|
+
# and is keyed by owning agent, so one host instance serves every session;
|
|
41
|
+
# what this preset chooses is whether its agent can use `run_in_background`.
|
|
42
|
+
- id: tool-jobs
|
|
43
|
+
name: '@deepseek-ai/dsh-tool-jobs'
|
|
44
|
+
|
|
45
|
+
# ── skills ──────────────────────────────────────────────────────────────────
|
|
46
|
+
|
|
47
|
+
# The skill registry lives in the host composition and is layered per scope,
|
|
48
|
+
# so these rows register into this preset's layer without needing a realm.
|
|
49
|
+
# skill-filesystem scans ~/.dsh/skills/ by default. Install maestro-skills
|
|
50
|
+
# (plugin or installer) for DSH; this package's install.sh validates the Magento
|
|
51
|
+
# review set.
|
|
52
|
+
- id: skill-filesystem
|
|
53
|
+
name: '@deepseek-ai/dsh-skill-filesystem'
|
|
54
|
+
|
|
55
|
+
- id: tool-skill
|
|
56
|
+
name: '@deepseek-ai/dsh-tool-skill'
|
|
57
|
+
|
|
58
|
+
# ── goals ───────────────────────────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
# Only the model-facing tool. The goal service, its session driver, and the
|
|
61
|
+
# `/goal` command stay on the host plane and are keyed by session, so what
|
|
62
|
+
# this preset chooses is whether its agent can call the goal tool.
|
|
63
|
+
- id: tool-goal
|
|
64
|
+
name: '@deepseek-ai/dsh-tool-goal'
|
|
65
|
+
|
|
66
|
+
# ── plan mode ───────────────────────────────────────────────────────────────
|
|
67
|
+
|
|
68
|
+
- id: planning
|
|
69
|
+
name: cordis:group
|
|
70
|
+
group: true
|
|
71
|
+
isolate:
|
|
72
|
+
planMode: true
|
|
73
|
+
config:
|
|
74
|
+
- id: plan-mode
|
|
75
|
+
name: '@deepseek-ai/dsh-plan-mode'
|
|
76
|
+
config:
|
|
77
|
+
section: |
|
|
78
|
+
You are in plan mode. Stay in plan mode until exit_plan_mode succeeds or the user switches the session mode. Imperative language to implement changes means plan the implementation, not execute it. A user's conversational agreement — including an answer confirming something you asked — approves nothing and does not end plan mode; fold the confirmed decision into the plan and submit it through exit_plan_mode.
|
|
79
|
+
|
|
80
|
+
Explore first. Use non-mutating reads, searches, static analysis, and checks to ground the plan in the actual repository. Do not edit or write files, change configuration, run formatters or code generation that rewrites tracked files, commit, or otherwise carry out the plan. Prefer existing functions and patterns over new machinery.
|
|
81
|
+
|
|
82
|
+
The tool catalog stays the same across modes for request-cache stability. These plan-mode rules override any later tool description or guidance that suggests using mutation tools; those tools remain listed to keep the tool catalog unchanged. Do not use todo_write to track this planning phase: it tracks implementation after an approved plan, while the plan itself belongs in exit_plan_mode.
|
|
83
|
+
|
|
84
|
+
Resolve discoverable facts by inspection. Use ask_user_question only for user-owned choices or material ambiguity that inspection cannot answer. Do not ask the user where code lives or how current behavior works when you can find out.
|
|
85
|
+
|
|
86
|
+
Make the plan decision-complete: state the goal and success criteria; group implementation changes by subsystem; identify public API, schema, and data-flow changes; cover edge cases, failure modes, tests, acceptance criteria, and explicit assumptions. Keep it concise enough to review but detailed enough that another engineer can implement it without making design decisions.
|
|
87
|
+
|
|
88
|
+
When ready, call exit_plan_mode with the complete plan markdown, starting with a # title. Make exit_plan_mode the only and final tool call in that assistant response: it presents the plan for approval, and implementation begins only in a later step after approval. Do not paste the final plan as a plain reply or ask "should I proceed?" through prose or ask_user_question. If review rejects it, incorporate the feedback and present again. If the review channel is unavailable or aborted, stay in plan mode and ask the user to switch modes manually; do not proceed with implementation.
|
|
89
|
+
|
|
90
|
+
# ── compaction ──────────────────────────────────────────────────────────────
|
|
91
|
+
|
|
92
|
+
# `compaction-basic` reads `toolResultPrune` through `ctx.get`, so the pruner
|
|
93
|
+
# must share this realm rather than sit outside it. `tokenMeter` is
|
|
94
|
+
# deliberately NOT in this realm: the meter stays on the HOST plane, keyed by
|
|
95
|
+
# Session, so what this preset chooses is only whether its agent compacts.
|
|
96
|
+
- id: compaction
|
|
97
|
+
name: cordis:group
|
|
98
|
+
group: true
|
|
99
|
+
isolate:
|
|
100
|
+
compaction: true
|
|
101
|
+
toolResultPruner: true
|
|
102
|
+
config:
|
|
103
|
+
- id: compaction-basic
|
|
104
|
+
name: '@deepseek-ai/dsh-compaction-basic'
|
|
105
|
+
|
|
106
|
+
- id: command-compact
|
|
107
|
+
name: '@deepseek-ai/dsh-command-compact'
|
|
108
|
+
|
|
109
|
+
- id: tool-result-pruner
|
|
110
|
+
name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
|
|
111
|
+
config:
|
|
112
|
+
thresholdChars: 8192
|
|
113
|
+
headChars: 4096
|
|
114
|
+
tailChars: 1024
|
|
115
|
+
|
|
116
|
+
# ── delegation and workflows ────────────────────────────────────────────────
|
|
117
|
+
|
|
118
|
+
# The `subagents` registry and its spawn/fork backends live in the HOST
|
|
119
|
+
# composition: it's a process singleton, and this preset contributes only the
|
|
120
|
+
# delegation TOOLS that resolve that registry. `workflows` is different —
|
|
121
|
+
# nothing outside an agent reads it — so every row reaching it shares this
|
|
122
|
+
# one entry-local realm.
|
|
123
|
+
- id: delegation
|
|
124
|
+
name: cordis:group
|
|
125
|
+
group: true
|
|
126
|
+
isolate:
|
|
127
|
+
workflowEngine: true
|
|
128
|
+
config:
|
|
129
|
+
- id: tool-subagent-control
|
|
130
|
+
name: '@deepseek-ai/dsh-tool-subagent-control'
|
|
131
|
+
|
|
132
|
+
- id: tool-subagent-list-agents
|
|
133
|
+
name: '@deepseek-ai/dsh-tool-subagent-control/list-agents'
|
|
134
|
+
|
|
135
|
+
- id: tool-subagent
|
|
136
|
+
name: '@deepseek-ai/dsh-tool-subagent'
|
|
137
|
+
config:
|
|
138
|
+
provider: spawn
|
|
139
|
+
toolName: subagent
|
|
140
|
+
backgroundMode: continuable
|
|
141
|
+
|
|
142
|
+
- id: tool-subagent-fork
|
|
143
|
+
name: '@deepseek-ai/dsh-tool-subagent'
|
|
144
|
+
config:
|
|
145
|
+
provider: fork
|
|
146
|
+
toolName: subagent_fork
|
|
147
|
+
backgroundMode: continuable
|
|
148
|
+
|
|
149
|
+
# Production dsh does not install these optional providers. Install the
|
|
150
|
+
# matching Bundle in this Profile and restart the Host, then copy this
|
|
151
|
+
# preset and remove `disabled` from the matching tool row. Host
|
|
152
|
+
# availability alone grants no tool.
|
|
153
|
+
- id: tool-subagent-codex
|
|
154
|
+
name: '@deepseek-ai/dsh-tool-subagent'
|
|
155
|
+
disabled: true
|
|
156
|
+
config:
|
|
157
|
+
provider: codex
|
|
158
|
+
toolName: subagent_codex
|
|
159
|
+
backgroundMode: one-shot
|
|
160
|
+
maxDepth: provider-managed
|
|
161
|
+
|
|
162
|
+
- id: tool-subagent-claude-code
|
|
163
|
+
name: '@deepseek-ai/dsh-tool-subagent'
|
|
164
|
+
disabled: true
|
|
165
|
+
config:
|
|
166
|
+
provider: claude-code
|
|
167
|
+
toolName: subagent_claude_code
|
|
168
|
+
backgroundMode: one-shot
|
|
169
|
+
maxDepth: provider-managed
|
|
170
|
+
|
|
171
|
+
- id: workflow-worker-thread
|
|
172
|
+
name: '@deepseek-ai/dsh-workflow-worker-thread'
|
|
173
|
+
config:
|
|
174
|
+
provider: spawn
|
|
175
|
+
|
|
176
|
+
- id: tool-workflow
|
|
177
|
+
name: '@deepseek-ai/dsh-tool-workflow'
|
|
178
|
+
|
|
179
|
+
- id: tool-ralph
|
|
180
|
+
name: '@deepseek-ai/dsh-tool-ralph'
|
|
181
|
+
config:
|
|
182
|
+
subagentProvider: spawn
|
|
183
|
+
maxRounds: 64
|
|
184
|
+
|
|
185
|
+
# ── remaining model-facing rows ─────────────────────────────────────────────
|
|
186
|
+
|
|
187
|
+
- id: tool-ask-user
|
|
188
|
+
name: '@deepseek-ai/dsh-tool-ask-user'
|
|
189
|
+
|
|
190
|
+
- id: tool-todo
|
|
191
|
+
name: '@deepseek-ai/dsh-tool-todo'
|
|
192
|
+
config:
|
|
193
|
+
allowParallelInProgress: true
|
|
194
|
+
|
|
195
|
+
- id: tool-web
|
|
196
|
+
name: '@deepseek-ai/dsh-tool-web'
|
|
197
|
+
config:
|
|
198
|
+
fetch: false
|
|
199
|
+
searchTimeoutMs: 60000
|
|
200
|
+
|
|
201
|
+
# ── maestro-coder-specific rows ─────────────────────────────────────────────
|
|
202
|
+
|
|
203
|
+
- id: persona
|
|
204
|
+
name: '@deepseek-ai/dsh-persona'
|
|
205
|
+
config:
|
|
206
|
+
text: |
|
|
207
|
+
You are Maestro Coder, a strictly-compliant Pair Programming Assistant.
|
|
208
|
+
MANDATORY WORKFLOW:
|
|
209
|
+
1. Always call maestro_get_skills BEFORE writing code to understand the conventions.
|
|
210
|
+
2. Use maestro_read_file to analyze existing project modules.
|
|
211
|
+
3. Write highly optimized, clean code and save via maestro_write_file.
|
|
212
|
+
4. If requested, call govard_shell to run unit tests and verify your code. Do not explain unnecessarily.
|
|
213
|
+
|
|
214
|
+
- id: skills-tool
|
|
215
|
+
name: '@ddtcorex/dsh-maestro-review/lib/skills-tool.js'
|
|
216
|
+
|
|
217
|
+
- id: workspace-tool
|
|
218
|
+
name: '@ddtcorex/dsh-maestro-govard/lib/workspace-tool.js'
|
|
219
|
+
|
|
220
|
+
- id: govard-tool
|
|
221
|
+
name: '@ddtcorex/dsh-maestro-govard/lib/govard-tool.js'
|
|
222
|
+
config:
|
|
223
|
+
rootPath: null
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
- id: persona
|
|
2
|
+
name: '@deepseek-ai/dsh-persona'
|
|
3
|
+
config:
|
|
4
|
+
text: |
|
|
5
|
+
You are Maestro Reviewer, an AI Tech Lead. Workflow:
|
|
6
|
+
1. Call maestro_load_review_profile with the profile named by the review request before inspecting code. It fails closed if the required skill set is incomplete.
|
|
7
|
+
2. Call gitlab_list_own_review_threads to see which findings you already raised on this merge request.
|
|
8
|
+
3. Call gitlab_get_mr_diff to read the current diff.
|
|
9
|
+
4. For each existing thread whose file/line was touched by the new commits, decide whether it still applies, looks fixed, or needs a different comment — reply to it (status: "reply"). Never resolve a thread yourself.
|
|
10
|
+
5. For genuinely new issues with no existing thread, prepare a new inline comment (status: "new").
|
|
11
|
+
6. Call report_review_findings exactly once with your complete list of findings, then stop. Do not call gitlab_post_mr_comment, gitlab_post_inline_comment, or gitlab_reply_to_thread yourself — the orchestrator posts them from your report_review_findings call.
|
|
12
|
+
|
|
13
|
+
- id: skills-tool
|
|
14
|
+
name: '@ddtcorex/dsh-maestro-review/lib/skills-tool.js'
|
package/src/augment.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ModelSelection } from '@deepseek-ai/dsh-agent'
|
|
2
|
+
|
|
3
|
+
declare module '@deepseek-ai/dsh-host-webserver' {}
|
|
4
|
+
declare module '@deepseek-ai/dsh-client-connection' {}
|
|
5
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {}
|
|
6
|
+
declare module '@deepseek-ai/dsh-client-ui-settings' {}
|
|
7
|
+
declare module '@deepseek-ai/dsh-host-apiproxy/api' {
|
|
8
|
+
export type RpcResult<T> = { ok: true; value: T } | { ok: false; error: any }
|
|
9
|
+
export type RpcErrorDetailsMap = { 'bad-request': { issues: any[] } }
|
|
10
|
+
}
|
|
11
|
+
declare module '@deepseek-ai/dsh-tools' {
|
|
12
|
+
export function defineTool(...args: any[]): any
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
import '@deepseek-ai/cordis'
|
|
16
|
+
|
|
17
|
+
declare module '@deepseek-ai/cordis' {
|
|
18
|
+
interface Context {
|
|
19
|
+
webServer: { port: number; register: any }
|
|
20
|
+
connection: { rpc: { handle: (channel: string, handler: any, opts?: any) => () => void; call: any } }
|
|
21
|
+
maestroTunnel: {
|
|
22
|
+
status(): any
|
|
23
|
+
start(): Promise<any>
|
|
24
|
+
stop(): Promise<any>
|
|
25
|
+
proxyStatus(): any
|
|
26
|
+
reloadConfig(): Promise<void>
|
|
27
|
+
initialReady(): Promise<void>
|
|
28
|
+
}
|
|
29
|
+
logger?: {
|
|
30
|
+
info?: (...args: any[]) => void
|
|
31
|
+
warn?: (...args: any[]) => void
|
|
32
|
+
error?: (...args: any[]) => void
|
|
33
|
+
}
|
|
34
|
+
tools: { register: any; preExecute?: any }
|
|
35
|
+
agents: any
|
|
36
|
+
sessions: any
|
|
37
|
+
skills: any
|
|
38
|
+
/** DSH default-model service (injected by the host; structural shape only). */
|
|
39
|
+
agentDefaultModel: {
|
|
40
|
+
currentSelection(): ModelSelection
|
|
41
|
+
}
|
|
42
|
+
agentPresets: { mount(agentCtx: Context, id: string): Promise<unknown> | unknown }
|
|
43
|
+
sessionTitle: { rename(session: unknown, title: string): Promise<unknown> | unknown }
|
|
44
|
+
/** Current agent identity inside an agent-scoped context (WeakMap key). */
|
|
45
|
+
agent?: object
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { chmod, mkdir, readFile, writeFile } from 'node:fs/promises'
|
|
2
|
+
import { homedir } from 'node:os'
|
|
3
|
+
import { dirname, join } from 'node:path'
|
|
4
|
+
import type { ReviewSkillProfile } from './skills-tool.js'
|
|
5
|
+
import {
|
|
6
|
+
RUNTIME_KEYS,
|
|
7
|
+
readFlat,
|
|
8
|
+
writeLegacyPatch,
|
|
9
|
+
} from '@ddtcorex/dsh-maestro-config-lib'
|
|
10
|
+
|
|
11
|
+
export interface ReviewModelSelection {
|
|
12
|
+
provider: string
|
|
13
|
+
model: string
|
|
14
|
+
reasoningEffort?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface MaestroUserConfig {
|
|
18
|
+
gitlabBaseUrl?: string
|
|
19
|
+
gitlabToken?: string
|
|
20
|
+
botUsername?: string
|
|
21
|
+
webhookSecret?: string
|
|
22
|
+
webhookPort?: number
|
|
23
|
+
projectMappings?: Array<{ projectPath: string; localRepoPath: string; reviewProfile?: ReviewSkillProfile; reviewModel?: ReviewModelSelection }>
|
|
24
|
+
/** Override the DSH default model for automated reviews. When absent the global DSH default is used. */
|
|
25
|
+
reviewModel?: ReviewModelSelection
|
|
26
|
+
/** Re-run a quick review whenever new commits land on a previously reviewed MR. */
|
|
27
|
+
autoRereviewOnPush?: boolean
|
|
28
|
+
/** Bound one automated review agent's turn. */
|
|
29
|
+
agentTimeoutMs?: number
|
|
30
|
+
/** Prune Maestro's own review records older than this many days (0 = keep forever). */
|
|
31
|
+
reviewSessionRetentionDays?: number
|
|
32
|
+
tunnelMode?: 'quick' | 'named'
|
|
33
|
+
quickTarget?: 'dsh-web' | 'webhook'
|
|
34
|
+
tunnelId?: string
|
|
35
|
+
tunnelCredentialsFile?: string
|
|
36
|
+
tunnelHostname?: string
|
|
37
|
+
proxyPort?: number
|
|
38
|
+
proxyHost?: string
|
|
39
|
+
lastTunnelRunning?: boolean
|
|
40
|
+
/** Gate LAN access behind a second PIN. Default false — LAN stays open. */
|
|
41
|
+
lanPinEnabled?: boolean
|
|
42
|
+
/** Telegram Bot API credentials for one-way notifications. */
|
|
43
|
+
telegramBotToken?: string
|
|
44
|
+
telegramChatId?: string
|
|
45
|
+
/** Also notify this chat when a review finishes. Default false. */
|
|
46
|
+
telegramReviewNotifications?: boolean
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function resolveDshHome(dshHome?: string): string {
|
|
50
|
+
return dshHome ?? process.env.DSH_HOME ?? join(homedir(), '.dsh')
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Settings live in the SHARED namespaced store (`~/.dsh/maestro/settings.json`,
|
|
55
|
+
* owned by @ddtcorex/dsh-maestro-config-lib); this store is a thin adapter that
|
|
56
|
+
* keeps the package's flat `MaestroUserConfig` API while delegating persistence.
|
|
57
|
+
* Machine runtime state (RUNTIME_KEYS) never enters settings — it stays in this
|
|
58
|
+
* package's own sidecar so a settings edit can never silently flip tunnel state.
|
|
59
|
+
*/
|
|
60
|
+
export function configStorePath(dshHome?: string): string {
|
|
61
|
+
return join(resolveDshHome(dshHome), 'maestro', 'settings.json')
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function runtimeStatePath(dshHome?: string): string {
|
|
65
|
+
return join(resolveDshHome(dshHome), 'dsh-maestro-review', 'runtime.json')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function readRuntimeState(dshHome?: string): Promise<Record<string, unknown>> {
|
|
69
|
+
try {
|
|
70
|
+
return JSON.parse(await readFile(runtimeStatePath(dshHome), 'utf8')) as Record<string, unknown>
|
|
71
|
+
} catch {
|
|
72
|
+
return {}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function mergeRuntimeState(
|
|
77
|
+
patch: Record<string, unknown>,
|
|
78
|
+
dshHome?: string,
|
|
79
|
+
): Promise<void> {
|
|
80
|
+
const path = runtimeStatePath(dshHome)
|
|
81
|
+
const merged = { ...(await readRuntimeState(dshHome)), ...patch }
|
|
82
|
+
await mkdir(dirname(path), { recursive: true, mode: 0o700 })
|
|
83
|
+
await writeFile(path, JSON.stringify(merged, null, 2), { encoding: 'utf-8', mode: 0o600 })
|
|
84
|
+
await chmod(path, 0o600)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export async function loadUserConfig(dshHome?: string): Promise<MaestroUserConfig> {
|
|
88
|
+
const [flat, runtime] = await Promise.all([
|
|
89
|
+
readFlat({ dshHome }),
|
|
90
|
+
readRuntimeState(dshHome),
|
|
91
|
+
])
|
|
92
|
+
return { ...flat, ...runtime } as MaestroUserConfig
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export async function saveUserConfig(patch: MaestroUserConfig, dshHome?: string): Promise<MaestroUserConfig> {
|
|
96
|
+
const settingsPatch: Record<string, unknown> = {}
|
|
97
|
+
const runtimePatch: Record<string, unknown> = {}
|
|
98
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
99
|
+
if ((RUNTIME_KEYS as readonly string[]).includes(key)) runtimePatch[key] = value
|
|
100
|
+
else settingsPatch[key] = value
|
|
101
|
+
}
|
|
102
|
+
if (Object.keys(settingsPatch).length > 0) {
|
|
103
|
+
await writeLegacyPatch(settingsPatch, { dshHome })
|
|
104
|
+
}
|
|
105
|
+
if (Object.keys(runtimePatch).length > 0) {
|
|
106
|
+
await mergeRuntimeState(runtimePatch, dshHome)
|
|
107
|
+
}
|
|
108
|
+
return loadUserConfig(dshHome)
|
|
109
|
+
}
|
package/src/events.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface MrOpenedPayload {
|
|
2
|
+
projectPath: string
|
|
3
|
+
projectId: number
|
|
4
|
+
mrIid: number
|
|
5
|
+
sourceBranch: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type ReviewMode = 'quick' | 'deep'
|
|
9
|
+
|
|
10
|
+
export type ReviewScope =
|
|
11
|
+
| { kind: 'mr' }
|
|
12
|
+
| { kind: 'discussion'; discussionId: string; path: string; line: number }
|
|
13
|
+
|
|
14
|
+
export interface ReviewRequest extends MrOpenedPayload {
|
|
15
|
+
/** `push` arrives only when auto re-review on push is enabled and passes the completed-history gate. */
|
|
16
|
+
trigger: 'reviewer-assignment' | 'mention' | 'push'
|
|
17
|
+
mode: ReviewMode
|
|
18
|
+
scope: ReviewScope
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare module '@deepseek-ai/cordis' {
|
|
22
|
+
interface Events {
|
|
23
|
+
'maestro/review-request': (payload: ReviewRequest) => void
|
|
24
|
+
}
|
|
25
|
+
}
|