@cat-factory/orchestration 0.140.1 → 0.142.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/dist/container/dependencies.d.ts +8 -1
- package/dist/container/dependencies.d.ts.map +1 -1
- package/dist/container/engine-collaborators.d.ts +4 -4
- package/dist/container/engine-dependent-modules.d.ts +8 -1
- package/dist/container/engine-dependent-modules.d.ts.map +1 -1
- package/dist/container/engine-dependent-modules.js +9 -2
- package/dist/container/engine-dependent-modules.js.map +1 -1
- package/dist/container/module-shapes.d.ts +127 -0
- package/dist/container/module-shapes.d.ts.map +1 -0
- package/dist/container/module-shapes.js +2 -0
- package/dist/container/module-shapes.js.map +1 -0
- package/dist/container/modules.d.ts +16 -2
- package/dist/container/modules.d.ts.map +1 -1
- package/dist/container/modules.js +32 -1
- package/dist/container/modules.js.map +1 -1
- package/dist/container.d.ts +5 -118
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +8 -21
- package/dist/container.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/modules/execution/ExecutionService.d.ts +22 -30
- package/dist/modules/execution/ExecutionService.d.ts.map +1 -1
- package/dist/modules/execution/ExecutionService.js +53 -54
- package/dist/modules/execution/ExecutionService.js.map +1 -1
- package/dist/modules/execution/ExecutionServiceDependencies.d.ts +9 -0
- package/dist/modules/execution/ExecutionServiceDependencies.d.ts.map +1 -1
- package/dist/modules/execution/MergeResolver.d.ts +18 -1
- package/dist/modules/execution/MergeResolver.d.ts.map +1 -1
- package/dist/modules/execution/MergeResolver.js +70 -17
- package/dist/modules/execution/MergeResolver.js.map +1 -1
- package/dist/modules/execution/ReviewGateController.d.ts +43 -1
- package/dist/modules/execution/ReviewGateController.d.ts.map +1 -1
- package/dist/modules/execution/ReviewGateController.js +55 -4
- package/dist/modules/execution/ReviewGateController.js.map +1 -1
- package/dist/modules/execution/RunMergePolicy.d.ts +59 -0
- package/dist/modules/execution/RunMergePolicy.d.ts.map +1 -0
- package/dist/modules/execution/RunMergePolicy.js +85 -0
- package/dist/modules/execution/RunMergePolicy.js.map +1 -0
- package/dist/modules/execution/RunStateMachine.d.ts +9 -0
- package/dist/modules/execution/RunStateMachine.d.ts.map +1 -1
- package/dist/modules/execution/RunStateMachine.js +11 -0
- package/dist/modules/execution/RunStateMachine.js.map +1 -1
- package/dist/modules/execution/gate-window-controllers.d.ts +4 -0
- package/dist/modules/execution/gate-window-controllers.d.ts.map +1 -1
- package/dist/modules/execution/gate-window-controllers.js +3 -1
- package/dist/modules/execution/gate-window-controllers.js.map +1 -1
- package/dist/modules/execution/policy-types.d.ts +37 -0
- package/dist/modules/execution/policy-types.d.ts.map +1 -0
- package/dist/modules/execution/policy-types.js +2 -0
- package/dist/modules/execution/policy-types.js.map +1 -0
- package/dist/modules/execution/prReport.logic.d.ts.map +1 -1
- package/dist/modules/execution/prReport.logic.js +22 -21
- package/dist/modules/execution/prReport.logic.js.map +1 -1
- package/dist/modules/execution/review-kinds.d.ts.map +1 -1
- package/dist/modules/execution/review-kinds.js +4 -0
- package/dist/modules/execution/review-kinds.js.map +1 -1
- package/dist/modules/execution/reviewQuestionWriteback.logic.d.ts +30 -0
- package/dist/modules/execution/reviewQuestionWriteback.logic.d.ts.map +1 -0
- package/dist/modules/execution/reviewQuestionWriteback.logic.js +50 -0
- package/dist/modules/execution/reviewQuestionWriteback.logic.js.map +1 -0
- package/dist/modules/execution/run-context-admission.d.ts +25 -0
- package/dist/modules/execution/run-context-admission.d.ts.map +1 -0
- package/dist/modules/execution/run-context-admission.js +54 -0
- package/dist/modules/execution/run-context-admission.js.map +1 -0
- package/dist/modules/merge/MergeTrackRecordService.d.ts +133 -0
- package/dist/modules/merge/MergeTrackRecordService.d.ts.map +1 -0
- package/dist/modules/merge/MergeTrackRecordService.js +191 -0
- package/dist/modules/merge/MergeTrackRecordService.js.map +1 -0
- package/dist/modules/merge/RiskPolicyService.d.ts.map +1 -1
- package/dist/modules/merge/RiskPolicyService.js +5 -0
- package/dist/modules/merge/RiskPolicyService.js.map +1 -1
- package/dist/modules/merge/externalMergeObserver.d.ts +27 -0
- package/dist/modules/merge/externalMergeObserver.d.ts.map +1 -0
- package/dist/modules/merge/externalMergeObserver.js +40 -0
- package/dist/modules/merge/externalMergeObserver.js.map +1 -0
- package/dist/modules/recurring/TrackerSettingsService.d.ts.map +1 -1
- package/dist/modules/recurring/TrackerSettingsService.js +4 -0
- package/dist/modules/recurring/TrackerSettingsService.js.map +1 -1
- package/package.json +11 -11
- package/dist/modules/execution/prReportText.logic.d.ts +0 -46
- package/dist/modules/execution/prReportText.logic.d.ts.map +0 -1
- package/dist/modules/execution/prReportText.logic.js +0 -188
- package/dist/modules/execution/prReportText.logic.js.map +0 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the observer the GitHub/GitLab webhook ingest calls when a pull request is merged
|
|
3
|
+
* OUTSIDE cat-factory — a human clicking merge on the provider rather than acting on the
|
|
4
|
+
* merge-review card. Two things follow:
|
|
5
|
+
*
|
|
6
|
+
* 1. The run's merge track record is attributed `external_merged` (it would otherwise sit at
|
|
7
|
+
* `pending_review` forever, overstating the class's un-decided share).
|
|
8
|
+
* 2. A `merge_tag_request` card asks for the one-tap reviewer-effort tag that the merge card
|
|
9
|
+
* would have collected. It is a NUDGE: dismissible, gates nothing, and the record stays
|
|
10
|
+
* perfectly valid untagged.
|
|
11
|
+
*
|
|
12
|
+
* `recordExternalMerge` returns a record ONLY on the delivery that actually flipped it, so a
|
|
13
|
+
* webhook redelivery — or the echo of cat-factory's own merge — raises no duplicate card.
|
|
14
|
+
*
|
|
15
|
+
* Lives in orchestration (not integrations) because it spans the track record and the
|
|
16
|
+
* notification inbox; the webhook service itself sees only a narrow
|
|
17
|
+
* `(workspaceId, repoId, prNumber)` callback and knows nothing about either.
|
|
18
|
+
*/
|
|
19
|
+
export function makeExternalMergeObserver(deps) {
|
|
20
|
+
return async (workspaceId, repoId, prNumber) => {
|
|
21
|
+
const record = await deps.trackRecord.recordExternalMerge(workspaceId, repoId, prNumber);
|
|
22
|
+
if (!record)
|
|
23
|
+
return;
|
|
24
|
+
await deps.notifications?.raise(workspaceId, {
|
|
25
|
+
type: 'merge_tag_request',
|
|
26
|
+
blockId: record.blockId,
|
|
27
|
+
executionId: record.executionId,
|
|
28
|
+
title: 'How much review did that PR need?',
|
|
29
|
+
body: `This PR was merged directly on the provider, so its review effort was not recorded. ` +
|
|
30
|
+
`One tap tells the merge policy how much review a ${record.changeClass} change actually ` +
|
|
31
|
+
`needed — or dismiss this card.`,
|
|
32
|
+
payload: {
|
|
33
|
+
...(record.prUrl ? { prUrl: record.prUrl } : {}),
|
|
34
|
+
...(record.changeClass !== 'unknown' ? { changeClass: record.changeClass } : {}),
|
|
35
|
+
mergeTrackRecordId: record.id,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=externalMergeObserver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"externalMergeObserver.js","sourceRoot":"","sources":["../../../src/modules/merge/externalMergeObserver.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,yBAAyB,CACvC,IAA+B;IAE/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;QAC7C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;QACxF,IAAI,CAAC,MAAM;YAAE,OAAM;QACnB,MAAM,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,WAAW,EAAE;YAC3C,IAAI,EAAE,mBAAmB;YACzB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,KAAK,EAAE,mCAAmC;YAC1C,IAAI,EACF,sFAAsF;gBACtF,oDAAoD,MAAM,CAAC,WAAW,mBAAmB;gBACzF,gCAAgC;YAClC,OAAO,EAAE;gBACP,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChD,GAAG,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChF,kBAAkB,EAAE,MAAM,CAAC,EAAE;aAC9B;SACF,CAAC,CAAA;IACJ,CAAC,CAAA;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TrackerSettingsService.d.ts","sourceRoot":"","sources":["../../../src/modules/recurring/TrackerSettingsService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,uBAAuB,EACvB,eAAe,EACf,yBAAyB,EACzB,mBAAmB,EACpB,MAAM,qBAAqB,CAAA;AAG5B,MAAM,WAAW,kCAAkC;IACjD,yBAAyB,EAAE,yBAAyB,CAAA;IACpD,mBAAmB,EAAE,mBAAmB,CAAA;IACxC,KAAK,EAAE,KAAK,CAAA;CACb;
|
|
1
|
+
{"version":3,"file":"TrackerSettingsService.d.ts","sourceRoot":"","sources":["../../../src/modules/recurring/TrackerSettingsService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,uBAAuB,EACvB,eAAe,EACf,yBAAyB,EACzB,mBAAmB,EACpB,MAAM,qBAAqB,CAAA;AAG5B,MAAM,WAAW,kCAAkC;IACjD,yBAAyB,EAAE,yBAAyB,CAAA;IACpD,mBAAmB,EAAE,mBAAmB,CAAA;IACxC,KAAK,EAAE,KAAK,CAAA;CACb;AAYD,gFAAgF;AAChF,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2B;IAChD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAO;IAE7B,YAAY,IAAI,EAAE,kCAAkC,EAInD;IAEK,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAGvD;IAEK,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,eAAe,CAAC,CAmBvF;CACF"}
|
|
@@ -6,6 +6,7 @@ const EMPTY = {
|
|
|
6
6
|
linearTeamId: null,
|
|
7
7
|
writebackCommentOnPrOpen: false,
|
|
8
8
|
writebackResolveOnMerge: false,
|
|
9
|
+
writebackQuestionsOnPark: false,
|
|
9
10
|
};
|
|
10
11
|
/** Read/write a workspace's issue-tracker selection (one row per workspace). */
|
|
11
12
|
export class TrackerSettingsService {
|
|
@@ -33,6 +34,9 @@ export class TrackerSettingsService {
|
|
|
33
34
|
// kept regardless of the filing tracker selection above. Default off.
|
|
34
35
|
writebackCommentOnPrOpen: input.writebackCommentOnPrOpen ?? false,
|
|
35
36
|
writebackResolveOnMerge: input.writebackResolveOnMerge ?? false,
|
|
37
|
+
// The headless clarification loop's question echo (see the contract): only consulted for
|
|
38
|
+
// runs started through the public API, so it is safe to keep alongside the PR toggles.
|
|
39
|
+
writebackQuestionsOnPark: input.writebackQuestionsOnPark ?? false,
|
|
36
40
|
updatedAt: this.clock.now(),
|
|
37
41
|
};
|
|
38
42
|
await this.repo.put(workspaceId, settings);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TrackerSettingsService.js","sourceRoot":"","sources":["../../../src/modules/recurring/TrackerSettingsService.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAQtD,+EAA+E;AAC/E,MAAM,KAAK,GAAuC;IAChD,OAAO,EAAE,IAAI;IACb,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE,IAAI;IAClB,wBAAwB,EAAE,KAAK;IAC/B,uBAAuB,EAAE,KAAK;
|
|
1
|
+
{"version":3,"file":"TrackerSettingsService.js","sourceRoot":"","sources":["../../../src/modules/recurring/TrackerSettingsService.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAQtD,+EAA+E;AAC/E,MAAM,KAAK,GAAuC;IAChD,OAAO,EAAE,IAAI;IACb,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE,IAAI;IAClB,wBAAwB,EAAE,KAAK;IAC/B,uBAAuB,EAAE,KAAK;IAC9B,wBAAwB,EAAE,KAAK;CAChC,CAAA;AAED,gFAAgF;AAChF,MAAM,OAAO,sBAAsB;IAChB,IAAI,CAA2B;IAC/B,mBAAmB,CAAqB;IACxC,KAAK,CAAO;IAE7B,YAAY,IAAwC;QAClD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,yBAAyB,CAAA;QAC1C,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,CAAA;QACnD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IACzB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,WAAmB;QAC3B,MAAM,gBAAgB,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAA;QAC7D,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,CAAA;IACzE,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,WAAmB,EAAE,KAA8B;QAC3D,MAAM,gBAAgB,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAA;QAC7D,MAAM,QAAQ,GAAoB;YAChC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,kEAAkE;YAClE,cAAc,EAAE,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI;YACtF,kEAAkE;YAClE,YAAY,EAAE,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI;YACpF,gFAAgF;YAChF,sEAAsE;YACtE,wBAAwB,EAAE,KAAK,CAAC,wBAAwB,IAAI,KAAK;YACjE,uBAAuB,EAAE,KAAK,CAAC,uBAAuB,IAAI,KAAK;YAC/D,yFAAyF;YACzF,uFAAuF;YACvF,wBAAwB,EAAE,KAAK,CAAC,wBAAwB,IAAI,KAAK;YACjE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;SAC5B,CAAA;QACD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;QAC1C,OAAO,QAAQ,CAAA;IACjB,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/orchestration",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.142.0",
|
|
4
4
|
"description": "Delivery-workflow engine for the Agent Architecture Board (execution, bootstrap, pipelines, board, boardScan, requirements, and composition root).",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -25,20 +25,20 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"ai": "^7.0.35",
|
|
28
|
-
"@cat-factory/agents": "0.69.
|
|
29
|
-
"@cat-factory/caching": "0.10.
|
|
30
|
-
"@cat-factory/contracts": "0.
|
|
31
|
-
"@cat-factory/integrations": "0.
|
|
32
|
-
"@cat-factory/kernel": "0.
|
|
33
|
-
"@cat-factory/prompt-fragments": "0.14.
|
|
34
|
-
"@cat-factory/sandbox": "0.9.
|
|
35
|
-
"@cat-factory/spend": "0.12.
|
|
36
|
-
"@cat-factory/workspaces": "0.18.
|
|
28
|
+
"@cat-factory/agents": "0.69.10",
|
|
29
|
+
"@cat-factory/caching": "0.10.43",
|
|
30
|
+
"@cat-factory/contracts": "0.167.0",
|
|
31
|
+
"@cat-factory/integrations": "0.100.0",
|
|
32
|
+
"@cat-factory/kernel": "0.161.0",
|
|
33
|
+
"@cat-factory/prompt-fragments": "0.14.15",
|
|
34
|
+
"@cat-factory/sandbox": "0.9.148",
|
|
35
|
+
"@cat-factory/spend": "0.12.87",
|
|
36
|
+
"@cat-factory/workspaces": "0.18.3"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"typescript": "7.0.2",
|
|
40
40
|
"vitest": "^4.1.10",
|
|
41
|
-
"@cat-factory/sandbox-fixtures": "0.7.
|
|
41
|
+
"@cat-factory/sandbox-fixtures": "0.7.198"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"build": "tsc -b tsconfig.build.json",
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/** Free-text prose (a tester summary, a merge rationale) is capped at this many characters. */
|
|
2
|
-
export declare const MAX_PROSE_CHARS = 4000;
|
|
3
|
-
/** A single markdown table cell is capped at this many characters. */
|
|
4
|
-
export declare const MAX_CELL_CHARS = 300;
|
|
5
|
-
/** Any rendered list/table in the report is capped at this many rows. */
|
|
6
|
-
export declare const MAX_LIST_ITEMS = 50;
|
|
7
|
-
/**
|
|
8
|
-
* Hard ceiling for the whole rendered section. GitHub rejects a PR body over 65,536
|
|
9
|
-
* characters with a 422, and the body also has to hold the agent's own description, so the
|
|
10
|
-
* managed region keeps well clear of the limit. With the per-field caps above this is
|
|
11
|
-
* unreachable for realistic runs; it exists so that pathological data degrades visibly
|
|
12
|
-
* instead of making every publish fail silently forever.
|
|
13
|
-
*/
|
|
14
|
-
export declare const MAX_SECTION_CHARS = 50000;
|
|
15
|
-
/**
|
|
16
|
-
* Close any code fence the text leaves open.
|
|
17
|
-
*
|
|
18
|
-
* An unbalanced fence in agent prose — an interrupted transcript, a truncated tool dump — would
|
|
19
|
-
* otherwise swallow every section rendered after it, including the fenced JSON block that is
|
|
20
|
-
* the report's machine-readable contract. Balancing preserves the agent's own formatting
|
|
21
|
-
* (unlike escaping the fences) while guaranteeing the enclosing document stays well-formed.
|
|
22
|
-
*/
|
|
23
|
-
export declare function balanceFences(text: string): string;
|
|
24
|
-
/**
|
|
25
|
-
* Render untrusted multi-line prose as a safe markdown block: auto-link triggers defused,
|
|
26
|
-
* length capped, and any code fence the value leaves open closed again.
|
|
27
|
-
*/
|
|
28
|
-
export declare function prose(value: string): string;
|
|
29
|
-
/**
|
|
30
|
-
* Render untrusted text as ONE markdown table cell: newlines folded to `<br>` (a raw newline
|
|
31
|
-
* ends the row and spills the rest of the value into the document as loose prose), pipes
|
|
32
|
-
* escaped so a value cannot open a new column, auto-link triggers defused, and the whole thing
|
|
33
|
-
* capped so a stack trace cannot dominate the table.
|
|
34
|
-
*/
|
|
35
|
-
export declare function cell(value: string): string;
|
|
36
|
-
/**
|
|
37
|
-
* Render untrusted text INLINE (a title, a label — not a table cell, so pipes are harmless).
|
|
38
|
-
* Newlines are folded to spaces because the surrounding line has its own meaning.
|
|
39
|
-
*/
|
|
40
|
-
export declare function inline(value: string): string;
|
|
41
|
-
/** Cap a list at {@link MAX_LIST_ITEMS}, returning the kept rows plus how many were dropped. */
|
|
42
|
-
export declare function capList<T>(items: readonly T[]): {
|
|
43
|
-
items: T[];
|
|
44
|
-
dropped: number;
|
|
45
|
-
};
|
|
46
|
-
//# sourceMappingURL=prReportText.logic.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prReportText.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/prReportText.logic.ts"],"names":[],"mappings":"AAmBA,+FAA+F;AAC/F,eAAO,MAAM,eAAe,OAAQ,CAAA;AACpC,sEAAsE;AACtE,eAAO,MAAM,cAAc,MAAM,CAAA;AACjC,yEAAyE;AACzE,eAAO,MAAM,cAAc,KAAK,CAAA;AAChC;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,QAAS,CAAA;AA8GvC;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGlD;AAWD;;;GAGG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ3C;AAED;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK1C;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,gGAAgG;AAChG,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG;IAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAG/E"}
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
// ---------------------------------------------------------------------------
|
|
2
|
-
// The PR verification report's TEXT BOUNDARY.
|
|
3
|
-
//
|
|
4
|
-
// A pull-request description is NOT an inert string sink. The host parses it: `#123` becomes
|
|
5
|
-
// an issue link, `@name` notifies a real person, a closing keyword in front of an issue
|
|
6
|
-
// reference CLOSES that issue when the PR merges, a newline ends a markdown table row, and an
|
|
7
|
-
// unbalanced code fence swallows everything after it — including the machine-readable JSON
|
|
8
|
-
// block external tooling ingests.
|
|
9
|
-
//
|
|
10
|
-
// Almost everything the report interpolates is written by an agent or a human (a task title,
|
|
11
|
-
// a tester summary, a merge rationale, a provisioner's stderr), so all of those are live
|
|
12
|
-
// hazards rather than theoretical ones: "This closes #42" is idiomatic prose for a merge
|
|
13
|
-
// rationale to emit, and it must not close issue 42.
|
|
14
|
-
//
|
|
15
|
-
// This module is the single place that turns untrusted text into something safe to splice
|
|
16
|
-
// into a PR body. It is deliberately separate from the composer (which decides WHAT to say)
|
|
17
|
-
// and from the marker splice in kernel (which decides WHERE it goes).
|
|
18
|
-
// ---------------------------------------------------------------------------
|
|
19
|
-
/** Free-text prose (a tester summary, a merge rationale) is capped at this many characters. */
|
|
20
|
-
export const MAX_PROSE_CHARS = 4_000;
|
|
21
|
-
/** A single markdown table cell is capped at this many characters. */
|
|
22
|
-
export const MAX_CELL_CHARS = 300;
|
|
23
|
-
/** Any rendered list/table in the report is capped at this many rows. */
|
|
24
|
-
export const MAX_LIST_ITEMS = 50;
|
|
25
|
-
/**
|
|
26
|
-
* Hard ceiling for the whole rendered section. GitHub rejects a PR body over 65,536
|
|
27
|
-
* characters with a 422, and the body also has to hold the agent's own description, so the
|
|
28
|
-
* managed region keeps well clear of the limit. With the per-field caps above this is
|
|
29
|
-
* unreachable for realistic runs; it exists so that pathological data degrades visibly
|
|
30
|
-
* instead of making every publish fail silently forever.
|
|
31
|
-
*/
|
|
32
|
-
export const MAX_SECTION_CHARS = 50_000;
|
|
33
|
-
/** Marks where a value was cut, so a reader never mistakes a truncation for the whole story. */
|
|
34
|
-
const TRUNCATION_NOTE = '… (truncated)';
|
|
35
|
-
/**
|
|
36
|
-
* The host's closing keywords. A PR body carrying one of these in front of an issue reference
|
|
37
|
-
* closes that issue on merge — a side effect the engine must never trigger on the agent's
|
|
38
|
-
* behalf. Same list on GitHub and GitLab.
|
|
39
|
-
*/
|
|
40
|
-
const CLOSING_KEYWORDS = 'close[sd]?|closing|fix|fixe[sd]|fixing|resolve[sd]?|resolving|implement(?:s|ed)?|implementing';
|
|
41
|
-
/** An issue/MR URL on either host, in the form a closing keyword can reference. */
|
|
42
|
-
const ISSUE_URL = String.raw `https?://\S+?/(?:issues|-/issues|merge_requests|pull)/\d+`;
|
|
43
|
-
/**
|
|
44
|
-
* Every auto-linking trigger, in ONE alternation.
|
|
45
|
-
*
|
|
46
|
-
* Deliberately a single pass rather than chained `.replace()` calls: each escape EMITS a `#`,
|
|
47
|
-
* so a later rule would re-escape the output of an earlier one (`@` → `@` → `&#64;`).
|
|
48
|
-
* One regex means the replacement text is never rescanned.
|
|
49
|
-
*/
|
|
50
|
-
const AUTO_LINK_TRIGGERS = new RegExp([
|
|
51
|
-
// A closing keyword in front of an issue/MR URL. The URL form survives the character
|
|
52
|
-
// escapes below (nothing in it is a trigger), so the KEYWORD is what gets defused.
|
|
53
|
-
String.raw `(?<keyword>\b(?:${CLOSING_KEYWORDS}))(?=\s*:?\s+${ISSUE_URL})`,
|
|
54
|
-
// `@name` / `@org/team` — a mention notifies a real account.
|
|
55
|
-
String.raw `(?<at>@(?=[A-Za-z0-9]))`,
|
|
56
|
-
// `#123` and `owner/repo#123` — an issue/PR cross-reference.
|
|
57
|
-
String.raw `(?<hash>#(?=\d))`,
|
|
58
|
-
// `!123` — GitLab's merge-request reference.
|
|
59
|
-
String.raw `(?<bang>!(?=\d))`,
|
|
60
|
-
].join('|'), 'gi');
|
|
61
|
-
/**
|
|
62
|
-
* Neutralise the host's auto-linking triggers in ONE line of untrusted text, leaving inline
|
|
63
|
-
* code spans alone (the host does not auto-link inside them, so escaping there would only
|
|
64
|
-
* show the reader a literal `#`).
|
|
65
|
-
*
|
|
66
|
-
* The escapes are numeric HTML entities, which render as the original character but are
|
|
67
|
-
* invisible to the reference parser — so the reader sees exactly what the agent wrote while
|
|
68
|
-
* the mention/close side effects are defused.
|
|
69
|
-
*/
|
|
70
|
-
function inertLine(line) {
|
|
71
|
-
return mapOutsideCodeSpans(line, (text) => text.replace(AUTO_LINK_TRIGGERS, (match, ...args) => {
|
|
72
|
-
const groups = args[args.length - 1];
|
|
73
|
-
// Entity-escaping the FIRST character is enough to break the parser's match while
|
|
74
|
-
// rendering identically — which matters most for the keyword, whose remaining letters
|
|
75
|
-
// are ordinary prose the reader should still see.
|
|
76
|
-
return `&#${match.charCodeAt(0)};${groups.keyword ? match.slice(1) : ''}`;
|
|
77
|
-
}));
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Apply `fn` to the parts of `line` that are NOT inline code spans. Code spans are matched by
|
|
81
|
-
* a backtick run and its matching closer, which is CommonMark's rule and — more to the point
|
|
82
|
-
* — the rule the host renderer applies when deciding where to auto-link.
|
|
83
|
-
*/
|
|
84
|
-
function mapOutsideCodeSpans(line, fn) {
|
|
85
|
-
const out = [];
|
|
86
|
-
let index = 0;
|
|
87
|
-
const span = /(`+)[\s\S]*?\1/g;
|
|
88
|
-
let match;
|
|
89
|
-
while ((match = span.exec(line)) !== null) {
|
|
90
|
-
out.push(fn(line.slice(index, match.index)), match[0]);
|
|
91
|
-
index = match.index + match[0].length;
|
|
92
|
-
}
|
|
93
|
-
return out.join('') + fn(line.slice(index));
|
|
94
|
-
}
|
|
95
|
-
/** A line that opens or closes a fenced code block, with the fence it uses. */
|
|
96
|
-
function fenceAt(line) {
|
|
97
|
-
const match = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line);
|
|
98
|
-
if (!match)
|
|
99
|
-
return null;
|
|
100
|
-
const fence = match[1];
|
|
101
|
-
// A ``` fence's info string may not contain a backtick (CommonMark), which is what stops an
|
|
102
|
-
// inline span from being read as a fence.
|
|
103
|
-
if (fence.startsWith('`') && match[2].includes('`'))
|
|
104
|
-
return null;
|
|
105
|
-
return { char: fence[0], length: fence.length, info: match[2].trim().length > 0 };
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Walk `lines`, tracking fenced-code state, and hand each line to `visit` together with
|
|
109
|
-
* whether it sits INSIDE a fenced block. Returns the fence still open at the end, if any.
|
|
110
|
-
*
|
|
111
|
-
* One shared walker so the two things that care about fences — leaving code untouched, and
|
|
112
|
-
* closing what the text left open — can never disagree about where a block starts and ends.
|
|
113
|
-
*/
|
|
114
|
-
function walkFences(lines, visit) {
|
|
115
|
-
let open = null;
|
|
116
|
-
for (const line of lines) {
|
|
117
|
-
const fence = fenceAt(line);
|
|
118
|
-
// The fence line itself belongs to the code block, so it is never rewritten.
|
|
119
|
-
visit(line, open !== null || fence !== null);
|
|
120
|
-
if (!fence)
|
|
121
|
-
continue;
|
|
122
|
-
if (!open)
|
|
123
|
-
open = { char: fence.char, length: fence.length };
|
|
124
|
-
else if (fence.char === open.char && fence.length >= open.length && !fence.info)
|
|
125
|
-
open = null;
|
|
126
|
-
}
|
|
127
|
-
return open;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Close any code fence the text leaves open.
|
|
131
|
-
*
|
|
132
|
-
* An unbalanced fence in agent prose — an interrupted transcript, a truncated tool dump — would
|
|
133
|
-
* otherwise swallow every section rendered after it, including the fenced JSON block that is
|
|
134
|
-
* the report's machine-readable contract. Balancing preserves the agent's own formatting
|
|
135
|
-
* (unlike escaping the fences) while guaranteeing the enclosing document stays well-formed.
|
|
136
|
-
*/
|
|
137
|
-
export function balanceFences(text) {
|
|
138
|
-
const open = walkFences(text.split('\n'), () => { });
|
|
139
|
-
return open ? `${text}\n${open.char.repeat(open.length)}` : text;
|
|
140
|
-
}
|
|
141
|
-
/** Cut `value` to `max` characters, marking the cut. Prefers a line boundary when one is near. */
|
|
142
|
-
function truncate(value, max) {
|
|
143
|
-
if (value.length <= max)
|
|
144
|
-
return value;
|
|
145
|
-
const head = value.slice(0, max);
|
|
146
|
-
const lastNewline = head.lastIndexOf('\n');
|
|
147
|
-
const body = lastNewline > max * 0.6 ? head.slice(0, lastNewline) : head;
|
|
148
|
-
return `${body.trimEnd()}\n\n${TRUNCATION_NOTE}`;
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Render untrusted multi-line prose as a safe markdown block: auto-link triggers defused,
|
|
152
|
-
* length capped, and any code fence the value leaves open closed again.
|
|
153
|
-
*/
|
|
154
|
-
export function prose(value) {
|
|
155
|
-
const capped = truncate(value.replace(/\r\n?/g, '\n'), MAX_PROSE_CHARS);
|
|
156
|
-
const rewritten = [];
|
|
157
|
-
const open = walkFences(capped.split('\n'), (line, insideFence) => {
|
|
158
|
-
rewritten.push(insideFence ? line : inertLine(line));
|
|
159
|
-
});
|
|
160
|
-
const text = rewritten.join('\n');
|
|
161
|
-
return open ? `${text}\n${open.char.repeat(open.length)}` : text;
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Render untrusted text as ONE markdown table cell: newlines folded to `<br>` (a raw newline
|
|
165
|
-
* ends the row and spills the rest of the value into the document as loose prose), pipes
|
|
166
|
-
* escaped so a value cannot open a new column, auto-link triggers defused, and the whole thing
|
|
167
|
-
* capped so a stack trace cannot dominate the table.
|
|
168
|
-
*/
|
|
169
|
-
export function cell(value) {
|
|
170
|
-
const flattened = truncate(value.replace(/\r\n?/g, '\n'), MAX_CELL_CHARS)
|
|
171
|
-
.replaceAll('|', '\\|')
|
|
172
|
-
.replace(/\n+/g, '<br>');
|
|
173
|
-
return inertLine(flattened);
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Render untrusted text INLINE (a title, a label — not a table cell, so pipes are harmless).
|
|
177
|
-
* Newlines are folded to spaces because the surrounding line has its own meaning.
|
|
178
|
-
*/
|
|
179
|
-
export function inline(value) {
|
|
180
|
-
return inertLine(truncate(value.replace(/\s+/g, ' '), MAX_CELL_CHARS));
|
|
181
|
-
}
|
|
182
|
-
/** Cap a list at {@link MAX_LIST_ITEMS}, returning the kept rows plus how many were dropped. */
|
|
183
|
-
export function capList(items) {
|
|
184
|
-
if (items.length <= MAX_LIST_ITEMS)
|
|
185
|
-
return { items: [...items], dropped: 0 };
|
|
186
|
-
return { items: items.slice(0, MAX_LIST_ITEMS), dropped: items.length - MAX_LIST_ITEMS };
|
|
187
|
-
}
|
|
188
|
-
//# sourceMappingURL=prReportText.logic.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prReportText.logic.js","sourceRoot":"","sources":["../../../src/modules/execution/prReportText.logic.ts"],"names":[],"mappings":"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"}
|