vouchington-tooling 0.20.0 → 0.22.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.
Files changed (257) hide show
  1. package/README.md +73 -10
  2. package/dist/agent-blackboard/snapshot-partition-format.mjs +2 -72
  3. package/dist/agent-blackboard/snapshot-partition-guards.d.mts +3 -0
  4. package/dist/agent-blackboard/snapshot-partition-guards.mjs +9 -0
  5. package/dist/agent-blackboard/snapshot-partition-predicates.d.mts +3 -0
  6. package/dist/agent-blackboard/snapshot-partition-predicates.mjs +65 -0
  7. package/dist/api-contract-discovery/header-contract-parser.d.mts +3 -0
  8. package/dist/api-contract-discovery/header-contract-parser.mjs +93 -0
  9. package/dist/api-contract-discovery/header-contract-registry.d.mts +3 -0
  10. package/dist/api-contract-discovery/header-contract-registry.mjs +38 -0
  11. package/dist/api-contract-discovery/header-contract-types.d.mts +19 -0
  12. package/dist/api-contract-discovery/header-contract-types.mjs +1 -0
  13. package/dist/api-contract-discovery/index.d.mts +31 -0
  14. package/dist/api-contract-discovery/index.mjs +26 -0
  15. package/dist/api-contract-discovery/query-contract-extraction.d.mts +3 -0
  16. package/dist/api-contract-discovery/query-contract-extraction.mjs +65 -0
  17. package/dist/api-contract-discovery/query-contract-literals.d.mts +8 -0
  18. package/dist/api-contract-discovery/query-contract-literals.mjs +54 -0
  19. package/dist/api-contract-discovery/query-contract-registry.d.mts +3 -0
  20. package/dist/api-contract-discovery/query-contract-registry.mjs +68 -0
  21. package/dist/api-contract-discovery/query-contract-types.d.mts +8 -0
  22. package/dist/api-contract-discovery/query-contract-types.mjs +1 -0
  23. package/dist/api-contract-discovery/registered-route-catalog.d.mts +10 -0
  24. package/dist/api-contract-discovery/registered-route-catalog.mjs +81 -0
  25. package/dist/api-contract-discovery/registered-route-handler-analysis.d.mts +2 -0
  26. package/dist/api-contract-discovery/registered-route-handler-analysis.mjs +74 -0
  27. package/dist/api-contract-discovery/request-contract-implicit.d.mts +17 -0
  28. package/dist/api-contract-discovery/request-contract-implicit.mjs +73 -0
  29. package/dist/api-contract-discovery/request-contract-lenient.d.mts +28 -0
  30. package/dist/api-contract-discovery/request-contract-lenient.mjs +59 -0
  31. package/dist/api-contract-discovery/request-contract-registry.d.mts +14 -0
  32. package/dist/api-contract-discovery/request-contract-registry.mjs +61 -0
  33. package/dist/api-contract-discovery/request-contract-route-analysis.d.mts +25 -0
  34. package/dist/api-contract-discovery/request-contract-route-analysis.mjs +68 -0
  35. package/dist/api-contract-discovery/request-contract-types.d.mts +12 -0
  36. package/dist/api-contract-discovery/request-contract-types.mjs +1 -0
  37. package/dist/api-contract-discovery/response-contract-ctx-analysis.d.mts +7 -0
  38. package/dist/api-contract-discovery/response-contract-ctx-analysis.mjs +28 -0
  39. package/dist/api-contract-discovery/response-contract-error-branch.d.mts +15 -0
  40. package/dist/api-contract-discovery/response-contract-error-branch.mjs +47 -0
  41. package/dist/api-contract-discovery/response-contract-implicit-sources.test-helpers.d.mts +145 -0
  42. package/dist/api-contract-discovery/response-contract-implicit-sources.test-helpers.mjs +145 -0
  43. package/dist/api-contract-discovery/response-contract-implicit.d.mts +5 -0
  44. package/dist/api-contract-discovery/response-contract-implicit.mjs +110 -0
  45. package/dist/api-contract-discovery/response-contract-lenient.d.mts +23 -0
  46. package/dist/api-contract-discovery/response-contract-lenient.mjs +52 -0
  47. package/dist/api-contract-discovery/response-contract-media.d.mts +3 -0
  48. package/dist/api-contract-discovery/response-contract-media.mjs +46 -0
  49. package/dist/api-contract-discovery/response-contract-registration.d.mts +11 -0
  50. package/dist/api-contract-discovery/response-contract-registration.mjs +61 -0
  51. package/dist/api-contract-discovery/response-contract-registry.d.mts +7 -0
  52. package/dist/api-contract-discovery/response-contract-registry.mjs +76 -0
  53. package/dist/api-contract-discovery/response-contract-route-analysis.d.mts +13 -0
  54. package/dist/api-contract-discovery/response-contract-route-analysis.mjs +144 -0
  55. package/dist/api-contract-discovery/response-contract-status.d.mts +27 -0
  56. package/dist/api-contract-discovery/response-contract-status.mjs +80 -0
  57. package/dist/api-contract-discovery/response-contract-types.d.mts +16 -0
  58. package/dist/api-contract-discovery/response-contract-types.mjs +1 -0
  59. package/dist/api-contract-discovery/test-setup.test-helpers.d.mts +3 -0
  60. package/dist/api-contract-discovery/test-setup.test-helpers.mjs +2 -0
  61. package/dist/ast-grep-examples/companion-parity-compare.d.mts +3 -0
  62. package/dist/ast-grep-examples/companion-parity-compare.mjs +58 -0
  63. package/dist/ast-grep-examples/companion-parity.d.mts +2 -1
  64. package/dist/ast-grep-examples/companion-parity.mjs +2 -58
  65. package/dist/browser-session-runner/attempt.mjs +29 -48
  66. package/dist/browser-session-runner/termination.d.mts +11 -0
  67. package/dist/browser-session-runner/termination.mjs +34 -0
  68. package/dist/cli/parse-direct-options.d.mts +26 -0
  69. package/dist/cli/parse-direct-options.mjs +72 -0
  70. package/dist/cli/parse-forwarded-commands.d.mts +42 -0
  71. package/dist/cli/parse-forwarded-commands.mjs +29 -0
  72. package/dist/cli/parse-options.d.mts +1 -2
  73. package/dist/cli/parse-options.mjs +2 -72
  74. package/dist/cli/parse.mjs +4 -26
  75. package/dist/compiler-build/freshness.d.mts +27 -0
  76. package/dist/compiler-build/freshness.mjs +116 -0
  77. package/dist/compiler-build/index.d.mts +2 -0
  78. package/dist/compiler-build/index.mjs +2 -0
  79. package/dist/compiler-build/settlement.d.mts +10 -0
  80. package/dist/compiler-build/settlement.mjs +14 -0
  81. package/dist/config-inventory/call-arguments.d.mts +1 -0
  82. package/dist/config-inventory/call-arguments.mjs +30 -0
  83. package/dist/config-inventory/collect.d.mts +3 -0
  84. package/dist/config-inventory/collect.mjs +43 -0
  85. package/dist/config-inventory/dynamic-configs.d.mts +2 -0
  86. package/dist/config-inventory/dynamic-configs.mjs +9 -0
  87. package/dist/config-inventory/env-expression-readers.d.mts +3 -0
  88. package/dist/config-inventory/env-expression-readers.mjs +117 -0
  89. package/dist/config-inventory/env-prefix-readers.d.mts +2 -0
  90. package/dist/config-inventory/env-prefix-readers.mjs +14 -0
  91. package/dist/config-inventory/env-reference-matchers.d.mts +3 -0
  92. package/dist/config-inventory/env-reference-matchers.mjs +9 -0
  93. package/dist/config-inventory/env-var-accumulator.d.mts +6 -0
  94. package/dist/config-inventory/env-var-accumulator.mjs +82 -0
  95. package/dist/config-inventory/env-vars.d.mts +4 -0
  96. package/dist/config-inventory/env-vars.mjs +108 -0
  97. package/dist/config-inventory/format.d.mts +2 -0
  98. package/dist/config-inventory/format.mjs +69 -0
  99. package/dist/config-inventory/index.d.mts +3 -0
  100. package/dist/config-inventory/index.mjs +2 -0
  101. package/dist/config-inventory/package-gates.d.mts +2 -0
  102. package/dist/config-inventory/package-gates.mjs +54 -0
  103. package/dist/config-inventory/shared.d.mts +3 -0
  104. package/dist/config-inventory/shared.mjs +7 -0
  105. package/dist/config-inventory/types.d.mts +96 -0
  106. package/dist/config-inventory/types.mjs +1 -0
  107. package/dist/contract-schema/contract-schema-bounded-array.d.mts +15 -0
  108. package/dist/contract-schema/contract-schema-bounded-array.mjs +32 -0
  109. package/dist/contract-schema/contract-schema-type-extractor.d.mts +2 -8
  110. package/dist/contract-schema/contract-schema-type-extractor.mjs +2 -31
  111. package/dist/coverage-transport/control-v2-parse-object.d.mts +12 -0
  112. package/dist/coverage-transport/control-v2-parse-object.mjs +28 -0
  113. package/dist/coverage-transport/control-v2.mjs +2 -27
  114. package/dist/dependency-license-policy/audit-directory.d.mts +28 -0
  115. package/dist/dependency-license-policy/audit-directory.mjs +115 -0
  116. package/dist/dependency-license-policy/audit-signals.d.mts +12 -0
  117. package/dist/dependency-license-policy/audit-signals.mjs +44 -0
  118. package/dist/dependency-license-policy/audit-store.d.mts +12 -0
  119. package/dist/dependency-license-policy/audit-store.mjs +32 -0
  120. package/dist/dependency-license-policy/collect.d.mts +3 -1
  121. package/dist/dependency-license-policy/collect.mjs +16 -21
  122. package/dist/dependency-license-policy/execute-pnpm.d.mts +10 -0
  123. package/dist/dependency-license-policy/execute-pnpm.mjs +83 -0
  124. package/dist/dependency-license-policy/types.d.mts +11 -9
  125. package/dist/dependency-license-policy/workspace.d.mts +3 -1
  126. package/dist/dependency-license-policy/workspace.mjs +12 -5
  127. package/dist/gh-api-shell-quoting/argument-scan.d.mts +7 -0
  128. package/dist/gh-api-shell-quoting/argument-scan.mjs +35 -0
  129. package/dist/gh-api-shell-quoting/logical-line.d.mts +3 -0
  130. package/dist/gh-api-shell-quoting/logical-line.mjs +90 -0
  131. package/dist/gh-api-shell-quoting/scan.d.mts +2 -4
  132. package/dist/gh-api-shell-quoting/scan.mjs +1 -119
  133. package/dist/gh-cli/diff.d.mts +24 -4
  134. package/dist/gh-cli/diff.mjs +111 -4
  135. package/dist/gh-cli/index.d.mts +2 -1
  136. package/dist/gh-cli/index.mjs +1 -1
  137. package/dist/gha-workspace-policy/docker-options.d.mts +4 -0
  138. package/dist/gha-workspace-policy/docker-options.mjs +93 -0
  139. package/dist/gha-workspace-policy/docker-workspace-user.mjs +1 -168
  140. package/dist/gha-workspace-policy/shell-token-modes.d.mts +10 -0
  141. package/dist/gha-workspace-policy/shell-token-modes.mjs +31 -0
  142. package/dist/gha-workspace-policy/shell-tokens.d.mts +1 -0
  143. package/dist/gha-workspace-policy/shell-tokens.mjs +65 -0
  144. package/dist/index.d.mts +2 -1
  145. package/dist/index.mjs +1 -1
  146. package/dist/openapi-document/contract-schema-types.d.mts +1 -1
  147. package/dist/openapi-document/openapi-types.d.mts +1 -1
  148. package/dist/pnpm-install/native-family.d.mts +3 -0
  149. package/dist/pnpm-install/native-family.mjs +31 -0
  150. package/dist/pnpm-install/native-health.d.mts +1 -4
  151. package/dist/pnpm-install/native-health.mjs +2 -31
  152. package/dist/retrospective-facts/local-merge.d.mts +2 -0
  153. package/dist/retrospective-facts/local-merge.mjs +21 -0
  154. package/dist/retrospective-facts/local.mjs +1 -21
  155. package/dist/retrospective-transcript/claude-blocks.d.mts +3 -0
  156. package/dist/retrospective-transcript/claude-blocks.mjs +38 -0
  157. package/dist/retrospective-transcript/claude.mjs +4 -34
  158. package/dist/retrospective-transcript/codex-payload.d.mts +2 -0
  159. package/dist/retrospective-transcript/codex-payload.mjs +51 -0
  160. package/dist/retrospective-transcript/codex-records.d.mts +2 -0
  161. package/dist/retrospective-transcript/codex-records.mjs +95 -0
  162. package/dist/retrospective-transcript/codex.mjs +2 -144
  163. package/dist/retrospective-transcript/index.d.mts +3 -16
  164. package/dist/retrospective-transcript/index.mjs +4 -48
  165. package/dist/retrospective-transcript/resolve-transcript-file.d.mts +19 -0
  166. package/dist/retrospective-transcript/resolve-transcript-file.mjs +50 -0
  167. package/dist/session-friction/command-segments.d.mts +3 -0
  168. package/dist/session-friction/command-segments.mjs +94 -0
  169. package/dist/session-friction/log-file.d.mts +7 -0
  170. package/dist/session-friction/log-file.mjs +83 -0
  171. package/dist/session-friction/log.mjs +3 -83
  172. package/dist/session-friction/normalize.mjs +1 -94
  173. package/dist/sql-scanner/comments.d.mts +1 -0
  174. package/dist/sql-scanner/comments.mjs +101 -0
  175. package/dist/sql-scanner/index.d.mts +1 -1
  176. package/dist/sql-scanner/index.mjs +1 -100
  177. package/dist/sql-scanner/literals.mjs +1 -35
  178. package/dist/sql-scanner/quote-decode.d.mts +2 -0
  179. package/dist/sql-scanner/quote-decode.mjs +35 -0
  180. package/dist/vitest-diagnostics/index.d.mts +7 -0
  181. package/dist/vitest-diagnostics/index.mjs +4 -0
  182. package/dist/vitest-diagnostics/vitest-fork-exit-error-detail.d.mts +7 -0
  183. package/dist/vitest-diagnostics/vitest-fork-exit-error-detail.mjs +26 -0
  184. package/dist/vitest-diagnostics/vitest-fork-exit-records.d.mts +26 -0
  185. package/dist/vitest-diagnostics/vitest-fork-exit-records.mjs +161 -0
  186. package/dist/vitest-diagnostics/vitest-fork-exit-sentinel.d.mts +14 -0
  187. package/dist/vitest-diagnostics/vitest-fork-exit-sentinel.mjs +131 -0
  188. package/dist/vitest-diagnostics/vitest-fork-leak-detection.d.mts +26 -0
  189. package/dist/vitest-diagnostics/vitest-fork-leak-detection.mjs +96 -0
  190. package/dist/vitest-diagnostics/vitest-fork-leak-diagnostics.d.mts +3 -0
  191. package/dist/vitest-diagnostics/vitest-fork-leak-diagnostics.mjs +14 -0
  192. package/dist/vitest-diagnostics/vitest-fork-leak-episode.d.mts +37 -0
  193. package/dist/vitest-diagnostics/vitest-fork-leak-episode.mjs +118 -0
  194. package/dist/vitest-diagnostics/vitest-worker-exit-diagnostics-errors.d.mts +2 -0
  195. package/dist/vitest-diagnostics/vitest-worker-exit-diagnostics-errors.mjs +42 -0
  196. package/dist/vitest-diagnostics/vitest-worker-exit-diagnostics-reporter.d.mts +12 -0
  197. package/dist/vitest-diagnostics/vitest-worker-exit-diagnostics-reporter.mjs +142 -0
  198. package/dist/workflow-policy/concurrency-scope.d.mts +4 -0
  199. package/dist/workflow-policy/concurrency-scope.mjs +66 -0
  200. package/dist/workflow-policy/concurrency.d.mts +10 -0
  201. package/dist/workflow-policy/concurrency.mjs +77 -0
  202. package/dist/workflow-policy/condition-entailment.d.mts +20 -0
  203. package/dist/workflow-policy/condition-entailment.mjs +132 -0
  204. package/dist/workflow-policy/condition-split.d.mts +15 -0
  205. package/dist/workflow-policy/condition-split.mjs +71 -0
  206. package/dist/workflow-policy/graph.d.mts +2 -0
  207. package/dist/workflow-policy/graph.mjs +138 -0
  208. package/dist/workflow-policy/index.d.mts +7 -0
  209. package/dist/workflow-policy/index.mjs +6 -0
  210. package/dist/workflow-policy/permission-mismatches.d.mts +3 -0
  211. package/dist/workflow-policy/permission-mismatches.mjs +52 -0
  212. package/dist/workflow-policy/permissions.d.mts +16 -0
  213. package/dist/workflow-policy/permissions.mjs +83 -0
  214. package/dist/workflow-policy/secret-readiness.d.mts +18 -0
  215. package/dist/workflow-policy/secret-readiness.mjs +163 -0
  216. package/dist/workflow-policy/shell-comments.d.mts +7 -0
  217. package/dist/workflow-policy/shell-comments.mjs +28 -0
  218. package/dist/workflow-policy/types.d.mts +90 -0
  219. package/dist/workflow-policy/types.mjs +1 -0
  220. package/dist/workspace-gates/manifest-version-parser.mjs +1 -52
  221. package/dist/workspace-gates/manifest-version-skips.d.mts +1 -0
  222. package/dist/workspace-gates/manifest-version-skips.mjs +52 -0
  223. package/docs/workflow-and-compiler.md +74 -0
  224. package/package.json +26 -2
  225. package/skills/agent-workflow/SKILL.md +4 -4
  226. package/skills/agent-workflow/references/review-response.md +47 -44
  227. package/skills/backend-vitest-test-authoring/SKILL.md +9 -6
  228. package/skills/blackboard/SKILL.md +8 -8
  229. package/skills/dependabot/SKILL.md +68 -67
  230. package/skills/dotnet-test-authoring/SKILL.md +11 -12
  231. package/skills/git-commit-checklist/SKILL.md +3 -3
  232. package/skills/github-actions-authoring/SKILL.md +40 -38
  233. package/skills/github-actions-checklist/SKILL.md +93 -85
  234. package/skills/github-issue/SKILL.md +82 -78
  235. package/skills/nextjs-vitest-test-authoring/SKILL.md +8 -6
  236. package/skills/npm-publishing/SKILL.md +42 -38
  237. package/skills/organize-github-issues/SKILL.md +18 -22
  238. package/skills/package-json-checklist/SKILL.md +5 -5
  239. package/skills/planning/SKILL.md +3 -3
  240. package/skills/playwright-authoring/SKILL.md +10 -9
  241. package/skills/postgres-node-performance-tuning/SKILL.md +10 -6
  242. package/skills/postgres-partitioning-uuid-v7/SKILL.md +10 -7
  243. package/skills/pr-description/SKILL.md +4 -3
  244. package/skills/retrospective/SKILL.md +14 -15
  245. package/skills/retrospective-distill/SKILL.md +14 -14
  246. package/skills/review-ci-logs/SKILL.md +18 -19
  247. package/skills/review-github-issue-taxonomy/SKILL.md +21 -18
  248. package/skills/revisit-followups/SKILL.md +3 -3
  249. package/skills/stacked-prs/SKILL.md +30 -61
  250. package/skills/static-analysis-checklist/SKILL.md +6 -4
  251. package/skills/storybook-authoring/SKILL.md +9 -9
  252. package/skills/swift-test-authoring/SKILL.md +10 -9
  253. package/skills/test-authoring/SKILL.md +14 -14
  254. package/skills/test-authoring/references/core-practice.md +12 -11
  255. package/skills/test-authoring/references/dependency-boundaries.md +36 -35
  256. package/skills/test-authoring/references/tautological-tests.md +45 -44
  257. package/skills/vitest-test-authoring/SKILL.md +9 -6
