@method-ai-hq/sdk 0.0.0-stage → 0.14.2

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 (262) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +23 -2
  3. package/dist/packages/contracts/src/identity.d.ts +16 -0
  4. package/dist/packages/contracts/src/identity.js +41 -0
  5. package/dist/packages/contracts/src/method-package.d.ts +71 -0
  6. package/dist/packages/contracts/src/method-package.js +22 -0
  7. package/dist/packages/method-document/src/conversion-report.d.ts +138 -0
  8. package/dist/packages/method-document/src/conversion-report.js +23 -0
  9. package/dist/packages/sdk/examples/daily-briefing/README.md +31 -0
  10. package/dist/packages/sdk/examples/daily-briefing/TASK.md +3 -0
  11. package/dist/packages/sdk/examples/daily-briefing/approved-report.md +138 -0
  12. package/dist/packages/sdk/examples/daily-briefing/briefing_artifacts.py +39 -0
  13. package/dist/packages/sdk/examples/daily-briefing/briefing_check_inputs.py +47 -0
  14. package/dist/packages/sdk/examples/daily-briefing/briefing_files.py +31 -0
  15. package/dist/packages/sdk/examples/daily-briefing/briefing_manifest.py +23 -0
  16. package/dist/packages/sdk/examples/daily-briefing/briefing_markdown.py +67 -0
  17. package/dist/packages/sdk/examples/daily-briefing/briefing_progress.py +18 -0
  18. package/dist/packages/sdk/examples/daily-briefing/briefing_render.py +71 -0
  19. package/dist/packages/sdk/examples/daily-briefing/briefing_sessions.py +37 -0
  20. package/dist/packages/sdk/examples/daily-briefing/briefing_times.py +158 -0
  21. package/dist/packages/sdk/examples/daily-briefing/briefing_validation.py +101 -0
  22. package/dist/packages/sdk/examples/daily-briefing/briefing_website.py +215 -0
  23. package/dist/packages/sdk/examples/daily-briefing/checks.json +19 -0
  24. package/dist/packages/sdk/examples/daily-briefing/daily-briefing.method +158 -0
  25. package/dist/packages/sdk/examples/daily-briefing/inputs.json +1 -0
  26. package/dist/packages/sdk/examples/daily-briefing/package-lock.json +10 -0
  27. package/dist/packages/sdk/examples/daily-briefing/package.json +4 -0
  28. package/dist/packages/sdk/examples/daily-briefing/pyproject.toml +8 -0
  29. package/dist/packages/sdk/examples/daily-briefing/reader/reader.css +35 -0
  30. package/dist/packages/sdk/examples/daily-briefing/reader/reader.js +42 -0
  31. package/dist/packages/sdk/examples/daily-briefing/sample/context.json +1 -0
  32. package/dist/packages/sdk/examples/daily-briefing/sample/documents/document-001.md +219 -0
  33. package/dist/packages/sdk/examples/daily-briefing/sample/media.json +1 -0
  34. package/dist/packages/sdk/examples/daily-briefing/sample/metadata/documents.json +39 -0
  35. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0001.json +49 -0
  36. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0002.json +49 -0
  37. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0003.json +49 -0
  38. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0004.json +49 -0
  39. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0005.json +49 -0
  40. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0006.json +49 -0
  41. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0007.json +49 -0
  42. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0008.json +49 -0
  43. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0009.json +49 -0
  44. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0010.json +49 -0
  45. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0011.json +49 -0
  46. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0012.json +49 -0
  47. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0013.json +49 -0
  48. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0014.json +49 -0
  49. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0015.json +49 -0
  50. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0016.json +49 -0
  51. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0017.json +49 -0
  52. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0018.json +49 -0
  53. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0019.json +49 -0
  54. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0020.json +49 -0
  55. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0021.json +49 -0
  56. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0022.json +49 -0
  57. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0023.json +49 -0
  58. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0024.json +49 -0
  59. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0025.json +49 -0
  60. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0026.json +49 -0
  61. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0027.json +49 -0
  62. package/dist/packages/sdk/examples/daily-briefing/sample/records/chatgpt-0028.json +49 -0
  63. package/dist/packages/sdk/examples/daily-briefing/sample/sessions.json +1 -0
  64. package/dist/packages/sdk/examples/daily-briefing/sample/timeline.jsonl +28 -0
  65. package/dist/packages/sdk/examples/daily-briefing/sample/untimed.jsonl +0 -0
  66. package/dist/packages/sdk/examples/daily-briefing/sample-output.zip +0 -0
  67. package/dist/packages/sdk/examples/daily-briefing/sample-report.md +51 -0
  68. package/dist/packages/sdk/examples/daily-briefing/uv.lock +128 -0
  69. package/dist/packages/sdk/examples/daily-briefing/vendor/marked-LICENSE.md +44 -0
  70. package/dist/packages/sdk/examples/daily-briefing/vendor/marked.mjs +77 -0
  71. package/dist/packages/sdk/examples/files.json +126 -0
  72. package/dist/packages/sdk/examples/message-routing/README.md +23 -0
  73. package/dist/packages/sdk/examples/message-routing/TASK.md +5 -0
  74. package/dist/packages/sdk/examples/message-routing/choose-destination.mjs +10 -0
  75. package/dist/packages/sdk/examples/message-routing/create-ticket.mjs +15 -0
  76. package/dist/packages/sdk/examples/message-routing/inputs.json +1 -0
  77. package/dist/packages/sdk/examples/message-routing/message-routing.method +45 -0
  78. package/dist/packages/sdk/examples/message-routing/result.fixture.json +6 -0
  79. package/dist/packages/sdk/examples/message-routing/routing.mjs +29 -0
  80. package/dist/packages/sdk/examples/message-routing/routing.test.mjs +27 -0
  81. package/dist/packages/sdk/examples/message-routing/ticket.method +88 -0
  82. package/dist/packages/sdk/examples/message-routing/ticket.test.mjs +64 -0
  83. package/dist/packages/sdk/examples/notes-summary/README.md +23 -0
  84. package/dist/packages/sdk/examples/notes-summary/TASK.md +3 -0
  85. package/dist/packages/sdk/examples/notes-summary/cases/dates-in-decisions/case.json +36 -0
  86. package/dist/packages/sdk/examples/notes-summary/cases/dates-in-decisions/examples.json +16 -0
  87. package/dist/packages/sdk/examples/notes-summary/cases/dates-in-decisions/files/0 +10 -0
  88. package/dist/packages/sdk/examples/notes-summary/cases/dates-in-decisions/recording.json +195 -0
  89. package/dist/packages/sdk/examples/notes-summary/notes/2026-10-05-standup.md +4 -0
  90. package/dist/packages/sdk/examples/notes-summary/notes/2026-10-07-planning.md +3 -0
  91. package/dist/packages/sdk/examples/notes-summary/notes-summary.method +54 -0
  92. package/dist/packages/sdk/examples/notes-summary/out/.keep +0 -0
  93. package/dist/packages/sdk/examples/notes-summary/read-notes.mjs +4 -0
  94. package/dist/packages/sdk/examples/notes-summary/save.mjs +7 -0
  95. package/dist/packages/sdk/examples/outbound-management/README.md +119 -0
  96. package/dist/packages/sdk/examples/outbound-management/TASK.md +5 -0
  97. package/dist/packages/sdk/examples/outbound-management/check_plan.py +16 -0
  98. package/dist/packages/sdk/examples/outbound-management/check_sources.py +14 -0
  99. package/dist/packages/sdk/examples/outbound-management/crm.py +153 -0
  100. package/dist/packages/sdk/examples/outbound-management/crm_test.py +141 -0
  101. package/dist/packages/sdk/examples/outbound-management/fixtures/README.md +15 -0
  102. package/dist/packages/sdk/examples/outbound-management/fixtures/crm.json +54 -0
  103. package/dist/packages/sdk/examples/outbound-management/fixtures/day-1/messages.json +29 -0
  104. package/dist/packages/sdk/examples/outbound-management/fixtures/day-2/messages.json +38 -0
  105. package/dist/packages/sdk/examples/outbound-management/fixtures/observations.json +12 -0
  106. package/dist/packages/sdk/examples/outbound-management/fixtures/plan.json +69 -0
  107. package/dist/packages/sdk/examples/outbound-management/fixtures/receipt.json +1 -0
  108. package/dist/packages/sdk/examples/outbound-management/fixtures/state.json +99 -0
  109. package/dist/packages/sdk/examples/outbound-management/fixtures/tasks.md +16 -0
  110. package/dist/packages/sdk/examples/outbound-management/inputs.json +4 -0
  111. package/dist/packages/sdk/examples/outbound-management/outbound.method +277 -0
  112. package/dist/packages/sdk/examples/outbound-management/read_crm.py +4 -0
  113. package/dist/packages/sdk/examples/outbound-management/save_day.py +4 -0
  114. package/dist/packages/sdk/examples/outbound-management/starter/crm.json +11 -0
  115. package/dist/packages/sdk/examples/social-briefing/README.md +41 -0
  116. package/dist/packages/sdk/examples/social-briefing/TASK.md +5 -0
  117. package/dist/packages/sdk/examples/social-briefing/inputs.json +5 -0
  118. package/dist/packages/sdk/examples/social-briefing/result.fixture.json +14 -0
  119. package/dist/packages/sdk/examples/social-briefing/social-briefing.method +110 -0
  120. package/dist/packages/sdk/examples/support-triage/README.md +77 -0
  121. package/dist/packages/sdk/examples/support-triage/TASK.md +3 -0
  122. package/dist/packages/sdk/examples/support-triage/cases/double-charge-to-billing/case.json +40 -0
  123. package/dist/packages/sdk/examples/support-triage/cases/double-charge-to-billing/recording.json +460 -0
  124. package/dist/packages/sdk/examples/support-triage/fake-helpdesk.mjs +38 -0
  125. package/dist/packages/sdk/examples/support-triage/helpdesk.mjs +33 -0
  126. package/dist/packages/sdk/examples/support-triage/inputs.json +1 -0
  127. package/dist/packages/sdk/examples/support-triage/read-ticket.mjs +8 -0
  128. package/dist/packages/sdk/examples/support-triage/route.mjs +4 -0
  129. package/dist/packages/sdk/examples/support-triage/sample-tickets.json +5 -0
  130. package/dist/packages/sdk/examples/support-triage/set-ticket.mjs +9 -0
  131. package/dist/packages/sdk/examples/support-triage/support-triage.method +165 -0
  132. package/dist/packages/sdk/examples/support-triage/triage.mjs +38 -0
  133. package/dist/packages/sdk/examples/support-triage/triage.test.mjs +68 -0
  134. package/dist/packages/sdk/observers/mail.delivery/fetch.mjs +87 -0
  135. package/dist/packages/sdk/observers/mail.delivery/fixtures/bounce-by-recipient.json +1 -0
  136. package/dist/packages/sdk/observers/mail.delivery/fixtures/bounce.json +1 -0
  137. package/dist/packages/sdk/observers/mail.delivery/fixtures/delayed.json +1 -0
  138. package/dist/packages/sdk/observers/mail.delivery/fixtures/delivered.json +1 -0
  139. package/dist/packages/sdk/observers/mail.delivery/fixtures/empty.json +1 -0
  140. package/dist/packages/sdk/observers/mail.delivery/fixtures/other-message.json +1 -0
  141. package/dist/packages/sdk/observers/mail.delivery/judge.mjs +13 -0
  142. package/dist/packages/sdk/observers/mail.delivery/observer.json +14 -0
  143. package/dist/packages/sdk/package.json +232 -0
  144. package/dist/packages/sdk/src/authoring-example.d.ts +91 -0
  145. package/dist/packages/sdk/src/authoring-example.js +50 -0
  146. package/dist/packages/sdk/src/authoring-instructions.d.ts +20 -0
  147. package/dist/packages/sdk/src/authoring-instructions.js +151 -0
  148. package/dist/packages/sdk/src/authoring-prompt.d.ts +2 -0
  149. package/dist/packages/sdk/src/authoring-prompt.js +8 -0
  150. package/dist/packages/sdk/src/authoring.d.ts +10 -0
  151. package/dist/packages/sdk/src/authoring.js +287 -0
  152. package/dist/packages/sdk/src/bindings.d.ts +4 -0
  153. package/dist/packages/sdk/src/bindings.js +124 -0
  154. package/dist/packages/sdk/src/bridge.d.ts +2 -0
  155. package/dist/packages/sdk/src/bridge.js +23 -0
  156. package/dist/packages/sdk/src/browser-runtime/pyproject.toml +5 -0
  157. package/dist/packages/sdk/src/browser-runtime/tools.json +189 -0
  158. package/dist/packages/sdk/src/browser-runtime/uv.lock +3894 -0
  159. package/dist/packages/sdk/src/browser-service.py +127 -0
  160. package/dist/packages/sdk/src/browser.d.ts +38 -0
  161. package/dist/packages/sdk/src/browser.js +203 -0
  162. package/dist/packages/sdk/src/capabilities.d.ts +13 -0
  163. package/dist/packages/sdk/src/capabilities.js +68 -0
  164. package/dist/packages/sdk/src/classification-client.d.ts +4 -0
  165. package/dist/packages/sdk/src/classification-client.js +27 -0
  166. package/dist/packages/sdk/src/cloud.d.ts +23 -0
  167. package/dist/packages/sdk/src/cloud.js +43 -0
  168. package/dist/packages/sdk/src/computer-settings.d.ts +28 -0
  169. package/dist/packages/sdk/src/computer-settings.js +57 -0
  170. package/dist/packages/sdk/src/connect.d.ts +47 -0
  171. package/dist/packages/sdk/src/connect.js +203 -0
  172. package/dist/packages/sdk/src/current-inspection.d.ts +3 -0
  173. package/dist/packages/sdk/src/current-inspection.js +146 -0
  174. package/dist/packages/sdk/src/current-runtime.d.ts +14 -0
  175. package/dist/packages/sdk/src/current-runtime.js +167 -0
  176. package/dist/packages/sdk/src/doctor.d.ts +17 -0
  177. package/dist/packages/sdk/src/doctor.js +68 -0
  178. package/dist/packages/sdk/src/executable.d.ts +2 -0
  179. package/dist/packages/sdk/src/executable.js +22 -0
  180. package/dist/packages/sdk/src/explain-effects.d.ts +32 -0
  181. package/dist/packages/sdk/src/explain-effects.js +192 -0
  182. package/dist/packages/sdk/src/explain.d.ts +115 -0
  183. package/dist/packages/sdk/src/explain.js +441 -0
  184. package/dist/packages/sdk/src/files.d.ts +9 -0
  185. package/dist/packages/sdk/src/files.js +50 -0
  186. package/dist/packages/sdk/src/guard-keys.d.ts +5 -0
  187. package/dist/packages/sdk/src/guard-keys.js +42 -0
  188. package/dist/packages/sdk/src/hosted-models.d.ts +49 -0
  189. package/dist/packages/sdk/src/hosted-models.js +81 -0
  190. package/dist/packages/sdk/src/improve.d.ts +55 -0
  191. package/dist/packages/sdk/src/improve.js +159 -0
  192. package/dist/packages/sdk/src/index.d.ts +13 -0
  193. package/dist/packages/sdk/src/index.js +13 -0
  194. package/dist/packages/sdk/src/inspect.d.ts +6 -0
  195. package/dist/packages/sdk/src/inspect.js +17 -0
  196. package/dist/packages/sdk/src/link.d.ts +12 -0
  197. package/dist/packages/sdk/src/link.js +53 -0
  198. package/dist/packages/sdk/src/local-cli.d.ts +24 -0
  199. package/dist/packages/sdk/src/local-cli.js +146 -0
  200. package/dist/packages/sdk/src/local-setup.d.ts +15 -0
  201. package/dist/packages/sdk/src/local-setup.js +42 -0
  202. package/dist/packages/sdk/src/method-client.d.ts +30 -0
  203. package/dist/packages/sdk/src/method-client.js +250 -0
  204. package/dist/packages/sdk/src/method-files.d.ts +29 -0
  205. package/dist/packages/sdk/src/method-files.js +93 -0
  206. package/dist/packages/sdk/src/method-help.d.ts +19 -0
  207. package/dist/packages/sdk/src/method-help.js +404 -0
  208. package/dist/packages/sdk/src/method-issues.d.ts +86 -0
  209. package/dist/packages/sdk/src/method-issues.js +192 -0
  210. package/dist/packages/sdk/src/method-sync.d.ts +46 -0
  211. package/dist/packages/sdk/src/method-sync.js +293 -0
  212. package/dist/packages/sdk/src/method.d.ts +5 -0
  213. package/dist/packages/sdk/src/method.js +359 -0
  214. package/dist/packages/sdk/src/model-checks.d.ts +96 -0
  215. package/dist/packages/sdk/src/model-checks.js +181 -0
  216. package/dist/packages/sdk/src/outbox.d.ts +120 -0
  217. package/dist/packages/sdk/src/outbox.js +297 -0
  218. package/dist/packages/sdk/src/own-model-key.d.ts +22 -0
  219. package/dist/packages/sdk/src/own-model-key.js +76 -0
  220. package/dist/packages/sdk/src/prepare.d.ts +24 -0
  221. package/dist/packages/sdk/src/prepare.js +245 -0
  222. package/dist/packages/sdk/src/process.d.ts +15 -0
  223. package/dist/packages/sdk/src/process.js +107 -0
  224. package/dist/packages/sdk/src/production.d.ts +182 -0
  225. package/dist/packages/sdk/src/production.js +284 -0
  226. package/dist/packages/sdk/src/progress.d.ts +12 -0
  227. package/dist/packages/sdk/src/progress.js +48 -0
  228. package/dist/packages/sdk/src/proposals.d.ts +73 -0
  229. package/dist/packages/sdk/src/proposals.js +284 -0
  230. package/dist/packages/sdk/src/quality.d.ts +82 -0
  231. package/dist/packages/sdk/src/quality.js +294 -0
  232. package/dist/packages/sdk/src/result-files.d.ts +5 -0
  233. package/dist/packages/sdk/src/result-files.js +149 -0
  234. package/dist/packages/sdk/src/result-transfer.d.ts +21 -0
  235. package/dist/packages/sdk/src/result-transfer.js +37 -0
  236. package/dist/packages/sdk/src/run-data.d.ts +11 -0
  237. package/dist/packages/sdk/src/run-data.js +80 -0
  238. package/dist/packages/sdk/src/run-method.d.ts +2 -0
  239. package/dist/packages/sdk/src/run-method.js +2 -0
  240. package/dist/packages/sdk/src/run-saved.d.ts +5 -0
  241. package/dist/packages/sdk/src/run-saved.js +138 -0
  242. package/dist/packages/sdk/src/run-worker.d.ts +6 -0
  243. package/dist/packages/sdk/src/run-worker.js +131 -0
  244. package/dist/packages/sdk/src/secrets.d.ts +37 -0
  245. package/dist/packages/sdk/src/secrets.js +196 -0
  246. package/dist/packages/sdk/src/update.d.ts +5 -0
  247. package/dist/packages/sdk/src/update.js +39 -0
  248. package/dist/packages/sdk/src/versions.d.ts +58 -0
  249. package/dist/packages/sdk/src/versions.js +144 -0
  250. package/dist/packages/sdk/src/worker.d.ts +120 -0
  251. package/dist/packages/sdk/src/worker.js +443 -0
  252. package/dist/packages/workflow-language/src/execution.d.ts +1 -0
  253. package/dist/packages/workflow-language/src/execution.js +1 -0
  254. package/dist/packages/workflow-language/src/inspection.d.ts +990 -0
  255. package/dist/packages/workflow-language/src/inspection.js +130 -0
  256. package/dist/packages/workflow-language/src/result-files.d.ts +160 -0
  257. package/dist/packages/workflow-language/src/result-files.js +67 -0
  258. package/dist/packages/workflow-language/src/schema.d.ts +207 -0
  259. package/dist/packages/workflow-language/src/schema.js +56 -0
  260. package/dist/packages/workflow-language/src/validate.d.ts +11 -0
  261. package/dist/packages/workflow-language/src/validate.js +77 -0
  262. package/package.json +230 -4
