@qawolf/api-contracts 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 (86) hide show
  1. package/dist/v1/automate/index.d.ts +1 -1
  2. package/dist/v1/automate/index.d.ts.map +1 -1
  3. package/dist/v1/automate/index.js +3 -3
  4. package/dist/v1/automate/index.js.map +1 -1
  5. package/dist/v1/environment/find.d.ts +1 -0
  6. package/dist/v1/environment/find.d.ts.map +1 -1
  7. package/dist/v1/environment/getVariable.d.ts +19 -0
  8. package/dist/v1/environment/getVariable.d.ts.map +1 -0
  9. package/dist/v1/environment/getVariable.js +34 -0
  10. package/dist/v1/environment/getVariable.js.map +1 -0
  11. package/dist/v1/environment/index.d.ts +3 -1
  12. package/dist/v1/environment/index.d.ts.map +1 -1
  13. package/dist/v1/environment/index.js +1 -1
  14. package/dist/v1/environment/index.js.map +1 -1
  15. package/dist/v1/environment/resource.d.ts +1 -0
  16. package/dist/v1/environment/resource.d.ts.map +1 -1
  17. package/dist/v1/environment/resource.js +3 -0
  18. package/dist/v1/environment/resource.js.map +1 -1
  19. package/dist/v1/environment/update.d.ts +39 -0
  20. package/dist/v1/environment/update.d.ts.map +1 -0
  21. package/dist/v1/environment/update.js +38 -0
  22. package/dist/v1/environment/update.js.map +1 -0
  23. package/dist/v1/flow/index.d.ts +4 -0
  24. package/dist/v1/flow/index.d.ts.map +1 -1
  25. package/dist/v1/flow/index.js +2 -0
  26. package/dist/v1/flow/index.js.map +1 -1
  27. package/dist/v1/flow/readiness.d.ts +12 -0
  28. package/dist/v1/flow/readiness.d.ts.map +1 -0
  29. package/dist/v1/flow/readiness.js +12 -0
  30. package/dist/v1/flow/readiness.js.map +1 -0
  31. package/dist/v1/flow/update.d.ts +28 -0
  32. package/dist/v1/flow/update.d.ts.map +1 -0
  33. package/dist/v1/flow/update.js +26 -0
  34. package/dist/v1/flow/update.js.map +1 -0
  35. package/dist/v1/index.d.ts +429 -6
  36. package/dist/v1/index.d.ts.map +1 -1
  37. package/dist/v1/index.js +31 -0
  38. package/dist/v1/index.js.map +1 -1
  39. package/dist/v1/run/get.d.ts +1 -1
  40. package/dist/v1/run/get.d.ts.map +1 -1
  41. package/dist/v1/run/get.js +3 -0
  42. package/dist/v1/run/get.js.map +1 -1
  43. package/dist/v1/run/summary.d.ts.map +1 -1
  44. package/dist/v1/run/summary.js +3 -0
  45. package/dist/v1/run/summary.js.map +1 -1
  46. package/dist/v1/runner/environment.d.ts +4 -0
  47. package/dist/v1/runner/environment.d.ts.map +1 -0
  48. package/dist/v1/runner/environment.js +46 -0
  49. package/dist/v1/runner/environment.js.map +1 -0
  50. package/dist/v1/runner/evaluateSnippet.d.ts +24 -0
  51. package/dist/v1/runner/evaluateSnippet.d.ts.map +1 -0
  52. package/dist/v1/runner/evaluateSnippet.js +54 -0
  53. package/dist/v1/runner/evaluateSnippet.js.map +1 -0
  54. package/dist/v1/runner/files.d.ts +26 -0
  55. package/dist/v1/runner/files.d.ts.map +1 -0
  56. package/dist/v1/runner/files.js +65 -0
  57. package/dist/v1/runner/files.js.map +1 -0
  58. package/dist/v1/runner/identity.d.ts +21 -0
  59. package/dist/v1/runner/identity.d.ts.map +1 -0
  60. package/dist/v1/runner/identity.js +21 -0
  61. package/dist/v1/runner/identity.js.map +1 -0
  62. package/dist/v1/runner/index.d.ts +45 -0
  63. package/dist/v1/runner/index.d.ts.map +1 -0
  64. package/dist/v1/runner/index.js +41 -0
  65. package/dist/v1/runner/index.js.map +1 -0
  66. package/dist/v1/runner/journal.d.ts +104 -0
  67. package/dist/v1/runner/journal.d.ts.map +1 -0
  68. package/dist/v1/runner/journal.js +52 -0
  69. package/dist/v1/runner/journal.js.map +1 -0
  70. package/dist/v1/runner/payloadSize.d.ts +27 -0
  71. package/dist/v1/runner/payloadSize.d.ts.map +1 -0
  72. package/dist/v1/runner/payloadSize.js +49 -0
  73. package/dist/v1/runner/payloadSize.js.map +1 -0
  74. package/dist/v1/runner/readJournal.d.ts +31 -0
  75. package/dist/v1/runner/readJournal.d.ts.map +1 -0
  76. package/dist/v1/runner/readJournal.js +22 -0
  77. package/dist/v1/runner/readJournal.js.map +1 -0
  78. package/dist/v1/runner/runFlow.d.ts +33 -0
  79. package/dist/v1/runner/runFlow.d.ts.map +1 -0
  80. package/dist/v1/runner/runFlow.js +48 -0
  81. package/dist/v1/runner/runFlow.js.map +1 -0
  82. package/dist/v1/runner/unreachable.d.ts +16 -0
  83. package/dist/v1/runner/unreachable.d.ts.map +1 -0
  84. package/dist/v1/runner/unreachable.js +16 -0
  85. package/dist/v1/runner/unreachable.js.map +1 -0
  86. package/package.json +6 -6
package/dist/v1/index.js CHANGED
@@ -1,12 +1,29 @@
1
1
  export { identityResponse } from "./identity/index.js";
2
2
  export { defaultIdSchemas, } from "./ids.js";
3
3
  export { makeFlowSelectionSchema } from "./run/index.js";