@@ -0,0 +1,93 @@
1
+ import { shellTokens } from './shell-tokens.mjs';
2
+ const DOCKER_GLOBAL_FLAG_OPTIONS = new Set(['--debug', '-D', '--help', '--tls', '--tlsverify']);
3
+ const DOCKER_GLOBAL_VALUE_OPTIONS = new Set([
4
+ '--config',
5
+ '--context',
6
+ '-c',
7
+ '--host',
8
+ '-H',
9
+ '--log-level',
10
+ '-l',
11
+ '--tlscacert',
12
+ '--tlscert',
13
+ '--tlskey',
14
+ ]);
15
+ const FLAG_OPTIONS = new Set([
16
+ '--detach',
17
+ '-d',
18
+ '--init',
19
+ '--interactive',
20
+ '-i',
21
+ '--privileged',
22
+ '--publish-all',
23
+ '-P',
24
+ '--read-only',
25
+ '--rm',
26
+ '--tty',
27
+ '-t',
28
+ ]);
29
+ export function dockerOptions(block) {
30
+ const tokens = shellTokens(block);
31
+ const dockerIndex = findDockerCommand(tokens);
32
+ if (dockerIndex < 0)
33
+ return undefined;
34
+ let start = dockerIndex + 1;
35
+ while (start < tokens.length && tokens[start].startsWith('-')) {
36
+ const option = tokens[start];
37
+ const name = option.includes('=') ? option.slice(0, option.indexOf('=')) : option;
38
+ if (DOCKER_GLOBAL_FLAG_OPTIONS.has(name) || option.includes('='))
39
+ start += 1;
40
+ else if (DOCKER_GLOBAL_VALUE_OPTIONS.has(name))
41
+ start += 2;
42
+ else
43
+ return undefined;
44
+ }
45
+ if (tokens[start] === 'container')
46
+ start += 1;
47
+ if (tokens[start] !== 'run')
48
+ return undefined;
49
+ start += 1;
50
+ const volumes = [];
51
+ let user;
52
+ for (let index = start; index < tokens.length; index += 1) {
53
+ const option = tokens[index];
54
+ if (!option.startsWith('-'))
55
+ break;
56
+ const equals = option.indexOf('=');
57
+ const compact = option.startsWith('-v') || option.startsWith('-u');
58
+ const name = equals > 0
59
+ ? option.slice(0, equals)
60
+ : compact && option.length > 2
61
+ ? option.slice(0, 2)
62
+ : option;
63
+ const inlineValue = equals > 0
64
+ ? option.slice(equals + 1)
65
+ : compact && option.length > 2
66
+ ? option.slice(2)
67
+ : undefined;
68
+ const bundledFlags = /^-[diPt]{2,}$/u.test(option);
69
+ const value = inlineValue ?? (FLAG_OPTIONS.has(name) || bundledFlags ? undefined : tokens[++index]);
70
+ if ((name === '-v' || name === '--volume' || name === '--mount') && value !== undefined)
71
+ volumes.push(value);
72
+ if ((name === '-u' || name === '--user') && value !== undefined)
73
+ user = value;
74
+ }
75
+ return { user, volumes };
76
+ }
77
+ function findDockerCommand(tokens) {
78
+ let commandStart = true;
79
+ for (const [index, token] of tokens.entries()) {
80
+ if (token === ';' || token === '|' || token === '&') {
81
+ commandStart = true;
82
+ continue;
83
+ }
84
+ if (!commandStart)
85
+ continue;
86
+ if (/^[A-Za-z_][A-Za-z0-9_]*=.*/u.test(token))
87
+ continue;
88
+ if (token === 'docker')
89
+ return index;
90
+ commandStart = false;
91
+ }
92
+ return -1;
93
+ }
@@ -1,32 +1,6 @@
1
+ import { dockerOptions } from './docker-options.mjs';
1
2
  import { visitRunSteps } from './shared.mjs';
