@bf-meishijian/aip 0.0.5 → 0.0.7
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 +114 -3
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +57 -23
- package/dist/cli.js.map +1 -1
- package/dist/coding-run-manager.d.ts +83 -17
- package/dist/coding-run-manager.d.ts.map +1 -1
- package/dist/coding-run-manager.js +861 -644
- package/dist/coding-run-manager.js.map +1 -1
- package/dist/coding-subagent-child.d.ts +22 -0
- package/dist/coding-subagent-child.d.ts.map +1 -0
- package/dist/coding-subagent-child.js +83 -0
- package/dist/coding-subagent-child.js.map +1 -0
- package/dist/coding-subagents.d.ts +65 -0
- package/dist/coding-subagents.d.ts.map +1 -0
- package/dist/coding-subagents.js +521 -0
- package/dist/coding-subagents.js.map +1 -0
- package/dist/command-wakeup.d.ts +19 -0
- package/dist/command-wakeup.d.ts.map +1 -0
- package/dist/command-wakeup.js +109 -0
- package/dist/command-wakeup.js.map +1 -0
- package/dist/daemon.d.ts +4 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +189 -79
- package/dist/daemon.js.map +1 -1
- package/dist/delivery-files.d.ts +24 -9
- package/dist/delivery-files.d.ts.map +1 -1
- package/dist/delivery-files.js +171 -45
- package/dist/delivery-files.js.map +1 -1
- package/dist/delivery-tools.d.ts +28 -0
- package/dist/delivery-tools.d.ts.map +1 -0
- package/dist/delivery-tools.js +167 -0
- package/dist/delivery-tools.js.map +1 -0
- package/dist/diagnostics.d.ts +1 -0
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +48 -14
- package/dist/diagnostics.js.map +1 -1
- package/dist/installer.d.ts +5 -8
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +155 -65
- package/dist/installer.js.map +1 -1
- package/dist/linux-service.d.ts +14 -0
- package/dist/linux-service.d.ts.map +1 -0
- package/dist/linux-service.js +63 -0
- package/dist/linux-service.js.map +1 -0
- package/dist/live-employee.d.ts +6 -3
- package/dist/live-employee.d.ts.map +1 -1
- package/dist/live-employee.js +245 -49
- package/dist/live-employee.js.map +1 -1
- package/dist/local-handoff-workspace.d.ts +20 -0
- package/dist/local-handoff-workspace.d.ts.map +1 -0
- package/dist/local-handoff-workspace.js +80 -0
- package/dist/local-handoff-workspace.js.map +1 -0
- package/dist/local-model-usage.d.ts +6 -0
- package/dist/local-model-usage.d.ts.map +1 -0
- package/dist/local-model-usage.js +40 -0
- package/dist/local-model-usage.js.map +1 -0
- package/dist/login-url.d.ts +3 -0
- package/dist/login-url.d.ts.map +1 -0
- package/dist/login-url.js +30 -0
- package/dist/login-url.js.map +1 -0
- package/dist/paths.d.ts +9 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +27 -3
- package/dist/paths.js.map +1 -1
- package/dist/pi-message-queue.d.ts +15 -0
- package/dist/pi-message-queue.d.ts.map +1 -0
- package/dist/pi-message-queue.js +57 -0
- package/dist/pi-message-queue.js.map +1 -0
- package/dist/pi-model-service.d.ts +11 -0
- package/dist/pi-model-service.d.ts.map +1 -1
- package/dist/pi-model-service.js +28 -11
- package/dist/pi-model-service.js.map +1 -1
- package/dist/platform-client.d.ts +230 -6
- package/dist/platform-client.d.ts.map +1 -1
- package/dist/platform-client.js +87 -0
- package/dist/platform-client.js.map +1 -1
- package/dist/profile.d.ts +9 -0
- package/dist/profile.d.ts.map +1 -0
- package/dist/profile.js +43 -0
- package/dist/profile.js.map +1 -0
- package/dist/project-facts.d.ts +19 -0
- package/dist/project-facts.d.ts.map +1 -0
- package/dist/project-facts.js +91 -0
- package/dist/project-facts.js.map +1 -0
- package/dist/provider-auth-error.d.ts +3 -0
- package/dist/provider-auth-error.d.ts.map +1 -0
- package/dist/provider-auth-error.js +12 -0
- package/dist/provider-auth-error.js.map +1 -0
- package/dist/qa-contract.d.ts +2 -0
- package/dist/qa-contract.d.ts.map +1 -0
- package/dist/qa-contract.js +165 -0
- package/dist/qa-contract.js.map +1 -0
- package/dist/qa-http-validation.js +145 -0
- package/dist/qa-project-checkout.d.ts +12 -0
- package/dist/qa-project-checkout.d.ts.map +1 -0
- package/dist/qa-project-checkout.js +68 -0
- package/dist/qa-project-checkout.js.map +1 -0
- package/dist/qa-session-manager.d.ts +101 -0
- package/dist/qa-session-manager.d.ts.map +1 -0
- package/dist/qa-session-manager.js +581 -0
- package/dist/qa-session-manager.js.map +1 -0
- package/dist/review-report.d.ts +9 -0
- package/dist/review-report.d.ts.map +1 -0
- package/dist/review-report.js +61 -0
- package/dist/review-report.js.map +1 -0
- package/dist/secure-json.d.ts.map +1 -1
- package/dist/secure-json.js +64 -2
- package/dist/secure-json.js.map +1 -1
- package/dist/stage-delivery.js +43 -25
- package/dist/state.d.ts +2 -2
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +6 -4
- package/dist/state.js.map +1 -1
- package/dist/test-cli.d.ts +2 -0
- package/dist/test-cli.d.ts.map +1 -0
- package/dist/test-cli.js +50 -0
- package/dist/test-cli.js.map +1 -0
- package/dist/test-executor.d.ts +44 -0
- package/dist/test-executor.d.ts.map +1 -0
- package/dist/test-executor.js +474 -0
- package/dist/test-executor.js.map +1 -0
- package/dist/test-reports.d.ts +13 -0
- package/dist/test-reports.d.ts.map +1 -0
- package/dist/test-reports.js +129 -0
- package/dist/test-reports.js.map +1 -0
- package/dist/test-run-manager.d.ts +24 -0
- package/dist/test-run-manager.d.ts.map +1 -0
- package/dist/test-run-manager.js +121 -0
- package/dist/test-run-manager.js.map +1 -0
- package/dist/tool-dispatch.d.ts +14 -0
- package/dist/tool-dispatch.d.ts.map +1 -0
- package/dist/tool-dispatch.js +56 -0
- package/dist/tool-dispatch.js.map +1 -0
- package/dist/windows-runtime.d.ts +9 -0
- package/dist/windows-runtime.d.ts.map +1 -0
- package/dist/windows-runtime.js +64 -0
- package/dist/windows-runtime.js.map +1 -0
- package/dist/windows-service.d.ts +20 -0
- package/dist/windows-service.d.ts.map +1 -0
- package/dist/windows-service.js +96 -0
- package/dist/windows-service.js.map +1 -0
- package/package.json +17 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-contract.d.ts","sourceRoot":"","sources":["../src/qa-contract.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,yBAAyB,EACzB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { Ajv } from "ajv";
|
|
2
|
+
|
|
3
|
+
export const qaTestGroupsSchema = {
|
|
4
|
+
type: "array",
|
|
5
|
+
minItems: 1,
|
|
6
|
+
items: {
|
|
7
|
+
type: "object",
|
|
8
|
+
additionalProperties: false,
|
|
9
|
+
properties: {
|
|
10
|
+
id: { type: "string", minLength: 1 },
|
|
11
|
+
name: { type: "string", minLength: 1 },
|
|
12
|
+
environments: {
|
|
13
|
+
type: "array",
|
|
14
|
+
minItems: 1,
|
|
15
|
+
uniqueItems: true,
|
|
16
|
+
items: { type: "string", minLength: 1 },
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
required: ["id", "name", "environments"],
|
|
20
|
+
},
|
|
21
|
+
} ;
|
|
22
|
+
export const qaContractSchema = {
|
|
23
|
+
type: "object",
|
|
24
|
+
additionalProperties: false,
|
|
25
|
+
properties: {
|
|
26
|
+
contractVersion: { const: 1 },
|
|
27
|
+
language: { type: "string", minLength: 1 },
|
|
28
|
+
groups: qaTestGroupsSchema,
|
|
29
|
+
doctor: { type: "array", minItems: 1, items: { type: "string" } },
|
|
30
|
+
collect: { type: "array", minItems: 1, items: { type: "string" } },
|
|
31
|
+
check: { type: "array", minItems: 1, items: { type: "string" } },
|
|
32
|
+
run: { type: "array", minItems: 1, items: { type: "string" } },
|
|
33
|
+
reportDir: { type: "string", minLength: 1 },
|
|
34
|
+
},
|
|
35
|
+
required: [
|
|
36
|
+
"groups",
|
|
37
|
+
"contractVersion",
|
|
38
|
+
"language",
|
|
39
|
+
"doctor",
|
|
40
|
+
"collect",
|
|
41
|
+
"check",
|
|
42
|
+
"run",
|
|
43
|
+
"reportDir",
|
|
44
|
+
],
|
|
45
|
+
} ;
|
|
46
|
+
export const qaManifestSchema = {
|
|
47
|
+
type: "object",
|
|
48
|
+
additionalProperties: false,
|
|
49
|
+
properties: {
|
|
50
|
+
contractVersion: { const: 1 },
|
|
51
|
+
language: { type: "string", minLength: 1 },
|
|
52
|
+
cases: {
|
|
53
|
+
type: "array",
|
|
54
|
+
items: {
|
|
55
|
+
type: "object",
|
|
56
|
+
additionalProperties: false,
|
|
57
|
+
properties: {
|
|
58
|
+
caseId: {
|
|
59
|
+
type: "string",
|
|
60
|
+
pattern: "^[a-zA-Z][\\w-]*\\.[a-zA-Z][\\w-]*\\.[a-zA-Z][\\w.-]*$",
|
|
61
|
+
},
|
|
62
|
+
tags: { type: "array", items: { type: "string", minLength: 1 }, uniqueItems: true },
|
|
63
|
+
suites: { type: "array", items: { type: "string", minLength: 1 }, uniqueItems: true },
|
|
64
|
+
name: { type: "string", minLength: 1 },
|
|
65
|
+
kind: { enum: ["CASE", "FLOW"] },
|
|
66
|
+
domain: { type: "string", minLength: 1 },
|
|
67
|
+
file: { type: "string", minLength: 1 },
|
|
68
|
+
selector: { type: "string", minLength: 1 },
|
|
69
|
+
endpoint: { type: "string" },
|
|
70
|
+
stubs: { type: "array", items: { type: "string", minLength: 1 }, uniqueItems: true },
|
|
71
|
+
covers: { type: "array", items: { type: "string", minLength: 1 }, uniqueItems: true },
|
|
72
|
+
},
|
|
73
|
+
required: ["caseId", "kind", "domain", "file", "selector", "stubs"],
|
|
74
|
+
},
|
|
75
|
+
minItems: 1,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
required: ["contractVersion", "language", "cases"],
|
|
79
|
+
} ;
|
|
80
|
+
export const qaSelectionSchema = {
|
|
81
|
+
type: "object",
|
|
82
|
+
additionalProperties: false,
|
|
83
|
+
properties: {
|
|
84
|
+
runId: { type: "string", minLength: 1 },
|
|
85
|
+
caseIds: { type: "array", items: { type: "string", minLength: 1 }, uniqueItems: true },
|
|
86
|
+
domains: { type: "array", items: { type: "string", minLength: 1 }, uniqueItems: true },
|
|
87
|
+
},
|
|
88
|
+
required: ["runId", "caseIds", "domains"],
|
|
89
|
+
} ;
|
|
90
|
+
|
|
91
|
+
const ajv = new Ajv({ allErrors: true });
|
|
92
|
+
const contractValidator = ajv.compile(qaContractSchema);
|
|
93
|
+
const manifestValidator = ajv.compile(qaManifestSchema);
|
|
94
|
+
const selectionValidator = ajv.compile(qaSelectionSchema);
|
|
95
|
+
export function parseQaContract(value ) {
|
|
96
|
+
if (!contractValidator(value))
|
|
97
|
+
throw new Error(`QA_CONTRACT_INVALID: ${ajv.errorsText(contractValidator.errors)}`);
|
|
98
|
+
const result = value ;
|
|
99
|
+
if (new Set(result.groups.map((g) => g.id)).size !== result.groups.length)
|
|
100
|
+
throw new Error("QA_GROUP_ID_DUPLICATE");
|
|
101
|
+
for (const key of ["doctor", "collect", "check", "run"] ) {
|
|
102
|
+
if (
|
|
103
|
+
result[key].some((v) => /[\n\r\0]/u.test(v)) ||
|
|
104
|
+
/^(?:.*[\\/])?(?:sh|bash|zsh|cmd(?:\.exe)?|powershell(?:\.exe)?)$/iu.test(result[key][0] ) ||
|
|
105
|
+
result[key].some((v) => ["&&", "||", ";", "|", ">", "<"].includes(v))
|
|
106
|
+
)
|
|
107
|
+
throw new Error("QA_COMMAND_SHELL_FORBIDDEN");
|
|
108
|
+
}
|
|
109
|
+
if (
|
|
110
|
+
/^(?:[\\/]|[a-z]:)/iu.test(result.reportDir) ||
|
|
111
|
+
result.reportDir.split(/[\\/]/u).includes("..")
|
|
112
|
+
)
|
|
113
|
+
throw new Error("QA_REPORT_DIRECTORY_INVALID");
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
export function parseQaManifest(value ) {
|
|
117
|
+
if (!manifestValidator(value))
|
|
118
|
+
throw new Error(`QA_MANIFEST_INVALID: ${ajv.errorsText(manifestValidator.errors)}`);
|
|
119
|
+
const result = value ;
|
|
120
|
+
const ids = new Set(result.cases.map((c) => c.caseId));
|
|
121
|
+
if (ids.size !== result.cases.length) throw new Error("QA_CASE_ID_DUPLICATE");
|
|
122
|
+
for (const c of result.cases)
|
|
123
|
+
if (c.covers?.some((id) => !ids.has(id))) throw new Error("QA_COVERS_UNKNOWN");
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
export function parseQaSelection(value ) {
|
|
127
|
+
if (!selectionValidator(value))
|
|
128
|
+
throw new Error(`QA_SELECTION_INVALID: ${ajv.errorsText(selectionValidator.errors)}`);
|
|
129
|
+
return value ;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function validateTestGroup(
|
|
133
|
+
groups ,
|
|
134
|
+
manifest ,
|
|
135
|
+
groupId ,
|
|
136
|
+
environment ,
|
|
137
|
+
caseIds ,
|
|
138
|
+
) {
|
|
139
|
+
const group = groups.find((g) => g.id === groupId);
|
|
140
|
+
if (!group) throw new Error("测试分组不存在,请刷新目录");
|
|
141
|
+
if (!group.environments.includes(environment)) throw new Error("所选环境不属于测试分组");
|
|
142
|
+
if (!caseIds.length) throw new Error("请选择用例后运行");
|
|
143
|
+
const invalid = caseIds.filter(
|
|
144
|
+
(id) => !manifest.cases.some((c) => c.caseId === id && c.domain === groupId),
|
|
145
|
+
);
|
|
146
|
+
if (invalid.length)
|
|
147
|
+
throw new Error(`用例不存在或不属于所选测试分组,请刷新目录:${invalid.join("、")}`);
|
|
148
|
+
}
|
|
149
|
+
export function validateTestCatalog(groups , manifest ) {
|
|
150
|
+
if (!new Ajv().validate(qaTestGroupsSchema, groups)) throw new Error("QA_GROUPS_INVALID");
|
|
151
|
+
if (new Set(groups.map((g) => g.id)).size !== groups.length)
|
|
152
|
+
throw new Error("QA_GROUP_ID_DUPLICATE");
|
|
153
|
+
const suites = new Map ();
|
|
154
|
+
for (const c of manifest.cases) {
|
|
155
|
+
if (!groups.some((g) => g.id === c.domain))
|
|
156
|
+
throw new Error(`用例 ${c.caseId} 的测试分组未声明`);
|
|
157
|
+
for (const suite of c.suites ?? []) {
|
|
158
|
+
if (suites.has(suite) && suites.get(suite) !== c.domain)
|
|
159
|
+
throw new Error(`套件 ${suite} 跨测试分组`);
|
|
160
|
+
suites.set(suite, c.domain);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export { parseQaHttpExchange, parseQaEvidenceReferences } from "./qa-http-validation.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-contract.js","sourceRoot":"","sources":["../src/qa-contract.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,OAAO,EACL,eAAe,EACf,yBAAyB,EACzB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { Ajv } from "ajv";
|
|
2
|
+
|
|
3
|
+
export const qaHttpExchangeSchema = {
|
|
4
|
+
type: "object",
|
|
5
|
+
additionalProperties: false,
|
|
6
|
+
properties: {
|
|
7
|
+
step: { type: "string", minLength: 1 },
|
|
8
|
+
id: {
|
|
9
|
+
type: "string",
|
|
10
|
+
},
|
|
11
|
+
sequence: {
|
|
12
|
+
type: "integer",
|
|
13
|
+
minimum: 1,
|
|
14
|
+
},
|
|
15
|
+
startedAt: {
|
|
16
|
+
type: "string",
|
|
17
|
+
},
|
|
18
|
+
durationMs: {
|
|
19
|
+
type: "integer",
|
|
20
|
+
minimum: 0,
|
|
21
|
+
},
|
|
22
|
+
request: {
|
|
23
|
+
type: "object",
|
|
24
|
+
additionalProperties: false,
|
|
25
|
+
properties: {
|
|
26
|
+
method: {
|
|
27
|
+
type: "string",
|
|
28
|
+
},
|
|
29
|
+
url: {
|
|
30
|
+
type: "string",
|
|
31
|
+
},
|
|
32
|
+
headers: {
|
|
33
|
+
type: "object",
|
|
34
|
+
additionalProperties: {
|
|
35
|
+
type: "array",
|
|
36
|
+
items: {
|
|
37
|
+
type: "string",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
body: {
|
|
42
|
+
anyOf: [
|
|
43
|
+
{
|
|
44
|
+
type: "string",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: "null",
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
bodyAttachment: {
|
|
52
|
+
type: "string",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
required: ["method", "url", "headers", "body"],
|
|
56
|
+
},
|
|
57
|
+
response: {
|
|
58
|
+
anyOf: [
|
|
59
|
+
{
|
|
60
|
+
type: "object",
|
|
61
|
+
additionalProperties: false,
|
|
62
|
+
properties: {
|
|
63
|
+
status: {
|
|
64
|
+
type: "integer",
|
|
65
|
+
minimum: 100,
|
|
66
|
+
maximum: 599,
|
|
67
|
+
},
|
|
68
|
+
headers: {
|
|
69
|
+
type: "object",
|
|
70
|
+
additionalProperties: {
|
|
71
|
+
type: "array",
|
|
72
|
+
items: {
|
|
73
|
+
type: "string",
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
body: {
|
|
78
|
+
anyOf: [
|
|
79
|
+
{
|
|
80
|
+
type: "string",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
type: "null",
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
bodyAttachment: {
|
|
88
|
+
type: "string",
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
required: ["status", "headers", "body"],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
type: "null",
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
error: {
|
|
99
|
+
type: "string",
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
required: ["id", "sequence", "startedAt", "durationMs", "request", "response"],
|
|
103
|
+
} ;
|
|
104
|
+
const ajv = new Ajv({ allErrors: true, strict: false });
|
|
105
|
+
const validate = ajv.compile(qaHttpExchangeSchema);
|
|
106
|
+
export function parseQaHttpExchange(value ) {
|
|
107
|
+
if (!validate(value))
|
|
108
|
+
throw new Error(`QA_HTTP_EXCHANGE_INVALID: ${ajv.errorsText(validate.errors)}`);
|
|
109
|
+
return value ;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export const qaEvidenceReferencesSchema = {
|
|
113
|
+
type: "array",
|
|
114
|
+
items: {
|
|
115
|
+
oneOf: [
|
|
116
|
+
{
|
|
117
|
+
type: "object",
|
|
118
|
+
additionalProperties: false,
|
|
119
|
+
required: ["kind", "exchangeId", "side", "label"],
|
|
120
|
+
properties: {
|
|
121
|
+
kind: { const: "http" },
|
|
122
|
+
exchangeId: { type: "string", minLength: 1 },
|
|
123
|
+
side: { enum: ["request", "response"] },
|
|
124
|
+
label: { type: "string" },
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
type: "object",
|
|
129
|
+
additionalProperties: false,
|
|
130
|
+
required: ["kind", "filename", "label"],
|
|
131
|
+
properties: {
|
|
132
|
+
kind: { const: "attachment" },
|
|
133
|
+
filename: { type: "string", minLength: 1 },
|
|
134
|
+
label: { type: "string" },
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
} ;
|
|
140
|
+
|
|
141
|
+
const validateReferences = new Ajv({ strict: false }).compile(qaEvidenceReferencesSchema);
|
|
142
|
+
export function parseQaEvidenceReferences(value ) {
|
|
143
|
+
if (!validateReferences(value)) throw new Error("QA_EVIDENCE_REFERENCES_INVALID");
|
|
144
|
+
return value ;
|
|
145
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { QaHostCommandPayload } from "@ai-platform/api-contracts";
|
|
2
|
+
type Project = Omit<QaHostCommandPayload["project"], "mainBranch">;
|
|
3
|
+
export declare function qaProjectDirectory(project: Project): string;
|
|
4
|
+
export declare function gitQa(args: string[], cwd?: string): Promise<string>;
|
|
5
|
+
/** 同一 Host 的同项目任务排队;文件锁同时保护 CLI 与 daemon。 */
|
|
6
|
+
export declare function withQaProject<T>(project: Project, work: () => Promise<T>): Promise<T>;
|
|
7
|
+
/** 仅更新 Host 专用检出,不接触开发者工作目录。调用期间必须持有项目锁。 */
|
|
8
|
+
export declare function prepareQaCheckout({ project }: {
|
|
9
|
+
project: Project;
|
|
10
|
+
}): Promise<string>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=qa-project-checkout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-project-checkout.d.ts","sourceRoot":"","sources":["../src/qa-project-checkout.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAIvE,KAAK,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC,CAAC;AAGnE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,UAGlD;AACD,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM,mBAIvD;AAED,6CAA6C;AAC7C,wBAAsB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAoB3F;AAED,4CAA4C;AAC5C,wBAAsB,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,mBAqBxE"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { access, mkdir } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import lockfile from "proper-lockfile";
|
|
6
|
+
import { paths } from "./paths.js";
|
|
7
|
+
const exec = promisify(execFile);
|
|
8
|
+
const pending = new Map();
|
|
9
|
+
export function qaProjectDirectory(project) {
|
|
10
|
+
if (!/^[a-zA-Z0-9_-]+$/u.test(project.id))
|
|
11
|
+
throw new Error("QA_PROJECT_ID_INVALID");
|
|
12
|
+
return join(paths().workspaceRoot, "qa-projects", project.id);
|
|
13
|
+
}
|
|
14
|
+
export async function gitQa(args, cwd) {
|
|
15
|
+
return (await exec("git", args, { cwd, encoding: "utf8", maxBuffer: 1024 * 1024, timeout: 60_000 })).stdout.trim();
|
|
16
|
+
}
|
|
17
|
+
/** 同一 Host 的同项目任务排队;文件锁同时保护 CLI 与 daemon。 */
|
|
18
|
+
export async function withQaProject(project, work) {
|
|
19
|
+
const directory = qaProjectDirectory(project);
|
|
20
|
+
const previous = pending.get(directory) ?? Promise.resolve();
|
|
21
|
+
const task = previous
|
|
22
|
+
.catch(() => undefined)
|
|
23
|
+
.then(async () => {
|
|
24
|
+
await mkdir(directory, { recursive: true, mode: 0o700 });
|
|
25
|
+
const release = await lockfile.lock(directory);
|
|
26
|
+
try {
|
|
27
|
+
return await work();
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
await release();
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
pending.set(directory, task);
|
|
34
|
+
try {
|
|
35
|
+
return await task;
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
if (pending.get(directory) === task)
|
|
39
|
+
pending.delete(directory);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** 仅更新 Host 专用检出,不接触开发者工作目录。调用期间必须持有项目锁。 */
|
|
43
|
+
export async function prepareQaCheckout({ project }) {
|
|
44
|
+
if (!project.commitSha || !/^[a-f\d]{40}$/iu.test(project.commitSha))
|
|
45
|
+
throw new Error("QA_COMMIT_REQUIRED");
|
|
46
|
+
if (!project.remoteUrl || project.remoteUrl.startsWith("-"))
|
|
47
|
+
throw new Error("QA_REMOTE_INVALID");
|
|
48
|
+
await gitQa(["check-ref-format", `refs/heads/${project.branch}`]);
|
|
49
|
+
const repository = join(qaProjectDirectory(project), "repository");
|
|
50
|
+
try {
|
|
51
|
+
await access(join(repository, ".git"));
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
if (error.code !== "ENOENT")
|
|
55
|
+
throw error;
|
|
56
|
+
await gitQa(["init", repository]);
|
|
57
|
+
await gitQa(["remote", "add", "origin", project.remoteUrl], repository);
|
|
58
|
+
}
|
|
59
|
+
await gitQa(["remote", "set-url", "origin", project.remoteUrl], repository);
|
|
60
|
+
await gitQa(["fetch", "--no-tags", "origin", project.commitSha], repository);
|
|
61
|
+
// 上一次报告已独立保存;清理专用仓库内产物,避免将旧结果当成本次结果。
|
|
62
|
+
await gitQa(["clean", "-ffdx"], repository);
|
|
63
|
+
await gitQa(["checkout", "--detach", "--force", project.commitSha], repository);
|
|
64
|
+
if ((await gitQa(["rev-parse", "HEAD"], repository)) !== project.commitSha.toLowerCase())
|
|
65
|
+
throw new Error("QA_CHECKOUT_MISMATCH");
|
|
66
|
+
return repository;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=qa-project-checkout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-project-checkout.js","sourceRoot":"","sources":["../src/qa-project-checkout.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { LocalCodingHostClaimedCommand, QaAttachmentView, QaCheckpoint, QaHostCommandPayload, QaPreparedWorkspace } from "@ai-platform/api-contracts";
|
|
2
|
+
import type { ExtensionFactory } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import type { PiModelService } from "./pi-model-service.js";
|
|
4
|
+
import type { PlatformClient } from "./platform-client.js";
|
|
5
|
+
import { bindHostTool } from "./tool-dispatch.js";
|
|
6
|
+
type QaSessionInput = Omit<QaHostCommandPayload, "employee">;
|
|
7
|
+
type Identity = {
|
|
8
|
+
hostId: string;
|
|
9
|
+
generation: number;
|
|
10
|
+
turnId: string;
|
|
11
|
+
};
|
|
12
|
+
type SessionEvent = {
|
|
13
|
+
id: string;
|
|
14
|
+
kind: string;
|
|
15
|
+
contentMarkdown: string;
|
|
16
|
+
payload?: Record<string, unknown>;
|
|
17
|
+
};
|
|
18
|
+
export interface QaSessionClient {
|
|
19
|
+
qaReadTestPlan: PlatformClient["qaReadTestPlan"];
|
|
20
|
+
qaSubmitTestPlan: PlatformClient["qaSubmitTestPlan"];
|
|
21
|
+
qaReadResults: PlatformClient["qaReadResults"];
|
|
22
|
+
qaReportDefects: PlatformClient["qaReportDefects"];
|
|
23
|
+
qaRequestRework: PlatformClient["qaRequestRework"];
|
|
24
|
+
qaResolveDefect: PlatformClient["qaResolveDefect"];
|
|
25
|
+
qaCompleteReview: PlatformClient["qaCompleteReview"];
|
|
26
|
+
qaReportAssetMerge: PlatformClient["qaReportAssetMerge"];
|
|
27
|
+
qaEmployeeConfig: PlatformClient["employeeConfig"];
|
|
28
|
+
qaEmployeeTool: PlatformClient["employeeTool"];
|
|
29
|
+
qaSessionEvents(id: string, body: Identity & {
|
|
30
|
+
events: SessionEvent[];
|
|
31
|
+
}): Promise<unknown>;
|
|
32
|
+
qaRequestExecution(id: string, body: Identity & {
|
|
33
|
+
branch: string;
|
|
34
|
+
environment: string;
|
|
35
|
+
caseIds?: string[];
|
|
36
|
+
domains?: string[];
|
|
37
|
+
note?: string;
|
|
38
|
+
}): Promise<unknown>;
|
|
39
|
+
qaUploadSessionAttachment(id: string, body: Identity & {
|
|
40
|
+
filename: string;
|
|
41
|
+
mediaType: string;
|
|
42
|
+
contentBase64: string;
|
|
43
|
+
}): Promise<QaAttachmentView>;
|
|
44
|
+
qaSubmitVerification(id: string, body: Identity & {
|
|
45
|
+
toolCallId: string;
|
|
46
|
+
content: string;
|
|
47
|
+
testItemIds: string[];
|
|
48
|
+
expected: string;
|
|
49
|
+
actual: string;
|
|
50
|
+
checkpoints: QaCheckpoint[];
|
|
51
|
+
unverifiableReason?: string;
|
|
52
|
+
steps: string[];
|
|
53
|
+
conclusion: "PASSED" | "FAILED" | "UNVERIFIABLE";
|
|
54
|
+
attachmentIds: string[];
|
|
55
|
+
ac?: string[];
|
|
56
|
+
}): Promise<unknown>;
|
|
57
|
+
qaSubmitConclusion(id: string, body: Identity & {
|
|
58
|
+
toolCallId: string;
|
|
59
|
+
contentMarkdown: string;
|
|
60
|
+
recommendation: "READY" | "NOT_READY";
|
|
61
|
+
unfinishedItems: string[];
|
|
62
|
+
risks: string[];
|
|
63
|
+
evidenceRefs: string[];
|
|
64
|
+
}): Promise<unknown>;
|
|
65
|
+
}
|
|
66
|
+
export declare class QaSessionManager {
|
|
67
|
+
private readonly pi;
|
|
68
|
+
private readonly active;
|
|
69
|
+
private readonly tasks;
|
|
70
|
+
constructor(pi: PiModelService);
|
|
71
|
+
isBusy(): boolean;
|
|
72
|
+
settled(sessionId: string): Promise<void>;
|
|
73
|
+
execute(client: QaSessionClient, { hostId, generation }: {
|
|
74
|
+
hostId: string;
|
|
75
|
+
generation: number;
|
|
76
|
+
}, command: LocalCodingHostClaimedCommand): Promise<void>;
|
|
77
|
+
private run;
|
|
78
|
+
}
|
|
79
|
+
export declare function prepareQaProject(input: QaSessionInput): Promise<string>;
|
|
80
|
+
export declare function prepareQaWorkspace(input: QaSessionInput, cwd: string): Promise<QaPreparedWorkspace>;
|
|
81
|
+
export declare function currentQaBranch(cwd: string): Promise<string>;
|
|
82
|
+
/** 只采集 Git 事实;未知状态直接报错,不替 Agent 合并、推送或重试。 */
|
|
83
|
+
export declare function readQaAssetState(cwd: string, remoteUrl: string, expectedBranch: string, mainBranch: string): Promise<{
|
|
84
|
+
sourceCommitSha: string;
|
|
85
|
+
mainCommitSha: string;
|
|
86
|
+
hasChanges: boolean;
|
|
87
|
+
}>;
|
|
88
|
+
export declare function verifyQaAssetMerge(cwd: string, remoteUrl: string, expectedBranch: string, mainBranch: string): Promise<{
|
|
89
|
+
sourceCommitSha: string;
|
|
90
|
+
mainCommitSha: string;
|
|
91
|
+
}>;
|
|
92
|
+
/** 对照批准内容及实际合入结果;主分支其他文件的并行改动不属于本次 QA。 */
|
|
93
|
+
export declare function qaAssetContentChanged(cwd: string, approvedSource: string, approvedMain: string, source: string, main: string): Promise<boolean>;
|
|
94
|
+
export declare function readQaScreenshot(cwd: string, filename: string): Promise<{
|
|
95
|
+
filename: string;
|
|
96
|
+
mediaType: string;
|
|
97
|
+
contentBase64: string;
|
|
98
|
+
}>;
|
|
99
|
+
export declare function qaTools(client: QaSessionClient, input: QaSessionInput, binding: Identity, cwd: string, definitions: Parameters<typeof bindHostTool>[0]): ExtensionFactory;
|
|
100
|
+
export {};
|
|
101
|
+
//# sourceMappingURL=qa-session-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-session-manager.d.ts","sourceRoot":"","sources":["../src/qa-session-manager.ts"],"names":[],"mappings":"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"}
|