4
+ // Carries the reservation of QA Wolf's own variable names, which the server
5
+ // validates with rather than restating — a second copy of that rule is how the
6
+ // reservation comes to differ from what is actually stamped.
7
+ export { runEnvironmentSchema } from "./runner/environment.js";
8
+ // The travel rule for files bound for a runner: which files travel, how much may
9
+ // travel, and what environment a run may carry. A client needs the predicate and
10
+ // the size bounds to collect and pre-check with; the schemas are also what the
11
+ // server and the runner validate with, so they are shared rather than restated.
12
+ export { isShippableRunFilePath, runFilePathSchema, runPackageJsonPath, shippableRunFileExtensions, } from "./runner/files.js";
13
+ export { makeRunnerSchema, runnerIdSchema, runnerNameSchema, } from "./runner/identity.js";
14
+ // A journal read is answered verbatim by the public API, so its wire shapes are
15
+ // published here and the private journal package imports them from here.
16
+ export { journalEntrySchema, journalStreamSchema, knownJournalStreams, maxJournalStreamNameLength, readJournalRequestSchema, readJournalResponseSchema, } from "./runner/journal.js";
17
+ export { maxRunFilesByteLength, maxRunnerRequestEncodedByteLength, runFilesByteLength, runFilesSchema, } from "./runner/payloadSize.js";
4
18
  import { makeAutomateContract } from "./automate/index.js";
5
19
  import { makeDeleteEnvironmentVariableContract } from "./environment/deleteVariable.js";
6
20
  import { makeFindEnvironmentsContract } from "./environment/find.js";
21
+ import { makeGetEnvironmentVariableContract } from "./environment/getVariable.js";
7
22
  import { makeCreateEnvironmentContract, makeGetEnvironmentContract, makeListEnvironmentVariableNamesContract, makeSetEnvironmentVariableContract, } from "./environment/index.js";
23
+ import { makeUpdateEnvironmentContract } from "./environment/update.js";
8
24
  import { makeAddTagToFlowsContract } from "./flow/addTag.js";
9
25
  import { makeListFlowsContract } from "./flow/index.js";
26
+ import { makeUpdateFlowContract } from "./flow/update.js";
10
27
  import { defaultIdSchemas, } from "./ids.js";
11
28
  import { makeCreateIssueContract } from "./issue/create.js";
12
29
  import { makeFindIssuesContract, makeGetIssueContract } from "./issue/index.js";
@@ -14,6 +31,10 @@ import { makeUpdateIssueContract } from "./issue/update.js";
14
31
  import { makeFindRunsContract } from "./run/find.js";
15
32
  import { makeGetRunContract } from "./run/get.js";
16
33
  import { makeCreateRunContract } from "./run/index.js";
34
+ import { makeEvaluateSnippetOnRunnerContract } from "./runner/evaluateSnippet.js";
35
+ import { makeLaunchRunnerContract, makeStopRunnerContract, } from "./runner/index.js";
36
+ import { makeReadRunnerJournalContract } from "./runner/readJournal.js";
37
+ import { makeRunFlowOnRunnerContract } from "./runner/runFlow.js";
17
38
  import { makeCreateTagContract } from "./tag/index.js";
18
39
  import { makeListTagsContract } from "./tag/list.js";