2
3
  const WORKSPACE_RE = /(?:\$\{?GITHUB_WORKSPACE\}?|\$\{\{\s*github\.workspace\s*\}\})/iu;
3
- const DOCKER_GLOBAL_FLAG_OPTIONS = new Set(['--debug', '-D', '--help', '--tls', '--tlsverify']);
4
- const DOCKER_GLOBAL_VALUE_OPTIONS = new Set([
5
- '--config',
6
- '--context',
7
- '-c',
8
- '--host',
9
- '-H',
10
- '--log-level',
11
- '-l',
12
- '--tlscacert',
13
- '--tlscert',
14
- '--tlskey',
15
- ]);
16
- const FLAG_OPTIONS = new Set([
17
- '--detach',
18
- '-d',
19
- '--init',
20
- '--interactive',
21
- '-i',
22
- '--privileged',
23
- '--publish-all',
24
- '-P',
25
- '--read-only',
26
- '--rm',
27
- '--tty',
28
- '-t',
29
- ]);
30
4
  export function checkDockerWorkspaceUserDocument(file, document, kind, errors) {
31
5
  visitRunSteps(document, kind === 'action', (scope, index, step) => {
32
6
  if (typeof step.run !== 'string')
@@ -44,82 +18,6 @@ export function checkDockerWorkspaceUserDocument(file, document, kind, errors) {
44
18
  }
45
19
  });
46
20
  }
