@on-par/factory-cli 0.9.11-next.4 → 0.9.11-next.40

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 (110) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/base-health-ci.d.ts +4 -0
  3. package/dist/cli/base-health-ci.d.ts.map +1 -0
  4. package/dist/cli/base-health-ci.js +9 -0
  5. package/dist/cli/base-health-ci.js.map +1 -0
  6. package/dist/cli/base-hold.d.ts +14 -11
  7. package/dist/cli/base-hold.d.ts.map +1 -1
  8. package/dist/cli/base-hold.js +43 -20
  9. package/dist/cli/base-hold.js.map +1 -1
  10. package/dist/cli/cost-json.d.ts +5 -31
  11. package/dist/cli/cost-json.d.ts.map +1 -1
  12. package/dist/cli/cost-json.js.map +1 -1
  13. package/dist/cli/daemon.d.ts +2 -15
  14. package/dist/cli/daemon.d.ts.map +1 -1
  15. package/dist/cli/daemon.js +5 -11
  16. package/dist/cli/daemon.js.map +1 -1
  17. package/dist/cli/doctor.js +1 -1
  18. package/dist/cli/doctor.js.map +1 -1
  19. package/dist/cli/index.d.ts +10 -48
  20. package/dist/cli/index.d.ts.map +1 -1
  21. package/dist/cli/index.js +27 -186
  22. package/dist/cli/index.js.map +1 -1
  23. package/dist/cli/json-contract.d.ts +299 -0
  24. package/dist/cli/json-contract.d.ts.map +1 -0
  25. package/dist/cli/json-contract.js +206 -0
  26. package/dist/cli/json-contract.js.map +1 -0
  27. package/dist/cli/land-pr.d.ts.map +1 -1
  28. package/dist/cli/land-pr.js +5 -0
  29. package/dist/cli/land-pr.js.map +1 -1
  30. package/dist/cli/lane-environment-pause-error.d.ts +19 -0
  31. package/dist/cli/lane-environment-pause-error.d.ts.map +1 -0
  32. package/dist/cli/lane-environment-pause-error.js +24 -0
  33. package/dist/cli/lane-environment-pause-error.js.map +1 -0
  34. package/dist/cli/logs.d.ts +14 -0
  35. package/dist/cli/logs.d.ts.map +1 -1
  36. package/dist/cli/logs.js +46 -4
  37. package/dist/cli/logs.js.map +1 -1
  38. package/dist/cli/program-observe.d.ts.map +1 -1
  39. package/dist/cli/program-observe.js +5 -2
  40. package/dist/cli/program-observe.js.map +1 -1
  41. package/dist/cli/queue-add-json.d.ts +3 -25
  42. package/dist/cli/queue-add-json.d.ts.map +1 -1
  43. package/dist/cli/queue-add-json.js.map +1 -1
  44. package/dist/cli/queue-list.d.ts +6 -24
  45. package/dist/cli/queue-list.d.ts.map +1 -1
  46. package/dist/cli/queue-list.js +6 -1
  47. package/dist/cli/queue-list.js.map +1 -1
  48. package/dist/cli/queue-preflight.d.ts +45 -0
  49. package/dist/cli/queue-preflight.d.ts.map +1 -0
  50. package/dist/cli/queue-preflight.js +277 -0
  51. package/dist/cli/queue-preflight.js.map +1 -0
  52. package/dist/cli/run-branch.d.ts +24 -0
  53. package/dist/cli/run-branch.d.ts.map +1 -0
  54. package/dist/cli/run-branch.js +38 -0
  55. package/dist/cli/run-branch.js.map +1 -0
  56. package/dist/cli/run-lane.d.ts.map +1 -1
  57. package/dist/cli/run-lane.js +5 -2
  58. package/dist/cli/run-lane.js.map +1 -1
  59. package/dist/cli/run.d.ts.map +1 -1
  60. package/dist/cli/run.js +10 -3
  61. package/dist/cli/run.js.map +1 -1
  62. package/dist/cli/runs-diffstat.d.ts +6 -25
  63. package/dist/cli/runs-diffstat.d.ts.map +1 -1
  64. package/dist/cli/runs-diffstat.js.map +1 -1
  65. package/dist/cli/runs.d.ts +4 -19
  66. package/dist/cli/runs.d.ts.map +1 -1
  67. package/dist/cli/runs.js +1 -1
  68. package/dist/cli/runs.js.map +1 -1
  69. package/dist/cli/self-update-stop.d.ts +7 -0
  70. package/dist/cli/self-update-stop.d.ts.map +1 -0
  71. package/dist/cli/self-update-stop.js +27 -0
  72. package/dist/cli/self-update-stop.js.map +1 -0
  73. package/dist/cli/ship-run-state.d.ts +5 -0
  74. package/dist/cli/ship-run-state.d.ts.map +1 -0
  75. package/dist/cli/ship-run-state.js +12 -0
  76. package/dist/cli/ship-run-state.js.map +1 -0
  77. package/dist/cli/ship-steps.d.ts +1 -1
  78. package/dist/cli/ship-steps.d.ts.map +1 -1
  79. package/dist/cli/ship-steps.js +5 -2
  80. package/dist/cli/ship-steps.js.map +1 -1
  81. package/dist/cli/ship.d.ts.map +1 -1
  82. package/dist/cli/ship.js +25 -21
  83. package/dist/cli/ship.js.map +1 -1
  84. package/dist/cli/status-json.d.ts +7 -28
  85. package/dist/cli/status-json.d.ts.map +1 -1
  86. package/dist/cli/status-json.js +3 -1
  87. package/dist/cli/status-json.js.map +1 -1
  88. package/dist/cli/status.d.ts.map +1 -1
  89. package/dist/cli/status.js +4 -1
  90. package/dist/cli/status.js.map +1 -1
  91. package/dist/cli/stop-resume-json.d.ts +2 -10
  92. package/dist/cli/stop-resume-json.d.ts.map +1 -1
  93. package/dist/cli/stop-resume-json.js +1 -0
  94. package/dist/cli/stop-resume-json.js.map +1 -1
  95. package/dist/cli/usage-json.d.ts +4 -13
  96. package/dist/cli/usage-json.d.ts.map +1 -1
  97. package/dist/cli/usage-json.js.map +1 -1
  98. package/package.json +8 -5
  99. package/schemas/cost.schema.json +100 -0
  100. package/schemas/daemon-status.schema.json +44 -0
  101. package/schemas/logs-line.schema.json +114 -0
  102. package/schemas/queue-add.schema.json +73 -0
  103. package/schemas/queue-list.schema.json +77 -0
  104. package/schemas/resume.schema.json +36 -0
  105. package/schemas/runs-diffstat.schema.json +81 -0
  106. package/schemas/runs.schema.json +75 -0
  107. package/schemas/status.schema.json +200 -0
  108. package/schemas/stop.schema.json +36 -0
  109. package/schemas/unpark.schema.json +57 -0
  110. package/schemas/usage.schema.json +28 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lane-environment-pause-error.js","sourceRoot":"","sources":["../../src/cli/lane-environment-pause-error.ts"],"names":[],"mappings":"AAAA,yGAAyG;AAEzG;2DAC2D;AAC3D,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IACzC,OAAO,CAAS;IAChB,aAAa,CAAW;IACxB,gBAAgB,CAAU;IACnC,iGAAiG;IACxF,cAAc,CAAW;IAClC,uEAAuE;IAC9D,UAAU,CAAW;IAE9B,YACE,OAAe,EACf,OAMC;QAED,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS;YAAE,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QAC3E,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS;YAAE,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QACvF,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;QAC3C,IAAI,OAAO,CAAC,gBAAgB,KAAK,SAAS;YAAE,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAC/F,CAAC;CACF"}
