hammerkit 1.25.0 → 1.27.0-next.1

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 (123) hide show
  1. package/build.schema.json +53 -1
  2. package/dist/cache/backends/local-cache-backend.js +10 -2
  3. package/dist/cache/explain.js +13 -11
  4. package/dist/cli.js +3 -0
  5. package/dist/docker/item-network.js +471 -0
  6. package/dist/docker/pull.js +4 -2
  7. package/dist/docker/remove-orphaned-containers.js +13 -6
  8. package/dist/environment/replace-env-variables.js +8 -6
  9. package/dist/executer/await-completed-dependencies.js +2 -1
  10. package/dist/executer/check-readiness.js +2 -2
  11. package/dist/executer/container-task-state.js +8 -6
  12. package/dist/executer/docker-service.js +24 -13
  13. package/dist/executer/docker-task.js +18 -29
  14. package/dist/executer/event-cache.js +4 -0
  15. package/dist/executer/execute-command.js +18 -5
  16. package/dist/executer/execute-docker.js +4 -1
  17. package/dist/executer/execution-steps.js +33 -7
  18. package/dist/executer/get-docker-executor.js +14 -7
  19. package/dist/executer/scheduler/enqueue-next.js +17 -3
  20. package/dist/executer/watch-loop.js +2 -2
  21. package/dist/executer/watch-state-key.js +1 -1
  22. package/dist/file/within-root.js +42 -0
  23. package/dist/harness/connect.js +99 -0
  24. package/dist/harness/format.js +73 -0
  25. package/dist/harness/mcp-command.js +59 -0
  26. package/dist/harness/mcp.js +432 -0
  27. package/dist/harness/opencode.js +492 -0
  28. package/dist/harness/pi.js +217 -0
  29. package/dist/harness/sandbox-client.js +373 -0
  30. package/dist/index.js +33 -36
  31. package/dist/kubernetes/apply.js +31 -1
  32. package/dist/kubernetes/await-running-state.js +33 -1
  33. package/dist/kubernetes/ensure-kubernetes-deployment-exists.js +44 -22
  34. package/dist/kubernetes/ensure-kubernetes-persistent-volume-claim-exists.js +131 -4
  35. package/dist/kubernetes/ensure-kubernetes-service-exists.js +25 -4
  36. package/dist/kubernetes/ensure-persistent-data.js +48 -7
  37. package/dist/kubernetes/get-service-ip.js +15 -1
  38. package/dist/kubernetes/job-placement.js +99 -0
  39. package/dist/kubernetes/job-secrets.js +306 -0
  40. package/dist/kubernetes/kept-claims.js +191 -0
  41. package/dist/kubernetes/kubernetes-instance.js +10 -2
  42. package/dist/kubernetes/network-gate.js +71 -0
  43. package/dist/kubernetes/network-policy.js +526 -0
  44. package/dist/kubernetes/resources.js +13 -2
  45. package/dist/kubernetes/restore-kubernetes-data.js +19 -4
  46. package/dist/kubernetes/secrets.js +2 -0
  47. package/dist/kubernetes/store-kubernetes-data.js +1 -1
  48. package/dist/kubernetes/volumes.js +100 -11
  49. package/dist/main.js +41 -0
  50. package/dist/network/egress-proxy.js +368 -0
  51. package/dist/network/port-relay.js +35 -0
  52. package/dist/optimizer/get-work-cache-stats.js +16 -0
  53. package/dist/optimizer/work-task-cache-description.js +3 -2
  54. package/dist/planner/service-definition.js +8 -2
  55. package/dist/planner/utils/append-work-environment.js +2 -0
  56. package/dist/planner/utils/append-work-service.js +4 -0
  57. package/dist/planner/utils/append-work-task.js +17 -1
  58. package/dist/planner/utils/assert-item-paths.js +50 -0
  59. package/dist/planner/utils/hosted-volumes.js +35 -0
  60. package/dist/planner/utils/task-arguments.js +155 -0
  61. package/dist/planner/work-cache-id.js +15 -1
  62. package/dist/planner/work-network.js +193 -0
  63. package/dist/planner/work-runtime-docker.js +43 -0
  64. package/dist/planner/work-runtime-kubernetes.js +336 -102
  65. package/dist/planner/work-runtime-local.js +16 -8
  66. package/dist/planner/work-service.js +7 -3
  67. package/dist/planner/work-state-record.js +30 -0
  68. package/dist/program.js +80 -7
  69. package/dist/remote/annotations.js +103 -0
  70. package/dist/remote/bundle-text.js +24 -0
  71. package/dist/remote/bundle.js +9 -1
  72. package/dist/remote/remote-commands.js +4 -1
  73. package/dist/remote/remote-work-commands.js +182 -69
  74. package/dist/remote/server-client.js +18 -5
  75. package/dist/remote/source-manifest.js +15 -2
  76. package/dist/remote/token-source.js +67 -0
  77. package/dist/schema/build-file-base-task-schema.js +3 -0
  78. package/dist/schema/build-file-container-service-schema.js +6 -0
  79. package/dist/schema/build-file-container-task-schema.js +3 -0
  80. package/dist/schema/build-file-environment-schema.js +9 -0
  81. package/dist/schema/network-schema.js +78 -0
  82. package/dist/schema/reference-parser.js +1 -0
  83. package/dist/schema/schema-parser.js +16 -3
  84. package/dist/schema/work-scope-parser.js +13 -0
  85. package/dist/secrets/command-secret-provider.js +73 -10
  86. package/dist/secrets/github-app-token-command.js +23 -0
  87. package/dist/secrets/github-app-token.js +191 -0
  88. package/dist/server/accounts-api.js +9 -2
  89. package/dist/server/definitions-api.js +69 -47
  90. package/dist/server/definitions.js +76 -51
  91. package/dist/server/executor.js +156 -41
  92. package/dist/server/git-checkout.js +72 -8
  93. package/dist/server/kubernetes-backend.js +554 -0
  94. package/dist/server/kubernetes-sandbox-storage.js +996 -0
  95. package/dist/server/oauth.js +1 -0
  96. package/dist/server/plan.js +51 -1
  97. package/dist/server/policy.js +104 -15
  98. package/dist/server/proposals-api.js +24 -40
  99. package/dist/server/proposals.js +12 -25
  100. package/dist/server/repo-access.js +37 -6
  101. package/dist/server/run-logs.js +217 -0
  102. package/dist/server/run-plan.js +51 -2
  103. package/dist/server/run-request.js +23 -10
  104. package/dist/server/run-store.js +5 -0
  105. package/dist/server/run-worker-command.js +13 -1
  106. package/dist/server/run-worker.js +121 -24
  107. package/dist/server/runs.js +184 -10
  108. package/dist/server/sandbox-docker.js +62 -0
  109. package/dist/server/sandbox-files-api.js +269 -0
  110. package/dist/server/sandbox-files.js +1054 -0
  111. package/dist/server/sandbox-patch.js +481 -0
  112. package/dist/server/sandbox-pod-command.js +15 -0
  113. package/dist/server/sandbox-pod.js +146 -0
  114. package/dist/server/sandbox-storage.js +462 -0
  115. package/dist/server/sandboxes-api.js +210 -0
  116. package/dist/server/sandboxes.js +519 -0
  117. package/dist/server/server-config.js +412 -22
  118. package/dist/server/server.js +204 -39
  119. package/dist/utils/run-id.js +12 -0
  120. package/harness/opencode.ts +11 -0
  121. package/harness/pi.ts +7 -0
  122. package/package.json +8 -2
  123. package/dist/remote/text-diff.js +0 -89