47
- function shellTokens(input) {
48
- const tokens = [];
49
- let token = '';
50
- let quote = '';
51
- let substitutionDepth = 0;
52
- let githubExpression = false;
53
- for (let index = 0; index < input.length; index += 1) {
54
- const character = input[index];
55
- if (githubExpression) {
56
- token += character;
57
- if (character === '}' && input[index + 1] === '}') {
58
- token += '}';
59
- index += 1;
60
- githubExpression = false;
61
- }
62
- continue;
63
- }
64
- if (substitutionDepth > 0) {
65
- token += character;
66
- if (character === '(')
67
- substitutionDepth += 1;
68
- if (character === ')')
69
- substitutionDepth -= 1;
70
- continue;
71
- }
72
- if (character === '$' && input[index + 1] === '{' && input[index + 2] === '{') {
73
- token += '${{';
74
- index += 2;
75
- githubExpression = true;
76
- continue;
77
- }
78
- if (character === '$' && input[index + 1] === '(') {
79
- token += '$(';
80
- substitutionDepth = 1;
81
- index += 1;
82
- continue;
83
- }
84
- if (quote) {
85
- if (character === '\\' && input[index + 1] !== undefined)
86
- token += input[++index];
87
- else if (character === quote)
88
- quote = '';
89
- else
90
- token += character;
91
- continue;
92
- }
93
- if (character === '"' || character === "'") {
94
- quote = character;
95
- continue;
96
- }
97
- if (/\s/u.test(character)) {
98
- if (token)
99
- tokens.push(token);
100
- token = '';
101
- continue;
102
- }
103
- if (character === '#' && !token)
104
- break;
105
- if (character === ';' || character === '|' || character === '&') {
106
- if (token)
107
- tokens.push(token);
108
- token = '';
109
- if ((character === '&' || character === '|') && input[index + 1] === character)
110
- index += 1;
111
- tokens.push(character);
112
- continue;
113
- }
114
- if (character === '\\' && input[index + 1] !== undefined)
115
- token += input[++index];
116
- else
117
- token += character;
118
- }
119
- if (token)
120
- tokens.push(token);
121
- return tokens;
122
- }
123
21
  function dockerRunBlocks(run) {
124
22
  const blocks = [];
125
23
  const lines = run.split('\n');
@@ -135,71 +33,6 @@ function dockerRunBlocks(run) {
135
33
  }
136
34
  return blocks;
137
35
  }
