@agent-relay/factory 0.1.79 → 0.1.81

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.
Files changed (62) hide show
  1. package/README.md +39 -5
  2. package/dist/cli/fleet.d.ts +8 -2
  3. package/dist/cli/fleet.d.ts.map +1 -1
  4. package/dist/cli/fleet.js +40 -4
  5. package/dist/cli/fleet.js.map +1 -1
  6. package/dist/config/schema.d.ts +9 -0
  7. package/dist/config/schema.d.ts.map +1 -1
  8. package/dist/config/schema.js +14 -3
  9. package/dist/config/schema.js.map +1 -1
  10. package/dist/fleet/relay-fleet-client.d.ts +5 -0
  11. package/dist/fleet/relay-fleet-client.d.ts.map +1 -1
  12. package/dist/fleet/relay-fleet-client.js +57 -12
  13. package/dist/fleet/relay-fleet-client.js.map +1 -1
  14. package/dist/github/gh-identity.d.ts +44 -0
  15. package/dist/github/gh-identity.d.ts.map +1 -0
  16. package/dist/github/gh-identity.js +31 -0
  17. package/dist/github/gh-identity.js.map +1 -0
  18. package/dist/github/index.d.ts +3 -1
  19. package/dist/github/index.d.ts.map +1 -1
  20. package/dist/github/index.js +2 -1
  21. package/dist/github/index.js.map +1 -1
  22. package/dist/github/merge-gate.d.ts +22 -1
  23. package/dist/github/merge-gate.d.ts.map +1 -1
  24. package/dist/github/merge-gate.js +103 -24
  25. package/dist/github/merge-gate.js.map +1 -1
  26. package/dist/github/probe-closer.d.ts +4 -3
  27. package/dist/github/probe-closer.d.ts.map +1 -1
  28. package/dist/github/probe-closer.js +37 -28
  29. package/dist/github/probe-closer.js.map +1 -1
  30. package/dist/github/standalone-babysitter.d.ts +7 -3
  31. package/dist/github/standalone-babysitter.d.ts.map +1 -1
  32. package/dist/github/standalone-babysitter.js +16 -46
  33. package/dist/github/standalone-babysitter.js.map +1 -1
  34. package/dist/index.d.ts +1 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +1 -1
  37. package/dist/index.js.map +1 -1
  38. package/dist/intake/notion.d.ts +36 -6
  39. package/dist/intake/notion.d.ts.map +1 -1
  40. package/dist/intake/notion.js +74 -16
  41. package/dist/intake/notion.js.map +1 -1
  42. package/dist/orchestrator/factory.d.ts +32 -5
  43. package/dist/orchestrator/factory.d.ts.map +1 -1
  44. package/dist/orchestrator/factory.js +424 -243
  45. package/dist/orchestrator/factory.js.map +1 -1
  46. package/dist/ports/fleet.d.ts +6 -0
  47. package/dist/ports/fleet.d.ts.map +1 -1
  48. package/dist/ports/mount.d.ts +1 -0
  49. package/dist/ports/mount.d.ts.map +1 -1
  50. package/dist/ports/state.d.ts +17 -0
  51. package/dist/ports/state.d.ts.map +1 -1
  52. package/dist/state/file-state-store.d.ts +1 -0
  53. package/dist/state/file-state-store.d.ts.map +1 -1
  54. package/dist/state/file-state-store.js +22 -1
  55. package/dist/state/file-state-store.js.map +1 -1
  56. package/dist/state/in-memory-state-store.d.ts +1 -0
  57. package/dist/state/in-memory-state-store.d.ts.map +1 -1
  58. package/dist/state/in-memory-state-store.js +15 -1
  59. package/dist/state/in-memory-state-store.js.map +1 -1
  60. package/dist/types.d.ts +8 -0
  61. package/dist/types.d.ts.map +1 -1
  62. package/package.json +1 -1
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Whether the configured identity permits mutating GitHub through local `gh`.
3
+ *
4
+ * This helper governs mutations only. Read provenance is not an authorship
5
+ * concern, although a capability-specific adapter may still reject reads when
6
+ * its runtime has no `gh` binary (for example Notion intake in the cloud
7
+ * container).
8
+ */
9
+ export function localGhMutationAllowed(identity) {
10
+ return identity !== 'app';
11
+ }
12
+ /**
13
+ * The refusal text for a local-`gh` mutation blocked by `github.identity: "app"`.
14
+ *
15
+ * @param operation what Factory was about to do, in caller-facing terms.
16
+ * @param capability the server-side operation Relayfile Cloud would need to
17
+ * expose on the connected App surface for this write to be
18
+ * performed as the app instead of refused.
19
+ */
20
+ export function localGhMutationRefusal(operation, capability) {
21
+ return `GitHub identity "app" refuses ${operation} through the local gh CLI, which would attribute the write to the operator's account instead of the workspace GitHub App. ` +
22
+ `Performing it as the app requires the connected write capability "${capability}", which the Relayfile GitHub connection does not expose. ` +
23
+ 'Set github.identity to "user" or "auto" to deliberately accept local-user attribution for this operation.';
24
+ }
25
+ /** Throw the standard refusal when `identity` forbids a local-`gh` mutation. */
26
+ export function assertLocalGhMutationAllowed(identity, operation, capability) {
27
+ if (localGhMutationAllowed(identity))
28
+ return;
29
+ throw new Error(localGhMutationRefusal(operation, capability));
30
+ }
31
+ //# sourceMappingURL=gh-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gh-identity.js","sourceRoot":"","sources":["../../src/github/gh-identity.ts"],"names":[],"mappings":"AAwBA;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAA6B;IAClE,OAAO,QAAQ,KAAK,KAAK,CAAA;AAC3B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAiB,EAAE,UAAkB;IAC1E,OAAO,iCAAiC,SAAS,4HAA4H;QAC3K,qEAAqE,UAAU,4DAA4D;QAC3I,2GAA2G,CAAA;AAC/G,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,4BAA4B,CAC1C,QAA6B,EAC7B,SAAiB,EACjB,UAAkB;IAElB,IAAI,sBAAsB,CAAC,QAAQ,CAAC;QAAE,OAAM;IAC5C,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAA;AAChE,CAAC"}
@@ -1,4 +1,5 @@
1
- export { GhCliGithubMergeGate, GithubMergeGate, defaultGhRunner, evaluateGithubMergeGate, } from './merge-gate.js';
1
+ export { GhCliGithubMergeGate, GithubMergeGate, MountedGithubMergeGate, defaultGhRunner, evaluateGithubMergeGate, } from './merge-gate.js';
2
+ export { assertLocalGhMutationAllowed, localGhMutationAllowed, localGhMutationRefusal, } from './gh-identity.js';
2
3
  export { closeProbePr, } from './probe-closer.js';