@@ -17,6 +17,10 @@ const work_instance_id_1 = require("./work-instance-id");
17
17
  const stream_1 = require("stream");
18
18
  const service_definition_1 = require("./service-definition");
19
19
  const container_task_state_1 = require("../executer/container-task-state");
20
+ const item_network_1 = require("../docker/item-network");
21
+ const execution_steps_1 = require("../executer/execution-steps");
22
+ const assert_item_paths_1 = require("./utils/assert-item-paths");
23
+ const log_1 = require("../log");
20
24
  function dockerTaskRuntime(task, workEnvironment) {
21
25
  const docker = (0, execute_docker_1.getContainerCli)(workEnvironment);
22
26
  return {
@@ -39,6 +43,8 @@ function dockerTaskRuntime(task, workEnvironment) {
39
43
  });
40
44
  },
41
45
  async restore(environment, path) {
46
+ // the restored outputs aren't the ones the record names any more
47
+ await (0, container_task_state_1.removeContainerTaskState)(environment, task);
42
48
  await restoreContainer(docker, environment, task, path);
43
49
  },
44
50
  async archive(environment, path) {
@@ -54,8 +60,18 @@ function dockerTaskRuntime(task, workEnvironment) {
54
60
  for (const container of containers) {
55
61
  await (0, remove_container_1.removeContainer)(docker.getContainer(container.Id));
56
62
  }
63
+ await (0, item_network_1.removeItemNetworks)(docker, task);
57
64
  },
58
65
  async execute(environment, options) {
66
+ if (environment.hosted) {
67
+ try {
68
+ await (0, assert_item_paths_1.assertItemPathsWithinRoot)(task, environment.cwd);
69
+ }
70
+ catch (e) {
71
+ options.state.set({ stateKey: options.stateKey, type: 'error', errorMessage: (0, log_1.getErrorMessage)(e) });
72
+ return;
73
+ }
74
+ }
59
75
  await (0, docker_task_1.dockerTask)(docker, task, environment, options);
60
76
  },
61
77
  async remove(environment) {
@@ -101,6 +117,18 @@ function isOnHost(generate) {
101
117
  return generate.isFile || generate.export;
102
118
  }
103
119
  async function restoreContainer(docker, environment, item, path) {
120
+ await (0, execution_steps_1.refuseHostLinks)(item, environment);
121
+ // on a server the volumes the outputs are restored into carry the run's files, so they
122
+ // are removed with a sandbox
123
+ const root = (0, execution_steps_1.hostedRoot)(environment);
124
+ if (root) {
125
+ const names = item.data.type === 'container-service'
126
+ ? item.data.volumes.filter((v) => !v.inherited).map((v) => v.name)
127
+ : item.data.generates.filter((v) => !v.inherited && !v.isFile).map((v) => v.volumeName);
128
+ for (const name of names) {
129
+ await (0, get_docker_executor_1.ensureVolumeExists)(docker, item.status, name, (0, get_docker_executor_1.volumeLabels)(root));
130
+ }
131
+ }
104
132
  await (0, using_container_1.usingContainer)(docker, item, {
105
133
  abortSignal: environment.abortCtrl.signal,
106
134
  Image: item.data.image,
@@ -140,6 +168,7 @@ async function restoreContainer(docker, environment, item, path) {
140
168
  }
141
169
  });
142
170
  if (item.data.type === 'container-task') {
171
+ await (0, execution_steps_1.refuseHostLinks)(item, environment);
143
172
  const onHost = new Set(item.data.generates.filter((g) => !g.inherited && isOnHost(g)).map((g) => g.path));
144
173
  for (const generate of (0, event_cache_1.getArchivePaths)(item.data, path)) {
145
174
  if (onHost.has(generate.path) && (await environment.file.exists(generate.filename))) {
@@ -165,6 +194,8 @@ function dockerServiceRuntime(service, workEnvironment) {
165
194
  if (currentService.Labels['hammerkit-definition'] !== (0, service_definition_1.getServiceDefinitionHash)(service)) {
166
195
  service.status.write('info', `${service.name} changed since it was started, recreating it`);
167
196
  await (0, remove_container_1.removeContainer)(docker.getContainer(currentService.Id));
197
+ // its network, proxy and relay go with it, whatever its new setting
198
+ await (0, item_network_1.removeItemNetworks)(docker, service);
168
199
  return;
169
200
  }
170
201
  const servicePid = 'hammerkit-pid' in currentService.Labels ? parseInt(currentService.Labels['hammerkit-pid']) : undefined;
@@ -188,6 +219,7 @@ function dockerServiceRuntime(service, workEnvironment) {
188
219
  for (const container of containers) {
189
220
  await (0, remove_container_1.removeContainer)(docker.getContainer(container.Id));
190
221
  }
222
+ await (0, item_network_1.removeItemNetworks)(docker, service);
191
223
  await (0, container_secrets_1.removeContainerSecrets)((0, work_instance_id_1.getWorkInstanceId)(service));
192
224
  },
193
225
  async remove() {
@@ -201,6 +233,16 @@ function dockerServiceRuntime(service, workEnvironment) {
201
233
  }
202
234
  },
203
235
  async execute(environment, options) {
236
+ if (environment.hosted) {
237
+ try {
238
+ await (0, assert_item_paths_1.assertItemPathsWithinRoot)(service, environment.cwd);
239
+ }
240
+ catch (e) {
241
+ service.status.write('error', (0, log_1.getErrorMessage)(e));
242
+ options.state.set({ type: 'end', reason: 'crash', stateKey: options.stateKey });
243
+ return;
244
+ }
245
+ }
204
246
  await (0, docker_service_1.dockerService)(docker, service, options, environment);
205
247
  },
206
248
  async restore(environment, path) {
@@ -229,6 +271,7 @@ function dockerServiceRuntime(service, workEnvironment) {
229
271
  }
230
272
  exports.dockerServiceRuntime = dockerServiceRuntime;
231
273
  async function archiveContainer(docker, environment, item, path) {
274
+ await (0, execution_steps_1.refuseHostLinks)(item, environment);
232
275
  await (0, using_container_1.usingContainer)(docker, item, {
233
276
  abortSignal: environment.abortCtrl.signal,
234
277
  Image: item.data.image,