@@ -0,0 +1,120 @@
1
+ import type { MethodClient } from './method-client.js';
2
+ /**
3
+ * The outbox on this computer holds what must reach the account: package file uploads, version saves, and run records.
4
+ * It sends them in parallel (6 at a time), retries with backoff, and stops when no bytes moved for 60 s, or after 3
5
+ * failures in a row that have no response, a server error, or too many requests. What is left stays here; any later method command sends it.
6
+ *
7
+ * Order: a version is sent after its files; a run record after its version. Every request is idempotent, so two
8
+ * processes that send the same item do no harm.
9
+ */
10
+ export type FileItem = {
11
+ kind: 'file';
12
+ server: string;
13
+ sha256: string;
14
+ size: number;
15
+ };
16
+ export type VersionItem = {
17
+ kind: 'version';
18
+ server: string;
19
+ method_id: string;
20
+ version_id: string;
21
+ file?: string;
22
+ body: {
23
+ workflow: unknown;
24
+ package: {
25
+ files: Array<{
26
+ sha256: string;
27
+ }>;
28
+ digest: string;
29
+ };
30
+ parent_version_id?: string;
31
+ reason: string;
32
+ };
33
+ };
34
+ export type RunItem = {
35
+ kind: 'run';
36
+ server: string;
37
+ run_dir: string;
38
+ version_id: string;
39
+ pid: number;
40
+ };
41
+ export type Item = FileItem | VersionItem | RunItem;
42
+ type Saved = {
43
+ method_id: string;
44
+ version_number: number;
45
+ };
46
+ export declare const outboxDir: () => string;
47
+ /** Versions this computer knows the server has: version_id -> {method_id, version_number}. */
48
+ export declare function savedVersions(server: string): Record<string, Saved>;
49
+ /** The last version this computer saved of a Method, for the parent and the change reason of the next one. */
50
+ export declare function lastSaved(server: string, methodId: string): {
51
+ version_id: string;
52
+ version_number?: number;
53
+ workflow: any;
54
+ } | undefined;
55
+ /** Note a version that the server is known to have (a saved Method run by ID). */
56
+ export declare function recordKnownVersion(server: string, methodId: string, versionId: string, versionNumber: number): void;
57
+ /** A checkout of a saved version: the next save of this Method on this computer has it as its parent. */
58
+ export declare function recordCheckout(server: string, methodId: string, versionId: string, versionNumber: number, workflow: unknown): void;
59
+ /** Errors that a retry can fix: no response, a stalled transfer, a server error, or too many requests. */
60
+ export declare function retryable(error: any): boolean;
61
+ export declare class Outbox {
62
+ readonly client: MethodClient;
63
+ readonly options: {
64
+ stallMs?: number;
65
+ concurrency?: number;
66
+ send?: (item: RunItem) => Promise<void>;
67
+ write?: (line: string) => void;
68
+ };
69
+ private running;
70
+ private wake;
71
+ private lastProgress;
72
+ private networkFailures;
73
+ /** Set when sending stopped after repeated failures. A later command tries again; this process does not wait again. */
74
+ private gaveUp;
75
+ private stopped;
76
+ private foreground;
77
+ private retryAt;
78
+ private waiters;
79
+ private failures;
80
+ private owned;
81
+ private activated;
82
+ private signInNoted;
83
+ constructor(client: MethodClient, options?: {
84
+ stallMs?: number;
85
+ concurrency?: number;
86
+ send?: (item: RunItem) => Promise<void>;
87
+ write?: (line: string) => void;
88
+ });
89
+ /** Add an item. A file item copies the bytes now, so later edits to the file cannot change what is uploaded. */
90
+ add(item: Item, source?: string): void;
91
+ /** Remove a run item that this process sent itself. */
92
+ remove(item: Item): void;
93
+ release(item: RunItem): void;
94
+ items(): Item[];
95
+ pending(): number;
96
+ /**
97
+ * Resolves true when the version is on the server (or this computer has no record of it: the server decides), and
98
+ * false when it cannot be saved now: it is still in the outbox after sending stopped, or the server refused it.
99
+ */
100
+ whenSaved(versionId: string): Promise<boolean>;
101
+ failure(versionId: string): string | undefined;
102
+ /** Start sending in the background. Never throws. */
103
+ start(): void;
104
+ /**
105
+ * Send what is left. Resolves when the outbox is empty, no bytes moved for stallMs, or the server is unreachable.
106
+ * After this outbox gave up on a failing server, it resolves at once: the items stay for a later command.
107
+ */
108
+ drain(): Promise<{
109
+ pending: number;
110
+ }>;
111
+ stop(): void;
112
+ private settleWaiters;
113
+ private ready;
114
+ private loop;
115
+ private skipPresent;
116
+ private send;
117
+ }
118
+ /** Send what earlier commands left in the outbox, in the background. Never throws and never delays the command. */
119
+ export declare function sendLeftovers(client: MethodClient): void;
120
+ export {};
@@ -0,0 +1,297 @@
1
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { sha256 } from '../../contracts/src/identity.js';
4
+ import { writePrivateJson } from './files.js';
5
+ import { fileHash } from './method-files.js';
6
+ import { methodCache } from './prepare.js';
7
+ export const outboxDir = () => join(methodCache(), 'outbox');
8
+ const blobPath = (hash) => join(outboxDir(), 'blobs', hash);
9
+ const itemKey = (item) => sha256([item.server, item.kind, item.kind === 'file' ? item.sha256 : item.kind === 'version' ? item.version_id : item.run_dir].join('\n')).slice(0, 32);
10
+ const savedFile = (server) => join(methodCache(), 'versions', `${sha256(server).slice(0, 24)}.json`);
11
+ const methodFile = (server, methodId) => join(methodCache(), 'versions', `${sha256(`${server}\n${methodId}`).slice(0, 24)}.json`);
12
+ const read = (path) => { try {
13
+ return JSON.parse(readFileSync(path, 'utf8'));
14
+ }
15
+ catch {
16
+ return undefined;
17
+ } };
18
+ const alive = (pid) => { try {
19
+ process.kill(pid, 0);
20
+ return true;
21
+ }
22
+ catch {
23
+ return false;
24
+ } };
25
+ /** Versions this computer knows the server has: version_id -> {method_id, version_number}. */
26
+ export function savedVersions(server) { return read(savedFile(server)) ?? {}; }
27
+ /** The last version this computer saved of a Method, for the parent and the change reason of the next one. */
28
+ export function lastSaved(server, methodId) { return read(methodFile(server, methodId)); }
29
+ /** Note a version that the server is known to have (a saved Method run by ID). */
30
+ export function recordKnownVersion(server, methodId, versionId, versionNumber) {
31
+ if (!savedVersions(server)[versionId])
32
+ writePrivateJson(savedFile(server), { ...savedVersions(server), [versionId]: { method_id: methodId, version_number: versionNumber } });
33
+ }
34
+ /** A checkout of a saved version: the next save of this Method on this computer has it as its parent. */
35
+ export function recordCheckout(server, methodId, versionId, versionNumber, workflow) {
36
+ recordKnownVersion(server, methodId, versionId, versionNumber);
37
+ writePrivateJson(methodFile(server, methodId), { version_id: versionId, version_number: versionNumber, workflow });
38
+ }
39
+ function recordSaved(item, versionNumber) {
40
+ writePrivateJson(savedFile(item.server), { ...savedVersions(item.server), [item.version_id]: { method_id: item.method_id, version_number: versionNumber } });
41
+ writePrivateJson(methodFile(item.server, item.method_id), { version_id: item.version_id, version_number: versionNumber, workflow: item.body.workflow });
42
+ }
43
+ /** Errors that a retry can fix: no response, a stalled transfer, a server error, or too many requests. */
44
+ export function retryable(error) {
45
+ const status = error?.status ?? Number(/^(\d{3}):/.exec(String(error?.message))?.[1]);
46
+ return !status || status >= 500 || status === 429 || status === 408;
47
+ }
48
+ const networkError = (error) => !(error?.status ?? /^\d{3}:/.test(String(error?.message))) && error?.code !== 'stalled';
49
+ export class Outbox {
50
+ client;
51
+ options;
52
+ running;
53
+ wake;
54
+ lastProgress = Date.now();
55
+ networkFailures = 0;
56
+ /** Set when sending stopped after repeated failures. A later command tries again; this process does not wait again. */
57
+ gaveUp = false;
58
+ stopped = false;
59
+ foreground = false;
60
+ retryAt = new Map();
61
+ waiters = new Map();
62
+ failures = new Map();
63
+ owned = new Set();
64
+ activated = false;
65
+ signInNoted = false;
66
+ constructor(client, options = {}) {
67
+ this.client = client;
68
+ this.options = options;
69
+ }
70
+ /** Add an item. A file item copies the bytes now, so later edits to the file cannot change what is uploaded. */
71
+ add(item, source) {
72
+ mkdirSync(join(outboxDir(), 'blobs'), { recursive: true, mode: 0o700 });
73
+ if (item.kind === 'file' && !existsSync(blobPath(item.sha256))) {
74
+ const temporary = `${blobPath(item.sha256)}.${process.pid}.tmp`;
75
+ copyFileSync(source, temporary);
76
+ if (fileHash(readFileSync(temporary)) !== item.sha256) {
77
+ rmSync(temporary, { force: true });
78
+ throw Error(`A file changed while it was being saved: ${source}`);
79
+ }
80
+ renameSync(temporary, blobPath(item.sha256));
81
+ }
82
+ if (item.kind === 'run')
83
+ this.owned.add(itemKey(item));
84
+ writePrivateJson(join(outboxDir(), `${itemKey(item)}.json`), item);
85
+ if (this.activated)
86
+ this.start();
87
+ this.wake?.();
88
+ }
89
+ /** Remove a run item that this process sent itself. */
90
+ remove(item) { this.owned.delete(itemKey(item)); rmSync(join(outboxDir(), `${itemKey(item)}.json`), { force: true }); }
91
+ release(item) { this.owned.delete(itemKey(item)); }
92
+ items() {
93
+ let names = [];
94
+ try {
95
+ names = readdirSync(outboxDir()).filter(name => /^[a-f0-9]{32}\.json$/.test(name));
96
+ }
97
+ catch {
98
+ return [];
99
+ }
100
+ return names.map(name => read(join(outboxDir(), name))).filter((item) => !!item && item.server === this.client.server);
101
+ }
102
+ pending() { return this.items().length; }
103
+ /**
104
+ * Resolves true when the version is on the server (or this computer has no record of it: the server decides), and
105
+ * false when it cannot be saved now: it is still in the outbox after sending stopped, or the server refused it.
106
+ */
107
+ whenSaved(versionId) {
108
+ if (savedVersions(this.client.server)[versionId])
109
+ return Promise.resolve(true);
110
+ if (this.failures.has(versionId))
111
+ return Promise.resolve(false);
112
+ if (!this.items().some(item => item.kind === 'version' && item.version_id === versionId))
113
+ return Promise.resolve(true);
114
+ this.start();
115
+ if (!this.running)
116
+ return Promise.resolve(false);
117
+ return new Promise(resolve => this.waiters.set(versionId, [...this.waiters.get(versionId) ?? [], resolve]));
118
+ }
119
+ failure(versionId) { return this.failures.get(versionId); }
120
+ /** Start sending in the background. Never throws. */
121
+ start() {
122
+ this.activated = true;
123
+ try {
124
+ if (this.running || !this.client.token())
125
+ return;
126
+ }
127
+ catch {
128
+ return;
129
+ }
130
+ this.stopped = false;
131
+ this.running = this.loop().catch(() => { }).finally(() => { this.running = undefined; this.settleWaiters(); });
132
+ }
133
+ /**
134
+ * Send what is left. Resolves when the outbox is empty, no bytes moved for stallMs, or the server is unreachable.
135
+ * After this outbox gave up on a failing server, it resolves at once: the items stay for a later command.
136
+ */
137
+ async drain() {
138
+ // A command waits for this: its timers keep the process alive, or Node would end it in the middle.
139
+ this.foreground = true;
140
+ this.lastProgress = Date.now();
141
+ if (!this.gaveUp)
142
+ this.networkFailures = 0;
143
+ this.start();
144
+ await this.running;
145
+ return { pending: this.items().filter(item => !(item.kind === 'run' && this.owned.has(itemKey(item)))).length };
146
+ }
147
+ stop() { this.stopped = true; this.wake?.(); }
148
+ settleWaiters() {
149
+ const saved = savedVersions(this.client.server);
150
+ for (const [id, waiters] of this.waiters) {
151
+ const waiting = this.items().some(item => item.kind === 'version' && item.version_id === id);
152
+ if (saved[id] || this.failures.has(id) || !waiting || !this.running) {
153
+ waiters.forEach(resolve => resolve(!!saved[id] || (!waiting && !this.failures.has(id))));
154
+ this.waiters.delete(id);
155
+ }
156
+ }
157
+ }
158
+ ready(item, all) {
159
+ if (item.kind === 'version')
160
+ return !all.some(other => other.kind === 'file' && item.body.package.files.some(f => f.sha256 === other.sha256));
161
+ if (item.kind === 'run')
162
+ return !this.owned.has(itemKey(item)) && !(item.pid !== process.pid && alive(item.pid))
163
+ && !all.some(other => other.kind === 'version' && other.version_id === item.version_id) && !this.failures.has(item.version_id);
164
+ return true;
165
+ }
166
+ async loop() {
167
+ const limit = this.options.concurrency ?? 6, stallMs = this.options.stallMs ?? Number(process.env.METHOD_OUTBOX_STALL_MS || 60_000);
168
+ const active = new Map();
169
+ let checked = false;
170
+ for (;;) {
171
+ const all = this.items();
172
+ const waiting = all.filter(item => !(item.kind === 'run' && this.owned.has(itemKey(item))));
173
+ if (!waiting.length || this.stopped)
174
+ break;
175
+ if (Date.now() - this.lastProgress > stallMs)
176
+ break;
177
+ // The server is unreachable: stop now and keep the items for a later command.
178
+ if (this.networkFailures >= 3 && !active.size) {
179
+ this.gaveUp = true;
180
+ break;
181
+ }
182
+ if (!checked) {
183
+ checked = true;
184
+ await this.skipPresent(all.filter((item) => item.kind === 'file'));
185
+ continue;
186
+ }
187
+ const now = Date.now();
188
+ const next = waiting.filter(item => !active.has(itemKey(item)) && this.ready(item, all) && (this.retryAt.get(itemKey(item))?.at ?? 0) <= now);
189
+ // Nothing this process can send now or later (the rest belongs to another running Method process): stop.
190
+ if (!next.length && !active.size && !waiting.some(item => this.retryAt.has(itemKey(item)) || this.ready(item, all)))
191
+ break;
192
+ for (const item of next.slice(0, Math.max(0, limit - active.size))) {
193
+ const key = itemKey(item);
194
+ active.set(key, this.send(item).then(() => {
195
+ rmSync(join(outboxDir(), `${key}.json`), { force: true });
196
+ if (item.kind === 'file')
197
+ rmSync(blobPath(item.sha256), { force: true });
198
+ this.retryAt.delete(key);
199
+ this.networkFailures = 0;
200
+ this.gaveUp = false;
201
+ this.lastProgress = Date.now();
202
+ }, (error) => {
203
+ const status = error?.status ?? Number(/^(\d{3}):/.exec(String(error?.message))?.[1]);
204
+ if (status === 401) {
205
+ // The sign-in expired: keep everything for the next signed-in command.
206
+ this.stopped = true;
207
+ if (!this.signInNoted)
208
+ (this.options.write ?? (line => process.stderr.write(line + '\n')))('Will save when signed in: run method login.');
209
+ this.signInNoted = true;
210
+ return;
211
+ }
212
+ if (!retryable(error)) {
213
+ // A request the server refuses will be refused again: keep it out of the outbox, and say why once.
214
+ mkdirSync(join(outboxDir(), 'failed'), { recursive: true, mode: 0o700 });
215
+ writePrivateJson(join(outboxDir(), 'failed', `${key}.json`), { item, error: String(error.message ?? error) });
216
+ rmSync(join(outboxDir(), `${key}.json`), { force: true });
217
+ if (item.kind === 'version')
218
+ this.failures.set(item.version_id, String(error.message ?? error));
219
+ (this.options.write ?? (line => process.stderr.write(line + '\n')))(`Not saved to your Method account: ${String(error.message ?? error)}`);
220
+ return;
221
+ }
222
+ // No response, a server error, or too many requests: after 3 in a row, stop and keep the items for a later
223
+ // command. A finished run never waits for a server that keeps failing.
224
+ if (networkError(error) || status >= 500 || status === 429)
225
+ this.networkFailures++;
226
+ const attempt = (this.retryAt.get(key)?.attempt ?? 0) + 1;
227
+ this.retryAt.set(key, { at: Date.now() + Math.min(30_000, 500 * 2 ** (attempt - 1)), attempt });
228
+ }).finally(() => { active.delete(key); this.settleWaiters(); this.wake?.(); }));
229
+ }
230
+ // Wait for a send to finish, a new item, or the next retry time.
231
+ const due = Math.min(1000, ...[...this.retryAt.values()].map(r => Math.max(10, r.at - Date.now())));
232
+ await new Promise(resolve => {
233
+ const timer = setTimeout(resolve, due);
234
+ if (!this.foreground)
235
+ timer.unref?.();
236
+ this.wake = () => { clearTimeout(timer); resolve(); };
237
+ Promise.race(active.size ? [...active.values()] : [new Promise(() => { })]).then(() => { clearTimeout(timer); resolve(); });
238
+ });
239
+ this.wake = undefined;
240
+ }
241
+ await Promise.allSettled(active.values());
242
+ }
243
+ async skipPresent(files) {
244
+ if (!files.length)
245
+ return;
246
+ try {
247
+ for (let offset = 0; offset < files.length; offset += 10_000) {
248
+ const found = await this.client.request('/api/cli/files/check', 'POST', { hashes: files.slice(offset, offset + 10_000).map(f => f.sha256) }, true, { stallMs: this.options.stallMs ?? 60_000 });
249
+ for (const hash of found.present ?? []) {
250
+ const item = files.find(f => f.sha256 === hash);
251
+ rmSync(join(outboxDir(), `${itemKey(item)}.json`), { force: true });
252
+ rmSync(blobPath(hash), { force: true });
253
+ }
254
+ }
255
+ this.lastProgress = Date.now();
256
+ }
257
+ catch (error) {
258
+ const status = error?.status ?? Number(/^(\d{3}):/.exec(String(error?.message))?.[1]);
259
+ if (networkError(error) || status >= 500 || status === 429)
260
+ this.networkFailures++;
261
+ }
262
+ }
263
+ async send(item) {
264
+ const stallMs = this.options.stallMs ?? Number(process.env.METHOD_OUTBOX_STALL_MS || 60_000);
265
+ const onProgress = () => { this.lastProgress = Date.now(); };
266
+ if (item.kind === 'file') {
267
+ if (!existsSync(blobPath(item.sha256)))
268
+ return;
269
+ await this.client.transfer(`/api/cli/files/${item.sha256}`, readFileSync(blobPath(item.sha256)), { stallMs, onProgress, attempts: 1 });
270
+ return;
271
+ }
272
+ if (item.kind === 'version') {
273
+ const saved = await this.client.request(`/api/cli/methods/${encodeURIComponent(item.method_id)}/versions/${encodeURIComponent(item.version_id)}`, 'PUT', item.body, true, { stallMs, onProgress });
274
+ if (saved.version_id !== item.version_id)
275
+ throw Object.assign(Error('The server saved another version ID than this content has.'), { status: 409 });
276
+ recordSaved(item, saved.version_number);
277
+ return;
278
+ }
279
+ if (!existsSync(join(item.run_dir, 'method-sync.json')))
280
+ return;
281
+ if (!this.options.send) {
282
+ const { MethodSync } = await import('./method-sync.js');
283
+ await MethodSync.retry(item.run_dir, this.client);
284
+ }
285
+ else
286
+ await this.options.send(item);
287
+ }
288
+ }
289
+ /** Send what earlier commands left in the outbox, in the background. Never throws and never delays the command. */
290
+ export function sendLeftovers(client) {
291
+ try {
292
+ const outbox = new Outbox(client, { write: () => { } });
293
+ if (outbox.pending())
294
+ outbox.start();
295
+ }
296
+ catch { /* sent by a later command */ }
297
+ }
@@ -0,0 +1,22 @@
1
+ import type { HostedModels } from '@withmethod/runtime';
2
+ export declare const ownKeyName = "OPENROUTER_API_KEY";
3
+ /** The name of this computer's own model key, or undefined. A local agent (--agent) replaces it for model steps. */
4
+ export declare const ownKeyEnv: () => string | undefined;
5
+ /** method config model-key [--off]: open the private form for the key, then use it for model and classify steps. */
6
+ export declare function modelKeyCommand(args: string[], set?: (name: string) => Promise<unknown>): Promise<void>;
7
+ /**
8
+ * Hosted model requests sent to OpenRouter with the own key, in place of the account: the same request, with the same
9
+ * private options as the account (no training on the data, zero data retention). Every hosted profile uses it, the
10
+ * Method's own models too.
11
+ */
12
+ export declare function ownKeyModels(env: string): HostedModels;
13
+ /** Put the own key's value into this process's environment (a shell value is used first). required: fail without one. */
14
+ export declare function loadOwnKey(env: string, required?: boolean): void;
15
+ /** The classifier setting that calls Jev through OpenRouter with the own key. */
16
+ export declare const ownKeyClassification: (env: string) => {
17
+ provider: string;
18
+ model: "jev-1.13.0";
19
+ api_key_env: string;
20
+ };
21
+ /** The run's one line about the own key. */
22
+ export declare function announceOwnKey(write?: (line: string) => void): void;
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Your own OpenRouter key on this computer (method config model-key). With it, every hosted model step (the Method's
3
+ * models, model IDs, and the account default) and every classify step calls OpenRouter directly with that key, in
4
+ * place of the account's model credit. The value stays in the device secret store; computer.json holds only its name.
5
+ */
6
+ import { typesafeModel } from '@withmethod/runtime/classification.js';
7
+ import { readComputerSettings, updateComputerSettings } from './computer-settings.js';
8
+ import { findSecrets, importSecrets, resolveSecrets, setSecret } from './secrets.js';
9
+ export const ownKeyName = 'OPENROUTER_API_KEY';
10
+ /** The name of this computer's own model key, or undefined. A local agent (--agent) replaces it for model steps. */
11
+ export const ownKeyEnv = () => readComputerSettings().model_key_env;
12
+ /** method config model-key [--off]: open the private form for the key, then use it for model and classify steps. */
13
+ export async function modelKeyCommand(args, set = setSecret) {
14
+ if (args.length > 1 || (args[0] !== undefined && args[0] !== '--off'))
15
+ throw Error('Use method config model-key, or method config model-key --off.');
16
+ if (args[0] === '--off') {
17
+ updateComputerSettings(settings => { delete settings.model_key_env; });
18
+ process.stdout.write('Model and classify steps use the Method account again. The key stays in the secret store; method secret list shows it.\n');
19
+ return;
20
+ }
21
+ if (!resolveSecrets([ownKeyName])[ownKeyName]) {
22
+ // One nearby key file holds the key (the team's .env, an old pipeline's): import it, without showing it. With
23
+ // several, the person chooses in the form.
24
+ const files = findSecrets([ownKeyName]).secrets?.[ownKeyName]?.in_files ?? [];
25
+ const file = files.length === 1 ? files[0] : undefined;
26
+ if (file) {
27
+ importSecrets(file, [ownKeyName]);
28
+ process.stdout.write(`Imported ${ownKeyName} from ${file}.\n`);
29
+ }
30
+ else
31
+ await set(ownKeyName);
32
+ }
33
+ updateComputerSettings(settings => { settings.model_key_env = ownKeyName; });
34
+ process.stdout.write(`Model and classify steps on this computer use your own OpenRouter key (${ownKeyName}). Turn it off with method config model-key --off.\n`);
35
+ }
36
+ /**
37
+ * Hosted model requests sent to OpenRouter with the own key, in place of the account: the same request, with the same
38
+ * private options as the account (no training on the data, zero data retention). Every hosted profile uses it, the
39
+ * Method's own models too.
40
+ */
41
+ export function ownKeyModels(env) {
42
+ loadOwnKey(env);
43
+ return {
44
+ async request(body, signal) {
45
+ const response = await fetch('https://openrouter.ai/api/v1/chat/completions', {
46
+ method: 'POST', signal, headers: { authorization: `Bearer ${process.env[env]}`, 'content-type': 'application/json' },
47
+ body: JSON.stringify({ ...body, provider: { ...(body.provider ?? {}), data_collection: 'deny', zdr: true }, usage: { include: true } }),
48
+ });
49
+ const data = await response.json().catch(() => null);
50
+ if (!response.ok)
51
+ throw Object.assign(Error(`${response.status}: ${data?.error?.message ?? 'OpenRouter refused the request'} (your own key, ${env})`), { status: response.status });
52
+ return data;
53
+ },
54
+ };
55
+ }
56
+ /** Put the own key's value into this process's environment (a shell value is used first). required: fail without one. */
57
+ export function loadOwnKey(env, required = true) {
58
+ const value = resolveSecrets([env])[env];
59
+ if (!value) {
60
+ if (required)
61
+ throw Object.assign(Error(`${env} has no value on this computer. Run method config model-key, or method config model-key --off.`), { code: 'needs_input' });
62
+ return;
63
+ }
64
+ if (!process.env[env])
65
+ process.env[env] = value;
66
+ }
67
+ /** The classifier setting that calls Jev through OpenRouter with the own key. */
68
+ export const ownKeyClassification = (env) => ({ provider: 'typesafe', model: typesafeModel, api_key_env: env });
69
+ let announced = false;
70
+ /** The run's one line about the own key. */
71
+ export function announceOwnKey(write = line => process.stderr.write(line + '\n')) {
72
+ if (announced)
73
+ return;
74
+ announced = true;
75
+ write('Using your own OpenRouter key');
76
+ }
@@ -0,0 +1,24 @@
1
+ export declare const methodCache: () => string;
2
+ export declare const runFolderDays = 30;
3
+ /**
4
+ * Delete the run folders that the SDK keeps under the cache when nothing in them changed for 30 days and the account
5
+ * has the run. A folder is kept when it is the only copy of the run: a device-only run, a run that was never sent, or
6
+ * a run that still waits in the outbox. A project's own .method-runs folder is not touched. A folder that cannot be
7
+ * read or removed is left as it is.
8
+ */
9
+ export declare function pruneCachedRuns(root?: string, now?: number): void;
10
+ /**
11
+ * A folder with a `method` command that runs this CLI. The SDK puts it first on the PATH that scripts get, so a script
12
+ * that runs `method` (such as improve.method's `method test`) uses the CLI that runs the Method, not an older one.
13
+ */
14
+ export declare function cliBin(): string;
15
+ export declare function command(program: string, args: string[], cwd: string, env?: NodeJS.ProcessEnv): Promise<{
16
+ stdout: string;
17
+ stderr: string;
18
+ }>;
19
+ export declare function lockDependencies(root: string): Promise<void>;
20
+ export declare function prepareRuntime(root: string, config: any, method: any): Promise<{
21
+ config: any;
22
+ processPath: string;
23
+ prepareBundle: (bundle: string) => Promise<void>;
24
+ }>;