@fitlab-ai/agent-infra 0.12.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/internal/manual-validation.js +11 -17
- package/dist/lib/internal/platform-comment.js +56 -7
- package/dist/lib/platform/issue-comments.js +373 -267
- package/dist/lib/platform/issue-summary-content.js +112 -0
- package/dist/lib/platform/pr-change-report.js +175 -26
- package/dist/lib/platform/pr-summary-content.js +54 -0
- package/dist/lib/platform/pr-summary.js +318 -284
- package/dist/lib/platform/summary-content-pipeline.js +18 -0
- package/dist/lib/sandbox/removal.js +59 -2
- package/dist/lib/task/finalization.js +16 -7
- package/dist/lib/task/platform-operation-recovery.js +87 -87
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/internal/manual-validation.ts +12 -18
- package/lib/internal/platform-comment.ts +46 -4
- package/lib/platform/issue-comments.ts +478 -280
- package/lib/platform/issue-summary-content.ts +132 -0
- package/lib/platform/pr-change-report.ts +165 -20
- package/lib/platform/pr-summary-content.ts +60 -0
- package/lib/platform/pr-summary.ts +364 -257
- package/lib/platform/summary-content-pipeline.ts +23 -0
- package/lib/sandbox/removal.ts +57 -1
- package/lib/task/finalization.ts +11 -6
- package/lib/task/platform-operation-recovery.ts +70 -81
- package/package.json +1 -1
- package/templates/.agents/rules/pr-sync.en.md +4 -2
- package/templates/.agents/rules/pr-sync.zh-CN.md +6 -9
- package/templates/.agents/skills/cancel-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +1 -1
- package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +1 -1
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +2 -2
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +2 -2
- package/templates/.agents/skills/complete-task/SKILL.en.md +10 -25
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +11 -26
- package/templates/.agents/skills/create-pr/SKILL.en.md +1 -1
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/create-pr/reference/change-report.en.md +9 -2
- package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +9 -2
- package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +2 -2
- package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +2 -2
- package/templates/.agents/skills/create-task/SKILL.en.md +0 -18
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +0 -18
- package/templates/.agents/skills/watch-pr/SKILL.en.md +1 -1
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +3 -3
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +3 -3
|
@@ -2,9 +2,10 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { locateActivityLog, pairEntries } from '../task/activity-log.js';
|
|
4
4
|
import { resolveTaskRef } from '../task/resolve-ref.js';
|
|
5
|
+
import { prepareAndRenderPrSummaryContent } from '../platform/pr-summary.js';
|
|
5
6
|
import { applyTaskEvent } from '../task/events.js';
|
|
6
7
|
import { normalizeAgentToken } from '../agent-clients/tokens.js';
|
|
7
|
-
import {
|
|
8
|
+
import { createManualValidationReceipt, manualValidationFinalSummaryDigest, manualValidationFinalSummaryProjectionMatches, readManualValidationReceipt, writeManualValidationReceiptAtomic } from '../task/manual-validation-receipt.js';
|
|
8
9
|
import { archiveManualValidationGeneration, createManualValidationTransaction, readManualValidationTransaction, retryManualValidationTransaction, summaryPreimageDigest, transitionManualValidationTransaction, validateManualValidationGenerationArchive, writeManualValidationTransactionAtomic } from '../task/manual-validation-transaction.js';
|
|
9
10
|
import { sha256File } from '../task/artifact-receipts.js';
|
|
10
11
|
import { summaryCommentState, syncPullRequestSummary } from '../platform/pr-summary.js';
|
|
@@ -21,22 +22,14 @@ function printFailure(format, error) {
|
|
|
21
22
|
process.stderr.write(`${error.code}: ${error.message}\n`);
|
|
22
23
|
process.exitCode = 1;
|
|
23
24
|
}
|
|
24
|
-
const MANUAL_VALIDATION_STATUS_HEADING = /^###\s+(?:⚠️\s+(?:需人工校验|Manual Validation Required)|✅\s+(?:人工验证已通过|无需人工校验|Manual Validation Passed|No Manual Validation Required)|⏳\s+(?:人工验证待收尾|Manual Validation Pending))\s*$/mu;
|
|
25
25
|
function manualSummaryBody(body, phase) {
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (MANUAL_VALIDATION_STATUS_HEADING.test(body)) {
|
|
34
|
-
return `${body.replace(MANUAL_VALIDATION_STATUS_HEADING, `${heading}${marker}`).replace(/\s+$/u, '')}\n`;
|
|
35
|
-
}
|
|
36
|
-
const fallback = phase === 'pending'
|
|
37
|
-
? chinese ? '人工验证正在等待最终完成。' : 'Manual validation is awaiting final promotion.'
|
|
38
|
-
: chinese ? '人工验证已通过。' : 'Manual validation passed.';
|
|
39
|
-
return `${body.replace(/\s+$/u, '')}\n\n${heading}${marker}\n\n${fallback}\n`;
|
|
26
|
+
const content = JSON.parse(body);
|
|
27
|
+
const manual = content.manualValidation;
|
|
28
|
+
manual.state = phase === 'pending' ? 'pending' : 'passed';
|
|
29
|
+
return JSON.stringify(content);
|
|
30
|
+
}
|
|
31
|
+
function renderedManualSummaryBody(body, phase, taskContent) {
|
|
32
|
+
return prepareAndRenderPrSummaryContent(JSON.parse(manualSummaryBody(body, phase)), taskContent).rendered;
|
|
40
33
|
}
|
|
41
34
|
function openManualValidationStarted(taskMdPath) {
|
|
42
35
|
let content;
|
|
@@ -90,6 +83,7 @@ async function executeManualValidationTransactionAtResolvedTask(taskRef, values,
|
|
|
90
83
|
const preimage = { commentId: currentState.comment?.id ?? null, body: preimageBody, digest: summaryPreimageDigest(preimageBody) };
|
|
91
84
|
const summaryPath = path.resolve(cwd, values.summaryFile);
|
|
92
85
|
const finalBodyWithoutReceipt = fs.readFileSync(summaryPath, 'utf8');
|
|
86
|
+
const taskContent = fs.readFileSync(resolved.taskMdPath, 'utf8');
|
|
93
87
|
const evidenceDigest = sha256File(summaryPath);
|
|
94
88
|
const archiveGeneration = options.archiveGeneration ?? archiveManualValidationGeneration;
|
|
95
89
|
let transactionResult = readManualValidationTransaction(resolved.taskDir, { taskId: resolved.taskId, prNumber: pullRequest.number, prHeadSha: pullRequest.head.sha, evidenceDigest, artifact: values.artifact });
|
|
@@ -132,7 +126,7 @@ async function executeManualValidationTransactionAtResolvedTask(taskRef, values,
|
|
|
132
126
|
evidenceDigest,
|
|
133
127
|
summaryPreimage: preimage,
|
|
134
128
|
pendingSummaryDigest: summaryPreimageDigest(pendingBody),
|
|
135
|
-
finalSummaryDigest: manualValidationFinalSummaryDigest(
|
|
129
|
+
finalSummaryDigest: manualValidationFinalSummaryDigest(renderedManualSummaryBody(finalBodyWithoutReceipt, 'final', taskContent)),
|
|
136
130
|
artifact: values.artifact,
|
|
137
131
|
attempt: 1,
|
|
138
132
|
createdAt: new Date().toISOString(),
|
|
@@ -10,6 +10,9 @@ import { recoverTaskFromComments } from '../platform/task-recovery.js';
|
|
|
10
10
|
import { backfillCompletionComments } from '../platform/completion-backfill.js';
|
|
11
11
|
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
|
|
12
12
|
import { resolveTaskRef } from '../task/resolve-ref.js';
|
|
13
|
+
import { enumerateArtifacts } from '../task/artifacts.js';
|
|
14
|
+
import { parseTaskFrontmatter } from '../task/frontmatter.js';
|
|
15
|
+
import { prepareAndRenderCancelSummaryContent, prepareAndRenderDeliverySummaryContent } from '../platform/issue-summary-content.js';
|
|
13
16
|
const USAGE = `Usage: agent-infra-internal platform-comment list --issue <token> [--cwd <path>]
|
|
14
17
|
agent-infra-internal platform-comment recover --issue <token> --task-id <TASK-id> --output <staging-task.md> [--cwd <path>]
|
|
15
18
|
agent-infra-internal platform-comment owner <task-ref> [--cwd <path>]
|
|
@@ -202,19 +205,34 @@ async function platformComment(args = []) {
|
|
|
202
205
|
fail(`unable to read body file: ${error instanceof Error ? error.message : String(error)}`);
|
|
203
206
|
return;
|
|
204
207
|
}
|
|
205
|
-
const canonical = canonicalizeSummaryBody(body);
|
|
206
|
-
if (!canonical.ok) {
|
|
207
|
-
fail(`unable to stage summary: ${canonical.error.code}: ${canonical.error.message}`);
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
body = canonical.value;
|
|
211
208
|
const resolved = resolveTaskRef(taskRef, { repoRoot: cwd });
|
|
212
209
|
if (!resolved.ok || resolved.state !== 'active') {
|
|
213
210
|
fail('stage-summary requires an active task');
|
|
214
211
|
return;
|
|
215
212
|
}
|
|
216
213
|
const target = path.join(resolved.taskDir, '.delivery-summary.json');
|
|
217
|
-
|
|
214
|
+
let content;
|
|
215
|
+
try {
|
|
216
|
+
const supplied = JSON.parse(body);
|
|
217
|
+
const taskContent = fs.readFileSync(resolved.taskMdPath, 'utf8');
|
|
218
|
+
const title = /^#\s+(.+)$/mu.exec(taskContent)?.[1]?.trim();
|
|
219
|
+
const prepared = prepareAndRenderDeliverySummaryContent(supplied, {
|
|
220
|
+
taskId: resolved.taskId,
|
|
221
|
+
title: title || resolved.taskId,
|
|
222
|
+
artifacts: enumerateArtifacts(resolved.taskDir).filter((artifact) => artifact.name !== 'task.md').map((artifact) => artifact.name),
|
|
223
|
+
verificationFallback: { state: 'not-run', detail: 'Final verification has not run at summary staging.' }
|
|
224
|
+
});
|
|
225
|
+
content = prepared.content;
|
|
226
|
+
const canonical = canonicalizeSummaryBody(prepared.rendered);
|
|
227
|
+
if (!canonical.ok)
|
|
228
|
+
throw new Error(`${canonical.error.code}: ${canonical.error.message}`);
|
|
229
|
+
body = canonical.value;
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
fail(`unable to stage summary: ${error instanceof Error ? error.message : String(error)}`);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const value = { taskId: resolved.taskId, content, contentSha256: createHash('sha256').update(JSON.stringify(content)).digest('hex') };
|
|
218
236
|
const previous = fs.existsSync(target) ? fs.readFileSync(target, 'utf8') : null;
|
|
219
237
|
const next = `${JSON.stringify(value)}\n`;
|
|
220
238
|
if (previous === next) {
|
|
@@ -273,6 +291,37 @@ async function platformComment(args = []) {
|
|
|
273
291
|
fail(`unable to read body file: ${error instanceof Error ? error.message : String(error)}`);
|
|
274
292
|
return;
|
|
275
293
|
}
|
|
294
|
+
if (kind === 'summary' || kind === 'cancel') {
|
|
295
|
+
try {
|
|
296
|
+
const input = JSON.parse(body);
|
|
297
|
+
const resolved = resolveTaskRef(taskRef, { repoRoot: cwd });
|
|
298
|
+
if (!resolved.ok)
|
|
299
|
+
throw new Error(resolved.message);
|
|
300
|
+
const taskContent = fs.readFileSync(resolved.taskMdPath, 'utf8');
|
|
301
|
+
const taskFrontmatter = parseTaskFrontmatter(taskContent);
|
|
302
|
+
const title = /^#\s+(.+)$/mu.exec(taskContent)?.[1]?.trim();
|
|
303
|
+
const artifacts = enumerateArtifacts(resolved.taskDir).filter((artifact) => artifact.name !== 'task.md').map((artifact) => artifact.name);
|
|
304
|
+
const rendered = kind === 'summary'
|
|
305
|
+
? prepareAndRenderDeliverySummaryContent(input, {
|
|
306
|
+
taskId: resolved.taskId,
|
|
307
|
+
title: title || resolved.taskId,
|
|
308
|
+
artifacts,
|
|
309
|
+
...(resolved.state === 'active' ? { verificationFallback: { state: 'not-run', detail: 'Final verification has not run at summary staging.' } } : {})
|
|
310
|
+
}).rendered
|
|
311
|
+
: prepareAndRenderCancelSummaryContent(input, {
|
|
312
|
+
taskId: resolved.taskId,
|
|
313
|
+
title: title || resolved.taskId,
|
|
314
|
+
reason: typeof taskFrontmatter.cancel_reason === 'string' ? taskFrontmatter.cancel_reason : '',
|
|
315
|
+
cancelledAt: typeof taskFrontmatter.cancelled_at === 'string' ? taskFrontmatter.cancelled_at : '',
|
|
316
|
+
lastCompletedArtifact: artifacts.at(-1) ?? null
|
|
317
|
+
}).rendered;
|
|
318
|
+
body = rendered;
|
|
319
|
+
}
|
|
320
|
+
catch (error) {
|
|
321
|
+
fail(`invalid ${kind} summary structure: ${error instanceof Error ? error.message : String(error)}`);
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
276
325
|
finish(await syncPlatformComment(taskRef, {
|
|
277
326
|
kind: kind,
|
|
278
327
|
agent: normalizedAgent,
|