138
- function findDockerCommand(tokens) {
139
- let commandStart = true;
140
- for (const [index, token] of tokens.entries()) {
141
- if (token === ';' || token === '|' || token === '&') {
142
- commandStart = true;
143
- continue;
144
- }
145
- if (!commandStart)
146
- continue;
147
- if (/^[A-Za-z_][A-Za-z0-9_]*=.*/u.test(token))
148
- continue;
149
- if (token === 'docker')
150
- return index;
151
- commandStart = false;
152
- }
153
- return -1;
154
- }
155
- function dockerOptions(block) {
156
- const tokens = shellTokens(block);
157
- const dockerIndex = findDockerCommand(tokens);
158
- if (dockerIndex < 0)
159
- return undefined;
160
- let start = dockerIndex + 1;
161
- while (start < tokens.length && tokens[start].startsWith('-')) {
162
- const option = tokens[start];
163
- const name = option.includes('=') ? option.slice(0, option.indexOf('=')) : option;
164
- if (DOCKER_GLOBAL_FLAG_OPTIONS.has(name) || option.includes('='))
165
- start += 1;
166
- else if (DOCKER_GLOBAL_VALUE_OPTIONS.has(name))
167
- start += 2;
168
- else
169
- return undefined;
170
- }
171
- if (tokens[start] === 'container')
172
- start += 1;
173
- if (tokens[start] !== 'run')
174
- return undefined;
175
- start += 1;
176
- const volumes = [];
177
- let user;
178
- for (let index = start; index < tokens.length; index += 1) {
179
- const option = tokens[index];
180
- if (!option.startsWith('-'))
181
- break;
182
- const equals = option.indexOf('=');
183
- const compact = option.startsWith('-v') || option.startsWith('-u');
184
- const name = equals > 0
185
- ? option.slice(0, equals)
186
- : compact && option.length > 2
187
- ? option.slice(0, 2)
188
- : option;
189
- const inlineValue = equals > 0
190
- ? option.slice(equals + 1)
191
- : compact && option.length > 2
192
- ? option.slice(2)
193
- : undefined;
194
- const bundledFlags = /^-[diPt]{2,}$/u.test(option);
195
- const value = inlineValue ?? (FLAG_OPTIONS.has(name) || bundledFlags ? undefined : tokens[++index]);
196
- if ((name === '-v' || name === '--volume' || name === '--mount') && value !== undefined)
197
- volumes.push(value);
198
- if ((name === '-u' || name === '--user') && value !== undefined)
199
- user = value;
200
- }
201
- return { user, volumes };
202
- }
203
36
  function hasHostUserMapping(value) {
204
37
  return value !== undefined && /^\$\(\s*id\s+-u\s*\):\$\(\s*id\s+-g\s*\)$/u.test(value);
205
38
  }