3
4
  export { explicitLinkedIssueKey, parseStandaloneBabysitTarget, readStandalonePullRequest, standaloneBabysitterAgentName, } from './standalone-babysitter.js';
4
5
  export { ROUTED_PR_BABYSITTER_ACTIVATION_ENABLED, discoverRoutedPullRequests, routedPrIdentity, routedPrRepos, } from './routed-pr-babysitter.js';
@@ -6,4 +7,5 @@ export type { GhRunner, GhRunResult, GithubMergeInput, GithubMergeGateInput, Git
6
7
  export type { CloseProbePrInput, CloseProbePrResult, } from './probe-closer.js';
7
8
  export type { StandaloneBabysitTarget, StandalonePullRequest, } from './standalone-babysitter.js';
8
9
  export type { RoutedPrCandidate, RoutedPrDiscoveryReport } from './routed-pr-babysitter.js';
10
+ export type { GithubWriteIdentity } from './gh-identity.js';
9
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/github/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,uBAAuB,GACxB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,YAAY,GACb,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,uCAAuC,EACvC,0BAA0B,EAC1B,gBAAgB,EAChB,aAAa,GACd,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EACV,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,IAAI,mBAAmB,GACvC,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,yBAAyB,CAAA;AAChC,YAAY,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/github/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,uBAAuB,GACxB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,YAAY,GACb,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,uCAAuC,EACvC,0BAA0B,EAC1B,gBAAgB,EAChB,aAAa,GACd,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EACV,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,IAAI,mBAAmB,GACvC,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,yBAAyB,CAAA;AAChC,YAAY,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AACxF,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA"}
@@ -1,4 +1,5 @@
1
- export { GhCliGithubMergeGate, GithubMergeGate, defaultGhRunner, evaluateGithubMergeGate, } from './merge-gate.js';
1
+ export { GhCliGithubMergeGate, GithubMergeGate, MountedGithubMergeGate, defaultGhRunner, evaluateGithubMergeGate, } from './merge-gate.js';
2
+ export { assertLocalGhMutationAllowed, localGhMutationAllowed, localGhMutationRefusal, } from './gh-identity.js';
2
3
  export { closeProbePr, } from './probe-closer.js';
3
4
  export { explicitLinkedIssueKey, parseStandaloneBabysitTarget, readStandalonePullRequest, standaloneBabysitterAgentName, } from './standalone-babysitter.js';
4
5
  export { ROUTED_PR_BABYSITTER_ACTIVATION_ENABLED, discoverRoutedPullRequests, routedPrIdentity, routedPrRepos, } from './routed-pr-babysitter.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/github/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,uBAAuB,GACxB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,YAAY,GACb,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,uCAAuC,EACvC,0BAA0B,EAC1B,gBAAgB,EAChB,aAAa,GACd,MAAM,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/github/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,uBAAuB,GACxB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,YAAY,GACb,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,uCAAuC,EACvC,0BAA0B,EAC1B,gBAAgB,EAChB,aAAa,GACd,MAAM,wBAAwB,CAAA"}
@@ -1,3 +1,5 @@
1
+ import type { MountClient } from '../ports/index.js';
2
+ import { type GithubWriteIdentity } from './gh-identity.js';
1
3
  export interface GhRunResult {
2
4
  stdout: string;
3
5
  stderr?: string;
@@ -7,6 +9,8 @@ export interface GithubMergeGateInput {
7
9
  repo: string;
8
10
  number: number;
9
11
  expectedHeadSha?: string;
12
+ /** Exact mounted PR metadata path returned by discovery. */
13
+ path?: string;
10
14
  }
11
15
  export interface GithubMergeInput {
12
16
  repo: string;
@@ -37,11 +41,28 @@ export interface GithubMergeGate {
37
41
  }
38
42
  export declare class GhCliGithubMergeGate implements GithubMergeGate {
39
43
  #private;
40
- constructor(run?: GhRunner);
44
+ /**
45
+ * @param identity the configured `github.identity`. `check` is a read and
46
+ * ignores it; `merge` mutates GitHub and refuses under exact `app` rather
47
+ * than squash-merging as the operator's own account. Defaults to `auto`
48
+ * so a directly-constructed gate keeps its historical behavior.
49
+ */
50
+ constructor(run?: GhRunner, identity?: GithubWriteIdentity);
41
51
  check(input: GithubMergeGateInput): Promise<GithubMergeGateVerdict>;
42
52
  merge(input: GithubMergeInput): Promise<GithubMergeResult>;
43
53
  }
44
54
  export declare const GithubMergeGate: typeof GhCliGithubMergeGate;
55
+ /**
56
+ * Reads provider-authoritative merge readiness from the GitHub App projection
57
+ * and delegates the guarded mutation separately. Discovery passes the exact PR
58
+ * path, so this adds one read and never scans the pulls tree.
59
+ */
60
+ export declare class MountedGithubMergeGate implements GithubMergeGate {
61
+ #private;
62
+ constructor(mount: Pick<MountClient, 'readFile'>, mutation?: Pick<GithubMergeGate, 'merge'>);
63
+ check(input: GithubMergeGateInput): Promise<GithubMergeGateVerdict>;
64
+ merge(input: GithubMergeInput): Promise<GithubMergeResult>;
65
+ }
45
66
  export declare function evaluateGithubMergeGate(input: GithubMergeGateInput, live: unknown): GithubMergeGateVerdict;
46
67
  export declare const defaultGhRunner: GhRunner;
47
68
  //# sourceMappingURL=merge-gate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"merge-gate.d.ts","sourceRoot":"","sources":["../../src/github/merge-gate.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,WAAW,CAAC,CAAA;AAE/D,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,GAAG,QAAQ,CAAA;IAC3B,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE;QACJ,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;QACzB,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,WAAW,EAAE,MAAM,EAAE,CAAA;KACtB,CAAA;CACF;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;IACnE,KAAK,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;CAC3D;AAED,qBAAa,oBAAqB,YAAW,eAAe;;gBAG9C,GAAG,GAAE,QAA0B;IAIrC,KAAK,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAuBnE,KAAK,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA0BjE;AAED,eAAO,MAAM,eAAe,6BAAuB,CAAA;AAEnD,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,EAC3B,IAAI,EAAE,OAAO,GACZ,sBAAsB,CA4DxB;AAED,eAAO,MAAM,eAAe,EAAE,QAK7B,CAAA"}
1
+ {"version":3,"file":"merge-gate.d.ts","sourceRoot":"","sources":["../../src/github/merge-gate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C,OAAO,EAAkD,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAIxG,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,WAAW,CAAC,CAAA;AAE/D,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,GAAG,QAAQ,CAAA;IAC3B,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE;QACJ,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;QACzB,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,WAAW,EAAE,MAAM,EAAE,CAAA;KACtB,CAAA;CACF;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;IACnE,KAAK,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;CAC3D;AAED,qBAAa,oBAAqB,YAAW,eAAe;;IAI1D;;;;;OAKG;gBACS,GAAG,GAAE,QAA0B,EAAE,QAAQ,GAAE,mBAA4B;IAK7E,KAAK,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAOnE,KAAK,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAwCjE;AAED,eAAO,MAAM,eAAe,6BAAuB,CAAA;AAEnD;;;;GAIG;AACH,qBAAa,sBAAuB,YAAW,eAAe;;gBAK1D,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,EACpC,QAAQ,GAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAA8B;IAMjE,KAAK,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAgBnE,KAAK,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAGjE;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,EAC3B,IAAI,EAAE,OAAO,GACZ,sBAAsB,CA4DxB;AAED,eAAO,MAAM,eAAe,EAAE,QAS7B,CAAA"}
@@ -1,34 +1,36 @@
1
1
  import { execFile } from 'node:child_process';
2
2
  import { promisify } from 'node:util';
3
+ import { wrappedPayload } from '../writeback/shared.js';
4
+ import { localGhMutationAllowed, localGhMutationRefusal } from './gh-identity.js';
3
5
  const execFileAsync = promisify(execFile);
4
6
  export class GhCliGithubMergeGate {
5
7
  #run;
6
- constructor(run = defaultGhRunner) {
8
+ #identity;
9
+ /**
10
+ * @param identity the configured `github.identity`. `check` is a read and
11
+ * ignores it; `merge` mutates GitHub and refuses under exact `app` rather
12
+ * than squash-merging as the operator's own account. Defaults to `auto`
13
+ * so a directly-constructed gate keeps its historical behavior.
14
+ */
15
+ constructor(run = defaultGhRunner, identity = 'auto') {
7
16
  this.#run = run;
17
+ this.#identity = identity;
8
18
  }
9
19
  async check(input) {
10
- try {
11
- const result = await this.#run([
12
- 'pr',
13
- 'view',
14
- String(input.number),
15
- '--repo',
16
- input.repo,
17
- '--json',
18
- 'mergeable,mergeStateStatus,statusCheckRollup,headRefOid,reviewDecision',
19
- ]);
20
- if (result.stdout.trim().length === 0) {
21
- return refuse('gh returned empty output', { checkStates: [] });
22
- }
23
- return evaluateGithubMergeGate(input, parseGhJson(result.stdout));
24
- }
25
- catch (error) {
26
- return refuse(`gh merge gate failed: ${error instanceof Error ? error.message : String(error)}`, {
27
- checkStates: [],
28
- });
29
- }
20
+ throw new Error(`GitHub merge-gate readiness for ${input.repo}#${input.number} requires mounted PR metadata; ` +
21
+ 'the local-gh adapter supports mutations only and Factory will not disguise a missing read capability as REFUSE');
30
22
  }
31
23
  async merge(input) {
24
+ // Fail closed before spawning `gh`. A guarded merge run through the local
25
+ // CLI is recorded by GitHub as the operator merging, which is precisely
26
+ // the split audit trail `github.identity: "app"` exists to remove. There
27
+ // is no app-authored merge to fall through to, so refuse and say why.
28
+ if (!localGhMutationAllowed(this.#identity)) {
29
+ return {
30
+ merged: false,
31
+ reason: localGhMutationRefusal(`the guarded squash merge of ${input.repo}#${input.number}`, 'mergePullRequest'),
32
+ };
33
+ }
32
34
  try {
33
35
  const result = await this.#run([
34
36
  'pr',
@@ -57,6 +59,34 @@ export class GhCliGithubMergeGate {
57
59
  }
58
60
  }
59
61
  export const GithubMergeGate = GhCliGithubMergeGate;
62
+ /**
63
+ * Reads provider-authoritative merge readiness from the GitHub App projection
64
+ * and delegates the guarded mutation separately. Discovery passes the exact PR
65
+ * path, so this adds one read and never scans the pulls tree.
66
+ */
67
+ export class MountedGithubMergeGate {
68
+ #mount;
69
+ #mutation;
70
+ constructor(mount, mutation = new GhCliGithubMergeGate()) {
71
+ this.#mount = mount;
72
+ this.#mutation = mutation;
73
+ }
74
+ async check(input) {
75
+ const path = input.path ?? mountedPullByIdPath(input.repo, input.number);
76
+ let content;
77
+ try {
78
+ content = (await this.#mount.readFile(path)).content;
79
+ }
80
+ catch (error) {
81
+ throw mountedMergeGateCapabilityError(input, `could not read ${path}: ${error instanceof Error ? error.message : String(error)}`);
82
+ }
83
+ const live = mountedMergeGateFields(content, input);
84
+ return evaluateGithubMergeGate(input, live);
85
+ }
86
+ async merge(input) {
87
+ return this.#mutation.merge(input);
88
+ }
89
+ }
60
90
  export function evaluateGithubMergeGate(input, live) {
61
91
  const record = asRecord(live);
62
92
  const mergeable = stringValue(record.mergeable);
@@ -110,12 +140,61 @@ export function evaluateGithubMergeGate(input, live) {
110
140
  };
111
141
  }
112
142
  export const defaultGhRunner = async (args) => {
113
- // TODO(issue-52): retire this compatibility runner when merge-gate reads and
114
- // guarded merges are fully represented by the mounted GitHub connection.
143
+ // Mutation-only compatibility runner. Merge-gate reads now come from the
144
+ // mounted App projection. Retire this when `GithubConnectionWrite` exposes
145
+ // a server-side `mergePullRequest` capability so Factory still holds no
146
+ // GitHub credential. Until then `merge` refuses under
147
+ // `github.identity: "app"` rather than merging as the operator (see
148
+ // ./gh-identity). Tracked on AgentWorkforce/factory#221.
115
149
  const { stdout, stderr } = await execFileAsync('gh', args, { maxBuffer: 1024 * 1024 });
116
150
  return { stdout, stderr };
117
151
  };
118
- const parseGhJson = (stdout) => JSON.parse(stdout);
152
+ const mountedPullByIdPath = (repo, number) => {
153
+ const [owner, name, ...extra] = repo.split('/');
154
+ if (!owner || !name || extra.length > 0 || !Number.isSafeInteger(number) || number <= 0) {
155
+ throw new Error(`Invalid GitHub pull request identity ${repo}#${number}`);
156
+ }
157
+ return `/github/repos/${encodeURIComponent(owner)}__${encodeURIComponent(name)}/pulls/by-id/${number}.json`;
158
+ };
159
+ const mountedMergeGateFields = (content, input) => {
160
+ let payload;
161
+ try {
162
+ payload = wrappedPayload(content);
163
+ }
164
+ catch (error) {
165
+ throw mountedMergeGateCapabilityError(input, `could not parse mounted PR metadata: ${error instanceof Error ? error.message : String(error)}`);
166
+ }
167
+ const explicitNumber = numberValue(payload.number);
168
+ if (explicitNumber !== undefined && explicitNumber !== input.number) {
169
+ throw mountedMergeGateCapabilityError(input, `mounted PR record number is ${explicitNumber}, expected ${input.number}`);
170
+ }
171
+ const head = asRecord(payload.head);
172
+ const mergeable = normalizeMergeable(payload.mergeable);
173
+ const mergeStateStatus = normalizedString(payload.mergeStateStatus ?? payload.merge_state_status ?? payload.mergeable_state);
174
+ const headRefOid = stringValue(payload.headRefOid) ?? stringValue(head.sha);
175
+ const reviewDecision = normalizedString(payload.reviewDecision ?? payload.review_decision);
176
+ const statusCheckRollup = payload.statusCheckRollup ?? payload.status_check_rollup;
177
+ const missing = [
178
+ ['mergeable', mergeable],
179
+ ['mergeStateStatus', mergeStateStatus],
180
+ ['headRefOid', headRefOid],
181
+ ['reviewDecision', reviewDecision],
182
+ ['statusCheckRollup', Array.isArray(statusCheckRollup) ? statusCheckRollup : undefined],
183
+ ].flatMap(([name, value]) => value === undefined ? [name] : []);
184
+ if (missing.length > 0) {
185
+ throw mountedMergeGateCapabilityError(input, `mounted PR metadata is missing ${missing.join(', ')}`);
186
+ }
187
+ return { mergeable, mergeStateStatus, headRefOid, reviewDecision, statusCheckRollup };
188
+ };
189
+ const mountedMergeGateCapabilityError = (input, detail) => new Error(`GitHub merge-gate capability unavailable for ${input.repo}#${input.number}: ${detail}; ` +
190
+ 'Factory requires the authenticated mounted PR projection and does not fall back to local gh');
191
+ const normalizeMergeable = (value) => {
192
+ if (typeof value === 'boolean')
193
+ return value ? 'MERGEABLE' : 'CONFLICTING';
194
+ return normalizedString(value);
195
+ };
196
+ const normalizedString = (value) => typeof value === 'string' && value.trim() ? value.trim().toUpperCase() : undefined;
197
+ const numberValue = (value) => typeof value === 'number' && Number.isSafeInteger(value) && value > 0 ? value : undefined;
119
198
  const refuse = (reason, live) => ({
120
199
  verdict: 'REFUSE',
121
200
  ready: false,
@@ -1 +1 @@
1
- {"version":3,"file":"merge-gate.js","sourceRoot":"","sources":["../../src/github/merge-gate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"merge-gate.js","sourceRoot":"","sources":["../../src/github/merge-gate.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,13 @@
1
- import type { GithubConnectionWrite } from '../ports/index.js';
2
- import { type GhRunner } from './merge-gate.js';
1
+ import type { GithubConnectionWrite, MountClient } from '../ports/index.js';
3
2
  export interface CloseProbePrInput {
4
3
  repo: string;
5
4
  prNumber: number;
6
5
  expectedIssueKey: string;
7
6
  requireTitleMarker?: boolean;
8
7
  githubWrite?: GithubConnectionWrite;
9
- runner?: GhRunner;
8
+ /** Exact mounted PR metadata path returned by discovery. */
9
+ path?: string;
10
+ mount?: Pick<MountClient, 'readFile'>;
10
11
  }
11
12
  export interface CloseProbePrResult {
12
13
  repo: string;
@@ -1 +1 @@
1
- {"version":3,"file":"probe-closer.d.ts","sourceRoot":"","sources":["../../src/github/probe-closer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AACrD,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAA;AAI7D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,EAAE,MAAM,CAAA;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,WAAW,CAAC,EAAE,qBAAqB,CAAA;IACnC,MAAM,CAAC,EAAE,QAAQ,CAAA;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,QAAQ,CAAA;CAChB;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAqBxF"}
1
+ {"version":3,"file":"probe-closer.d.ts","sourceRoot":"","sources":["../../src/github/probe-closer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAKlE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,EAAE,MAAM,CAAA;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,WAAW,CAAC,EAAE,qBAAqB,CAAA;IACnC,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAA;CACtC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,QAAQ,CAAA;CAChB;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAmBxF"}
@@ -1,41 +1,45 @@
1
1
  import { containsIssueKey } from '../issue-key-match.js';
2
- import { defaultGhRunner } from './merge-gate.js';
2
+ import { wrappedPayload } from '../writeback/shared.js';
3
3
  const FACTORY_E2E_MARKER = '[factory-e2e]';
4
4
  export async function closeProbePr(input) {
5
5
  const githubWrite = input.githubWrite;
6
6
  if (!githubWrite) {
7
7
  throw new Error('GitHub write path not available on this mount — connect GitHub to your workspace');
8
8
  }
9
- const run = input.runner ?? defaultGhRunner;
10
- const before = await viewPr(run, input);
9
+ if (!input.mount) {
10
+ throw new Error(`Mounted GitHub PR read path is unavailable for ${input.repo}#${input.prNumber}; ` +
11
+ 'Factory will not fall back to the local gh CLI');
12
+ }
13
+ const before = await viewPr(input.mount, input);
11
14
  const beforeState = assertClosableProbe(before, input);
12
15
  if (beforeState === 'CLOSED') {
13
16
  return { repo: input.repo, prNumber: input.prNumber, state: 'CLOSED' };
14
17
  }
15
18
  await githubWrite.closePullRequest({ repo: input.repo, number: input.prNumber });
16
- const after = await viewPr(run, input);
17
- const afterState = stringValue(after.state);
18
- if (normalizeState(afterState) !== 'CLOSED') {
19
- throw new Error(`Refusing to report probe PR closed: live state is ${afterState ?? 'unknown'}`);
20
- }
21
19
  return { repo: input.repo, prNumber: input.prNumber, state: 'CLOSED' };
22
20
  }
23
- const viewPr = async (run, input) => {
24
- // TODO(issue-52): replace this transitional gh read with the mounted PR meta
25
- // once every supported adapter shape exposes the probe guard fields.
26
- const result = await run([
27
- 'pr',
28
- 'view',
29
- String(input.prNumber),
30
- '--repo',
31
- input.repo,
32
- '--json',
33
- 'state,headRefName,body,title',
34
- ]);
35
- if (!result.stdout.trim()) {
36
- throw new Error(`Unable to guard probe PR #${input.prNumber}: gh returned empty output`);
21
+ const viewPr = async (mount, input) => {
22
+ const path = input.path ?? pullByIdPath(input.repo, input.prNumber);
23
+ let content;
24
+ try {
25
+ content = (await mount.readFile(path)).content;
26
+ }
27
+ catch (error) {
28
+ throw new Error(`Unable to guard probe PR ${input.repo}#${input.prNumber} from mounted metadata at ${path}: ` +
29
+ `${error instanceof Error ? error.message : String(error)}`);
37
30
  }
38
- return parseGhJson(result.stdout);
31
+ const payload = wrappedPayload(content);
32
+ const explicitNumber = numberValue(payload.number);
33
+ if (explicitNumber !== undefined && explicitNumber !== input.prNumber) {
34
+ throw new Error(`Unable to guard probe PR ${input.repo}#${input.prNumber}: mounted record at ${path} identifies PR #${explicitNumber}`);
35
+ }
36
+ const head = recordValue(payload.head);
37
+ return {
38
+ state: stringValue(payload.state),
39
+ headRefName: stringValue(payload.headRefName) ?? stringValue(payload.head_ref) ?? stringValue(head.ref),
40
+ body: stringValue(payload.body),
41
+ title: stringValue(payload.title),
42
+ };
39
43
  };
40
44
  const assertClosableProbe = (live, input) => {
41
45
  const state = stringValue(live.state);
@@ -58,10 +62,15 @@ const assertClosableProbe = (live, input) => {
58
62
  const hasFactoryE2eMarker = (title) => title === FACTORY_E2E_MARKER || title.startsWith(`${FACTORY_E2E_MARKER} `);
59
63
  const normalizeState = (state) => state?.toUpperCase();
60
64
  const stringValue = (value) => typeof value === 'string' ? value : undefined;
61
- const parseGhJson = (stdout) => {
62
- const parsed = JSON.parse(stdout);
63
- return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)
64
- ? parsed
65
- : {};
65
+ const pullByIdPath = (repo, number) => {
66
+ const [owner, name, ...extra] = repo.split('/');
67
+ if (!owner || !name || extra.length > 0 || !Number.isSafeInteger(number) || number <= 0) {
68
+ throw new Error(`Invalid GitHub pull request identity ${repo}#${number}`);
69
+ }
70
+ return `/github/repos/${encodeURIComponent(owner)}__${encodeURIComponent(name)}/pulls/by-id/${number}.json`;
66
71
  };
72
+ const numberValue = (value) => typeof value === 'number' && Number.isSafeInteger(value) && value > 0 ? value : undefined;
73
+ const recordValue = (value) => value !== null && typeof value === 'object' && !Array.isArray(value)
74
+ ? value
75
+ : {};
67
76
  //# sourceMappingURL=probe-closer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"probe-closer.js","sourceRoot":"","sources":["../../src/github/probe-closer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"probe-closer.js","sourceRoot":"","sources":["../../src/github/probe-closer.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- import type { GhRunner } from './merge-gate.js';
2
1
  import type { MountClient } from '../ports/index.js';
3
2
  export interface StandaloneBabysitTarget {
4
3
  repo?: string;
@@ -21,14 +20,19 @@ export interface StandalonePullRequest {
21
20
  crossRepository?: boolean;
22
21
  maintainerCanModify?: boolean;
23
22
  filesChanged?: string[];
24
- source: 'mount' | 'gh' | 'mount+gh';
23
+ /**
24
+ * Where this PR's metadata was read from. Standalone babysitting requires a
25
+ * complete authenticated mounted projection and never shells out to local
26
+ * gh in the production control-plane container.
27
+ */
28
+ source: 'mount';
25
29
  }
26
30
  export declare function parseStandaloneBabysitTarget(value: string | undefined): StandaloneBabysitTarget;
27
31
  export declare function readStandalonePullRequest(mount: MountClient, target: {
28
32
  repo: string;
29
33
  prNumber: number;
30
34
  url?: string;
31
- }, ghRunner: GhRunner): Promise<StandalonePullRequest>;
35
+ }): Promise<StandalonePullRequest>;
32
36
  export declare function standaloneBabysitterAgentName(repo: string, prNumber: number): string;
33
37
  export declare function explicitLinkedIssueKey(body: string): string | undefined;
34
38
  //# sourceMappingURL=standalone-babysitter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"standalone-babysitter.d.ts","sourceRoot":"","sources":["../../src/github/standalone-babysitter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,MAAM,EAAE,OAAO,GAAG,IAAI,GAAG,UAAU,CAAA;CACpC;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,uBAAuB,CA6C/F;AAED,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,EACxD,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,qBAAqB,CAAC,CA2BhC;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CASpF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASvE"}
1
+ {"version":3,"file":"standalone-babysitter.d.ts","sourceRoot":"","sources":["../../src/github/standalone-babysitter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;;;OAIG;IACH,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,uBAAuB,CA6C/F;AAED,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACvD,OAAO,CAAC,qBAAqB,CAAC,CAQhC;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CASpF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASvE"}
@@ -42,34 +42,13 @@ export function parseStandaloneBabysitTarget(value) {
42
42
  url: `https://github.com/${repo}/pull/${match[3]}`,
43
43
  };
44
44
  }
45
- export async function readStandalonePullRequest(mount, target, ghRunner) {
45
+ export async function readStandalonePullRequest(mount, target) {
46
46
  const mounted = await readPullRequestFromMount(mount, target);
47
- let ghFailure;
48
- try {
49
- const result = await ghRunner([
50
- 'pr',
51
- 'view',
52
- String(target.prNumber),
53
- '--repo',
54
- target.repo,
55
- '--json',
56
- 'number,title,body,state,isDraft,url,headRefName,headRefOid,headRepository,headRepositoryOwner,baseRefName,isCrossRepository,maintainerCanModify,files',
57
- ]);
58
- const parsed = parsePullRequestPayload(JSON.parse(result.stdout), target);
59
- if (parsed) {
60
- const merged = mergePullMetadata(mounted, parsed);
61
- if (hasRequiredPullMetadata(merged)) {
62
- return { ...merged, source: mounted ? 'mount+gh' : 'gh' };
63
- }
64
- }
65
- }
66
- catch (error) {
67
- ghFailure = error instanceof Error ? error.message : String(error);
68
- }
69
47
  if (mounted && hasRequiredPullMetadata(mounted))
70
48
  return mounted;
71
- const suffix = ghFailure ? `: ${ghFailure}` : '';
72
- throw new Error(`Unable to read complete metadata for ${target.repo} PR #${target.prNumber} from the connected GitHub mount or gh${suffix}`);
49
+ const missing = missingRequiredPullMetadata(mounted);
50
+ throw new Error(`Unable to read complete metadata for ${target.repo} PR #${target.prNumber} from the connected GitHub mount: ` +
51
+ `missing ${missing.join(', ')}; Factory does not fall back to local gh`);
73
52
  }
74
53
  export function standaloneBabysitterAgentName(repo, prNumber) {
75
54
  const slug = repo
@@ -177,27 +156,18 @@ const hasRequiredPullMetadata = (pr) => Boolean(pr.title.trim()) &&
177
156
  Boolean(pr.headRepo?.trim()) &&
178
157
  Boolean(pr.baseRef?.trim()) &&
179
158
  pr.crossRepository !== undefined;
180
- function mergePullMetadata(mounted, live) {
181
- if (!mounted)
182
- return live;
183
- return {
184
- repo: live.repo,
185
- number: live.number,
186
- title: live.title || mounted.title,
187
- body: live.body || mounted.body,
188
- state: live.state ?? mounted.state,
189
- draft: live.draft ?? mounted.draft,
190
- merged: live.merged ?? mounted.merged,
191
- url: live.url || mounted.url,
192
- headRef: live.headRef ?? mounted.headRef,
193
- headSha: live.headSha ?? mounted.headSha,
194
- baseRef: live.baseRef ?? mounted.baseRef,
195
- headRepo: live.headRepo ?? mounted.headRepo,
196
- crossRepository: live.crossRepository ?? mounted.crossRepository,
197
- maintainerCanModify: live.maintainerCanModify ?? mounted.maintainerCanModify,
198
- filesChanged: live.filesChanged ?? mounted.filesChanged,
199
- };
200
- }
159
+ const missingRequiredPullMetadata = (pr) => !pr
160
+ ? ['PR record']
161
+ : [
162
+ ['title', pr.title.trim() || undefined],
163
+ ['state', pr.state?.trim()],
164
+ ['draft', pr.draft],
165
+ ['headRef', pr.headRef?.trim()],
166
+ ['headSha', pr.headSha?.trim()],
167
+ ['headRepo', pr.headRepo?.trim()],
168
+ ['baseRef', pr.baseRef?.trim()],
169
+ ['crossRepository', pr.crossRepository],
170
+ ].flatMap(([name, value]) => value === undefined ? [String(name)] : []);
201
171
  function changedFiles(value) {
202
172
  if (!Array.isArray(value))
203
173
  return undefined;