@cat-factory/executor-harness 1.70.0 → 1.74.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/job.js +8 -2
- package/dist/server.js +5 -0
- package/package.json +4 -4
- package/src/job.ts +20 -3
- package/src/server.ts +5 -0
package/dist/job.js
CHANGED
|
@@ -309,8 +309,12 @@ export function parsePackageRegistries(value, env = process.env) {
|
|
|
309
309
|
if (!allowed.has(host)) {
|
|
310
310
|
throw new Error(`Invalid job: 'packageRegistries[${i}].host' '${host}' is not an allowed npm registry host`);
|
|
311
311
|
}
|
|
312
|
-
|
|
313
|
-
|
|
312
|
+
// An EMPTY scope list is valid and deliberate: the entry then only authenticates its
|
|
313
|
+
// host, leaving every package to resolve from the default registry unless a dependency
|
|
314
|
+
// pins this one itself. Mapping a scope is all-or-nothing, so a workspace mixing private
|
|
315
|
+
// and public packages under one scope must be able to skip it.
|
|
316
|
+
if (!Array.isArray(entry.scopes)) {
|
|
317
|
+
throw new Error(`Invalid job: 'packageRegistries[${i}].scopes' must be an array`);
|
|
314
318
|
}
|
|
315
319
|
const scopes = entry.scopes.map((scope, j) => {
|
|
316
320
|
const s = str(scope, `packageRegistries[${i}].scopes[${j}]`).trim();
|
|
@@ -703,6 +707,8 @@ function assembleAgentJob(o, mode, agentField, parts) {
|
|
|
703
707
|
*/
|
|
704
708
|
function collectOptionalRequestFields(o) {
|
|
705
709
|
return {
|
|
710
|
+
...(typeof o.workspaceId === 'string' && o.workspaceId ? { workspaceId: o.workspaceId } : {}),
|
|
711
|
+
...(typeof o.executionId === 'string' && o.executionId ? { executionId: o.executionId } : {}),
|
|
706
712
|
...(typeof o.githubApiBase === 'string' ? { githubApiBase: o.githubApiBase } : {}),
|
|
707
713
|
...(typeof o.webToolsGuidance === 'string' ? { webToolsGuidance: o.webToolsGuidance } : {}),
|
|
708
714
|
...(o.webSearch === true ? { webSearch: true } : {}),
|
package/dist/server.js
CHANGED
|
@@ -65,6 +65,11 @@ describe) {
|
|
|
65
65
|
// image carries no runtime deps.
|
|
66
66
|
const KINDS = {
|
|
67
67
|
agent: defineKind(parseAgentJob, handleAgent, (job) => ({
|
|
68
|
+
// The backend's correlation ids first, so EVERY line this job emits joins to the run in the
|
|
69
|
+
// backend's own logs. Absent on a body from a backend older than the field — the rest of the
|
|
70
|
+
// description is unaffected.
|
|
71
|
+
...(job.workspaceId ? { workspaceId: job.workspaceId } : {}),
|
|
72
|
+
...(job.executionId ? { executionId: job.executionId } : {}),
|
|
68
73
|
mode: job.mode,
|
|
69
74
|
repo: `${job.repo.owner}/${job.repo.name}`,
|
|
70
75
|
branch: job.branch,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/executor-harness",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.74.0",
|
|
4
4
|
"description": "Container payload: a thin TypeScript wrapper that runs the Pi coding agent against a cloned repo and opens a PR. Runs in the Cloudflare Container (and, in local native mode, as a host process); carries no secrets.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
"hono": "^4.12.32",
|
|
27
27
|
"typescript": "7.0.2",
|
|
28
28
|
"vitest": "^4.1.10",
|
|
29
|
-
"@cat-factory/kernel": "0.
|
|
30
|
-
"@cat-factory/server": "0.
|
|
31
|
-
"@cat-factory/spend": "0.12.
|
|
29
|
+
"@cat-factory/kernel": "0.185.1",
|
|
30
|
+
"@cat-factory/server": "0.172.2",
|
|
31
|
+
"@cat-factory/spend": "0.12.115"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
34
|
"build": "tsc -p tsconfig.json",
|
package/src/job.ts
CHANGED
|
@@ -420,7 +420,7 @@ export interface PackageRegistrySpec {
|
|
|
420
420
|
ecosystem: 'npm'
|
|
421
421
|
/** Registry host, e.g. `registry.npmjs.org` — allowlisted, never a full URL. */
|
|
422
422
|
host: string
|
|
423
|
-
/** npm scopes (`@org`) routed to this registry. */
|
|
423
|
+
/** npm scopes (`@org`) routed to this registry; EMPTY ⇒ authenticate the host only. */
|
|
424
424
|
scopes: string[]
|
|
425
425
|
token: string
|
|
426
426
|
}
|
|
@@ -468,8 +468,12 @@ export function parsePackageRegistries(
|
|
|
468
468
|
`Invalid job: 'packageRegistries[${i}].host' '${host}' is not an allowed npm registry host`,
|
|
469
469
|
)
|
|
470
470
|
}
|
|
471
|
-
|
|
472
|
-
|
|
471
|
+
// An EMPTY scope list is valid and deliberate: the entry then only authenticates its
|
|
472
|
+
// host, leaving every package to resolve from the default registry unless a dependency
|
|
473
|
+
// pins this one itself. Mapping a scope is all-or-nothing, so a workspace mixing private
|
|
474
|
+
// and public packages under one scope must be able to skip it.
|
|
475
|
+
if (!Array.isArray(entry.scopes)) {
|
|
476
|
+
throw new Error(`Invalid job: 'packageRegistries[${i}].scopes' must be an array`)
|
|
473
477
|
}
|
|
474
478
|
const scopes = entry.scopes.map((scope, j) => {
|
|
475
479
|
const s = str(scope, `packageRegistries[${i}].scopes[${j}]`).trim()
|
|
@@ -703,6 +707,17 @@ export interface ValidationSpec {
|
|
|
703
707
|
|
|
704
708
|
export interface AgentJob extends HarnessAuthFields {
|
|
705
709
|
jobId: string
|
|
710
|
+
/**
|
|
711
|
+
* The backend run this job belongs to, bound onto the per-job logger beside `jobId` and used
|
|
712
|
+
* for NOTHING else. The container is the far side of the platform's longest seam: the backend
|
|
713
|
+
* knows a run as `executionId` and the harness knew it only as `jobId`, so a container log line
|
|
714
|
+
* could not be joined to the run that dispatched it except through the
|
|
715
|
+
* `${executionId}-${agentKind}` job-id naming convention. Optional because a body predating the
|
|
716
|
+
* field (or a hand-rolled acceptance fixture) must still run — an absent id costs correlation,
|
|
717
|
+
* never the job.
|
|
718
|
+
*/
|
|
719
|
+
workspaceId?: string
|
|
720
|
+
executionId?: string
|
|
706
721
|
mode: AgentMode
|
|
707
722
|
systemPrompt: string
|
|
708
723
|
userPrompt: string
|
|
@@ -1435,6 +1450,8 @@ function assembleAgentJob(
|
|
|
1435
1450
|
*/
|
|
1436
1451
|
function collectOptionalRequestFields(o: Record<string, unknown>): Partial<AgentJob> {
|
|
1437
1452
|
return {
|
|
1453
|
+
...(typeof o.workspaceId === 'string' && o.workspaceId ? { workspaceId: o.workspaceId } : {}),
|
|
1454
|
+
...(typeof o.executionId === 'string' && o.executionId ? { executionId: o.executionId } : {}),
|
|
1438
1455
|
...(typeof o.githubApiBase === 'string' ? { githubApiBase: o.githubApiBase } : {}),
|
|
1439
1456
|
...(typeof o.webToolsGuidance === 'string' ? { webToolsGuidance: o.webToolsGuidance } : {}),
|
|
1440
1457
|
...(o.webSearch === true ? { webSearch: true } : {}),
|
package/src/server.ts
CHANGED
|
@@ -82,6 +82,11 @@ function defineKind<TJob extends { jobId: string }, TResult extends JobResultBas
|
|
|
82
82
|
// image carries no runtime deps.
|
|
83
83
|
const KINDS: Record<string, KindEntry> = {
|
|
84
84
|
agent: defineKind(parseAgentJob, handleAgent, (job) => ({
|
|
85
|
+
// The backend's correlation ids first, so EVERY line this job emits joins to the run in the
|
|
86
|
+
// backend's own logs. Absent on a body from a backend older than the field — the rest of the
|
|
87
|
+
// description is unaffected.
|
|
88
|
+
...(job.workspaceId ? { workspaceId: job.workspaceId } : {}),
|
|
89
|
+
...(job.executionId ? { executionId: job.executionId } : {}),
|
|
85
90
|
mode: job.mode,
|
|
86
91
|
repo: `${job.repo.owner}/${job.repo.name}`,
|
|
87
92
|
branch: job.branch,
|