@@ -0,0 +1,10 @@
1
+ export type ShellTokenScan = {
2
+ githubExpression: boolean;
3
+ quote: string;
4
+ substitutionDepth: number;
5
+ token: string;
6
+ tokens: string[];
7
+ };
8
+ export declare function consumeGithubExpression(input: string, index: number, scan: ShellTokenScan): number;
9
+ export declare function consumeCommandSubstitution(input: string, index: number, scan: ShellTokenScan): number;
10
+ export declare function consumeQuotedCharacter(input: string, index: number, scan: ShellTokenScan): number;
@@ -0,0 +1,31 @@
1
+ export function consumeGithubExpression(input, index, scan) {
2
+ const character = input[index];
3
+ scan.token += character;
4
+ if (character === '}' && input[index + 1] === '}') {
5
+ scan.token += '}';
6
+ scan.githubExpression = false;
7
+ return index + 1;
8
+ }
9
+ return index;
10
+ }
11
+ export function consumeCommandSubstitution(input, index, scan) {
12
+ const character = input[index];
13
+ scan.token += character;
14
+ if (character === '(')
15
+ scan.substitutionDepth += 1;
16
+ if (character === ')')
17
+ scan.substitutionDepth -= 1;
18
+ return index;
19
+ }
20
+ export function consumeQuotedCharacter(input, index, scan) {
21
+ const character = input[index];
22
+ if (character === '\\' && input[index + 1] !== undefined) {
23
+ scan.token += input[index + 1];
24
+ return index + 1;
25
+ }
26
+ if (character === scan.quote)
27
+ scan.quote = '';
28
+ else
29
+ scan.token += character;
30
+ return index;
31
+ }
@@ -0,0 +1 @@
1
+ export declare function shellTokens(input: string): string[];
@@ -0,0 +1,65 @@
1
+ import { consumeCommandSubstitution, consumeGithubExpression, consumeQuotedCharacter, } from './shell-token-modes.mjs';
2
+ export function shellTokens(input) {
3
+ const scan = {
4
+ githubExpression: false,
5
+ quote: '',
6
+ substitutionDepth: 0,
7
+ token: '',
8
+ tokens: [],
9
+ };
10
+ for (let index = 0; index < input.length; index += 1) {
11
+ const character = input[index];
12
+ if (scan.githubExpression) {
13
+ index = consumeGithubExpression(input, index, scan);
14
+ continue;
15
+ }
16
+ if (scan.substitutionDepth > 0) {
17
+ index = consumeCommandSubstitution(input, index, scan);
18
+ continue;
19
+ }
20
+ if (character === '$' && input[index + 1] === '{' && input[index + 2] === '{') {
21
+ scan.token += '${{';
22
+ index += 2;
23
+ scan.githubExpression = true;
24
+ continue;
25
+ }
26
+ if (character === '$' && input[index + 1] === '(') {
27
+ scan.token += '$(';
28
+ scan.substitutionDepth = 1;
29
+ index += 1;
30
+ continue;
31
+ }
32
+ if (scan.quote) {
33
+ index = consumeQuotedCharacter(input, index, scan);
34
+ continue;
35
+ }
36
+ if (character === '"' || character === "'") {
37
+ scan.quote = character;
38
+ continue;
39
+ }
40
+ if (/\s/u.test(character)) {
41
+ if (scan.token)
42
+ scan.tokens.push(scan.token);
43
+ scan.token = '';
44
+ continue;
45
+ }
46
+ if (character === '#' && !scan.token)
47
+ break;
48
+ if (character === ';' || character === '|' || character === '&') {
49
+ if (scan.token)
50
+ scan.tokens.push(scan.token);
51
+ scan.token = '';
52
+ if ((character === '&' || character === '|') && input[index + 1] === character)
53
+ index += 1;
54
+ scan.tokens.push(character);
55
+ continue;
56
+ }
57
+ if (character === '\\' && input[index + 1] !== undefined)
58
+ scan.token += input[++index];
59
+ else
60
+ scan.token += character;
61
+ }
62
+ if (scan.token)
63
+ scan.tokens.push(scan.token);
64
+ return scan.tokens;
65
+ }
package/dist/index.d.mts CHANGED
@@ -97,7 +97,8 @@ export { DEFAULT_MAX_DIAGNOSTIC_REPORTS, DEFAULT_MAX_FORMATTED_DIAGNOSTIC_REPORT
97
97
  export type { DiagnosticReportLimitOptions, DiagnosticReportSummary, } from './vitest-diagnostics/index.mts';
98
98
  export { createCommandRunner, runGh, runGit } from './gh-cli/index.mts';
99
99
  export type { ExecFileText, RunTextCommand } from './gh-cli/index.mts';
100
- export { getDiffAgainstBase } from './gh-cli/index.mts';
100
+ export { DiffCommandError, processDiffCommand } from './gh-cli/index.mts';
101
+ export type { DiffBlockCallback, DiffCommand } from './gh-cli/index.mts';
101
102
  export { GITHUB_BODY_MAX_CHARACTERS, validateGitHubBodyLength } from './gh-cli/index.mts';
102
103
  export type { GitHubBodyLengthValidation } from './gh-cli/index.mts';
103
104
  export { assertHeadPushed, buildGhPrCreateArgs, createPullRequest, DetachedHeadError, HeadNotPushedError, HeadOutOfDateError, resolveHeadBranch, } from './gh-cli/index.mts';
package/dist/index.mjs CHANGED
@@ -53,6 +53,6 @@ export { isSwiftCodeOffset, parseUniqueSwiftBinaryTargetChecksum, } from './swif
53
53
  export { validateResolvedPinDelta } from './swift-resolved-pin-delta/index.mjs';
54
54
  export { DEFAULT_MAX_DIAGNOSTIC_REPORTS, DEFAULT_MAX_FORMATTED_DIAGNOSTIC_REPORTS, formatDiagnosticReportSummaries, HARD_MAX_DIAGNOSTIC_REPORTS, readDiagnosticReportSummaries, summarizeDiagnosticReport, } from './vitest-diagnostics/index.mjs';
55
55
  export { createCommandRunner, runGh, runGit } from './gh-cli/index.mjs';
56
- export { getDiffAgainstBase } from './gh-cli/index.mjs';
56
+ export { DiffCommandError, processDiffCommand } from './gh-cli/index.mjs';
57
57
  export { GITHUB_BODY_MAX_CHARACTERS, validateGitHubBodyLength } from './gh-cli/index.mjs';
58
58
  export { assertHeadPushed, buildGhPrCreateArgs, createPullRequest, DetachedHeadError, HeadNotPushedError, HeadOutOfDateError, resolveHeadBranch, } from './gh-cli/index.mjs';
@@ -12,7 +12,7 @@ export type ContractSchemaNode = {
12
12
  type: 'number';
13
13
  } | {
14
14
  type: 'string';
15
- format?: 'uuid';
15
+ format?: 'uuid' | 'binary';
16
16
  } | {
17
17
  type: 'literal';
18
18
  value: boolean | number | string;
@@ -1,7 +1,7 @@
1
1
  export type OpenApiSchema = {
2
2
  $ref?: string;
3
3
  type?: 'null' | 'boolean' | 'integer' | 'number' | 'string' | 'array' | 'object';
4
- format?: 'uri' | 'uuid';
4
+ format?: 'uri' | 'uuid' | 'binary';
5
5
  const?: boolean | number | string;
6
6
  enum?: (boolean | number | string)[];
7
7
  items?: OpenApiSchema | false;
@@ -0,0 +1,3 @@
1
+ export type NativeFamily = 'elf' | 'macho' | 'pe';
2
+ export declare function nativeFamilyFromMagic(buffer: Buffer): NativeFamily | undefined;
3
+ export declare function expectedNativeFamily(platform?: NodeJS.Platform): NativeFamily | undefined;
@@ -0,0 +1,31 @@
1
+ const ELF = Buffer.from([0x7f, 0x45, 0x4c, 0x46]);
2
+ const PE = Buffer.from([0x4d, 0x5a]);
3
+ const MACHO = [
4
+ Buffer.from([0xcf, 0xfa, 0xed, 0xfe]),
5
+ Buffer.from([0xfe, 0xed, 0xfa, 0xcf]),
6
+ Buffer.from([0xce, 0xfa, 0xed, 0xfe]),
7
+ Buffer.from([0xfe, 0xed, 0xfa, 0xce]),
8
+ Buffer.from([0xca, 0xfe, 0xba, 0xbe]),
9
+ Buffer.from([0xbe, 0xba, 0xfe, 0xca]),
10
+ ];
11
+ function startsWith(buffer, magic) {
12
+ return buffer.length >= magic.length && buffer.subarray(0, magic.length).equals(magic);
13
+ }
14
+ export function nativeFamilyFromMagic(buffer) {
15
+ if (startsWith(buffer, ELF))
16
+ return 'elf';
17
+ if (MACHO.some((magic) => startsWith(buffer, magic)))
18
+ return 'macho';
19
+ if (startsWith(buffer, PE))
20
+ return 'pe';
21
+ return undefined;
22
+ }
23
+ export function expectedNativeFamily(platform = process.platform) {
24
+ if (platform === 'linux')
25
+ return 'elf';
26
+ if (platform === 'darwin')
27
+ return 'macho';
28
+ if (platform === 'win32')
29
+ return 'pe';
30
+ return undefined;
31
+ }
@@ -1,8 +1,5 @@
1
- export type NativeFamily = 'elf' | 'macho' | 'pe';
2
- export declare function nativeFamilyFromMagic(buffer: Buffer): NativeFamily | undefined;
3
- export declare function expectedNativeFamily(platform?: NodeJS.Platform): NativeFamily | undefined;
1
+ export { expectedNativeFamily, nativeFamilyFromMagic } from './native-family.mts';
4
2
  declare function packageExcludesPlatform(owner: string, platform: string): Promise<boolean>;
5
3
  export declare function mismatchedNativeBinaries(root?: string, platform?: NodeJS.Platform, readPackageExclusion?: typeof packageExcludesPlatform): Promise<string[]>;
6
4
  export declare function nativeBinariesMatchRuntime(root?: string, platform?: NodeJS.Platform): Promise<boolean>;
7
5
  export declare function repairedNativeBinariesMatchRuntime(paths: string[], platform?: NodeJS.Platform): Promise<boolean>;
8
- export {};
@@ -1,36 +1,7 @@
1
1
  import { glob, open, readFile, stat } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
- const ELF = Buffer.from([0x7f, 0x45, 0x4c, 0x46]);
4
- const PE = Buffer.from([0x4d, 0x5a]);
5
- const MACHO = [
6
- Buffer.from([0xcf, 0xfa, 0xed, 0xfe]),
7
- Buffer.from([0xfe, 0xed, 0xfa, 0xcf]),
8
- Buffer.from([0xce, 0xfa, 0xed, 0xfe]),
9
- Buffer.from([0xfe, 0xed, 0xfa, 0xce]),
10
- Buffer.from([0xca, 0xfe, 0xba, 0xbe]),
11
- Buffer.from([0xbe, 0xba, 0xfe, 0xca]),
12
- ];
13
- function startsWith(buffer, magic) {
14
- return buffer.length >= magic.length && buffer.subarray(0, magic.length).equals(magic);
15
- }
16
- export function nativeFamilyFromMagic(buffer) {
17
- if (startsWith(buffer, ELF))
18
- return 'elf';
19
- if (MACHO.some((magic) => startsWith(buffer, magic)))
20
- return 'macho';
21
- if (startsWith(buffer, PE))
22
- return 'pe';
23
- return undefined;
24
- }
25
- export function expectedNativeFamily(platform = process.platform) {
26
- if (platform === 'linux')
27
- return 'elf';
28
- if (platform === 'darwin')
29
- return 'macho';
30
- if (platform === 'win32')
31
- return 'pe';
32
- return undefined;
33
- }
3
+ import { expectedNativeFamily, nativeFamilyFromMagic } from './native-family.mjs';
4
+ export { expectedNativeFamily, nativeFamilyFromMagic } from './native-family.mjs';
34
5
  async function readMagic(pathname) {
35
6
  let handle;
36
7
  try {
@@ -0,0 +1,2 @@
1
+ import type { CommandResult, RetrospectiveFactsOptions } from './shared.mts';
2
+ export declare function mergeFact(data: Record<string, unknown> | undefined, state: string, merge: string | undefined, range: string | undefined, originMain: boolean, options: RetrospectiveFactsOptions, run: (command: string, args: string[]) => Promise<CommandResult>): Promise<string>;
@@ -0,0 +1,21 @@
1
+ export async function mergeFact(data, state, merge, range, originMain, options, run) {
2
+ if (merge && originMain) {
3
+ const inOrigin = await run('git', ['merge-base', '--is-ancestor', merge, 'origin/main']);
4
+ if (!inOrigin.ok)
5
+ return inOrigin.exitCode === 1 ? `no (origin/main lacks ${merge})` : 'unavailable';
6
+ const inLocalMain = await run('git', ['merge-base', '--is-ancestor', merge, 'main']);
7
+ if (!inLocalMain.ok && inLocalMain.exitCode === 1)
8
+ options.onWarning?.(`Warning: local main lacks PR merge commit ${merge}, but origin/main contains it.`);
9
+ return `yes (origin/main contains ${merge})`;
10
+ }
11
+ if (data && (state === 'OPEN' || state === 'CLOSED'))
12
+ return 'unmerged at time of retro';
13
+ if (!data && range && originMain) {
14
+ const rangeInOrigin = await run('git', ['merge-base', '--is-ancestor', range, 'origin/main']);
15
+ if (rangeInOrigin.ok)
16
+ return `yes (origin/main contains ${range})`;
17
+ if (rangeInOrigin.exitCode === 1)
18
+ return `no (origin/main lacks ${range})`;
19
+ }
20
+ return 'unavailable';
21
+ }
@@ -1,5 +1,6 @@
1
1
  import { rawBlock } from './exec.mjs';
2
2
  import { apiFiles, count, dirs, format, objectField, readJson, stringField, topDirs, } from './format.mjs';
3
+ import { mergeFact } from './local-merge.mjs';
3
4
  import { PR_JSON_FIELDS, } from './shared.mjs';
4
5
  export async function localFacts(options, execute) {
5
6
  const calls = [];
@@ -121,24 +122,3 @@ async function resolveNamedRef(name, run, fetched = false) {
121
122
  function unresolvedRange() {
122
123
  return { range: undefined, refreshed: false };
123
124
  }
124
- async function mergeFact(data, state, merge, range, originMain, options, run) {
125
- if (merge && originMain) {
126
- const inOrigin = await run('git', ['merge-base', '--is-ancestor', merge, 'origin/main']);
127
- if (!inOrigin.ok)
128
- return inOrigin.exitCode === 1 ? `no (origin/main lacks ${merge})` : 'unavailable';
129
- const inLocalMain = await run('git', ['merge-base', '--is-ancestor', merge, 'main']);
130
- if (!inLocalMain.ok && inLocalMain.exitCode === 1)
131
- options.onWarning?.(`Warning: local main lacks PR merge commit ${merge}, but origin/main contains it.`);
132
- return `yes (origin/main contains ${merge})`;
133
- }
134
- if (data && (state === 'OPEN' || state === 'CLOSED'))
135
- return 'unmerged at time of retro';
136
- if (!data && range && originMain) {
137
- const rangeInOrigin = await run('git', ['merge-base', '--is-ancestor', range, 'origin/main']);
138
- if (rangeInOrigin.ok)
139
- return `yes (origin/main contains ${range})`;
140
- if (rangeInOrigin.exitCode === 1)
141
- return `no (origin/main lacks ${range})`;
142
- }
143
- return 'unavailable';
144
- }
@@ -0,0 +1,3 @@
1
+ import { type ParsedLine, type TranscriptFacts } from './shared.mts';
2
+ export declare function applyAssistantUsage(record: ParsedLine, message: ParsedLine | undefined, subagent: boolean, facts: TranscriptFacts): void;
3
+ export declare function applyToolBlocks(message: ParsedLine | undefined, subagent: boolean, facts: TranscriptFacts, advisorIds: Set<string>): void;
@@ -0,0 +1,38 @@
1
+ import { applyCommand, asNumber, asRecord, } from './shared.mjs';
2
+ export function applyAssistantUsage(record, message, subagent, facts) {
3
+ if (record.type === 'assistant') {
4
+ if (!subagent)
5
+ facts.assistantResponses++;
6
+ const usage = asRecord(message?.usage);
7
+ const totals = subagent ? facts.subagentTokens : facts.tokens;
8
+ totals.input += asNumber(usage?.input_tokens);
9
+ totals.output += asNumber(usage?.output_tokens);
10
+ totals.cacheRead += asNumber(usage?.cache_read_input_tokens);
11
+ totals.cacheCreation += asNumber(usage?.cache_creation_input_tokens);
12
+ }
13
+ }
14
+ export function applyToolBlocks(message, subagent, facts, advisorIds) {
15
+ const blocks = Array.isArray(message?.content) ? message.content : [];
16
+ for (const block of blocks) {
17
+ const value = asRecord(block);
18
+ if (!value)
19
+ continue;
20
+ if (value.type === 'tool_use' || value.type === 'server_tool_use') {
21
+ facts.toolCalls++;
22
+ if (subagent)
23
+ facts.subagentToolCalls++;
24
+ if (value.name === 'advisor' && typeof value.id === 'string')
25
+ advisorIds.add(value.id);
26
+ if (value.name === 'Bash' || value.name === 'bash') {
27
+ const command = asRecord(value.input)?.command;
28
+ if (typeof command === 'string')
29
+ applyCommand(command, facts);
30
+ }
31
+ }
32
+ else if ((value.type === 'tool_result' && value.is_error === true) ||
33
+ (typeof value.type === 'string' && value.type.endsWith('_tool_result_error')))
34
+ facts.failedToolCalls++;
35
+ else if (value.type === 'advisor_tool_result' && typeof value.tool_use_id === 'string')
36
+ advisorIds.add(value.tool_use_id);
37
+ }
38
+ }