19
40
  /**
@@ -34,12 +55,15 @@ export const makeContractsV1 = (ids) => {
34
55
  deleteVariable: makeDeleteEnvironmentVariableContract(resolvedIds),
35
56
  find: makeFindEnvironmentsContract(resolvedIds),
36
57
  get: makeGetEnvironmentContract(resolvedIds),
58
+ getVariable: makeGetEnvironmentVariableContract(resolvedIds),
37
59
  listVariableNames: makeListEnvironmentVariableNamesContract(resolvedIds),
38
60
  setVariable: makeSetEnvironmentVariableContract(resolvedIds),
61
+ update: makeUpdateEnvironmentContract(resolvedIds),
39
62
  },
40
63
  flow: {
41
64
  addTag: makeAddTagToFlowsContract(resolvedIds),
42
65
  list: makeListFlowsContract(resolvedIds),
66
+ update: makeUpdateFlowContract(resolvedIds),
43
67
  },
44
68
  issue: {
45
69
  create: makeCreateIssueContract(resolvedIds),
@@ -52,6 +76,13 @@ export const makeContractsV1 = (ids) => {
52
76
  find: makeFindRunsContract(resolvedIds),
53
77
  get: makeGetRunContract(resolvedIds),
54
78
  },
79
+ runner: {
80
+ evaluateSnippet: makeEvaluateSnippetOnRunnerContract(),
81
+ launch: makeLaunchRunnerContract(),
82
+ readJournal: makeReadRunnerJournalContract(),
83
+ runFlow: makeRunFlowOnRunnerContract(),
84
+ stop: makeStopRunnerContract(),
85
+ },
55
86
  tag: {
56
87
  create: makeCreateTagContract(),
57
88
  list: makeListTagsContract(resolvedIds),
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/v1/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAyB,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAGL,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAE,qCAAqC,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EACL,6BAA6B,EAC7B,0BAA0B,EAC1B,wCAAwC,EACxC,kCAAkC,GACnC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAGL,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAUrD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAQ7B,GAOC,EACD,EAAE;IACF,MAAM,WAAW,GAAG,EAAE,GAAG,gBAAgB,EAAE,GAAG,GAAG,EAAE,CAAC;IACpD,OAAO;QACL,qEAAqE;QACrE,0CAA0C;QAC1C,QAAQ,EAAE,oBAAoB,CAAC,WAAW,CAAC;QAC3C,WAAW,EAAE;YACX,MAAM,EAAE,6BAA6B,CAAC,WAAW,CAAC;YAClD,cAAc,EAAE,qCAAqC,CAAC,WAAW,CAAC;YAClE,IAAI,EAAE,4BAA4B,CAAC,WAAW,CAAC;YAC/C,GAAG,EAAE,0BAA0B,CAAC,WAAW,CAAC;YAC5C,iBAAiB,EAAE,wCAAwC,CAAC,WAAW,CAAC;YACxE,WAAW,EAAE,kCAAkC,CAAC,WAAW,CAAC;SAC7D;QACD,IAAI,EAAE;YACJ,MAAM,EAAE,yBAAyB,CAAC,WAAW,CAAC;YAC9C,IAAI,EAAE,qBAAqB,CAAC,WAAW,CAAC;SACzC;QACD,KAAK,EAAE;YACL,MAAM,EAAE,uBAAuB,CAAC,WAAW,CAAC;YAC5C,IAAI,EAAE,sBAAsB,CAAC,WAAW,CAAC;YACzC,GAAG,EAAE,oBAAoB,CAAC,WAAW,CAAC;YACtC,MAAM,EAAE,uBAAuB,CAAC,WAAW,CAAC;SAC7C;QACD,GAAG,EAAE;YACH,MAAM,EAAE,qBAAqB,CAAC,WAAW,CAAC;YAC1C,IAAI,EAAE,oBAAoB,CAAC,WAAW,CAAC;YACvC,GAAG,EAAE,kBAAkB,CAAC,WAAW,CAAC;SACrC;QACD,GAAG,EAAE;YACH,MAAM,EAAE,qBAAqB,EAAE;YAC/B,IAAI,EAAE,oBAAoB,CAAC,WAAW,CAAC;SACxC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/v1/index.ts"],"names":[],"mappings":"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"}
@@ -29,6 +29,7 @@ export declare const makeGetRunContract: <FlowId extends PublicIdSchema, RunId e
29
29
  passed: "passed";
30
30
  }>;
31
31
  }, z.core.$strip>], "status">>;
32
+ runId: RunId;
32
33
  completedAt: z.ZodOptional<z.ZodISODateTime>;
33
34
  createdAt: z.ZodISODateTime;
34
35
  git: z.ZodObject<{
@@ -37,7 +38,6 @@ export declare const makeGetRunContract: <FlowId extends PublicIdSchema, RunId e
37
38
  commitSha: z.ZodOptional<z.ZodString>;
38
39
  commitUrl: z.ZodOptional<z.ZodString>;
39
40
  }, z.core.$strip>;
40
- runId: RunId;
41
41
  status: z.ZodEnum<{
42
42
  running: "running";
43
43
  canceled: "canceled";
@@ -1 +1 @@
1
- {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/v1/run/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAKhD,eAAO,MAAM,kBAAkB,GAC7B,MAAM,SAAS,cAAc,EAC7B,KAAK,SAAS,cAAc,EAC5B,KAAK;IACL,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,KAAK,CAAC;CACZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6DA,CAAC"}
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/v1/run/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAKhD,eAAO,MAAM,kBAAkB,GAC7B,MAAM,SAAS,cAAc,EAC7B,KAAK,SAAS,cAAc,EAC5B,KAAK;IACL,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,KAAK,CAAC;CACZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkEA,CAAC"}
@@ -43,6 +43,9 @@ export const makeGetRunContract = (ids) => {
43
43
  const output = resource({
44
44
  ...makeRunSummaryFields(ids),
45
45
  flows,
46
+ // Overrides the shared field: only this endpoint takes a run id, so only
47
+ // here can the answer describe a different run than the one requested.
48
+ runId: ids.run.describe("The run this response describes. Treat it as canonical: it can differ from the id you asked for. A deploy notification returns a run id before the run exists, and if a second notification for the same commit is folded into an earlier run, that id resolves to the earlier run instead."),
46
49
  }, { urlFieldDescription: "Absolute URL of the run page." });
47
50
  return {
48
51
  description: "Get a run's status, per-flow results, and links.",
@@ -1 +1 @@
1
- {"version":3,"file":"get.js","sourceRoot":"","sources":["../../../src/v1/run/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAGhC,GAID,EAAE,EAAE;IACH,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;QACrB,KAAK,EAAE,GAAG,CAAC,GAAG;KACf,CAAC,CAAC;IAEH,0EAA0E;IAC1E,8EAA8E;IAC9E,yEAAyE;IACzE,0EAA0E;IAC1E,4EAA4E;IAC5E,sEAAsE;IACtE,4BAA4B;IAC5B,0EAA0E;IAC1E,8EAA8E;IAC9E,4EAA4E;IAC5E,iEAAiE;IACjE,2EAA2E;IAC3E,4CAA4C;IAC5C,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;QAC1B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;YAChB,0EAA0E;YAC1E,2EAA2E;YAC3E,yEAAyE;YACzE,+DAA+D;YAC/D,oEAAoE;YACpE,oDAAoD;YACpD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;SAClB,CAAC;QACF,MAAM,EAAE,GAAG,CAAC,IAAI;QAChB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;KAC5B,CAAC,CAAC;IACH,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;QAC7B,MAAM,EAAE,GAAG,CAAC,IAAI;QAChB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;KAC5D,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,CAAC;SACZ,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;SAClE,QAAQ,CAAC,kDAAkD,CAAC,CAAC;IAEhE,MAAM,MAAM,GAAG,QAAQ,CACrB;QACE,GAAG,oBAAoB,CAAC,GAAG,CAAC;QAC5B,KAAK;KACN,EACD,EAAE,mBAAmB,EAAE,+BAA+B,EAAE,CACzD,CAAC;IAEF,OAAO;QACL,WAAW,EAAE,kDAAkD;QAC/D,KAAK;QACL,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,SAAS;QACf,MAAM;KAMP,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../../src/v1/run/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAGhC,GAID,EAAE,EAAE;IACH,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;QACrB,KAAK,EAAE,GAAG,CAAC,GAAG;KACf,CAAC,CAAC;IAEH,0EAA0E;IAC1E,8EAA8E;IAC9E,yEAAyE;IACzE,0EAA0E;IAC1E,4EAA4E;IAC5E,sEAAsE;IACtE,4BAA4B;IAC5B,0EAA0E;IAC1E,8EAA8E;IAC9E,4EAA4E;IAC5E,iEAAiE;IACjE,2EAA2E;IAC3E,4CAA4C;IAC5C,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;QAC1B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;YAChB,0EAA0E;YAC1E,2EAA2E;YAC3E,yEAAyE;YACzE,+DAA+D;YAC/D,oEAAoE;YACpE,oDAAoD;YACpD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;SAClB,CAAC;QACF,MAAM,EAAE,GAAG,CAAC,IAAI;QAChB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;KAC5B,CAAC,CAAC;IACH,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;QAC7B,MAAM,EAAE,GAAG,CAAC,IAAI;QAChB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;KAC5D,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,CAAC;SACZ,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;SAClE,QAAQ,CAAC,kDAAkD,CAAC,CAAC;IAEhE,MAAM,MAAM,GAAG,QAAQ,CACrB;QACE,GAAG,oBAAoB,CAAC,GAAG,CAAC;QAC5B,KAAK;QACL,yEAAyE;QACzE,uEAAuE;QACvE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,CACrB,6RAA6R,CAC9R;KACF,EACD,EAAE,mBAAmB,EAAE,+BAA+B,EAAE,CACzD,CAAC;IAEF,OAAO;QACL,WAAW,EAAE,kDAAkD;QAC/D,KAAK;QACL,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,SAAS;QACf,MAAM;KAMP,CAAC;AACJ,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../../src/v1/run/summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAKhD,eAAO,MAAM,oBAAoB,GAAI,KAAK,SAAS,cAAc,EAAE,KAAK;IACtE,GAAG,EAAE,KAAK,CAAC;CACZ;;;;;;;;;;;;;;;;;CA+BC,CAAC"}
1
+ {"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../../src/v1/run/summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAKhD,eAAO,MAAM,oBAAoB,GAAI,KAAK,SAAS,cAAc,EAAE,KAAK;IACtE,GAAG,EAAE,KAAK,CAAC;CACZ;;;;;;;;;;;;;;;;;CAkCC,CAAC"}
@@ -23,6 +23,9 @@ export const makeRunSummaryFields = (ids) => ({
23
23
  .describe("Link to the commit on the code host."),
24
24
  })
25
25
  .describe("The branch and commit under test. The fields are present when a deploy notification started the run, and absent for runs started another way, for example manually or with run.create."),
26
+ // Deliberately not described here: run.find builds its rows from this factory
27
+ // too, and its rows answer no requested id, so wording about the id you asked
28
+ // for belongs on run.get alone.
26
29
  runId: ids.run,
27
30
  status: z
28
31
  .enum(["queued", "running", "passed", "failed", "canceled"])
@@ -1 +1 @@
1
- {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../../src/v1/run/summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,6EAA6E;AAC7E,2EAA2E;AAC3E,sCAAsC;AACtC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAA+B,GAElE,EAAE,EAAE,CAAC,CAAC;IACL,WAAW,EAAE,CAAC,CAAC,GAAG;SACf,QAAQ,EAAE;SACV,QAAQ,EAAE;SACV,QAAQ,CACP,+KAA+K,CAChL;IACH,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE;IAC3B,GAAG,EAAE,CAAC;SACH,MAAM,CAAC;QACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC7B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACpC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAChC,wEAAwE;QACxE,uEAAuE;QACvE,sEAAsE;QACtE,mDAAmD;QACnD,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,sCAAsC,CAAC;KACpD,CAAC;SACD,QAAQ,CACP,wLAAwL,CACzL;IACH,KAAK,EAAE,GAAG,CAAC,GAAG;IACd,MAAM,EAAE,CAAC;SACN,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;SAC3D,QAAQ,CACP,kGAAkG,CACnG;CACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../../src/v1/run/summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,6EAA6E;AAC7E,2EAA2E;AAC3E,sCAAsC;AACtC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAA+B,GAElE,EAAE,EAAE,CAAC,CAAC;IACL,WAAW,EAAE,CAAC,CAAC,GAAG;SACf,QAAQ,EAAE;SACV,QAAQ,EAAE;SACV,QAAQ,CACP,+KAA+K,CAChL;IACH,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE;IAC3B,GAAG,EAAE,CAAC;SACH,MAAM,CAAC;QACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC7B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACpC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAChC,wEAAwE;QACxE,uEAAuE;QACvE,sEAAsE;QACtE,mDAAmD;QACnD,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,sCAAsC,CAAC;KACpD,CAAC;SACD,QAAQ,CACP,wLAAwL,CACzL;IACH,8EAA8E;IAC9E,8EAA8E;IAC9E,gCAAgC;IAChC,KAAK,EAAE,GAAG,CAAC,GAAG;IACd,MAAM,EAAE,CAAC;SACN,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;SAC3D,QAAQ,CACP,kGAAkG,CACnG;CACJ,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { z } from "zod";
2
+ /** Bounded on its own, so a large project is never refused for its environment. */
3
+ export declare const runEnvironmentSchema: z.ZodRecord<z.ZodString, z.ZodString>;
4
+ //# sourceMappingURL=environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../../src/v1/runner/environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkCxB,mFAAmF;AACnF,eAAO,MAAM,oBAAoB,uCAmB9B,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * The environment variables a caller may give a run, and the names they may not.
4
+ */
5
+ /**
6
+ * The prefix QA Wolf reserves for the variables it sets on a run itself. A
7
+ * caller-supplied value under it is refused, and would be overridden anyway.
8
+ */
9
+ const reservedRunEnvironmentVariablePrefix = "QAWOLF_";
10
+ /**
11
+ * A name becomes a name in the run's process environment, so it is held to what
12
+ * a shell accepts — and may not be one of QA Wolf's own. A refusal rather than
13
+ * a key schema, whose message would reach the caller as a bare "invalid key in
14
+ * record".
15
+ */
16
+ function refusalForRunEnvironmentVariableName(name) {
17
+ if (name.length < 1 || name.length > 256)
18
+ return "An environment variable name must be between 1 and 256 characters.";
19
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
20
+ return "An environment variable name may contain only letters, digits and underscores, and must not start with a digit.";
21
+ // Case-insensitively, so the reservation cannot be worked around by case.
22
+ if (name.toUpperCase().startsWith(reservedRunEnvironmentVariablePrefix))
23
+ return `Environment variable names beginning with ${reservedRunEnvironmentVariablePrefix} are reserved by QA Wolf and set for you.`;
24
+ return undefined;
25
+ }
26
+ const maxRunEnvironmentVariables = 100;
27
+ const maxRunEnvironmentValueLength = 8 * 1024;
28
+ /** Bounded on its own, so a large project is never refused for its environment. */
29
+ export const runEnvironmentSchema = z
30
+ .record(z.string(), z.string().max(maxRunEnvironmentValueLength))
31
+ .superRefine((environment, refinementContext) => {
32
+ for (const name of Object.keys(environment)) {
33
+ const refusal = refusalForRunEnvironmentVariableName(name);
34
+ if (refusal === undefined)
35
+ continue;
36
+ refinementContext.addIssue({
37
+ code: "custom",
38
+ message: refusal,
39
+ path: [name],
40
+ });
41
+ }
42
+ })
43
+ .refine((environment) => Object.keys(environment).length <= maxRunEnvironmentVariables, {
44
+ error: `At most ${maxRunEnvironmentVariables} environment variables may be supplied.`,
45
+ });
46
+ //# sourceMappingURL=environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../../src/v1/runner/environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AAEH;;;GAGG;AACH,MAAM,oCAAoC,GAAG,SAAS,CAAC;AAEvD;;;;;GAKG;AACH,SAAS,oCAAoC,CAC3C,IAAY;IAEZ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG;QACtC,OAAO,oEAAoE,CAAC;IAC9E,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC;QACxC,OAAO,iHAAiH,CAAC;IAC3H,0EAA0E;IAC1E,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,oCAAoC,CAAC;QACrE,OAAO,6CAA6C,oCAAoC,2CAA2C,CAAC;IACtI,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,0BAA0B,GAAG,GAAG,CAAC;AACvC,MAAM,4BAA4B,GAAG,CAAC,GAAG,IAAI,CAAC;AAE9C,mFAAmF;AACnF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC;KAClC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;KAChE,WAAW,CAAC,CAAC,WAAW,EAAE,iBAAiB,EAAE,EAAE;IAC9C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,oCAAoC,CAAC,IAAI,CAAC,CAAC;QAC3D,IAAI,OAAO,KAAK,SAAS;YAAE,SAAS;QACpC,iBAAiB,CAAC,QAAQ,CAAC;YACzB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,CAAC,IAAI,CAAC;SACb,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC;KACD,MAAM,CACL,CAAC,WAAW,EAAE,EAAE,CACd,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,IAAI,0BAA0B,EAC/D;IACE,KAAK,EAAE,WAAW,0BAA0B,yCAAyC;CACtF,CACF,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+ export declare const makeEvaluateSnippetOnRunnerContract: () => {
3
+ readonly description: "Evaluate a snippet against whatever the runner's browser is showing right now. Answers whether the snippet ran, and its error if it threw — not the value it evaluated to, so read anything you want back out of the runner's journal (a snippet's `console.log` lands in the `console` stream). A snippet starts no run and leaves no run-scoped journal entries of its own. `runner-unreachable` if the runner could not be reached or could not evaluate: as well as a runner that is still starting, has terminated after inactivity, or is busy, this covers a runner with no live page to evaluate against — which will never clear, so check that the runner you launched is one that runs a browser before retrying. It is NOT proof the snippet did not run: a snippet that outlives the answer window is still executing when you read this, so do not blindly resubmit one that mutates what the page is looking at.";
4
+ readonly input: z.ZodObject<{
5
+ code: z.ZodString;
6
+ filePath: z.ZodOptional<z.ZodString>;
7
+ files: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
8
+ id: z.ZodString;
9
+ }, z.core.$strip>;
10
+ readonly kind: "write";
11
+ readonly name: "runner.evaluateSnippet";
12
+ readonly output: z.ZodDiscriminatedUnion<[z.ZodObject<{
13
+ errorMessage: z.ZodOptional<z.ZodString>;
14
+ outcome: z.ZodLiteral<"evaluated">;
15
+ result: z.ZodEnum<{
16
+ success: "success";
17
+ error: "error";
18
+ stopped: "stopped";
19
+ }>;
20
+ }, z.core.$strip>, z.ZodObject<{
21
+ outcome: z.ZodLiteral<"runner-unreachable">;
22
+ }, z.core.$strip>], "outcome">;
23
+ };
24
+ //# sourceMappingURL=evaluateSnippet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluateSnippet.d.ts","sourceRoot":"","sources":["../../../src/v1/runner/evaluateSnippet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;CA+D/C,CAAC"}
@@ -0,0 +1,54 @@
1
+ import { z } from "zod";
2
+ import { runFilePathSchema } from "./files.js";
3
+ import { runnerIdSchema } from "./identity.js";
4
+ import { runFilesSchema } from "./payloadSize.js";
5
+ import { runnerUnreachableSchema } from "./unreachable.js";
6
+ /**
7
+ * A snippet is one expression or a handful of statements, not a program: it is
8
+ * bounded so a caller cannot smuggle a whole project through as code instead of
9
+ * as files, where the travel rule applies.
10
+ */
11
+ const maxSnippetCodeLength = 64 * 1024;
12
+ export const makeEvaluateSnippetOnRunnerContract = () => {
13
+ const input = z
14
+ .object({
15
+ code: z
16
+ .string()
17
+ .min(1)
18
+ .max(maxSnippetCodeLength)
19
+ .describe("The code to evaluate against the runner's live page, in the scope of `filePath` when one is given."),
20
+ filePath: runFilePathSchema
21
+ .optional()
22
+ .describe("Path of the file the snippet is evaluated in the scope of. Omit to evaluate a snippet that imports nothing of yours."),
23
+ files: runFilesSchema
24
+ .optional()
25
+ .describe("The file named by `filePath` and everything it imports. A runner holds no copy of your project, so a snippet's scope has to travel with it."),
26
+ id: runnerIdSchema.describe("Id of the runner to evaluate the snippet on."),
27
+ })
28
+ .refine((request) => request.filePath === undefined ||
29
+ Object.hasOwn(request.files ?? {}, request.filePath), {
30
+ error: "A snippet naming a file must carry that file in files.",
31
+ path: ["files"],
32
+ });
33
+ const output = z.discriminatedUnion("outcome", [
34
+ z.object({
35
+ errorMessage: z
36
+ .string()
37
+ .optional()
38
+ .describe("Present when `result` is `error`."),
39
+ outcome: z.literal("evaluated"),
40
+ result: z
41
+ .enum(["success", "stopped", "error"])
42
+ .describe("`success` if the snippet ran to completion, `stopped` if it was interrupted, `error` if it threw. Whether it ran, not what it evaluated to."),
43
+ }),
44
+ runnerUnreachableSchema,
45
+ ]);
46
+ return {
47
+ description: "Evaluate a snippet against whatever the runner's browser is showing right now. Answers whether the snippet ran, and its error if it threw — not the value it evaluated to, so read anything you want back out of the runner's journal (a snippet's `console.log` lands in the `console` stream). A snippet starts no run and leaves no run-scoped journal entries of its own. `runner-unreachable` if the runner could not be reached or could not evaluate: as well as a runner that is still starting, has terminated after inactivity, or is busy, this covers a runner with no live page to evaluate against — which will never clear, so check that the runner you launched is one that runs a browser before retrying. It is NOT proof the snippet did not run: a snippet that outlives the answer window is still executing when you read this, so do not blindly resubmit one that mutates what the page is looking at.",
48
+ input,
49
+ kind: "write",
50
+ name: "runner.evaluateSnippet",
51
+ output,
52
+ };
53
+ };
54
+ //# sourceMappingURL=evaluateSnippet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluateSnippet.js","sourceRoot":"","sources":["../../../src/v1/runner/evaluateSnippet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE3D;;;;GAIG;AACH,MAAM,oBAAoB,GAAG,EAAE,GAAG,IAAI,CAAC;AAEvC,MAAM,CAAC,MAAM,mCAAmC,GAAG,GAAG,EAAE;IACtD,MAAM,KAAK,GAAG,CAAC;SACZ,MAAM,CAAC;QACN,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,oBAAoB,CAAC;aACzB,QAAQ,CACP,oGAAoG,CACrG;QACH,QAAQ,EAAE,iBAAiB;aACxB,QAAQ,EAAE;aACV,QAAQ,CACP,sHAAsH,CACvH;QACH,KAAK,EAAE,cAAc;aAClB,QAAQ,EAAE;aACV,QAAQ,CACP,6IAA6I,CAC9I;QACH,EAAE,EAAE,cAAc,CAAC,QAAQ,CACzB,8CAA8C,CAC/C;KACF,CAAC;SACD,MAAM,CACL,CAAC,OAAO,EAAE,EAAE,CACV,OAAO,CAAC,QAAQ,KAAK,SAAS;QAC9B,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,OAAO,CAAC,QAAQ,CAAC,EACtD;QACE,KAAK,EAAE,wDAAwD;QAC/D,IAAI,EAAE,CAAC,OAAO,CAAC;KAChB,CACF,CAAC;IAEJ,MAAM,MAAM,GAAG,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE;QAC7C,CAAC,CAAC,MAAM,CAAC;YACP,YAAY,EAAE,CAAC;iBACZ,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,mCAAmC,CAAC;YAChD,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;YAC/B,MAAM,EAAE,CAAC;iBACN,IAAI,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;iBACrC,QAAQ,CACP,6IAA6I,CAC9I;SACJ,CAAC;QACF,uBAAuB;KACxB,CAAC,CAAC;IAEH,OAAO;QACL,WAAW,EACT,i4BAAi4B;QACn4B,KAAK;QACL,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,wBAAwB;QAC9B,MAAM;KAMP,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Which of a project's files travel to a runner. Published so a client collects
4
+ * with exactly what the server validates with; the predicate is the schema
5
+ * asked as a question. How much may travel is in `payloadSize.ts`.
6
+ */
7
+ /**
8
+ * An allowlist, because everything here is written into the run program and
9
+ * some of it is transformed — and one that can be widened later, which a
10
+ * stricter rule could not be.
11
+ */
12
+ export declare const shippableRunFileExtensions: readonly [".cjs", ".js", ".json", ".mjs", ".ts", ".tsx"];
13
+ /** Whether this file travels to a runner. Filter a working tree with it. */
14
+ export declare function isShippableRunFilePath(path: string): boolean;
15
+ /**
16
+ * Exported because `runFilesSchema` checks record keys as a refinement — a key
17
+ * schema's message would reach the caller as a bare "invalid key in record".
18
+ */
19
+ export declare const runFilePathRefusal: string;
20
+ export declare const runFilePathSchema: z.ZodString;
21
+ /**
22
+ * The file a runner reads npm dependencies from. It travels like any other file
23
+ * and is not written to the run program: the runner writes its own.
24
+ */
25
+ export declare const runPackageJsonPath = "package.json";
26
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../src/v1/runner/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AAEH;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,0DAO7B,CAAC;AAuBX,4EAA4E;AAC5E,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAW5D;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAuR,CAAC;AAEvT,eAAO,MAAM,iBAAiB,aAE5B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,iBAAiB,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Which of a project's files travel to a runner. Published so a client collects
4
+ * with exactly what the server validates with; the predicate is the schema
5
+ * asked as a question. How much may travel is in `payloadSize.ts`.
6
+ */
7
+ /**
8
+ * An allowlist, because everything here is written into the run program and
9
+ * some of it is transformed — and one that can be widened later, which a
10
+ * stricter rule could not be.
11
+ */
12
+ export const shippableRunFileExtensions = [
13
+ ".cjs",
14
+ ".js",
15
+ ".json",
16
+ ".mjs",
17
+ ".ts",
18
+ ".tsx",
19
+ ];
20
+ /** A path becomes a filesystem path on the runner, so it is bounded. */
21
+ const maxRunFilePathLength = 1024;
22
+ /**
23
+ * A denylist of what would make the path address somewhere outside the run
24
+ * program: `.`/`..` navigate, a leading dot ships `.env` and `.git`, an empty
25
+ * segment is an absolute or doubled separator, a backslash can smuggle a
26
+ * separator past the check, and control characters confuse the tooling.
27
+ * Everything else — including non-ASCII names — travels.
28
+ */
29
+ function isShippableRunFilePathSegment(segment) {
30
+ if (segment === "" || segment === "." || segment === "..")
31
+ return false;
32
+ if (segment.startsWith("."))
33
+ return false;
34
+ if (segment.includes("\\"))
35
+ return false;
36
+ // eslint-disable-next-line no-control-regex -- refusing control characters is the point
37
+ return !/[\u0000-\u001f\u007f]/.test(segment);
38
+ }
39
+ /** The runner installs dependencies itself, so `node_modules` never ships. */
40
+ const neverShippedPathSegments = new Set(["node_modules"]);
41
+ /** Whether this file travels to a runner. Filter a working tree with it. */
42
+ export function isShippableRunFilePath(path) {
43
+ if (path.length < 1 || path.length > maxRunFilePathLength)
44
+ return false;
45
+ if (!shippableRunFileExtensions.some((extension) => path.endsWith(extension)))
46
+ return false;
47
+ return path
48
+ .split("/")
49
+ .every((segment) => isShippableRunFilePathSegment(segment) &&
50
+ !neverShippedPathSegments.has(segment));
51
+ }
52
+ /**
53
+ * Exported because `runFilesSchema` checks record keys as a refinement — a key
54
+ * schema's message would reach the caller as a bare "invalid key in record".
55
+ */
56
+ export const runFilePathRefusal = `A run file path must end in one of ${shippableRunFileExtensions.join(", ")}, be at most ${maxRunFilePathLength} characters, and be a relative path whose segments are none of: empty, "." or "..", dot-prefixed, "node_modules", or containing a backslash or a control character.`;
57
+ export const runFilePathSchema = z.string().refine(isShippableRunFilePath, {
58
+ error: runFilePathRefusal,
59
+ });
60
+ /**
61
+ * The file a runner reads npm dependencies from. It travels like any other file
62
+ * and is not written to the run program: the runner writes its own.
63
+ */
64
+ export const runPackageJsonPath = "package.json";
65
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../../src/v1/runner/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,MAAM;IACN,KAAK;IACL,OAAO;IACP,MAAM;IACN,KAAK;IACL,MAAM;CACE,CAAC;AAEX,wEAAwE;AACxE,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAElC;;;;;;GAMG;AACH,SAAS,6BAA6B,CAAC,OAAe;IACpD,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACxE,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,wFAAwF;IACxF,OAAO,CAAC,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAChD,CAAC;AAED,8EAA8E;AAC9E,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;AAE3D,4EAA4E;AAC5E,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,oBAAoB;QAAE,OAAO,KAAK,CAAC;IACxE,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC3E,OAAO,KAAK,CAAC;IACf,OAAO,IAAI;SACR,KAAK,CAAC,GAAG,CAAC;SACV,KAAK,CACJ,CAAC,OAAO,EAAE,EAAE,CACV,6BAA6B,CAAC,OAAO,CAAC;QACtC,CAAC,wBAAwB,CAAC,GAAG,CAAC,OAAO,CAAC,CACzC,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,sCAAsC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,oBAAoB,qKAAqK,CAAC;AAEvT,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,sBAAsB,EAAE;IACzE,KAAK,EAAE,kBAAkB;CAC1B,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,cAAc,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ export declare const runnerNameSchema: z.ZodEnum<{
3
+ node20Basic: "node20Basic";
4
+ node20WithAndroid: "node20WithAndroid";
5
+ node20WithIos: "node20WithIos";
6
+ node20WithPlaywright: "node20WithPlaywright";
7
+ }>;
8
+ export type RunnerNameForPublicApi = z.infer<typeof runnerNameSchema>;
9
+ export declare const runnerIdSchema: z.ZodString;
10
+ /** The shared interactive runner shape. */
11
+ export declare const makeRunnerSchema: () => z.ZodObject<{
12
+ gpuAccelerated: z.ZodBoolean;
13
+ id: z.ZodString;
14
+ runnerName: z.ZodEnum<{
15
+ node20Basic: "node20Basic";
16
+ node20WithAndroid: "node20WithAndroid";
17
+ node20WithIos: "node20WithIos";
18
+ node20WithPlaywright: "node20WithPlaywright";
19
+ }>;
20
+ }, z.core.$strip>;
21
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../src/v1/runner/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gBAAgB;;;;;EAK3B,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEtE,eAAO,MAAM,cAAc,aAOxB,CAAC;AAEJ,2CAA2C;AAC3C,eAAO,MAAM,gBAAgB;;;;;;;;;iBAazB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ export const runnerNameSchema = z.enum([
3
+ "node20Basic",
4
+ "node20WithAndroid",
5
+ "node20WithIos",
6
+ "node20WithPlaywright",
7
+ ]);
8
+ export const runnerIdSchema = z
9
+ .string()
10
+ .min(1)
11
+ .max(63)
12
+ .regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/, "A runner id may contain only lowercase letters, digits and dashes, and must start and end with a letter or digit.");
13
+ /** The shared interactive runner shape. */
14
+ export const makeRunnerSchema = () => z.object({
15
+ gpuAccelerated: z
16
+ .boolean()
17
+ .describe("Whether the runner was placed on GPU hardware. Chosen by QA Wolf from the team's configuration and what the fleet can provide, not requested."),
18
+ id: runnerIdSchema.describe("The runner's id, as supplied when launching it."),
19
+ runnerName: runnerNameSchema.describe("The image requested when the runner was launched. QA Wolf may place it on faster hardware, reported in gpuAccelerated."),
20
+ });
21
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/v1/runner/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC;IACrC,aAAa;IACb,mBAAmB;IACnB,eAAe;IACf,sBAAsB;CACvB,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC;KAC5B,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,GAAG,CAAC,EAAE,CAAC;KACP,KAAK,CACJ,iCAAiC,EACjC,mHAAmH,CACpH,CAAC;AAEJ,2CAA2C;AAC3C,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE,CACnC,CAAC,CAAC,MAAM,CAAC;IACP,cAAc,EAAE,CAAC;SACd,OAAO,EAAE;SACT,QAAQ,CACP,+IAA+I,CAChJ;IACH,EAAE,EAAE,cAAc,CAAC,QAAQ,CACzB,iDAAiD,CAClD;IACD,UAAU,EAAE,gBAAgB,CAAC,QAAQ,CACnC,wHAAwH,CACzH;CACF,CAAC,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { z } from "zod";
2
+ export declare const makeLaunchRunnerContract: () => {
3
+ readonly description: "Launch an interactive runner on the caller's team under an id the caller chooses. Launching the same id again returns the runner already running rather than starting a second one, and the same id with a different runnerName is refused. A runner is not permanent: it terminates on its own after a period of inactivity, and launching the same id after that starts and bills a new runner — so read `outcome` to tell which happened.";
4
+ readonly input: z.ZodObject<{
5
+ id: z.ZodString;
6
+ runnerName: z.ZodOptional<z.ZodEnum<{
7
+ node20Basic: "node20Basic";
8
+ node20WithAndroid: "node20WithAndroid";
9
+ node20WithIos: "node20WithIos";
10
+ node20WithPlaywright: "node20WithPlaywright";
11
+ }>>;
12
+ }, z.core.$strip>;
13
+ readonly kind: "write";
14
+ readonly name: "runner.launch";
15
+ readonly output: z.ZodObject<{
16
+ gpuAccelerated: z.ZodBoolean;
17
+ id: z.ZodString;
18
+ runnerName: z.ZodEnum<{
19
+ node20Basic: "node20Basic";
20
+ node20WithAndroid: "node20WithAndroid";
21
+ node20WithIos: "node20WithIos";
22
+ node20WithPlaywright: "node20WithPlaywright";
23
+ }>;
24
+ outcome: z.ZodEnum<{
25
+ launched: "launched";
26
+ "already-running": "already-running";
27
+ }>;
28
+ }, z.core.$strip>;
29
+ };
30
+ export declare const makeStopRunnerContract: () => {
31
+ readonly description: "Stop an interactive runner on the caller's team. Stopping a runner that is not running succeeds and reports `not-running`, so a retry needs no special handling.";
32
+ readonly input: z.ZodObject<{
33
+ id: z.ZodString;
34
+ }, z.core.$strip>;
35
+ readonly kind: "write";
36
+ readonly name: "runner.stop";
37
+ readonly output: z.ZodObject<{
38
+ id: z.ZodString;
39
+ outcome: z.ZodEnum<{
40
+ stopped: "stopped";
41
+ "not-running": "not-running";
42
+ }>;
43
+ }, z.core.$strip>;
44
+ };
45
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/v1/runner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCpC,CAAC;AAEF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;CA0BlC,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { z } from "zod";
2
+ import { makeRunnerSchema, runnerIdSchema, runnerNameSchema, } from "./identity.js";
3
+ export const makeLaunchRunnerContract = () => {
4
+ const input = z.object({
5
+ id: runnerIdSchema.describe("Id to launch the runner under, chosen by the caller. Launching the same id again returns the runner already running under it."),
6
+ runnerName: runnerNameSchema
7
+ .optional()
8
+ .describe("Image to run. Defaults to the standard web image, node20WithPlaywright."),
9
+ });
10
+ const output = makeRunnerSchema().extend({
11
+ outcome: z
12
+ .enum(["launched", "already-running"])
13
+ .describe("`launched` if this call started the runner. `already-running` if a runner was already running under this id and was returned unchanged — no second runner was started."),
14
+ });
15
+ return {
16
+ description: "Launch an interactive runner on the caller's team under an id the caller chooses. Launching the same id again returns the runner already running rather than starting a second one, and the same id with a different runnerName is refused. A runner is not permanent: it terminates on its own after a period of inactivity, and launching the same id after that starts and bills a new runner — so read `outcome` to tell which happened.",
17
+ input,
18
+ kind: "write",
19
+ name: "runner.launch",
20
+ output,
21
+ };
22
+ };
23
+ export const makeStopRunnerContract = () => {
24
+ const input = z.object({
25
+ id: runnerIdSchema.describe("Id of the runner to stop."),
26
+ });
27
+ const output = z.object({
28
+ id: runnerIdSchema.describe("Id of the runner the call addressed."),
29
+ outcome: z
30
+ .enum(["stopped", "not-running"])
31
+ .describe("`stopped` if the runner was running and has been stopped. `not-running` if no running runner has this id — it was already stopped, was never launched, or terminated on its own after inactivity; these are not distinguished, because the run system keeps no record of a runner once it is gone."),
32
+ });
33
+ return {
34
+ description: "Stop an interactive runner on the caller's team. Stopping a runner that is not running succeeds and reports `not-running`, so a retry needs no special handling.",
35
+ input,
36
+ kind: "write",
37
+ name: "runner.stop",
38
+ output,
39
+ };
40
+ };
41
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/v1/runner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,gBAAgB,GACjB,MAAM,eAAe,CAAC;AAEvB,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,EAAE;IAC3C,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;QACrB,EAAE,EAAE,cAAc,CAAC,QAAQ,CACzB,+HAA+H,CAChI;QACD,UAAU,EAAE,gBAAgB;aACzB,QAAQ,EAAE;aACV,QAAQ,CACP,yEAAyE,CAC1E;KACJ,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC,MAAM,CAAC;QACvC,OAAO,EAAE,CAAC;aACP,IAAI,CAAC,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;aACrC,QAAQ,CACP,wKAAwK,CACzK;KACJ,CAAC,CAAC;IAEH,OAAO;QACL,WAAW,EACT,8aAA8a;QAChb,KAAK;QACL,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,eAAe;QACrB,MAAM;KAMP,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,EAAE;IACzC,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;QACrB,EAAE,EAAE,cAAc,CAAC,QAAQ,CAAC,2BAA2B,CAAC;KACzD,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;QACtB,EAAE,EAAE,cAAc,CAAC,QAAQ,CAAC,sCAAsC,CAAC;QACnE,OAAO,EAAE,CAAC;aACP,IAAI,CAAC,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;aAChC,QAAQ,CACP,oSAAoS,CACrS;KACJ,CAAC,CAAC;IAEH,OAAO;QACL,WAAW,EACT,kKAAkK;QACpK,KAAK;QACL,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,aAAa;QACnB,MAAM;KAMP,CAAC;AACJ,CAAC,CAAC"}