@@ -1,8 +1,13 @@
1
1
  import type { FactoryEvent } from '@on-par/factory-core';
2
+ import type { LogsLineJson } from './json-contract.js';
2
3
  export interface LogsOptions {
3
4
  follow?: boolean;
4
5
  json?: boolean;
5
6
  issue?: string;
7
+ /** Newest N matching events (oldest first); with `since`, the first N after the cursor. */
8
+ limit?: number;
9
+ /** Only events after this cursor (the `cursor` field of a previous --json line). */
10
+ since?: string;
6
11
  }
7
12
  export interface LogsDeps {
8
13
  out?: {
@@ -12,7 +17,16 @@ export interface LogsDeps {
12
17
  env?: NodeJS.ProcessEnv;
13
18
  /** Poll interval for --follow; tests pass ~10. Default 250 (satisfies the <1 s AC). */
14
19
  pollMs?: number;
20
+ /** Where cmdLogs writes JSON errors (default process.stderr). */
21
+ err?: {
22
+ write(s: string): unknown;
23
+ };
24
+ /** Test hook: bytes read from the log by --limit/--since. */
25
+ onBytesRead?: (n: number) => void;
15
26
  }
27
+ export declare function buildLogsJson(event: FactoryEvent, extra?: {
28
+ cursor?: string;
29
+ }): LogsLineJson;
16
30
  export declare function eventMatchesIssue(e: FactoryEvent, issue?: string): boolean;
17
31
  export declare function renderEvent(e: FactoryEvent, opts: {
18
32
  json?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/cli/logs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,EAAE;QAAE,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACrD,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,uFAAuF;IACvF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAE1E;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAG7F;AAED,8GAA8G;AAC9G,wBAAgB,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,GAAE,QAAa,GAAG,MAAM,IAAI,CAwB9F;AAED,wGAAwG;AACxG,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAavG"}
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/cli/logs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AASzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,EAAE;QAAE,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACrD,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,uFAAuF;IACvF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,GAAG,CAAC,EAAE;QAAE,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACpC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,YAAY,CAEhG;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAE1E;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAG7F;AAED,8GAA8G;AAC9G,wBAAgB,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,GAAE,QAAa,GAAG,MAAM,IAAI,CAkD9F;AAED,wGAAwG;AACxG,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCvG"}
package/dist/cli/logs.js CHANGED
@@ -1,12 +1,15 @@
1
- // packages/cli/src/cli/logs.ts — `factory logs` [--follow] [--json] [--issue <n>]
1
+ // packages/cli/src/cli/logs.ts — `factory logs` [--follow] [--json] [--issue <n>] [--limit <n>] [--since <cursor>]
2
2
  import { followEvents, readEvents } from '@on-par/factory-core';
3
- import { colorEnabled, formatEventLine } from '@on-par/factory-core/internal';
3
+ import { InvalidEventCursorError, colorEnabled, formatEventLine, readEventsSince, readEventsTail, } from '@on-par/factory-core/internal';
4
+ export function buildLogsJson(event, extra = {}) {
5
+ return { ...event, ...extra };
6
+ }
4
7
  export function eventMatchesIssue(e, issue) {
5
8
  return !issue || e.issue === issue;
6
9
  }
7
10
  export function renderEvent(e, opts) {
8
11
  if (opts.json)
9
- return JSON.stringify(e);
12
+ return JSON.stringify(buildLogsJson(e));
10
13
  return formatEventLine(e.type, e.issue, e.msg, { color: opts.color, lane: e.lane, ts: e.ts });
11
14
  }
12
15
  /** Print current events; with follow, keep tailing. Returns a stop() function (no-op stop for non-follow). */
@@ -14,6 +17,26 @@ export function runLogs(eventsFile, opts, deps = {}) {
14
17
  const out = deps.out ?? process.stdout;
15
18
  const env = deps.env ?? process.env;
16
19
  const color = colorEnabled(out, env) && !opts.json;
20
+ const { limit, since } = opts;
21
+ const match = (e) => eventMatchesIssue(e, opts.issue);
22
+ const readOpts = { match, onBytesRead: deps.onBytesRead };
23
+ const page = since !== undefined
24
+ ? readEventsSince(eventsFile, since, { ...readOpts, limit })
25
+ : limit !== undefined
26
+ ? readEventsTail(eventsFile, { ...readOpts, limit })
27
+ : undefined;
28
+ if (page) {
29
+ for (const { event, cursor } of page.events) {
30
+ out.write((opts.json ? JSON.stringify(buildLogsJson(event, { cursor })) : renderEvent(event, { json: false, color })) +
31
+ '\n');
32
+ }
33
+ if (!opts.follow)
34
+ return () => { };
35
+ return followEvents(eventsFile, (e) => {
36
+ if (eventMatchesIssue(e, opts.issue))
37
+ out.write(renderEvent(e, { json: opts.json, color }) + '\n');
38
+ }, { startOffset: page.endOffset, pollMs: deps.pollMs ?? 250 });
39
+ }
17
40
  let delivered = 0;
18
41
  const emit = (e) => {
19
42
  delivered++;
@@ -37,7 +60,26 @@ export function runLogs(eventsFile, opts, deps = {}) {
37
60
  }
38
61
  /** Command entry point wired up to commander. Keeps the process alive until Ctrl-C in --follow mode. */
39
62
  export async function cmdLogs(opts, deps) {
40
- const stop = runLogs(deps.eventsFile, opts, deps);
63
+ const errOut = deps.err ?? process.stderr;
64
+ const fail = (error, message) => {
65
+ errOut.write(JSON.stringify({ error, message }) + '\n');
66
+ process.exitCode = 1;
67
+ };
68
+ if (opts.limit !== undefined && (!Number.isInteger(opts.limit) || opts.limit < 1)) {
69
+ fail('invalid-limit', `--limit must be a positive integer, got ${opts.limit}`);
70
+ return;
71
+ }
72
+ let stop;
73
+ try {
74
+ stop = runLogs(deps.eventsFile, opts, deps);
75
+ }
76
+ catch (e) {
77
+ if (e instanceof InvalidEventCursorError) {
78
+ fail(e.code, e.message);
79
+ return;
80
+ }
81
+ throw e;
82
+ }
41
83
  if (!opts.follow)
42
84
  return;
43
85
  const keepAlive = setInterval(() => { }, 60_000);
@@ -1 +1 @@
1
- {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/cli/logs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/cli/logs.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"program-observe.d.ts","sourceRoot":"","sources":["../../src/cli/program-observe.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMzC,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE3D,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CA4GxG"}
1
+ {"version":3,"file":"program-observe.d.ts","sourceRoot":"","sources":["../../src/cli/program-observe.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMzC,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE3D,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAuHxG"}
@@ -72,14 +72,17 @@ export function registerObserveCommands(program, handlers, deps) {
72
72
  .action((opts) => handlers.cmdTui(opts, deps.runTui ?? runTui));
73
73
  program
74
74
  .command('logs')
75
- .description('Print pipeline events from .factory/events.ndjson (--follow to tail)')
75
+ .description('Print pipeline events from .factory/events.ndjson (--follow to tail, --limit/--since to read only part)')
76
76
  .option('--follow', 'Keep watching for new events')
77
77
  .option('--json', 'Emit one JSON object per line')
78
78
  .option('--issue <number>', 'Only show events for this issue')
79
+ .option('--limit <n>', 'Only the newest <n> matching events (oldest first); with --since, the first <n> after the cursor')
80
+ .option('--since <cursor>', 'Only events after this cursor (the "cursor" field of a previous --json line)')
79
81
  .action(async (opts) => {
80
82
  const repoRoot = await handlers.getRepoRoot();
81
83
  const paths = getFactoryPaths(repoRoot);
82
- await handlers.cmdLogs(opts, { eventsFile: paths.events });
84
+ const { limit, ...rest } = opts;
85
+ await handlers.cmdLogs({ ...rest, ...(limit !== undefined ? { limit: Number(limit) } : {}) }, { eventsFile: paths.events });
83
86
  });
84
87
  }
85
88
  //# sourceMappingURL=program-observe.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"program-observe.js","sourceRoot":"","sources":["../../src/cli/program-observe.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAG9F,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAClG,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,sCAAsC,EAAE,MAAM,oBAAoB,CAAC;AAI5E,MAAM,UAAU,uBAAuB,CAAC,OAAgB,EAAE,QAAyB,EAAE,IAAa;IAChG,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,4DAA4D,CAAC;SACzE,MAAM,CAAC,kBAAkB,EAAE,qCAAqC,CAAC;SACjE,MAAM,CAAC,QAAQ,EAAE,uFAAuF,CAAC;SACzG,MAAM,CAAC,CAAC,IAAwC,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAEhF,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,wEAAwE,CAAC;SACrF,MAAM,CAAC,QAAQ,EAAE,yDAAyD,CAAC;SAC3E,MAAM,CAAC,CAAC,IAAwB,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;IAErE,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,wEAAwE,CAAC;SACrF,MAAM,CAAC,QAAQ,EAAE,yDAAyD,CAAC;SAC3E,MAAM,CACL,QAAQ,EACR,iHAAiH,CAClH;SACA,MAAM,CAAC,CAAC,IAAwC,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAElF,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,sGAAsG,CAAC;SACnH,MAAM,CAAC,QAAQ,EAAE,oDAAoD,CAAC;SACtE,MAAM,CAAC,aAAa,EAAE,kCAAkC,CAAC;SACzD,MAAM,CACL,oBAAoB,EACpB,gGAAgG,CACjG;SACA,MAAM,CAAC,KAAK,EAAE,IAA2D,EAAE,EAAE;QAC5E,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,yDAAyD,CAAC;SACtE,MAAM,CAAC,0BAA0B,EAAE,sCAAsC,CAAC;SAC1E,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEL,MAAM,aAAa,GAAG,OAAO;SAC1B,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,CAAC,2DAA2D,CAAC,CAAC;IAC5E,aAAa;SACV,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CACV,wGAAwG,CACzG;SACA,MAAM,CAAC,QAAQ,EAAE,6CAA6C,CAAC;SAC/D,MAAM,CAAC,CAAC,IAAwB,EAAE,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5E,aAAa;SACV,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,6FAA6F,CAAC;SAC1G,cAAc,CAAC,gBAAgB,EAAE,oDAAoD,CAAC;SACtF,MAAM,CAAC,aAAa,EAAE,6CAA6C,CAAC;SACpE,MAAM,CACL,iBAAiB,EACjB,4FAA4F,CAC7F;SACA,MAAM,CAAC,kBAAkB,EAAE,0EAA0E,CAAC;SACtG,MAAM,CAAC,0BAA0B,EAAE,sCAAsC,CAAC;SAC1E,MAAM,CAAC,QAAQ,EAAE,4CAA4C,CAAC;SAC9D,MAAM,CAAC,CAAC,IAA+B,EAAE,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC;IAE1F,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CACV,8GAA8G,CAC/G;SACA,MAAM,CAAC,UAAU,EAAE,8DAA8D,CAAC;SAClF,MAAM,CAAC,oBAAoB,EAAE,yDAAyD,EAAE,oBAAoB,CAAC;SAC7G,MAAM,CAAC,oBAAoB,EAAE,kCAAkC,EAAE,MAAM,CAAC,2BAA2B,CAAC,CAAC;SACrG,MAAM,CAAC,QAAQ,EAAE,qCAAqC,CAAC;SACvD,MAAM,CAAC,cAAc,EAAE,iDAAiD,CAAC;SACzE,MAAM,CAAC,YAAY,EAAE,oFAAoF,CAAC;SAC1G,MAAM,CACL,CAAC,IAOA,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAC/B,CAAC;IAEJ,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,oDAAoD,CAAC;SACjE,MAAM,CAAC,eAAe,EAAE,mEAAmE,CAAC;SAC5F,MAAM,CAAC,CAAC,IAA8B,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC;IAE5F,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,sEAAsE,CAAC;SACnF,MAAM,CAAC,UAAU,EAAE,8BAA8B,CAAC;SAClD,MAAM,CAAC,QAAQ,EAAE,+BAA+B,CAAC;SACjD,MAAM,CAAC,kBAAkB,EAAE,iCAAiC,CAAC;SAC7D,MAAM,CAAC,KAAK,EAAE,IAA0D,EAAE,EAAE;QAC3E,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"program-observe.js","sourceRoot":"","sources":["../../src/cli/program-observe.ts"],"names":[],"mappings":"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"}
@@ -1,27 +1,5 @@
1
- import type { EnqueueOutcome, EnqueueResult, OrderCollision } from '@on-par/factory-core/internal';
2
- /** One issue in `factory queue add --json` (#2275). */
3
- export interface QueueAddIssueJson {
4
- number: number;
5
- outcome: EnqueueOutcome;
6
- /** 1-based order position; null when failed or the existing order label is unparsable. */
7
- order: number | null;
8
- labelsAdded: string[];
9
- /** Set only when outcome === 'failed'. */
10
- detail?: string;
11
- /** Set only when this placement bumped past an order held without factory:queued (#2988). */
12
- collision?: OrderCollision;
13
- }
14
- /** `factory queue add --json` payload (#2275). Additive changes only; bump schemaVersion on a breaking change. */
15
- export interface QueueAddJson {
16
- schemaVersion: 1;
17
- /** False when any issue failed. */
18
- ok: boolean;
19
- action: 'queue-add';
20
- lane: string;
21
- /** Input order (deduped). */
22
- issues: QueueAddIssueJson[];
23
- /** Union of per-result labelsCreated, first-seen order, deduped. */
24
- labelsCreated: string[];
25
- }
1
+ import type { EnqueueResult } from '@on-par/factory-core/internal';
2
+ import type { QueueAddJson } from './json-contract.js';
3
+ export type { QueueAddIssueJson, QueueAddJson } from './json-contract.js';
26
4
  export declare function buildQueueAddJson(lane: string, results: readonly EnqueueResult[]): QueueAddJson;
27
5
  //# sourceMappingURL=queue-add-json.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"queue-add-json.d.ts","sourceRoot":"","sources":["../../src/cli/queue-add-json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEnG,uDAAuD;AACvD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,CAAC;IACxB,0FAA0F;IAC1F,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6FAA6F;IAC7F,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B;AAED,kHAAkH;AAClH,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,CAAC,CAAC;IACjB,mCAAmC;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,oEAAoE;IACpE,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,aAAa,EAAE,GAAG,YAAY,CAsB/F"}
1
+ {"version":3,"file":"queue-add-json.d.ts","sourceRoot":"","sources":["../../src/cli/queue-add-json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAqB,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE1E,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE1E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,aAAa,EAAE,GAAG,YAAY,CAsB/F"}
@@ -1 +1 @@
1
- {"version":3,"file":"queue-add-json.js","sourceRoot":"","sources":["../../src/cli/queue-add-json.ts"],"names":[],"mappings":"AA4BA,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,OAAiC;IAC/E,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAqB,EAAE;QAClD,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,aAAa,IAAI,EAAE;YAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC;QACtC,OAAO;YACL,MAAM,EAAE,CAAC,CAAC,KAAK;YACf,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC;YAC3C,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9D,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,OAAO;QACL,aAAa,EAAE,CAAC;QAChB,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC;QAChD,MAAM,EAAE,WAAW;QACnB,IAAI;QACJ,MAAM;QACN,aAAa,EAAE,CAAC,GAAG,OAAO,CAAC;KAC5B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"queue-add-json.js","sourceRoot":"","sources":["../../src/cli/queue-add-json.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,OAAiC;IAC/E,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAqB,EAAE;QAClD,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,aAAa,IAAI,EAAE;YAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC;QACtC,OAAO;YACL,MAAM,EAAE,CAAC,CAAC,KAAK;YACf,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC;YAC3C,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9D,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,OAAO;QACL,aAAa,EAAE,CAAC;QAChB,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC;QAChD,MAAM,EAAE,WAAW;QACnB,IAAI;QACJ,MAAM;QACN,aAAa,EAAE,CAAC,GAAG,OAAO,CAAC;KAC5B,CAAC;AACJ,CAAC"}
@@ -1,29 +1,11 @@
1
1
  import type { QueueSnapshot } from '@on-par/factory-core/internal';
2
+ import type { QueueListJson } from './json-contract.js';
3
+ /** `factory queue list --json` payload (#2268); additive changes bump schemaVersion only when breaking. */
4
+ export type { QueueListJson } from './json-contract.js';
2
5
  /** One item in `factory queue list --json` (#2268). */
3
- export interface QueueListItemJson {
4
- issue: number;
5
- title?: string;
6
- status: 'queued' | 'in-progress' | 'parked';
7
- /** 1-based rank within the lane after sorting by the factory:order label (ties broken by issue number) — not the label value (#3101). */
8
- order: number;
9
- claimedBy: string | null;
10
- }
11
- /** A duplicated `factory:order:<n>` position in one lane (#3101); `order` is the label value. */
12
- export interface QueueListOrderConflictJson {
13
- lane: string;
14
- order: number;
15
- issues: number[];
16
- }
17
- /** `factory queue list --json` payload (#2268). Additive changes only; bump schemaVersion on a breaking change. */
18
- export interface QueueListJson {
19
- schemaVersion: 1;
20
- lanes: Array<{
21
- lane: string;
22
- items: QueueListItemJson[];
23
- }>;
24
- /** Duplicated order positions, filtered by `--lane`; additive, present since #3101. */
25
- orderConflicts: QueueListOrderConflictJson[];
26
- }
6
+ export type QueueListItemJson = QueueListJson['lanes'][number]['items'][number];
7
+ /** Duplicated order positions or skipped issues; `order` is null for a skipped issue (#3101, #3192). */
8
+ export type QueueListOrderConflictJson = QueueListJson['orderConflicts'][number];
27
9
  /**
28
10
  * Group the reader's already-sorted entries by lane (lane order preserved) and
29
11
  * rank each item 1-based within its lane. `lane` keeps only that lane.
@@ -1 +1 @@
1
- {"version":3,"file":"queue-list.d.ts","sourceRoot":"","sources":["../../src/cli/queue-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEnE,uDAAuD;AACvD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,QAAQ,GAAG,aAAa,GAAG,QAAQ,CAAC;IAC5C,yIAAyI;IACzI,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,iGAAiG;AACjG,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,mHAAmH;AACnH,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,CAAC,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,iBAAiB,EAAE,CAAA;KAAE,CAAC,CAAC;IAC3D,uFAAuF;IACvF,cAAc,EAAE,0BAA0B,EAAE,CAAC;CAC9C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAqBxF"}
1
+ {"version":3,"file":"queue-list.d.ts","sourceRoot":"","sources":["../../src/cli/queue-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,2GAA2G;AAC3G,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,uDAAuD;AACvD,MAAM,MAAM,iBAAiB,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhF,wGAAwG;AACxG,MAAM,MAAM,0BAA0B,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CA0BxF"}
@@ -22,7 +22,12 @@ export function buildQueueListJson(snapshot, lane) {
22
22
  }
23
23
  const orderConflicts = (snapshot.orderConflicts ?? [])
24
24
  .filter((c) => lane === undefined || c.lane === lane)
25
- .map((c) => ({ lane: c.lane, order: c.position, issues: c.issues }));
25
+ .map((c) => ({
26
+ lane: c.lane,
27
+ order: c.position,
28
+ issues: c.issues,
29
+ ...(c.reason === undefined ? {} : { reason: c.reason }),
30
+ }));
26
31
  return { schemaVersion: 1, lanes: [...byLane].map(([name, items]) => ({ lane: name, items })), orderConflicts };
27
32
  }
28
33
  //# sourceMappingURL=queue-list.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"queue-list.js","sourceRoot":"","sources":["../../src/cli/queue-list.ts"],"names":[],"mappings":"AA2BA;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAuB,EAAE,IAAa;IACvE,MAAM,MAAM,GAAG,IAAI,GAAG,EAA+B,CAAC;IACtD,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrC,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI;YAAE,SAAS;QACxD,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,KAAK,GAAG,EAAE,CAAC;YACX,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,KAAK,CAAC,IAAI,CAAC;YACT,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;YAC5D,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,QAAQ;YAChC,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC;YACvB,SAAS,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI;SAClC,CAAC,CAAC;IACL,CAAC;IACD,MAAM,cAAc,GAAG,CAAC,QAAQ,CAAC,cAAc,IAAI,EAAE,CAAC;SACnD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;SACpD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACvE,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC;AAClH,CAAC"}
1
+ {"version":3,"file":"queue-list.js","sourceRoot":"","sources":["../../src/cli/queue-list.ts"],"names":[],"mappings":"AAYA;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAuB,EAAE,IAAa;IACvE,MAAM,MAAM,GAAG,IAAI,GAAG,EAA+B,CAAC;IACtD,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrC,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI;YAAE,SAAS;QACxD,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,KAAK,GAAG,EAAE,CAAC;YACX,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,KAAK,CAAC,IAAI,CAAC;YACT,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;YAC5D,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,QAAQ;YAChC,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC;YACvB,SAAS,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI;SAClC,CAAC,CAAC;IACL,CAAC;IACD,MAAM,cAAc,GAAG,CAAC,QAAQ,CAAC,cAAc,IAAI,EAAE,CAAC;SACnD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;SACpD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACX,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,KAAK,EAAE,CAAC,CAAC,QAAQ;QACjB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;KACxD,CAAC,CAAC,CAAC;IACN,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC;AAClH,CAAC"}
@@ -0,0 +1,45 @@
1
+ import type { Octokit } from '@octokit/rest';
2
+ import type { CiOutcome, QueueIssue, QueuePreflightDecision, SlicePlan, SlicePlanCommentLookup } from '@on-par/factory-core/internal';
3
+ import { getPullRequestLandState } from './land-pr.js';
4
+ export interface OpenPullRequestEvidence {
5
+ number: number;
6
+ branch: string;
7
+ headSha: string;
8
+ headRepoFullName: string | null;
9
+ }
10
+ /** A slice PR's state as the queue preflight sees it (ADR-0147). */
11
+ export type SlicePullState = 'open' | 'merged' | 'closed';
12
+ export interface QueuePreflightOps {
13
+ expectedHeadRepoFullName: string;
14
+ findOpenPR(issue: number): Promise<OpenPullRequestEvidence | undefined>;
15
+ getLandState(prNumber: number): ReturnType<typeof getPullRequestLandState>;
16
+ watch(ref: string): Promise<CiOutcome>;
17
+ /** The factory-written slice plan comment on the issue (ADR-0147). */
18
+ findSlicePlan(issue: number): Promise<SlicePlanCommentLookup>;
19
+ /** State of a slice PR found by the number recorded in the slice plan. */
20
+ getPullState(prNumber: number): Promise<SlicePullState>;
21
+ /** Rewrite the factory's slice plan comment in place. */
22
+ saveSlicePlan(issue: number, plan: SlicePlan): Promise<void>;
23
+ /** ADR-0161: sizeGate.mode is `stack` and the merge policy is auto, so preflight may adopt the lowest open stack layer. */
24
+ autoMergeStack: boolean;
25
+ readIssueBody(issue: number): Promise<string>;
26
+ getPrerequisiteState(issue: number): Promise<{
27
+ state: 'open' | 'closed';
28
+ mergedClosingPr: boolean;
29
+ }>;
30
+ onDeferred?: (issue: number, message: string) => void;
31
+ /** Current head/base refs of a slice PR; the head SHA is the rebased one after GitHub retargets a layer. */
32
+ getPullRefs(prNumber: number): Promise<{
33
+ headRef: string;
34
+ baseRef: string;
35
+ headSha: string;
36
+ }>;
37
+ }
38
+ export declare function makeQueuePreflightOps(octokit: Octokit, owner: string, repo: string, opts: {
39
+ watch: (ref: string) => Promise<CiOutcome>;
40
+ autoMergeStack?: boolean;
41
+ onDeferred?: (issue: number, message: string) => void;
42
+ }): QueuePreflightOps;
43
+ /** Resolve queued work from GitHub evidence without consuming model or worktree resources. */
44
+ export declare function preflightQueuedIssue(issue: QueueIssue, deps: QueuePreflightOps): Promise<QueuePreflightDecision>;
45
+ //# sourceMappingURL=queue-preflight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-preflight.d.ts","sourceRoot":"","sources":["../../src/cli/queue-preflight.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EACV,SAAS,EACT,UAAU,EACV,sBAAsB,EACtB,SAAS,EACT,sBAAsB,EACvB,MAAM,+BAA+B,CAAC;AASvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAEvD,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,oEAAoE;AACpE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAChC,wBAAwB,EAAE,MAAM,CAAC;IACjC,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC,CAAC;IACxE,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;IAC3E,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACvC,sEAAsE;IACtE,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC9D,0EAA0E;IAC1E,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACxD,yDAAyD;IACzD,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,2HAA2H;IAC3H,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;QAAC,eAAe,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACrG,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACtD,4GAA4G;IAC5G,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/F;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;IACJ,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IAC3C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvD,GACA,iBAAiB,CAyFnB;AA2FD,8FAA8F;AAC9F,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,sBAAsB,CAAC,CA4EjC"}
@@ -0,0 +1,277 @@
1
+ import { findDeclaredPrerequisites, findSlicePlanComment, upsertSlicePlanComment, withSliceState, } from '@on-par/factory-core/internal';
2
+ import { errorDetail } from './index.js';
3
+ import { findOpenPRForIssue } from './land.js';
4
+ import { getPullRequestLandState } from './land-pr.js';
5
+ export function makeQueuePreflightOps(octokit, owner, repo, opts) {
6
+ return {
7
+ autoMergeStack: opts.autoMergeStack ?? false,
8
+ onDeferred: opts.onDeferred,
9
+ getPullRefs: async (prNumber) => {
10
+ const { data } = await octokit.rest.pulls.get({ owner, repo, pull_number: prNumber });
11
+ return { headRef: data.head.ref, baseRef: data.base.ref, headSha: data.head.sha };
12
+ },
13
+ expectedHeadRepoFullName: `${owner}/${repo}`,
14
+ findOpenPR: (issue) => findOpenPRForIssue(octokit, owner, repo, issue),
15
+ getLandState: (prNumber) => getPullRequestLandState(octokit, owner, repo, prNumber),
16
+ watch: opts.watch,
17
+ findSlicePlan: (issue) => findSlicePlanComment({ octokit, repo: `${owner}/${repo}`, issue }),
18
+ getPullState: async (prNumber) => {
19
+ const { data } = await octokit.rest.pulls.get({ owner, repo, pull_number: prNumber });
20
+ if (data.merged || data.merged_at)
21
+ return 'merged';
22
+ return data.state === 'open' ? 'open' : 'closed';
23
+ },
24
+ saveSlicePlan: async (issue, plan) => {
25
+ await upsertSlicePlanComment({ octokit, repo: `${owner}/${repo}`, issue, plan });
26
+ },
27
+ readIssueBody: async (issue) => {
28
+ const { data } = await octokit.rest.issues.get({ owner, repo, issue_number: issue });
29
+ if (!data ||
30
+ typeof data !== 'object' ||
31
+ data.number !== issue ||
32
+ !(data.body === null || typeof data.body === 'string')) {
33
+ throw new Error(`issue #${issue} body response was malformed`);
34
+ }
35
+ return data.body ?? '';
36
+ },
37
+ getPrerequisiteState: async (issue) => {
38
+ let after = null;
39
+ let mergedClosingPr = false;
40
+ let state;
41
+ do {
42
+ const response = await octokit.graphql(`query QueuePrerequisite($owner: String!, $repo: String!, $number: Int!, $after: String) {
43
+ repository(owner: $owner, name: $repo) {
44
+ issue(number: $number) {
45
+ state
46
+ closedByPullRequestsReferences(first: 100, includeClosedPrs: true, after: $after) {
47
+ nodes { merged }
48
+ pageInfo { hasNextPage endCursor }
49
+ }
50
+ }
51
+ }
52
+ }`, { owner, repo, number: issue, after });
53
+ if (!isRecord(response) || !isRecord(response.repository) || !isRecord(response.repository.issue)) {
54
+ throw new Error(`prerequisite #${issue} response was incomplete`);
55
+ }
56
+ const item = response.repository.issue;
57
+ if (item.state !== 'OPEN' && item.state !== 'CLOSED')
58
+ throw new Error(`prerequisite #${issue} state was malformed`);
59
+ const nextState = item.state === 'OPEN' ? 'open' : 'closed';
60
+ if (state !== undefined && state !== nextState)
61
+ throw new Error(`prerequisite #${issue} state changed during pagination`);
62
+ state = nextState;
63
+ if (nextState === 'open')
64
+ return { state: 'open', mergedClosingPr: false };
65
+ if (!isRecord(item.closedByPullRequestsReferences))
66
+ throw new Error(`prerequisite #${issue} closing PR evidence was incomplete`);
67
+ const connection = item.closedByPullRequestsReferences;
68
+ if (!Array.isArray(connection.nodes) ||
69
+ !isRecord(connection.pageInfo) ||
70
+ typeof connection.pageInfo.hasNextPage !== 'boolean') {
71
+ throw new Error(`prerequisite #${issue} closing PR evidence was malformed`);
72
+ }
73
+ for (const node of connection.nodes) {
74
+ if (!isRecord(node) || typeof node.merged !== 'boolean')
75
+ throw new Error(`prerequisite #${issue} closing PR node was malformed`);
76
+ if (node.merged)
77
+ mergedClosingPr = true;
78
+ }
79
+ const hasNextPage = connection.pageInfo.hasNextPage;
80
+ const cursor = connection.pageInfo.endCursor;
81
+ if (hasNextPage && (typeof cursor !== 'string' || cursor.length === 0 || cursor === after)) {
82
+ throw new Error(`prerequisite #${issue} pagination cursor was malformed`);
83
+ }
84
+ after = hasNextPage ? cursor : null;
85
+ } while (after !== null && !mergedClosingPr);
86
+ if (state === undefined)
87
+ throw new Error(`prerequisite #${issue} state was unavailable`);
88
+ return { state, mergedClosingPr };
89
+ },
90
+ };
91
+ }
92
+ function isRecord(value) {
93
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
94
+ }
95
+ /** ADR-0147/ADR-0161: walk every pr-open slice PR bottom-up. Merged layers are recorded, a closed layer parks
96
+ * (naming the layers above it), and the lowest open layer defers, or is adopted when stack auto-merge is on and
97
+ * its base is main with green CI on the rebased head. Returns undefined to fall through to the Closes-PR
98
+ * preflight only when no slice PR is still open. */
99
+ async function preflightSlice(issue, deps) {
100
+ let lookup;
101
+ try {
102
+ lookup = await deps.findSlicePlan(issue);
103
+ }
104
+ catch (err) {
105
+ return { kind: 'park', reason: `slice plan lookup failed: ${errorDetail(err)}` };
106
+ }
107
+ if (lookup.status === 'invalid') {
108
+ return {
109
+ kind: 'park',
110
+ reason: `slice plan comment ${lookup.commentId} on #${issue} is unreadable (${lookup.error})`,
111
+ };
112
+ }
113
+ if (lookup.status === 'not-found')
114
+ return undefined;
115
+ const { plan } = lookup;
116
+ const n = plan.slices.length;
117
+ const open = plan.slices.filter((s) => s.state === 'pr-open');
118
+ if (open.length === 0)
119
+ return undefined;
120
+ let next = plan;
121
+ let lastMerged;
122
+ const save = async () => {
123
+ if (lastMerged === undefined)
124
+ return undefined;
125
+ try {
126
+ await deps.saveSlicePlan(issue, next);
127
+ }
128
+ catch (err) {
129
+ return {
130
+ kind: 'park',
131
+ reason: `${lastMerged.label} PR #${lastMerged.pr} merged but updating the slice plan failed: ${errorDetail(err)}`,
132
+ };
133
+ }
134
+ return undefined;
135
+ };
136
+ for (const [at, slice] of open.entries()) {
137
+ const label = `slice ${slice.index}/${n}`;
138
+ if (slice.prNumber === undefined) {
139
+ return { kind: 'park', reason: `${label} of #${issue} is pr-open but the slice plan records no PR number` };
140
+ }
141
+ const pr = slice.prNumber;
142
+ let state;
143
+ try {
144
+ state = await deps.getPullState(pr);
145
+ }
146
+ catch (err) {
147
+ return { kind: 'park', reason: `${label} PR #${pr} state lookup failed: ${errorDetail(err)}` };
148
+ }
149
+ if (state === 'merged') {
150
+ next = withSliceState(next, slice.index, 'merged', pr);
151
+ lastMerged = { label, pr };
152
+ continue;
153
+ }
154
+ if (state === 'closed') {
155
+ const above = open.slice(at + 1);
156
+ const suffix = above.length > 0
157
+ ? `; layers above it: ${above.map((a) => `slice ${a.index}/${n} (#${a.prNumber})`).join(', ')}`
158
+ : '';
159
+ return { kind: 'park', reason: `${label} PR #${pr} was closed without merging${suffix}` };
160
+ }
161
+ const saved = await save();
162
+ if (saved)
163
+ return saved;
164
+ if (!deps.autoMergeStack)
165
+ return { kind: 'defer' };
166
+ let refs;
167
+ try {
168
+ refs = await deps.getPullRefs(pr);
169
+ }
170
+ catch (err) {
171
+ return { kind: 'park', reason: `${label} PR #${pr} ref lookup failed: ${errorDetail(err)}` };
172
+ }
173
+ // GitHub has not retargeted the layer to main yet: the lower layer is still unmerged.
174
+ if (refs.baseRef !== 'main')
175
+ return { kind: 'defer' };
176
+ let outcome;
177
+ try {
178
+ outcome = await deps.watch(refs.headSha);
179
+ }
180
+ catch (err) {
181
+ return { kind: 'park', reason: `CI watch for ${label} PR #${pr} failed: ${errorDetail(err)}` };
182
+ }
183
+ if (outcome === 'failure')
184
+ return { kind: 'park', reason: `CI for ${label} PR #${pr} ended failure` };
185
+ if (outcome !== 'success')
186
+ return { kind: 'defer' };
187
+ return { kind: 'adopt', branch: refs.headRef, stackLayer: { index: slice.index, count: n, prNumber: pr } };
188
+ }
189
+ return (await save()) ?? undefined;
190
+ }
191
+ /** Resolve queued work from GitHub evidence without consuming model or worktree resources. */
192
+ export async function preflightQueuedIssue(issue, deps) {
193
+ if (issue.labels.includes('factory:in-progress'))
194
+ return { kind: 'defer' };
195
+ let body;
196
+ try {
197
+ body = await deps.readIssueBody(issue.number);
198
+ }
199
+ catch (err) {
200
+ deps.onDeferred?.(issue.number, `issue body lookup failed: ${errorDetail(err)}`);
201
+ return { kind: 'defer' };
202
+ }
203
+ const prerequisites = findDeclaredPrerequisites(body);
204
+ const open = [];
205
+ const closedUnmerged = [];
206
+ const errors = [];
207
+ for (const prerequisite of prerequisites) {
208
+ try {
209
+ const evidence = await deps.getPrerequisiteState(prerequisite);
210
+ if (evidence.state === 'open')
211
+ open.push(prerequisite);
212
+ else if (evidence.state === 'closed' && !evidence.mergedClosingPr)
213
+ closedUnmerged.push(prerequisite);
214
+ else if (evidence.state !== 'closed')
215
+ errors.push(`#${prerequisite}: unexpected state`);
216
+ }
217
+ catch (err) {
218
+ errors.push(`#${prerequisite}: ${errorDetail(err)}`);
219
+ }
220
+ }
221
+ if (errors.length > 0) {
222
+ const unresolved = [...open, ...closedUnmerged].map((number) => `#${number}`);
223
+ const message = [
224
+ `prerequisite evidence lookup failed: ${errors.join('; ')}`,
225
+ unresolved.length ? `unresolved: ${unresolved.join(', ')}` : '',
226
+ ]
227
+ .filter(Boolean)
228
+ .join('; ');
229
+ deps.onDeferred?.(issue.number, message);
230
+ return { kind: 'defer' };
231
+ }
232
+ if (closedUnmerged.length > 0)
233
+ return { kind: 'park', reason: `prerequisite #${closedUnmerged[0]} closed unmerged` };
234
+ if (open.length > 0) {
235
+ deps.onDeferred?.(issue.number, `waiting for prerequisites: ${open.map((number) => `#${number}`).join(', ')}`);
236
+ return { kind: 'defer' };
237
+ }
238
+ const slice = await preflightSlice(issue.number, deps);
239
+ if (slice)
240
+ return slice;
241
+ let pr;
242
+ try {
243
+ pr = await deps.findOpenPR(issue.number);
244
+ }
245
+ catch (err) {
246
+ return { kind: 'park', reason: `PR lookup failed: ${errorDetail(err)}` };
247
+ }
248
+ if (!pr)
249
+ return { kind: 'build' };
250
+ if (pr.headRepoFullName !== deps.expectedHeadRepoFullName) {
251
+ return { kind: 'park', reason: `PR #${pr.number} head is not in ${deps.expectedHeadRepoFullName}` };
252
+ }
253
+ let state;
254
+ try {
255
+ state = await deps.getLandState(pr.number);
256
+ }
257
+ catch (err) {
258
+ return { kind: 'park', reason: `PR #${pr.number} merge-state lookup failed: ${errorDetail(err)}` };
259
+ }
260
+ if (state.isDraft !== false) {
261
+ return { kind: 'park', reason: `PR #${pr.number} is draft or its draft state is unavailable` };
262
+ }
263
+ if (!state.mergeStateStatus || state.mergeStateStatus === 'UNKNOWN') {
264
+ return { kind: 'park', reason: `PR #${pr.number} merge state is unavailable` };
265
+ }
266
+ let outcome;
267
+ try {
268
+ outcome = await deps.watch(pr.headSha);
269
+ }
270
+ catch (err) {
271
+ return { kind: 'park', reason: `CI watch for PR #${pr.number} failed: ${errorDetail(err)}` };
272
+ }
273
+ if (outcome !== 'success')
274
+ return { kind: 'park', reason: `CI for PR #${pr.number} ended ${outcome}` };
275
+ return { kind: 'adopt', branch: pr.branch };
276
+ }
277
+ //# sourceMappingURL=queue-preflight.js.map