@fitlab-ai/agent-infra 0.11.6 → 0.11.8
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/bin/internal-cli.js +8 -2
- package/dist/lib/agent-clients/adapters/codex.js +1 -1
- package/dist/lib/agent-clients/config.js +11 -3
- package/dist/lib/defaults.json +6 -3
- package/dist/lib/git/primary-worktree.js +58 -0
- package/dist/lib/internal/cli-route-inventory.js +3 -0
- package/dist/lib/internal/platform-pr-review.js +20 -3
- package/dist/lib/internal/task-operation-registry.js +3 -1
- package/dist/lib/internal/task-platform-recovery.js +56 -0
- package/dist/lib/merge.js +25 -5
- package/dist/lib/platform/completion-backfill.js +2 -1
- package/dist/lib/platform/in-label-sync.js +12 -1
- package/dist/lib/platform/issue-comments.js +58 -4
- package/dist/lib/platform/issues.js +105 -5
- package/dist/lib/platform/operation-coordinator.js +74 -0
- package/dist/lib/platform/pr-review.js +107 -1
- package/dist/lib/platform/pr-summary.js +79 -57
- package/dist/lib/platform/pull-requests.js +125 -7
- package/dist/lib/sandbox/commands/create.js +6 -3
- package/dist/lib/sandbox/commands/ls.js +4 -3
- package/dist/lib/sandbox/commands/rm.js +1 -1
- package/dist/lib/sandbox/config.js +22 -4
- package/dist/lib/sandbox/control/server.js +6 -2
- package/dist/lib/sandbox/git-metadata.js +50 -0
- package/dist/lib/sandbox/index.js +1 -1
- package/dist/lib/sandbox/mounts.js +12 -0
- package/dist/lib/sandbox/recovery.js +11 -0
- package/dist/lib/sandbox/removal.js +58 -20
- package/dist/lib/sandbox/tools.js +29 -7
- package/dist/lib/server/config.js +7 -27
- package/dist/lib/server/daemon.js +4 -3
- package/dist/lib/server/process-control.js +4 -2
- package/dist/lib/server/runner.js +4 -3
- package/dist/lib/task/activity-intent.js +4 -3
- package/dist/lib/task/artifact-lifecycle.js +42 -10
- package/dist/lib/task/artifact-receipts.js +62 -22
- package/dist/lib/task/capabilities.js +22 -4
- package/dist/lib/task/completion-facts.js +56 -0
- package/dist/lib/task/create-service.js +11 -5
- package/dist/lib/task/create.js +60 -79
- package/dist/lib/task/events.js +268 -195
- package/dist/lib/task/finalization-artifacts.js +4 -1
- package/dist/lib/task/finalization-handoff.js +2 -1
- package/dist/lib/task/finalization.js +157 -24
- package/dist/lib/task/invalidation-command.js +4 -2
- package/dist/lib/task/invalidation.js +38 -9
- package/dist/lib/task/lifecycle.js +38 -2
- package/dist/lib/task/local-artifact-finalization.js +17 -3
- package/dist/lib/task/platform-operation-journal.js +152 -0
- package/dist/lib/task/platform-operation-recovery.js +459 -0
- package/dist/lib/task/qualification-audit.js +23 -105
- package/dist/lib/task/review-finalization.js +7 -0
- package/dist/lib/task/review-identity.js +69 -0
- package/dist/lib/task/sections.js +6 -5
- package/dist/lib/task/task-execution-lock.js +6 -3
- package/dist/lib/task/verification-engine.js +14 -63
- package/dist/lib/task/verification.js +35 -38
- package/dist/lib/task/workflow-warning-intents.js +7 -1
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-clients/adapters/codex.ts +1 -1
- package/lib/agent-clients/config.ts +9 -3
- package/lib/defaults.json +6 -3
- package/lib/git/primary-worktree.ts +62 -0
- package/lib/internal/cli-route-inventory.ts +2 -0
- package/lib/internal/platform-pr-review.ts +14 -3
- package/lib/internal/task-operation-registry.ts +3 -1
- package/lib/internal/task-platform-recovery.ts +53 -0
- package/lib/merge.ts +26 -6
- package/lib/platform/completion-backfill.ts +2 -1
- package/lib/platform/in-label-sync.ts +12 -0
- package/lib/platform/issue-comments.ts +59 -3
- package/lib/platform/issues.ts +103 -5
- package/lib/platform/operation-coordinator.ts +96 -0
- package/lib/platform/pr-review.ts +113 -1
- package/lib/platform/pr-summary.ts +22 -1
- package/lib/platform/pull-requests.ts +132 -8
- package/lib/sandbox/commands/create.ts +7 -8
- package/lib/sandbox/commands/ls.ts +4 -3
- package/lib/sandbox/commands/rm.ts +1 -1
- package/lib/sandbox/config.ts +23 -5
- package/lib/sandbox/control/server.ts +5 -2
- package/lib/sandbox/git-metadata.ts +66 -0
- package/lib/sandbox/index.ts +1 -1
- package/lib/sandbox/mounts.ts +14 -0
- package/lib/sandbox/recovery.ts +13 -0
- package/lib/sandbox/removal.ts +57 -19
- package/lib/sandbox/tool-types.ts +1 -1
- package/lib/sandbox/tools.ts +36 -7
- package/lib/server/config.ts +7 -29
- package/lib/server/daemon.ts +5 -3
- package/lib/server/process-control.ts +4 -2
- package/lib/server/runner.ts +7 -4
- package/lib/server/server.schema.json +0 -4
- package/lib/task/activity-intent.ts +4 -3
- package/lib/task/artifact-lifecycle.ts +35 -11
- package/lib/task/artifact-receipts.ts +55 -15
- package/lib/task/capabilities.ts +17 -3
- package/lib/task/completion-facts.ts +66 -0
- package/lib/task/create-service.ts +12 -6
- package/lib/task/create.ts +54 -69
- package/lib/task/events.ts +248 -182
- package/lib/task/finalization-artifacts.ts +4 -1
- package/lib/task/finalization-handoff.ts +2 -1
- package/lib/task/finalization.ts +154 -21
- package/lib/task/invalidation-command.ts +4 -2
- package/lib/task/invalidation.ts +35 -10
- package/lib/task/lifecycle.ts +35 -3
- package/lib/task/local-artifact-finalization.ts +13 -3
- package/lib/task/platform-operation-journal.ts +230 -0
- package/lib/task/platform-operation-recovery.ts +435 -0
- package/lib/task/qualification-audit.ts +21 -114
- package/lib/task/review-finalization.ts +7 -0
- package/lib/task/review-identity.ts +85 -0
- package/lib/task/sections.ts +6 -6
- package/lib/task/task-execution-lock.ts +7 -3
- package/lib/task/verification-engine.ts +13 -86
- package/lib/task/verification.ts +34 -38
- package/lib/task/workflow-warning-intents.ts +9 -1
- package/package.json +1 -1
- package/templates/.agents/README.en.md +19 -17
- package/templates/.agents/README.zh-CN.md +18 -16
- package/templates/.agents/rules/README.en.md +2 -1
- package/templates/.agents/rules/README.zh-CN.md +2 -1
- package/templates/.agents/rules/decision-qualification.en.md +4 -3
- package/templates/.agents/rules/decision-qualification.zh-CN.md +4 -3
- package/templates/.agents/rules/task-management.en.md +12 -0
- package/templates/.agents/rules/task-management.zh-CN.md +12 -0
- package/templates/.agents/rules/validation-output.en.md +19 -0
- package/templates/.agents/rules/validation-output.zh-CN.md +19 -0
- package/templates/.agents/skills/analyze-task/SKILL.en.md +3 -1
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/block-task/SKILL.en.md +2 -0
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/cancel-task/SKILL.en.md +6 -2
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +5 -3
- package/templates/.agents/skills/code-task/SKILL.en.md +5 -3
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/code-task/reference/report-template.en.md +4 -8
- package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +4 -8
- package/templates/.agents/skills/commit/SKILL.en.md +1 -1
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +1 -1
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/complete-task/SKILL.en.md +4 -0
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +4 -0
- package/templates/.agents/skills/create-pr/SKILL.en.md +2 -0
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/create-task/SKILL.en.md +2 -0
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-codescan/SKILL.en.md +2 -0
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-dependabot/SKILL.en.md +2 -0
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-issue/SKILL.en.md +2 -0
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/plan-task/SKILL.en.md +3 -1
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/plan-task/config/verify.en.json +1 -1
- package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +1 -1
- package/templates/.agents/skills/review-analysis/SKILL.en.md +3 -1
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +3 -1
- package/templates/.agents/skills/review-analysis/reference/report-template.en.md +4 -8
- package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +4 -8
- package/templates/.agents/skills/review-code/SKILL.en.md +13 -12
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +11 -12
- package/templates/.agents/skills/review-code/config/verify.en.json +1 -3
- package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -3
- package/templates/.agents/skills/review-code/reference/output-templates.en.md +23 -46
- package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +27 -48
- package/templates/.agents/skills/review-code/reference/report-template.en.md +8 -11
- package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +8 -11
- package/templates/.agents/skills/review-code/reference/review-criteria.en.md +2 -2
- package/templates/.agents/skills/review-code/reference/review-criteria.zh-CN.md +2 -2
- package/templates/.agents/skills/review-plan/SKILL.en.md +3 -1
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +3 -1
- package/templates/.agents/skills/review-plan/reference/report-template.en.md +5 -9
- package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +5 -9
- package/templates/.agents/skills/review-pr/SKILL.en.md +13 -11
- package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +13 -11
- package/templates/.agents/skills/review-pr/reference/output-guidance.en.md +3 -3
- package/templates/.agents/skills/review-pr/reference/output-guidance.zh-CN.md +3 -3
- package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -0
- package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -0
- package/templates/.agents/skills/run-manual-validation/SKILL.en.md +1 -1
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +19 -6
- package/templates/.agents/skills/watch-pr/SKILL.en.md +2 -0
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +1 -1
- package/templates/.agents/templates/task.en.md +2 -2
- package/templates/.agents/templates/task.zh-CN.md +2 -2
package/dist/bin/internal-cli.js
CHANGED
|
@@ -15,6 +15,7 @@ const taskWorkflowCommand = command === 'task-artifact'
|
|
|
15
15
|
|| command === 'task-ledger'
|
|
16
16
|
|| command === 'task-invalidation'
|
|
17
17
|
|| command === 'task-warning';
|
|
18
|
+
const taskPlatformRecoveryCommand = command === 'task-platform-recovery';
|
|
18
19
|
const manualValidationWorkflowCommand = command === 'manual-validation';
|
|
19
20
|
const taskControlMarkers = [
|
|
20
21
|
'AGENT_INFRA_TASK_ID', 'AGENT_INFRA_CONTROL_TOKEN', 'AGENT_INFRA_CONTROL_GENERATION',
|
|
@@ -48,9 +49,9 @@ function taskControlTransportFailure(message, code = 'TASK_CONTROL_TRANSPORT_INV
|
|
|
48
49
|
process.exit(1);
|
|
49
50
|
}
|
|
50
51
|
let controlRouted = false;
|
|
51
|
-
if (!taskViewGuardFailed && !markerlessHelp && (taskControlCommand || taskWorkflowCommand || manualValidationWorkflowCommand)) {
|
|
52
|
+
if (!taskViewGuardFailed && !markerlessHelp && (taskControlCommand || taskWorkflowCommand || manualValidationWorkflowCommand || taskPlatformRecoveryCommand)) {
|
|
52
53
|
const transport = resolveSandboxControlTransport(process.env, {
|
|
53
|
-
localWorkflow: command === 'task-orchestration' || command === 'task-finalization' || taskWorkflowCommand || manualValidationWorkflowCommand
|
|
54
|
+
localWorkflow: command === 'task-orchestration' || command === 'task-finalization' || taskWorkflowCommand || manualValidationWorkflowCommand || taskPlatformRecoveryCommand
|
|
54
55
|
});
|
|
55
56
|
switch (transport.kind) {
|
|
56
57
|
case 'fail-closed': {
|
|
@@ -90,6 +91,11 @@ if (!controlRouted && !taskViewGuardFailed && internalRouteRegistered)
|
|
|
90
91
|
await taskFinalization(process.argv.slice(3));
|
|
91
92
|
break;
|
|
92
93
|
}
|
|
94
|
+
case 'task-platform-recovery': {
|
|
95
|
+
const { taskPlatformRecovery } = await import('../lib/internal/task-platform-recovery.js');
|
|
96
|
+
await taskPlatformRecovery(process.argv.slice(3));
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
93
99
|
case 'task-create': {
|
|
94
100
|
const { taskCreate } = await import('../lib/internal/task-create.js');
|
|
95
101
|
await taskCreate(process.argv.slice(3));
|
|
@@ -50,7 +50,7 @@ const codexAdapter = defineAgentClientAdapter({
|
|
|
50
50
|
containerMount: '/home/devuser/.codex',
|
|
51
51
|
versionCmd: 'codex --version',
|
|
52
52
|
setupHint: 'Run codex once inside the container and choose Device Code login if needed.',
|
|
53
|
-
tmpfs: { size: '512m', seed: ['config.toml', 'model-catalogs'] },
|
|
53
|
+
tmpfs: { size: '512m', seed: ['config.toml', 'model-catalogs'], exec: true },
|
|
54
54
|
hostLiveMounts: [
|
|
55
55
|
{
|
|
56
56
|
hostPath: hostJoin(home, '.codex', 'auth.json'),
|
|
@@ -114,10 +114,18 @@ function normalizeAgentClients(input) {
|
|
|
114
114
|
if (hasOwn(input, 'tuis'))
|
|
115
115
|
fail('INVALID_AGENT_CLIENTS', 'tuis');
|
|
116
116
|
const sandbox = isRecord(input.sandbox) ? input.sandbox : undefined;
|
|
117
|
-
if (
|
|
118
|
-
|
|
117
|
+
if (sandbox && hasOwn(sandbox, 'customTools')) {
|
|
118
|
+
fail('INVALID_AGENT_CLIENTS', 'sandbox.customTools');
|
|
119
|
+
}
|
|
120
|
+
if (sandbox && hasOwn(sandbox, 'tools')) {
|
|
121
|
+
if (!isRecord(sandbox.tools))
|
|
122
|
+
fail('INVALID_AGENT_CLIENTS', 'sandbox.tools');
|
|
123
|
+
const tools = sandbox.tools;
|
|
124
|
+
if (!Array.isArray(tools.ids))
|
|
125
|
+
fail('INVALID_AGENT_CLIENTS', 'sandbox.tools.ids');
|
|
126
|
+
for (const [index, tool] of tools.ids.entries()) {
|
|
119
127
|
if (isAgentClientId(tool)) {
|
|
120
|
-
fail('INVALID_AGENT_CLIENTS', `sandbox.tools[${index}]`);
|
|
128
|
+
fail('INVALID_AGENT_CLIENTS', `sandbox.tools.ids[${index}]`);
|
|
121
129
|
}
|
|
122
130
|
}
|
|
123
131
|
}
|
package/dist/lib/defaults.json
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { sameFilesystemEntry } from './worktree-identity.js';
|
|
4
|
+
function gitText(repositoryRoot, args) {
|
|
5
|
+
return execFileSync('git', ['-C', repositoryRoot, ...args], {
|
|
6
|
+
encoding: 'utf8',
|
|
7
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
8
|
+
}).replace(/\r?\n$/, '');
|
|
9
|
+
}
|
|
10
|
+
function isPrimaryWorktree(candidate, expectedCommonDirectory) {
|
|
11
|
+
try {
|
|
12
|
+
const root = fs.realpathSync.native(candidate);
|
|
13
|
+
if (!fs.statSync(root).isDirectory())
|
|
14
|
+
return false;
|
|
15
|
+
if (gitText(root, ['rev-parse', '--show-prefix']) !== '')
|
|
16
|
+
return false;
|
|
17
|
+
const commonDirectory = gitText(root, ['rev-parse', '--path-format=absolute', '--git-common-dir']);
|
|
18
|
+
const gitDirectory = gitText(root, ['rev-parse', '--absolute-git-dir']);
|
|
19
|
+
return sameFilesystemEntry(commonDirectory, expectedCommonDirectory) &&
|
|
20
|
+
sameFilesystemEntry(gitDirectory, expectedCommonDirectory);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function worktreePaths(repositoryRoot) {
|
|
27
|
+
const output = execFileSync('git', ['-C', repositoryRoot, 'worktree', 'list', '--porcelain', '-z'], {
|
|
28
|
+
encoding: 'utf8',
|
|
29
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
30
|
+
});
|
|
31
|
+
return output
|
|
32
|
+
.split('\0\0')
|
|
33
|
+
.flatMap((record) => record.split('\0'))
|
|
34
|
+
.filter((field) => field.startsWith('worktree '))
|
|
35
|
+
.map((field) => field.slice('worktree '.length));
|
|
36
|
+
}
|
|
37
|
+
export function resolvePrimaryWorktreeRoot(repositoryRoot) {
|
|
38
|
+
try {
|
|
39
|
+
const root = fs.realpathSync.native(repositoryRoot);
|
|
40
|
+
if (!fs.statSync(root).isDirectory() || gitText(root, ['rev-parse', '--show-prefix']) !== '') {
|
|
41
|
+
throw new Error('repository root is not a worktree root');
|
|
42
|
+
}
|
|
43
|
+
const commonDirectory = gitText(root, ['rev-parse', '--path-format=absolute', '--git-common-dir']);
|
|
44
|
+
const gitDirectory = gitText(root, ['rev-parse', '--absolute-git-dir']);
|
|
45
|
+
if (sameFilesystemEntry(gitDirectory, commonDirectory))
|
|
46
|
+
return root;
|
|
47
|
+
const matches = worktreePaths(root).filter((candidate) => isPrimaryWorktree(candidate, commonDirectory));
|
|
48
|
+
if (matches.length !== 1) {
|
|
49
|
+
throw new Error(matches.length === 0 ? 'primary worktree metadata was not found' : 'primary worktree metadata is ambiguous');
|
|
50
|
+
}
|
|
51
|
+
return fs.realpathSync.native(matches[0]);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
55
|
+
throw new Error(`server: unable to locate primary worktree: ${detail}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=primary-worktree.js.map
|
|
@@ -60,6 +60,7 @@ export const INTERNAL_HANDLER_ROUTE_SELECTORS = Object.freeze({
|
|
|
60
60
|
'task-invalidation': ['reconcile'],
|
|
61
61
|
'task-lifecycle': ['intent'],
|
|
62
62
|
'task-finalization': ['complete'],
|
|
63
|
+
'task-platform-recovery': ['inspect', 'recover'],
|
|
63
64
|
'task-short-id': ['list', 'list-verify', 'alloc', 'release', 'resolve'],
|
|
64
65
|
'task-snapshot': ['snapshot'],
|
|
65
66
|
'task-verify': ['event'],
|
|
@@ -88,6 +89,8 @@ export function internalRouteSelector(command, args) {
|
|
|
88
89
|
return args[1] ? 'intent' : '';
|
|
89
90
|
if (command === 'task-finalization')
|
|
90
91
|
return args[1] === 'complete' ? 'complete' : '';
|
|
92
|
+
if (command === 'task-platform-recovery')
|
|
93
|
+
return args[1] ?? '';
|
|
91
94
|
if (command === 'task-event')
|
|
92
95
|
return args[1] ? 'event' : '';
|
|
93
96
|
if (command === 'task-verify')
|
|
@@ -3,12 +3,13 @@ import path from 'node:path';
|
|
|
3
3
|
import { inspectPlatformPullRequestByNumber } from '../platform/pull-requests.js';
|
|
4
4
|
import { listPrReviews, publishPrReview } from '../platform/pr-review.js';
|
|
5
5
|
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
|
|
6
|
+
import { normalizeAgentToken, AGENT_USAGE_HINT } from '../agent-clients/tokens.js';
|
|
6
7
|
const USAGE = `Usage: agent-infra-internal platform-pr-review inspect --pr <token> [--cwd <path>]
|
|
7
8
|
agent-infra-internal platform-pr-review list --pr <token> [--cwd <path>]
|
|
8
|
-
agent-infra-internal platform-pr-review publish --pr <token> --scope <taskId|pr{N}> --round <N> --commit <sha> --event <COMMENT|APPROVE|REQUEST_CHANGES> --body-file <path|-> [--dry-run] [--cwd <path>]
|
|
9
|
+
agent-infra-internal platform-pr-review publish --pr <token> --scope <taskId|pr{N}> --round <N> --commit <sha> --event <COMMENT|APPROVE|REQUEST_CHANGES> --body-file <path|-> [--artifact <pr-review-artifact>] [--agent <agent>] [--dry-run] [--cwd <path>]
|
|
9
10
|
`;
|
|
10
11
|
const BOOLEAN_FLAGS = new Set(['--dry-run']);
|
|
11
|
-
const VALUE_FLAGS = new Set(['--cwd', '--pr', '--scope', '--round', '--commit', '--event', '--body-file']);
|
|
12
|
+
const VALUE_FLAGS = new Set(['--cwd', '--pr', '--scope', '--round', '--commit', '--event', '--body-file', '--artifact', '--agent']);
|
|
12
13
|
function key(flag) {
|
|
13
14
|
return flag.slice(2).replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
14
15
|
}
|
|
@@ -74,7 +75,7 @@ async function platformPrReview(args = []) {
|
|
|
74
75
|
const allowed = {
|
|
75
76
|
inspect: ['cwd', 'pr'],
|
|
76
77
|
list: ['cwd', 'pr'],
|
|
77
|
-
publish: ['cwd', 'pr', 'scope', 'round', 'commit', 'event', 'bodyFile', 'dryRun']
|
|
78
|
+
publish: ['cwd', 'pr', 'scope', 'round', 'commit', 'event', 'bodyFile', 'artifact', 'agent', 'dryRun']
|
|
78
79
|
};
|
|
79
80
|
const unexpected = Object.keys(values).find((name) => !allowed[operation].includes(name));
|
|
80
81
|
if (unexpected) {
|
|
@@ -99,6 +100,8 @@ async function platformPrReview(args = []) {
|
|
|
99
100
|
const round = Number(values.round);
|
|
100
101
|
const commit = typeof values.commit === 'string' ? values.commit : '';
|
|
101
102
|
const event = values.event;
|
|
103
|
+
const rawAgent = typeof values.agent === 'string' ? values.agent : '';
|
|
104
|
+
const agent = rawAgent ? normalizeAgentToken(rawAgent) : null;
|
|
102
105
|
if (!scope || !/^(?:pr\d+|TASK-\d{8}-\d{6})$/.test(scope)) {
|
|
103
106
|
fail('publish requires --scope <taskId|pr{N}>');
|
|
104
107
|
return;
|
|
@@ -124,6 +127,18 @@ async function platformPrReview(args = []) {
|
|
|
124
127
|
fail('publish requires --body-file');
|
|
125
128
|
return;
|
|
126
129
|
}
|
|
130
|
+
if (/^TASK-\d{8}-\d{6}$/u.test(scope) && typeof values.artifact !== 'string') {
|
|
131
|
+
fail('task-scoped publish requires --artifact <pr-review-artifact>');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (/^TASK-\d{8}-\d{6}$/u.test(scope) && !agent) {
|
|
135
|
+
fail(`task-scoped publish requires --agent <agent>${rawAgent ? `: invalid '${rawAgent}'` : ''}: ${AGENT_USAGE_HINT}`);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (rawAgent && !agent) {
|
|
139
|
+
fail(`invalid --agent '${rawAgent}': ${AGENT_USAGE_HINT}`);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
127
142
|
let body;
|
|
128
143
|
try {
|
|
129
144
|
body = readBodyFile(values.bodyFile, cwd);
|
|
@@ -138,6 +153,8 @@ async function platformPrReview(args = []) {
|
|
|
138
153
|
identity: { scope, round, commitSha: commit },
|
|
139
154
|
event: event,
|
|
140
155
|
body,
|
|
156
|
+
...(typeof values.artifact === 'string' ? { recoveryArtifact: values.artifact } : {}),
|
|
157
|
+
...(agent ? { agent } : {}),
|
|
141
158
|
dryRun: values.dryRun === true
|
|
142
159
|
}));
|
|
143
160
|
}
|
|
@@ -105,6 +105,8 @@ function internalTaskRoutes() {
|
|
|
105
105
|
descriptor('internal', 'task-invalidation', 'reconcile', 'task-bound', 'progress'),
|
|
106
106
|
descriptor('internal', 'task-lifecycle', 'intent', 'task-bound', 'progress'),
|
|
107
107
|
descriptor('internal', 'task-finalization', 'complete', 'task-bound', 'progress'),
|
|
108
|
+
descriptor('internal', 'task-platform-recovery', 'inspect', 'task-bound', 'diagnostic'),
|
|
109
|
+
descriptor('internal', 'task-platform-recovery', 'recover', 'task-bound', 'recovery'),
|
|
108
110
|
descriptor('internal', 'task-short-id', 'list', 'conditional', 'diagnostic'),
|
|
109
111
|
descriptor('internal', 'task-short-id', 'list-verify', 'conditional', 'diagnostic'),
|
|
110
112
|
descriptor('internal', 'task-short-id', 'alloc', 'task-bound', 'progress'),
|
|
@@ -178,7 +180,7 @@ export const INTERNAL_DISPATCHER_ROUTES = Object.freeze([
|
|
|
178
180
|
'platform-comment', 'platform-issue', 'platform-pr', 'platform-pr-review', 'pr-review-grade',
|
|
179
181
|
'platform-checks', 'task-context', 'task-ledger', 'task-warning', 'task-activity', 'task-artifact',
|
|
180
182
|
'task-orchestration', 'task-review', 'task-event', 'task-invalidation', 'task-lifecycle',
|
|
181
|
-
'task-finalization', 'task-short-id', 'task-snapshot', 'task-verify', 'task-validate', 'manual-validation'
|
|
183
|
+
'task-finalization', 'task-platform-recovery', 'task-short-id', 'task-snapshot', 'task-verify', 'task-validate', 'manual-validation'
|
|
182
184
|
]);
|
|
183
185
|
export const PUBLIC_DISPATCHER_ROUTES = Object.freeze([
|
|
184
186
|
'agent-client', 'cp', 'data', 'decide', 'help', 'init', 'merge', 'run', 'sandbox', 'server', 'task', 'sync', 'update', 'version'
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { detectRepoRoot, resolveTaskRef } from '../task/resolve-ref.js';
|
|
2
|
+
import { readPlatformOperationJournal } from '../task/platform-operation-journal.js';
|
|
3
|
+
import { recoverPlatformOperations } from '../task/platform-operation-recovery.js';
|
|
4
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
|
|
5
|
+
const USAGE = 'Usage: agent-infra-internal task-platform-recovery <N | TASK-id> <inspect | recover> [--agent <agent>] [--selection required|deferred|all]\n';
|
|
6
|
+
function option(args, name) {
|
|
7
|
+
const index = args.indexOf(name);
|
|
8
|
+
return index >= 0 ? args[index + 1] : undefined;
|
|
9
|
+
}
|
|
10
|
+
async function taskPlatformRecovery(args = []) {
|
|
11
|
+
if (args[0] === '--help' || args[0] === '-h') {
|
|
12
|
+
process.stdout.write(USAGE);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (!ensureInternalHandlerRoute('task-platform-recovery', args))
|
|
16
|
+
return;
|
|
17
|
+
const action = args[1];
|
|
18
|
+
const registered = action === 'inspect'
|
|
19
|
+
? internalHandlerRoute('task-platform-recovery', 'inspect', action)
|
|
20
|
+
: action === 'recover' && internalHandlerRoute('task-platform-recovery', 'recover', action);
|
|
21
|
+
if (!registered)
|
|
22
|
+
return;
|
|
23
|
+
const repoRoot = detectRepoRoot();
|
|
24
|
+
const task = resolveTaskRef(args[0] ?? '', { repoRoot });
|
|
25
|
+
if (!task.ok) {
|
|
26
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: task.code, message: task.message } })}\n`);
|
|
27
|
+
process.exitCode = 1;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (action === 'inspect') {
|
|
31
|
+
try {
|
|
32
|
+
const journal = readPlatformOperationJournal(task.taskId, repoRoot);
|
|
33
|
+
process.stdout.write(`${JSON.stringify({ status: 'ready', changed: false, taskId: task.taskId, journal })}\n`);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
const value = error;
|
|
37
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: value.code || 'PLATFORM_OPERATION_JOURNAL_INVALID', message: value.message || String(error) } })}\n`);
|
|
38
|
+
process.exitCode = 1;
|
|
39
|
+
}
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const agent = option(args, '--agent');
|
|
43
|
+
const selection = option(args, '--selection') ?? 'all';
|
|
44
|
+
if (!agent || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u.test(agent)
|
|
45
|
+
|| !['required', 'deferred', 'all'].includes(selection)) {
|
|
46
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'PLATFORM_OPERATION_RECOVERY_PAYLOAD_INVALID', message: 'recover requires a valid --agent and --selection' } })}\n`);
|
|
47
|
+
process.stderr.write(USAGE);
|
|
48
|
+
process.exitCode = 1;
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const result = await recoverPlatformOperations(task.taskId, selection, { agent, cwd: repoRoot });
|
|
52
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
53
|
+
process.exitCode = result.status === 'applied' || result.status === 'no-op' ? 0 : result.status === 'blocked' ? 2 : 1;
|
|
54
|
+
}
|
|
55
|
+
export { taskPlatformRecovery };
|
|
56
|
+
//# sourceMappingURL=task-platform-recovery.js.map
|
package/dist/lib/merge.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
import crypto from 'node:crypto';
|
|
4
5
|
import { removeDirRecursive } from './remove-dir.js';
|
|
@@ -305,6 +306,23 @@ function formatBackupTimestamp(date) {
|
|
|
305
306
|
String(date.getDate()).padStart(2, '0')
|
|
306
307
|
].join('') + `-${String(date.getHours()).padStart(2, '0')}${String(date.getMinutes()).padStart(2, '0')}${String(date.getSeconds()).padStart(2, '0')}`;
|
|
307
308
|
}
|
|
309
|
+
function resolveRecoveryProjectKey(repoRoot) {
|
|
310
|
+
let projectKey;
|
|
311
|
+
try {
|
|
312
|
+
const config = JSON.parse(fs.readFileSync(path.join(repoRoot, '.agents', '.airc.json'), 'utf8'));
|
|
313
|
+
if (typeof config.project === 'string' && config.project.trim() !== '') {
|
|
314
|
+
projectKey = config.project.trim();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
// Fall back to the repository directory when project config is unavailable.
|
|
319
|
+
}
|
|
320
|
+
projectKey ??= path.basename(repoRoot);
|
|
321
|
+
if (!/^[A-Za-z0-9_.@-]+$/.test(projectKey) || projectKey === '.' || projectKey === '..') {
|
|
322
|
+
throw new Error(`Invalid project name for recovery backups: ${projectKey}`);
|
|
323
|
+
}
|
|
324
|
+
return projectKey;
|
|
325
|
+
}
|
|
308
326
|
function toPosixPath(relativePath) {
|
|
309
327
|
return relativePath.split(path.sep).join('/');
|
|
310
328
|
}
|
|
@@ -400,7 +418,7 @@ function buildWorkspaceIndex(workspaceDir) {
|
|
|
400
418
|
function backupTaskDir(backupRoot, section, taskDir, taskId) {
|
|
401
419
|
const backupDir = path.join(backupRoot, section, taskId);
|
|
402
420
|
fs.mkdirSync(path.dirname(backupDir), { recursive: true });
|
|
403
|
-
fs.cpSync(taskDir, backupDir, { recursive: true });
|
|
421
|
+
fs.cpSync(taskDir, backupDir, { recursive: true, verbatimSymlinks: true });
|
|
404
422
|
return backupDir;
|
|
405
423
|
}
|
|
406
424
|
function copyTaskToSection(sourceTask, workspaceDir) {
|
|
@@ -872,12 +890,14 @@ async function cmdMerge(args) {
|
|
|
872
890
|
if (!fs.lstatSync(resolvedSource).isDirectory()) {
|
|
873
891
|
throw new Error(`Source path is not a directory: ${sourcePath}`);
|
|
874
892
|
}
|
|
875
|
-
const
|
|
893
|
+
const repoRoot = process.cwd();
|
|
894
|
+
const workspaceDir = path.join(repoRoot, '.agents', 'workspace');
|
|
876
895
|
const archiveDir = path.join(workspaceDir, 'archive');
|
|
877
896
|
const backupStamp = formatBackupTimestamp(new Date());
|
|
878
|
-
const
|
|
879
|
-
const
|
|
880
|
-
const
|
|
897
|
+
const projectKey = resolveRecoveryProjectKey(repoRoot);
|
|
898
|
+
const recoveryRoot = path.join(os.homedir(), '.agent-infra', 'recovery-backups', projectKey, 'workspace-merge');
|
|
899
|
+
const backupRoot = path.join(recoveryRoot, backupStamp);
|
|
900
|
+
const report = createReport(resolvedSource, backupRoot);
|
|
881
901
|
detectSourceMode(resolvedSource);
|
|
882
902
|
validateSourceWorkspace(resolvedSource);
|
|
883
903
|
validateArchiveSection(workspaceDir, new Map());
|
|
@@ -19,7 +19,7 @@ function referencedBackfillArtifact(taskDir, message) {
|
|
|
19
19
|
if (names.length !== 1)
|
|
20
20
|
return { status: 'ignored', artifact: null, error: null };
|
|
21
21
|
const parsed = parseArtifactName(names[0]);
|
|
22
|
-
if (!parsed ||
|
|
22
|
+
if (!parsed || !COMPLETION_BACKFILL_FAMILIES.includes(parsed.family)) {
|
|
23
23
|
return { status: 'ignored', artifact: null, error: null };
|
|
24
24
|
}
|
|
25
25
|
const artifactPath = path.join(taskDir, parsed.name);
|
|
@@ -112,6 +112,7 @@ async function backfillCompletionComments(taskRef, options) {
|
|
|
112
112
|
artifact: artifact.name,
|
|
113
113
|
agent: options.agent,
|
|
114
114
|
backfill: true,
|
|
115
|
+
dependency: 'required',
|
|
115
116
|
cwd: resolved.repoRoot,
|
|
116
117
|
client: options.client
|
|
117
118
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { computeInLabels } from './metadata-labels.js';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
2
3
|
function inLabels(labels) {
|
|
3
4
|
return [...new Set(labels.filter((label) => label.startsWith('in:')))].sort();
|
|
4
5
|
}
|
|
@@ -26,6 +27,16 @@ function validateInLabelMapping(value) {
|
|
|
26
27
|
}
|
|
27
28
|
return { ok: true, value: normalized };
|
|
28
29
|
}
|
|
30
|
+
function inLabelMappingDigest(value) {
|
|
31
|
+
const mapping = validateInLabelMapping(value);
|
|
32
|
+
if (!mapping.ok)
|
|
33
|
+
return mapping;
|
|
34
|
+
const canonical = Object.fromEntries(Object.keys(mapping.value).sort().map((name) => [
|
|
35
|
+
name,
|
|
36
|
+
[...new Set(mapping.value[name])].sort()
|
|
37
|
+
]));
|
|
38
|
+
return { ok: true, digest: createHash('sha256').update(JSON.stringify(canonical)).digest('hex') };
|
|
39
|
+
}
|
|
29
40
|
function repositoryLabelPages(value) {
|
|
30
41
|
if (!Array.isArray(value))
|
|
31
42
|
return null;
|
|
@@ -139,5 +150,5 @@ function extractPullRequestFileNames(value) {
|
|
|
139
150
|
function resourceSnapshot(kind, number, labels) {
|
|
140
151
|
return { kind, number, labels: [...labels].sort() };
|
|
141
152
|
}
|
|
142
|
-
export { extractPullRequestFileNames, extractRepositoryLabelNames, flattenPages, inLabels, labelDelta, mergeInLabels, planInLabelUpdate, resourceSnapshot, syncLabelDelta, validateInLabelMapping, validateRepositoryLabelPayload };
|
|
153
|
+
export { extractPullRequestFileNames, extractRepositoryLabelNames, flattenPages, inLabels, inLabelMappingDigest, labelDelta, mergeInLabels, planInLabelUpdate, resourceSnapshot, syncLabelDelta, validateInLabelMapping, validateRepositoryLabelPayload };
|
|
143
154
|
//# sourceMappingURL=in-label-sync.js.map
|
|
@@ -3,6 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import { createHash } from 'node:crypto';
|
|
4
4
|
import { parseTaskFrontmatter } from '../task/frontmatter.js';
|
|
5
5
|
import { resolveTaskRef } from '../task/resolve-ref.js';
|
|
6
|
+
import { coordinatePlatformWrite } from './operation-coordinator.js';
|
|
6
7
|
import { resolvePlatformProviderContext } from './context.js';
|
|
7
8
|
import { platformResult } from './types.js';
|
|
8
9
|
import { providerError, providerOperationContext, providerStatus, providerResourceToken, unsupportedProviderOperation } from './provider-bridge.js';
|
|
@@ -29,6 +30,8 @@ const ARTIFACT_TITLES = {
|
|
|
29
30
|
'review-plan': '技术方案审查',
|
|
30
31
|
code: '实现报告',
|
|
31
32
|
'review-code': '代码审查',
|
|
33
|
+
'manual-validation': '人工验证',
|
|
34
|
+
'validation-run': '验证运行证据',
|
|
32
35
|
'pr-review': 'PR 审查报告'
|
|
33
36
|
};
|
|
34
37
|
function normalizeCommentContent(content) {
|
|
@@ -98,7 +101,7 @@ function taskCommentLanguage(repoRoot) {
|
|
|
98
101
|
}
|
|
99
102
|
function artifactIdentity(artifact) {
|
|
100
103
|
const stem = path.basename(artifact, '.md');
|
|
101
|
-
const match = stem.match(/^(analysis|review-analysis|plan|review-plan|code|review-code|pr-review)(?:-r(\d+))?$/);
|
|
104
|
+
const match = stem.match(/^(analysis|review-analysis|plan|review-plan|code|review-code|manual-validation|validation-run|pr-review)(?:-r(\d+))?$/);
|
|
102
105
|
if (!match)
|
|
103
106
|
throw new Error(`unsupported artifact '${artifact}'`);
|
|
104
107
|
const base = ARTIFACT_TITLES[match[1]];
|
|
@@ -430,7 +433,7 @@ function writeComment(client, repo, issue, cwd, body, id) {
|
|
|
430
433
|
const endpoint = id ? `repos/${repo}/issues/comments/${id}` : `repos/${repo}/issues/${issue}/comments`;
|
|
431
434
|
return client.json(['api', endpoint, '-X', id ? 'PATCH' : 'POST', '--input', '-'], { cwd, method: id ? 'PATCH' : 'POST', input: JSON.stringify({ body }) });
|
|
432
435
|
}
|
|
433
|
-
async function
|
|
436
|
+
async function syncPlatformCommentImpl(taskRef, options) {
|
|
434
437
|
const resolved = resolveTaskRef(taskRef, options.cwd ? { repoRoot: options.cwd } : {});
|
|
435
438
|
if (!resolved.ok) {
|
|
436
439
|
return platformResult('failed', {
|
|
@@ -452,7 +455,12 @@ async function syncPlatformComment(taskRef, options) {
|
|
|
452
455
|
}
|
|
453
456
|
let desired;
|
|
454
457
|
try {
|
|
455
|
-
|
|
458
|
+
const projectedContent = options.kind === 'task' && options.taskProjection ? options.taskProjection.content : taskContent;
|
|
459
|
+
if (options.kind === 'task' && options.taskProjection
|
|
460
|
+
&& createHash('sha256').update(projectedContent).digest('hex') !== options.taskProjection.sha256) {
|
|
461
|
+
throw Object.assign(new Error('finalization task projection digest does not match content'), { code: 'FINALIZATION_PROJECTION_INVALID' });
|
|
462
|
+
}
|
|
463
|
+
desired = expectedComments(resolved.taskId, projectedContent, resolved.taskDir, resolved.repoRoot, options);
|
|
456
464
|
}
|
|
457
465
|
catch (error) {
|
|
458
466
|
return platformResult('failed', {
|
|
@@ -644,6 +652,52 @@ async function syncPlatformComment(taskRef, options) {
|
|
|
644
652
|
});
|
|
645
653
|
return result;
|
|
646
654
|
}
|
|
655
|
+
async function syncPlatformComment(taskRef, options) {
|
|
656
|
+
const resolved = resolveTaskRef(taskRef, options.cwd ? { repoRoot: options.cwd } : {});
|
|
657
|
+
if (!resolved.ok)
|
|
658
|
+
return syncPlatformCommentImpl(taskRef, options);
|
|
659
|
+
const taskContent = fs.readFileSync(resolved.taskMdPath, 'utf8');
|
|
660
|
+
if (!taskIssueIdentity(parseTaskFrontmatter(taskContent)))
|
|
661
|
+
return syncPlatformCommentImpl(taskRef, options);
|
|
662
|
+
let operation;
|
|
663
|
+
try {
|
|
664
|
+
const sourceContent = options.kind === 'task' && options.taskProjection ? options.taskProjection.content : taskContent;
|
|
665
|
+
const desired = expectedComments(resolved.taskId, sourceContent, resolved.taskDir, resolved.repoRoot, options);
|
|
666
|
+
const content = desired.map((chunk) => chunk.content).join('\0');
|
|
667
|
+
const kind = options.kind === 'task' ? 'task-comment' : options.kind === 'summary' ? 'summary-comment'
|
|
668
|
+
: options.kind === 'cancel' ? 'cancel-comment' : 'artifact-comment';
|
|
669
|
+
const target = options.kind === 'artifact' ? options.artifact : options.kind;
|
|
670
|
+
operation = { kind, target, expectedDigest: createHash('sha256').update(content).digest('hex') };
|
|
671
|
+
}
|
|
672
|
+
catch {
|
|
673
|
+
return syncPlatformCommentImpl(taskRef, options);
|
|
674
|
+
}
|
|
675
|
+
const execute = () => syncPlatformCommentImpl(taskRef, options);
|
|
676
|
+
if (options.skipQueue)
|
|
677
|
+
return execute();
|
|
678
|
+
return coordinatePlatformWrite({
|
|
679
|
+
operation: { taskRef: resolved.taskId, cwd: resolved.repoRoot, ...operation, dependency: options.dependency ?? 'deferred' },
|
|
680
|
+
agent: options.agent,
|
|
681
|
+
execute,
|
|
682
|
+
block: (error) => platformResult('blocked', { error }),
|
|
683
|
+
persistenceFailure: (error) => platformResult('failed', { error })
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
function inspectPlatformCommentOperation(taskRef, options) {
|
|
687
|
+
const resolved = resolveTaskRef(taskRef, options.cwd ? { repoRoot: options.cwd } : {});
|
|
688
|
+
if (!resolved.ok)
|
|
689
|
+
return null;
|
|
690
|
+
const taskContent = fs.readFileSync(resolved.taskMdPath, 'utf8');
|
|
691
|
+
if (!taskIssueIdentity(parseTaskFrontmatter(taskContent)))
|
|
692
|
+
return null;
|
|
693
|
+
const sourceContent = options.kind === 'task' && options.taskProjection ? options.taskProjection.content : taskContent;
|
|
694
|
+
const desired = expectedComments(resolved.taskId, sourceContent, resolved.taskDir, resolved.repoRoot, options);
|
|
695
|
+
const kind = options.kind === 'task' ? 'task-comment' : options.kind === 'summary' ? 'summary-comment'
|
|
696
|
+
: options.kind === 'cancel' ? 'cancel-comment' : 'artifact-comment';
|
|
697
|
+
const target = options.kind === 'artifact' ? options.artifact : options.kind;
|
|
698
|
+
const expectedDigest = createHash('sha256').update(desired.map((chunk) => chunk.content).join('\0')).digest('hex');
|
|
699
|
+
return { kind, target, expectedDigest, id: createHash('sha256').update(`${kind}\0${target}\0${expectedDigest}`).digest('hex') };
|
|
700
|
+
}
|
|
647
701
|
async function listPlatformComments(issue, cwd = process.cwd(), client) {
|
|
648
702
|
const loaded = await resolvePlatformProviderContext({ cwd, client });
|
|
649
703
|
const context = loaded.ok ? loaded.value.context : loaded.context;
|
|
@@ -708,5 +762,5 @@ async function checkPlatformCommentOwner(taskRef, options = {}) {
|
|
|
708
762
|
}
|
|
709
763
|
return platformResult('no-op', { ...contextFields(context), resource: { kind: 'issue', number: resourceIdentityNumber(issueIdentity), identity: issueIdentity }, error: null });
|
|
710
764
|
}
|
|
711
|
-
export { COMMENT_BYTE_LIMIT, MARKERS, chunkArtifactComment, findMarkerComments, listRemoteComments, checkPlatformCommentOwner, listPlatformComments, normalizeCommentContent, renderTaskComment, renderTaskCommentResult, isTaskCommentTooLarge, syncPlatformComment, validateRelatedMarkerSet, writeComment };
|
|
765
|
+
export { COMMENT_BYTE_LIMIT, MARKERS, chunkArtifactComment, inspectPlatformCommentOperation, findMarkerComments, listRemoteComments, checkPlatformCommentOwner, listPlatformComments, normalizeCommentContent, renderTaskComment, renderTaskCommentResult, isTaskCommentTooLarge, syncPlatformComment, validateRelatedMarkerSet, writeComment };
|
|
712
766
|
//# sourceMappingURL=issue-comments.js.map
|