@prestack/thread 0.1.3 → 0.1.5

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 (270) hide show
  1. package/CHANGELOG.md +563 -0
  2. package/dist/core/actor.d.ts +1 -1
  3. package/dist/core/actor.js +5 -4
  4. package/dist/core/actor.ts +5 -4
  5. package/dist/core/attach.d.ts +0 -7
  6. package/dist/core/attach.js +38 -67
  7. package/dist/core/attach.ts +34 -80
  8. package/dist/core/chain.js +13 -17
  9. package/dist/core/chain.ts +11 -15
  10. package/dist/core/condition.d.ts +4 -4
  11. package/dist/core/condition.js +2 -2
  12. package/dist/core/descend.d.ts +4 -2
  13. package/dist/core/descend.js +91 -23
  14. package/dist/core/descend.ts +90 -21
  15. package/dist/core/errors/catalogue.d.ts +52 -0
  16. package/dist/{operations/errors/errors.js → core/errors/catalogue.js} +1 -1
  17. package/dist/{operations/errors/errors.ts → core/errors/catalogue.ts} +1 -1
  18. package/dist/{operations/errors/catalog.d.ts → core/errors/error.d.ts} +2 -3
  19. package/dist/{operations/errors/catalog.js → core/errors/error.js} +1 -16
  20. package/dist/{operations/errors/catalog.ts → core/errors/error.ts} +3 -19
  21. package/dist/core/errors/namespaces.d.ts +3 -0
  22. package/dist/core/errors/namespaces.js +15 -0
  23. package/dist/core/errors/namespaces.ts +19 -0
  24. package/dist/core/finding.js +2 -2
  25. package/dist/core/finding.ts +1 -2
  26. package/dist/core/init.d.ts +1 -1
  27. package/dist/core/init.js +51 -5
  28. package/dist/core/init.ts +58 -5
  29. package/dist/core/invoked.d.ts +1 -1
  30. package/dist/core/invoked.js +3 -1
  31. package/dist/core/invoked.ts +5 -2
  32. package/dist/core/round.js +36 -22
  33. package/dist/core/round.ts +26 -9
  34. package/dist/core/rows.d.ts +4 -0
  35. package/dist/core/rows.js +31 -2
  36. package/dist/core/rows.ts +33 -1
  37. package/dist/core/scope.d.ts +1 -0
  38. package/dist/core/scope.js +1 -0
  39. package/dist/core/scope.ts +2 -0
  40. package/dist/core/thread.d.ts +3 -3
  41. package/dist/core/tree.d.ts +4 -1
  42. package/dist/core/tree.js +26 -6
  43. package/dist/core/tree.ts +29 -6
  44. package/dist/core/types.d.ts +3 -3
  45. package/dist/core/types.js +3 -1
  46. package/dist/core/types.ts +2 -1
  47. package/dist/derivation/attach.js +3 -2
  48. package/dist/derivation/attach.ts +2 -1
  49. package/dist/derivation/generators/build.js +6 -6
  50. package/dist/derivation/generators/build.ts +1 -1
  51. package/dist/derivation/generators/check.js +1 -1
  52. package/dist/derivation/generators/determinism.js +1 -1
  53. package/dist/derivation/generators/release.js +60 -47
  54. package/dist/derivation/generators/release.ts +66 -43
  55. package/dist/derivation/release.d.ts +7 -3
  56. package/dist/derivation/release.js +14 -1
  57. package/dist/derivation/release.ts +22 -2
  58. package/dist/integrations/attach.d.ts +4 -0
  59. package/dist/integrations/attach.js +37 -56
  60. package/dist/integrations/attach.ts +54 -60
  61. package/dist/integrations/cli.d.ts +37 -0
  62. package/dist/integrations/cli.js +440 -0
  63. package/dist/integrations/cli.ts +543 -0
  64. package/dist/{core/files.d.ts → integrations/disk.d.ts} +16 -24
  65. package/dist/integrations/disk.js +435 -0
  66. package/dist/integrations/disk.ts +465 -0
  67. package/dist/integrations/generators/read.js +6 -6
  68. package/dist/integrations/generators/read.ts +4 -4
  69. package/dist/integrations/generators/vault.js +10 -11
  70. package/dist/integrations/generators/vault.ts +4 -5
  71. package/dist/{operations/http.d.ts → integrations/https.d.ts} +10 -6
  72. package/dist/integrations/https.js +170 -0
  73. package/dist/integrations/https.ts +216 -0
  74. package/dist/integrations/pglite.d.ts +26 -0
  75. package/dist/integrations/pglite.js +143 -0
  76. package/dist/integrations/pglite.ts +206 -0
  77. package/dist/integrations/secret.d.ts +8 -2
  78. package/dist/integrations/secret.js +3 -5
  79. package/dist/integrations/secret.ts +10 -6
  80. package/dist/integrations/target.d.ts +155 -14
  81. package/dist/integrations/target.js +171 -50
  82. package/dist/integrations/target.ts +377 -61
  83. package/dist/integrations/vault.d.ts +1 -0
  84. package/dist/integrations/vault.js +20 -5
  85. package/dist/integrations/vault.ts +17 -5
  86. package/dist/integrity/attach.js +8 -77
  87. package/dist/integrity/attach.ts +7 -76
  88. package/dist/integrity/check-threads.js +5 -5
  89. package/dist/integrity/check-threads.ts +2 -2
  90. package/dist/integrity/constraint.d.ts +0 -1
  91. package/dist/integrity/constraint.js +267 -366
  92. package/dist/integrity/constraint.ts +267 -375
  93. package/dist/integrity/generators/compiler.js +14 -17
  94. package/dist/integrity/generators/compiler.ts +10 -15
  95. package/dist/integrity/generators/gate.js +15 -15
  96. package/dist/integrity/generators/gate.ts +10 -10
  97. package/dist/integrity/generators/issues.js +7 -7
  98. package/dist/integrity/generators/publish.js +39 -57
  99. package/dist/integrity/generators/publish.ts +44 -55
  100. package/dist/integrity/generators/trial.d.ts +3 -3
  101. package/dist/integrity/generators/trial.js +133 -165
  102. package/dist/integrity/generators/trial.ts +145 -169
  103. package/dist/integrity/lint.js +9 -13
  104. package/dist/integrity/lint.ts +7 -10
  105. package/dist/integrity/lsp/bin.js +5 -4
  106. package/dist/integrity/lsp/bin.ts +3 -1
  107. package/dist/integrity/lsp/diagnostics.js +3 -3
  108. package/dist/integrity/lsp/diagnostics.ts +1 -1
  109. package/dist/integrity/lsp/lint.js +19 -30
  110. package/dist/integrity/lsp/lint.ts +16 -32
  111. package/dist/integrity/lsp/server.js +3 -3
  112. package/dist/integrity/slopnator.d.ts +3 -13
  113. package/dist/integrity/slopnator.js +59 -38
  114. package/dist/integrity/slopnator.ts +54 -38
  115. package/dist/integrity/slopnators/sl_broken_lineage.js +2 -2
  116. package/dist/integrity/slopnators/sl_declared_elsewhere.js +1 -1
  117. package/dist/integrity/slopnators/sl_derived_drift.js +4 -4
  118. package/dist/integrity/slopnators/sl_derived_drift.ts +1 -1
  119. package/dist/integrity/slopnators/sl_door_in_a_node.js +220 -0
  120. package/dist/integrity/slopnators/sl_door_in_a_node.ts +250 -0
  121. package/dist/integrity/slopnators/sl_inert_island.js +10 -8
  122. package/dist/integrity/slopnators/sl_inert_island.ts +8 -6
  123. package/dist/integrity/slopnators/sl_missing_row.js +6 -51
  124. package/dist/integrity/slopnators/sl_missing_row.ts +4 -50
  125. package/dist/integrity/slopnators/sl_no_barrel.js +1 -1
  126. package/dist/integrity/slopnators/sl_no_child_process.js +36 -18
  127. package/dist/integrity/slopnators/sl_no_child_process.ts +44 -18
  128. package/dist/integrity/slopnators/sl_no_dispatch_bypass.js +80 -149
  129. package/dist/integrity/slopnators/sl_no_dispatch_bypass.ts +95 -147
  130. package/dist/integrity/slopnators/sl_no_import_cycle.js +15 -4
  131. package/dist/integrity/slopnators/sl_no_import_cycle.ts +20 -4
  132. package/dist/integrity/slopnators/sl_no_such_command.js +2 -2
  133. package/dist/integrity/slopnators/sl_no_such_command.ts +1 -1
  134. package/dist/integrity/slopnators/sl_outside_an_operation.js +20 -0
  135. package/dist/integrity/slopnators/sl_outside_an_operation.ts +25 -0
  136. package/dist/integrity/slopnators/sl_screen_holds_only_declared.d.ts +2 -0
  137. package/dist/integrity/slopnators/sl_screen_holds_only_declared.js +61 -0
  138. package/dist/integrity/slopnators/sl_screen_holds_only_declared.ts +70 -0
  139. package/dist/integrity/slopnators/sl_secret_literal.js +1 -33
  140. package/dist/integrity/slopnators/sl_secret_literal.ts +1 -33
  141. package/dist/integrity/slopnators/sl_stale_path.js +5 -22
  142. package/dist/integrity/slopnators/sl_stale_path.ts +4 -20
  143. package/dist/integrity/slopnators/sl_twice_meant.js +1 -1
  144. package/dist/integrity/slopnators/sl_twice_parented.js +29 -5
  145. package/dist/integrity/slopnators/sl_twice_parented.ts +28 -4
  146. package/dist/integrity/slopnators/sl_undeclared_crossing.d.ts +4 -1
  147. package/dist/integrity/slopnators/sl_undeclared_crossing.js +426 -62
  148. package/dist/integrity/slopnators/sl_undeclared_crossing.ts +454 -70
  149. package/dist/integrity/slopnators/sl_undeclared_destination.js +59 -25
  150. package/dist/integrity/slopnators/sl_undeclared_destination.ts +69 -21
  151. package/dist/integrity/slopnators/sl_undeclared_list.d.ts +2 -0
  152. package/dist/integrity/slopnators/sl_undeclared_list.js +363 -0
  153. package/dist/integrity/slopnators/sl_undeclared_list.ts +358 -0
  154. package/dist/integrity/slopnators/sl_undeclared_node.js +1 -11
  155. package/dist/integrity/slopnators/sl_undeclared_node.ts +0 -10
  156. package/dist/integrity/slopnators/sl_undeclared_operation.js +111 -29
  157. package/dist/integrity/slopnators/sl_undeclared_operation.ts +134 -26
  158. package/dist/integrity/slopnators/sl_undeclared_variant.js +2 -2
  159. package/dist/integrity/slopnators/sl_undeclared_webhook.d.ts +2 -0
  160. package/dist/integrity/slopnators/sl_undeclared_webhook.js +90 -0
  161. package/dist/integrity/slopnators/sl_undeclared_webhook.ts +108 -0
  162. package/dist/integrity/slopnators/sl_underived_route.d.ts +2 -0
  163. package/dist/integrity/slopnators/sl_underived_route.js +61 -0
  164. package/dist/integrity/slopnators/sl_underived_route.ts +72 -0
  165. package/dist/integrity/slopnators/sl_ungoverned_island.js +3 -3
  166. package/dist/integrity/slopnators/sl_ungoverned_island.ts +1 -1
  167. package/dist/integrity/slopnators/sl_unlisted_program.d.ts +2 -0
  168. package/dist/integrity/slopnators/sl_unlisted_program.js +39 -0
  169. package/dist/integrity/slopnators/sl_unlisted_program.ts +40 -0
  170. package/dist/integrity/slopnators/sl_unnamed_island.js +1 -1
  171. package/dist/integrity/slopnators/sl_unpaired_member.js +3 -3
  172. package/dist/integrity/slopnators/sl_unpaired_member.ts +1 -1
  173. package/dist/integrity/slopnators/sl_unpaired_slopnator.js +4 -4
  174. package/dist/integrity/slopnators/sl_unpaired_slopnator.ts +1 -1
  175. package/dist/integrity/slopnators/sl_unprefixed_member.js +5 -31
  176. package/dist/integrity/slopnators/sl_unprefixed_member.ts +2 -28
  177. package/dist/integrity/slopnators/sl_unthreaded.js +11 -7
  178. package/dist/integrity/slopnators/sl_unthreaded.ts +6 -7
  179. package/dist/integrity/slopnators/sl_untranslated_key.js +2 -25
  180. package/dist/integrity/slopnators/sl_untranslated_key.ts +1 -25
  181. package/dist/integrity/slopnators/sl_unvaulted_secret.d.ts +2 -0
  182. package/dist/integrity/slopnators/sl_unvaulted_secret.js +107 -0
  183. package/dist/integrity/slopnators/sl_unvaulted_secret.ts +132 -0
  184. package/dist/integrity/slopnators/sl_unversioned.js +6 -4
  185. package/dist/integrity/slopnators/sl_unversioned.ts +5 -3
  186. package/dist/integrity/sweep.d.ts +1 -0
  187. package/dist/integrity/sweep.js +105 -42
  188. package/dist/integrity/sweep.ts +115 -42
  189. package/dist/knowledge/attach.js +4 -3
  190. package/dist/knowledge/attach.ts +3 -2
  191. package/dist/knowledge/generators/docsgen.js +8 -6
  192. package/dist/knowledge/generators/docsgen.ts +4 -2
  193. package/dist/knowledge/generators/glossary.js +4 -4
  194. package/dist/knowledge/generators/glossary.ts +1 -1
  195. package/dist/operations/access.d.ts +23 -0
  196. package/dist/operations/access.js +28 -1
  197. package/dist/operations/access.ts +43 -0
  198. package/dist/operations/attach.js +33 -113
  199. package/dist/operations/attach.ts +51 -117
  200. package/dist/operations/capabilities.d.ts +14 -5
  201. package/dist/operations/capabilities.js +13 -4
  202. package/dist/operations/capabilities.ts +27 -8
  203. package/dist/operations/dispatch.d.ts +8 -2
  204. package/dist/operations/dispatch.js +128 -185
  205. package/dist/operations/dispatch.ts +138 -191
  206. package/dist/operations/error-results.d.ts +1 -1
  207. package/dist/operations/error-results.js +2 -2
  208. package/dist/operations/error-results.ts +2 -2
  209. package/dist/operations/generators/capability.d.ts +11 -1
  210. package/dist/operations/generators/capability.js +481 -224
  211. package/dist/operations/generators/capability.ts +562 -233
  212. package/dist/operations/generators/compile.js +66 -39
  213. package/dist/operations/generators/compile.ts +78 -39
  214. package/dist/operations/generators/permits.js +11 -12
  215. package/dist/operations/generators/permits.ts +3 -4
  216. package/dist/operations/generators/seed.d.ts +1 -0
  217. package/dist/operations/generators/seed.js +19 -17
  218. package/dist/operations/generators/seed.ts +22 -14
  219. package/dist/operations/generators/trial.d.ts +6 -8
  220. package/dist/operations/generators/trial.js +200 -70
  221. package/dist/operations/generators/trial.ts +230 -93
  222. package/dist/operations/nodes.d.ts +15 -16
  223. package/dist/operations/nodes.ts +16 -17
  224. package/dist/operations/operations.d.ts +40 -4
  225. package/dist/operations/operations.js +1 -0
  226. package/dist/operations/operations.ts +61 -4
  227. package/dist/operations/result.d.ts +2 -2
  228. package/dist/operations/result.ts +2 -2
  229. package/package.json +1 -4
  230. package/dist/core/answers.d.ts +0 -171
  231. package/dist/core/answers.js +0 -789
  232. package/dist/core/answers.ts +0 -999
  233. package/dist/core/client.d.ts +0 -63
  234. package/dist/core/client.js +0 -249
  235. package/dist/core/client.ts +0 -289
  236. package/dist/core/files.js +0 -171
  237. package/dist/core/files.ts +0 -222
  238. package/dist/integrations/module.d.ts +0 -6
  239. package/dist/integrations/module.js +0 -153
  240. package/dist/integrations/module.ts +0 -191
  241. package/dist/integrity/slopnators/sl_unkept_rows.js +0 -104
  242. package/dist/integrity/slopnators/sl_unkept_rows.ts +0 -111
  243. package/dist/integrity/slopnators/sl_unseamed_reach.js +0 -73
  244. package/dist/integrity/slopnators/sl_unseamed_reach.ts +0 -79
  245. package/dist/operations/cost.d.ts +0 -14
  246. package/dist/operations/cost.js +0 -37
  247. package/dist/operations/cost.ts +0 -58
  248. package/dist/operations/errors/errors.d.ts +0 -52
  249. package/dist/operations/http.js +0 -124
  250. package/dist/operations/http.ts +0 -169
  251. package/dist/operations/memory.d.ts +0 -104
  252. package/dist/operations/memory.js +0 -365
  253. package/dist/operations/memory.ts +0 -470
  254. package/dist/operations/metering.d.ts +0 -55
  255. package/dist/operations/metering.js +0 -247
  256. package/dist/operations/metering.ts +0 -328
  257. package/dist/operations/queue-policy.d.ts +0 -3
  258. package/dist/operations/queue-policy.js +0 -8
  259. package/dist/operations/queue-policy.ts +0 -10
  260. package/dist/operations/seams.d.ts +0 -239
  261. package/dist/operations/seams.js +0 -45
  262. package/dist/operations/seams.ts +0 -364
  263. package/dist/operations/store.d.ts +0 -14
  264. package/dist/operations/store.js +0 -1
  265. package/dist/operations/store.ts +0 -29
  266. /package/dist/{operations → core}/errors/classes.d.ts +0 -0
  267. /package/dist/{operations → core}/errors/classes.js +0 -0
  268. /package/dist/{operations → core}/errors/classes.ts +0 -0
  269. /package/dist/integrity/slopnators/{sl_unkept_rows.d.ts → sl_door_in_a_node.d.ts} +0 -0
  270. /package/dist/integrity/slopnators/{sl_unseamed_reach.d.ts → sl_outside_an_operation.d.ts} +0 -0
@@ -1,15 +1,14 @@
1
- import { existsSync, readFileSync, writeFileSync } from "../../core/files.js";
1
+ import { existsSync, readFileSync, writeFileSync } from '../../integrations/disk.js';
2
2
  import { resolve } from 'node:path';
3
3
  import { argv, stdout } from 'node:process';
4
4
  import ts from 'typescript';
5
- import { ROOT, descend } from "../../core/descend.js";
6
- import { runChecker } from "../../core/finding.js";
7
- import { exit, invoked } from "../../core/invoked.js";
8
- import { inCode, valuesIn } from "../../core/rows.js";
9
- import { addressOf, credentialsOf, reachOf } from "../../integrations/target.js";
10
- import { DISPATCH_AT, dispatched } from "../dispatch.js";
11
- import { SUPPLIES } from "../seams.js";
12
- import { beside, blockIn, builtFrom, operations, problem, quoted, runtime, types } from "./seed.js";
5
+ import { ROOT, descend } from '../../core/descend.js';
6
+ import { runChecker } from '../../core/finding.js';
7
+ import { exit, invoked } from '../../core/invoked.js';
8
+ import { inCode, valuesIn } from '../../core/rows.js';
9
+ import { credentialsOf, holdsOf, reachOf } from '../../integrations/target.js';
10
+ import { DISPATCH_AT, dispatched } from '../dispatch.js';
11
+ import { beside, blockIn, builtFrom, operations, problem, quoted, runtime, types } from './seed.js';
13
12
  async function reaching() {
14
13
  const held = async (file, list) => {
15
14
  const path = resolve(ROOT, `_threads/${file}`);
@@ -34,18 +33,27 @@ function reached(targets, calls, secrets) {
34
33
  const mine = calls.filter((each) => each.of === one.id && one.takes.includes(each.id));
35
34
  out[one.id] = {
36
35
  reach: reachOf(one.id) ?? 'nothing known',
37
- address: addressOf(one, secrets)?.id ?? null,
38
- sends: credentialsOf(one, secrets).map((each) => ({
36
+ address: one.address,
37
+ headers: one.headers ?? {},
38
+ signs: credentialsOf(one, secrets)
39
+ .filter((each) => each.signs !== undefined)
40
+ .map((each) => ({
41
+ secret: each.id,
42
+ header: each.signs?.header ?? '',
43
+ prefix: each.signs?.prefix ?? '',
44
+ })),
45
+ sends: credentialsOf(one, secrets).filter((each) => each.sends !== undefined).map((each) => ({
39
46
  secret: each.id,
40
47
  header: each.sends?.header ?? '',
41
48
  prefix: each.sends?.prefix ?? '',
42
49
  })),
43
- calls: Object.fromEntries(mine.map((each) => [each.id.replace(/^cl_/, ''), { method: each.method, path: each.path }])),
50
+ calls: Object.fromEntries(mine.map((each) => [each.id.replace(/^cl_/, ''), { method: each.method ?? null, path: each.path }])),
44
51
  };
45
52
  }
46
53
  return out;
47
54
  }
48
55
  const OWN = '$';
56
+ const OPENED = 'opened';
49
57
  const ENTERED = `${OWN}at`;
50
58
  const PLAIN = /^(?:[A-Za-z_][A-Za-z0-9_]*|'(?:[^'\\]|\\.)*')$/;
51
59
  export function parts(text) {
@@ -91,10 +99,10 @@ function keyed(text) {
91
99
  }
92
100
  const OPENS = 'const $ = ';
93
101
  const ROLES = {
94
- block: ['hands', 'held'],
102
+ block: ['opened', 'held'],
95
103
  over: ['held'],
96
- item: ['item', 'hands', 'held'],
97
- again: ['pass', 'carried', 'hands', 'held'],
104
+ item: ['item', 'opened', 'held'],
105
+ again: ['pass', 'carried', 'opened', 'held'],
98
106
  };
99
107
  function arrowIn(text, roles) {
100
108
  const file = ts.createSourceFile('block.ts', `${OPENS}${text}`, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
@@ -208,6 +216,10 @@ function spliced(text, names, mine, roles) {
208
216
  const body = again.arrow.body;
209
217
  if (again.arrow.parameters.length > 1)
210
218
  return { form: 'call', text: whole, whole };
219
+ const opens = again.arrow.parameters[0];
220
+ if (opens !== undefined && ts.isIdentifier(opens.name) && opens.name.text !== OPENED) {
221
+ return { form: 'call', text: whole, whole };
222
+ }
211
223
  if (!ts.isBlock(body))
212
224
  return { form: 'expression', text: body.getText(), whole };
213
225
  const found = [];
@@ -220,15 +232,15 @@ function spliced(text, names, mine, roles) {
220
232
  return { form: 'call', text: whole, whole };
221
233
  }
222
234
  const ANSWERS = `${OWN}ANSWER`;
223
- function answered(name, one, hands, kind) {
235
+ function answered(name, one, opened, kind) {
224
236
  if (one.form === 'expression')
225
237
  return [`${kind} ${name}: unknown = ${one.text}`];
226
238
  if (one.form === 'statements') {
227
239
  return [`let ${name}: unknown`, '{', ...one.text.split('\n').map((line) => ` ${line.replace(ANSWERS, name)}`), '}'];
228
240
  }
229
- return [`${kind} ${name}: unknown = await ${asFn(one.whole, hands)}(hands)`];
241
+ return [`${kind} ${name}: unknown = await ${asFn(one.whole, opened)}(opened)`];
230
242
  }
231
- const asFn = (text, hands, more = '') => `((${text}) as (${more}hands: ${hands}) => Promise<unknown>)`;
243
+ const asFn = (text, opened, more = '') => `((${text}) as (${more}opened: ${opened}) => Promise<unknown>)`;
232
244
  function forked(name, said, shape) {
233
245
  if (said.length !== 2)
234
246
  return `takes a chooser and the ways it chooses between, and was handed ${String(said.length)} thing(s)`;
@@ -245,7 +257,7 @@ function forked(name, said, shape) {
245
257
  `let ${name}: unknown`,
246
258
  chose.form === 'expression'
247
259
  ? `const ${picked}: string = await (${chose.text})`
248
- : `const ${picked}: string = await ((${said[0] ?? ''}) as (hands: ${shape.reads}) => Promise<string>)(hands)`,
260
+ : `const ${picked}: string = await ((${said[0] ?? ''}) as (opened: ${shape.reads}) => Promise<string>)(opened)`,
249
261
  `switch (${picked}) {`,
250
262
  ];
251
263
  for (const way of named) {
@@ -258,7 +270,7 @@ function forked(name, said, shape) {
258
270
  else if (each.form === 'statements')
259
271
  runs.push(...each.text.split('\n').map((line) => ` ${line.replace(ANSWERS, name)}`));
260
272
  else
261
- runs.push(` ${name} = await ${asFn(each.whole, shape.all)}(hands)`);
273
+ runs.push(` ${name} = await ${asFn(each.whole, shape.all)}(opened)`);
262
274
  runs.push(' break');
263
275
  runs.push(' }');
264
276
  }
@@ -285,9 +297,9 @@ const SHAPES = {
285
297
  return {
286
298
  runs: [
287
299
  `const ${all}: unknown[] = []`,
288
- `const ${each} = (${block.whole}) as (item: unknown, hands: ${shape.all}) => Promise<unknown>`,
300
+ `const ${each} = (${block.whole}) as (item: unknown, opened: ${shape.all}) => Promise<unknown>`,
289
301
  `for (const ${item} of ${over.form === 'expression' ? `(${over.text})` : `((${over.whole}) as () => readonly unknown[])()`} as readonly unknown[]) {`,
290
- ` ${all}.push(await ${each}(${item}, hands))`,
302
+ ` ${all}.push(await ${each}(${item}, opened))`,
291
303
  '}',
292
304
  `const ${name}: unknown = ${all}`,
293
305
  ],
@@ -307,7 +319,7 @@ const SHAPES = {
307
319
  const each = spliced(one, shape.names, shape.mine, ROLES.block);
308
320
  if (typeof each === 'string')
309
321
  return `runs a block at position ${String(order + 1)} that ${each}`;
310
- calls.push(each.form === 'expression' ? `(async () => ${each.text})()` : `${asFn(each.whole, shape.all)}(hands)`);
322
+ calls.push(each.form === 'expression' ? `(async () => ${each.text})()` : `${asFn(each.whole, shape.all)}(opened)`);
311
323
  }
312
324
  return { runs: [`const ${name}: unknown = await Promise.all([${calls.join(', ')}])`] };
313
325
  },
@@ -327,11 +339,11 @@ const SHAPES = {
327
339
  runs: [
328
340
  `let ${name}: unknown`,
329
341
  `const ${ceiling}: number = ${said[0] ?? ''}`,
330
- `const ${again} = (${block.whole}) as (pass: number, carried: unknown, hands: ${shape.all}) => Promise<{ readonly done: boolean; readonly value: unknown }>`,
342
+ `const ${again} = (${block.whole}) as (pass: number, carried: unknown, opened: ${shape.all}) => Promise<{ readonly done: boolean; readonly value: unknown }>`,
331
343
  `let ${carried}: unknown`,
332
344
  `let ${done} = false`,
333
345
  `for (let ${pass} = 0; ${pass} < ${ceiling}; ${pass} += 1) {`,
334
- ` const ${answer} = await ${again}(${pass}, ${carried}, hands)`,
346
+ ` const ${answer} = await ${again}(${pass}, ${carried}, opened)`,
335
347
  ` if (${answer}.done) { ${name} = ${answer}.value; ${done} = true; break }`,
336
348
  ` ${carried} = ${answer}.value`,
337
349
  '}',
@@ -342,21 +354,23 @@ const SHAPES = {
342
354
  nd_branch: forked,
343
355
  };
344
356
  const STOPS = "Symbol.for('thread.operation.stopped')";
345
- function plainly(name, said, shape, hands, ends) {
357
+ function plainly(name, said, shape, opened, ends) {
346
358
  if (said.length !== 1)
347
359
  return `takes one block, and was handed ${String(said.length)} thing(s)`;
348
360
  const one = spliced(said[0] ?? '', shape.names, shape.mine, ROLES.block);
349
361
  if (typeof one === 'string')
350
362
  return one;
351
363
  if (!ends)
352
- return { runs: answered(name, one, hands, 'const') };
364
+ return { runs: answered(name, one, opened, 'const') };
353
365
  return {
354
366
  runs: [
355
- ...answered(name, one, hands, 'const'),
367
+ ...answered(name, one, opened, 'const'),
356
368
  `throw Object.assign(new Error(${quoted(`${name} ended the operation`)}), { [${STOPS}]: true, value: ${name} })`,
357
369
  ],
358
370
  };
359
371
  }
372
+ const saidIn = (held) => held !== undefined && ts.isStringLiteral(held) ? held.text : undefined;
373
+ const sourceIn = (held) => held?.getText();
360
374
  function compiled(at, id, one, known) {
361
375
  const because = problem(id, one);
362
376
  if (because !== undefined)
@@ -364,6 +378,18 @@ function compiled(at, id, one, known) {
364
378
  const takes = one.takes[0]?.at;
365
379
  if (takes === undefined)
366
380
  return { because: `\`${id}\` seeds what it takes and states no file for it` };
381
+ const { timeout } = one;
382
+ const fields = descend().stated.get(id)?.fields;
383
+ const entitled = saidIn(fields?.get('entitled'));
384
+ const rate = sourceIn(fields?.get('rate'));
385
+ const quota = sourceIn(fields?.get('quota'));
386
+ if (timeout === undefined) {
387
+ return {
388
+ because: `\`${id}\` states no \`timeout\`, and an operation says how long it waits. Add \`timeout: 10_000\` to its row in ` +
389
+ '_threads/operations.ts, or change it with `thread edit ' + id + ' --timeout <milliseconds>`. How long a call may ' +
390
+ 'run is part of the operation, not something the place it reaches decides',
391
+ };
392
+ }
367
393
  const only = one.requires.length === 0 ? 'never' : one.requires.map((each) => quoted(each)).join(' | ');
368
394
  const mine = new Set(['input', ...one.nodes.map((row) => String(row.id))]);
369
395
  const runs = [];
@@ -392,7 +418,7 @@ function compiled(at, id, one, known) {
392
418
  if (held === undefined) {
393
419
  return { because: `the node \`${name}\` states no block this can read in ${row.at} — run \`thread seed\` and write it again` };
394
420
  }
395
- const shape = { all: `Handed<${only}>`, reads: `Reads<Handed<${only}>>`, names, mine };
421
+ const shape = { all: `Opened<${only}>`, reads: `Reads<Opened<${only}>>`, names, mine };
396
422
  const made = (SHAPES[from] ?? ownType)(name, parts(held), shape);
397
423
  if (typeof made === 'string')
398
424
  return { because: `the node \`${name}\` ${made}` };
@@ -407,18 +433,21 @@ function compiled(at, id, one, known) {
407
433
  "import type { z } from 'zod'",
408
434
  '',
409
435
  `import type { Operation } from ${quoted(runtime(at, '../operations.ts'))}`,
410
- `import type { Handed, Reads } from ${quoted(runtime(at, '../seams.ts'))}`,
436
+ 'import type { Opened, Reads } from ' + quoted(runtime(at, '../operations.ts')),
411
437
  '',
412
- `import { estimate, input, resource } from ${quoted(beside(at, takes))}`,
438
+ `import { input, resource } from ${quoted(beside(at, takes))}`,
413
439
  '',
414
440
  `export const operation: Operation<z.infer<typeof input>, ${only}> = {`,
415
441
  ` id: ${quoted(id)},`,
416
442
  ' input,',
417
- ' estimate,',
443
+ ` timeout: ${String(timeout)},`,
418
444
  ' resource,',
419
445
  ` requires: [${one.requires.map((each) => quoted(each)).join(', ')}],`,
446
+ ...(entitled === undefined ? [] : [` entitled: ${quoted(entitled)},`]),
447
+ ...(rate === undefined ? [] : [` rate: ${rate},`]),
448
+ ...(quota === undefined ? [] : [` quota: ${quota},`]),
420
449
  '',
421
- ' run: async (hands, held) => {',
450
+ ' run: async (opened, held) => {',
422
451
  ' const input = held.input',
423
452
  ` let ${ENTERED} = ''`,
424
453
  ' try {',
@@ -440,8 +469,8 @@ async function planned() {
440
469
  const known = types(pass);
441
470
  const reach = await reaching();
442
471
  const found = [];
443
- const answers = Object.keys(reach).filter((one) => Object.keys(reach[one]?.calls ?? {}).length > 0);
444
- const may = [...SUPPLIES, ...answers];
472
+ const answers = Object.keys(reach).filter((one) => Object.keys(reach[one]?.calls ?? {}).length > 0 || holdsOf(one)?.takes !== 'calls');
473
+ const may = [...answers];
445
474
  for (const [id, one] of operations(pass, known)) {
446
475
  if (one.body === undefined)
447
476
  continue;
@@ -452,11 +481,9 @@ async function planned() {
452
481
  because: silent
453
482
  .map((each) => {
454
483
  const how = reach[each]?.reach ?? 'nothing known';
455
- const instead = how === 'module' || how === 'cli'
456
- ? 'run it with `thread run ' + each.replace(/^[a-z]+_/, '') + '`'
457
- : 'reach the rows it keeps with `sm_store`';
484
+ const instead = 'declare what it answers with `thread create target call ' + each + ' <name>`';
458
485
  return ('`' + id + '` requires `' + each + '`, which is reached over ' + how + ' and answers no call, so there ' +
459
- 'is nothing for a node to be handed. ' + instead + ', give it a call with `thread create target call`, ' +
486
+ 'is nothing for a node to be handed. ' + instead + ', ' +
460
487
  'or take the word off that operation\'s row');
461
488
  })
462
489
  .join('; '),
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync, writeFileSync } from '../../core/files.ts'
1
+ import { existsSync, readFileSync, writeFileSync } from '../../integrations/disk.ts'
2
2
  import { dirname, resolve } from 'node:path'
3
3
  import { argv, stdout } from 'node:process'
4
4
 
@@ -9,11 +9,10 @@ import { runChecker, type Finding } from '../../core/finding.ts'
9
9
  import { exit, invoked } from '../../core/invoked.ts'
10
10
  import { inCode, valuesIn } from '../../core/rows.ts'
11
11
 
12
- import { addressOf, credentialsOf, reachOf, type Call, type Target } from '../../integrations/target.ts'
12
+ import { credentialsOf, holdsOf, reachOf, type Call, type Target } from '../../integrations/target.ts'
13
13
  import type { Secret } from '../../integrations/secret.ts'
14
14
 
15
15
  import { DISPATCH_AT, dispatched } from '../dispatch.ts'
16
- import { SUPPLIES } from '../seams.ts'
17
16
  import { beside, blockIn, builtFrom, operations, problem, quoted, runtime, types } from './seed.ts'
18
17
 
19
18
  async function reaching(): Promise<Readonly<Record<string, ReturnType<typeof reached>[string]>>> {
@@ -42,10 +41,11 @@ function reached(
42
41
  string,
43
42
  {
44
43
  readonly reach: string
45
- readonly address: string | null
46
- readonly sends: readonly { readonly secret: string; readonly header: string; readonly prefix: string }[]
47
- readonly calls: Readonly<Record<string, { readonly method: string; readonly path: string }>>
48
-
44
+ readonly address?: string
45
+ readonly headers: Readonly<Record<string, string>>
46
+ readonly sends: readonly { readonly secret: string; readonly header: string; readonly prefix: string }[]
47
+ readonly signs: readonly { readonly secret: string; readonly header: string; readonly prefix: string }[]
48
+ readonly calls: Readonly<Record<string, { readonly method: string | null; readonly path: string }>>
49
49
  }
50
50
  >
51
51
  > {
@@ -54,15 +54,23 @@ function reached(
54
54
  const mine = calls.filter((each) => each.of === one.id && one.takes.includes(each.id))
55
55
  out[one.id] = {
56
56
  reach: reachOf(one.id) ?? 'nothing known',
57
- address: addressOf(one, secrets)?.id ?? null,
58
- sends: credentialsOf(one, secrets).map((each) => ({
57
+ address: one.address,
58
+ headers: one.headers ?? {},
59
+ signs: credentialsOf(one, secrets)
60
+ .filter((each) => each.signs !== undefined)
61
+ .map((each) => ({
62
+ secret: each.id,
63
+ header: each.signs?.header ?? '',
64
+ prefix: each.signs?.prefix ?? '',
65
+ })),
66
+ sends: credentialsOf(one, secrets).filter((each) => each.sends !== undefined).map((each) => ({
59
67
  secret: each.id,
60
68
  header: each.sends?.header ?? '',
61
69
  prefix: each.sends?.prefix ?? '',
62
70
  })),
63
71
 
64
72
  calls: Object.fromEntries(
65
- mine.map((each) => [each.id.replace(/^cl_/, ''), { method: each.method, path: each.path }]),
73
+ mine.map((each) => [each.id.replace(/^cl_/, ''), { method: each.method ?? null, path: each.path }]),
66
74
  ),
67
75
  }
68
76
  }
@@ -71,6 +79,8 @@ function reached(
71
79
 
72
80
  const OWN = '$'
73
81
 
82
+ const OPENED = 'opened'
83
+
74
84
  const ENTERED = `${OWN}at`
75
85
 
76
86
  const PLAIN = /^(?:[A-Za-z_][A-Za-z0-9_]*|'(?:[^'\\]|\\.)*')$/
@@ -115,10 +125,10 @@ function keyed(text: string): { readonly key: string; readonly held: string } |
115
125
  const OPENS = 'const $ = '
116
126
 
117
127
  const ROLES = {
118
- block: ['hands', 'held'],
128
+ block: ['opened', 'held'],
119
129
  over: ['held'],
120
- item: ['item', 'hands', 'held'],
121
- again: ['pass', 'carried', 'hands', 'held'],
130
+ item: ['item', 'opened', 'held'],
131
+ again: ['pass', 'carried', 'opened', 'held'],
122
132
  } as const satisfies Readonly<Record<string, readonly string[]>>
123
133
 
124
134
  interface Read {
@@ -261,6 +271,11 @@ function spliced(
261
271
 
262
272
  if (again.arrow.parameters.length > 1) return { form: 'call', text: whole, whole }
263
273
 
274
+ const opens = again.arrow.parameters[0]
275
+ if (opens !== undefined && ts.isIdentifier(opens.name) && opens.name.text !== OPENED) {
276
+ return { form: 'call', text: whole, whole }
277
+ }
278
+
264
279
  if (!ts.isBlock(body)) return { form: 'expression', text: body.getText(), whole }
265
280
 
266
281
  const found: ts.ReturnStatement[] = []
@@ -287,16 +302,16 @@ interface Shape {
287
302
  readonly mine: ReadonlySet<string>
288
303
  }
289
304
 
290
- function answered(name: string, one: Spliced, hands: string, kind: 'const' | 'let'): readonly string[] {
305
+ function answered(name: string, one: Spliced, opened: string, kind: 'const' | 'let'): readonly string[] {
291
306
  if (one.form === 'expression') return [`${kind} ${name}: unknown = ${one.text}`]
292
307
  if (one.form === 'statements') {
293
308
  return [`let ${name}: unknown`, '{', ...one.text.split('\n').map((line) => ` ${line.replace(ANSWERS, name)}`), '}']
294
309
  }
295
- return [`${kind} ${name}: unknown = await ${asFn(one.whole, hands)}(hands)`]
310
+ return [`${kind} ${name}: unknown = await ${asFn(one.whole, opened)}(opened)`]
296
311
  }
297
312
 
298
- const asFn = (text: string, hands: string, more: string = ''): string =>
299
- `((${text}) as (${more}hands: ${hands}) => Promise<unknown>)`
313
+ const asFn = (text: string, opened: string, more: string = ''): string =>
314
+ `((${text}) as (${more}opened: ${opened}) => Promise<unknown>)`
300
315
 
301
316
  function forked(name: string, said: readonly string[], shape: Shape): Made | string {
302
317
  if (said.length !== 2) return `takes a chooser and the ways it chooses between, and was handed ${String(said.length)} thing(s)`
@@ -314,7 +329,7 @@ function forked(name: string, said: readonly string[], shape: Shape): Made | str
314
329
  `let ${name}: unknown`,
315
330
  chose.form === 'expression'
316
331
  ? `const ${picked}: string = await (${chose.text})`
317
- : `const ${picked}: string = await ((${said[0] ?? ''}) as (hands: ${shape.reads}) => Promise<string>)(hands)`,
332
+ : `const ${picked}: string = await ((${said[0] ?? ''}) as (opened: ${shape.reads}) => Promise<string>)(opened)`,
318
333
  `switch (${picked}) {`,
319
334
  ]
320
335
 
@@ -324,7 +339,7 @@ function forked(name: string, said: readonly string[], shape: Shape): Made | str
324
339
  runs.push(` case ${(way?.key ?? '').startsWith("'") ? (way?.key ?? '') : quoted(way?.key ?? '')}: {`)
325
340
  if (each.form === 'expression') runs.push(` ${name} = ${each.text}`)
326
341
  else if (each.form === 'statements') runs.push(...each.text.split('\n').map((line) => ` ${line.replace(ANSWERS, name)}`))
327
- else runs.push(` ${name} = await ${asFn(each.whole, shape.all)}(hands)`)
342
+ else runs.push(` ${name} = await ${asFn(each.whole, shape.all)}(opened)`)
328
343
  runs.push(' break')
329
344
  runs.push(' }')
330
345
  }
@@ -351,9 +366,9 @@ const SHAPES: Readonly<Record<string, (name: string, said: readonly string[], sh
351
366
  return {
352
367
  runs: [
353
368
  `const ${all}: unknown[] = []`,
354
- `const ${each} = (${block.whole}) as (item: unknown, hands: ${shape.all}) => Promise<unknown>`,
369
+ `const ${each} = (${block.whole}) as (item: unknown, opened: ${shape.all}) => Promise<unknown>`,
355
370
  `for (const ${item} of ${over.form === 'expression' ? `(${over.text})` : `((${over.whole}) as () => readonly unknown[])()`} as readonly unknown[]) {`,
356
- ` ${all}.push(await ${each}(${item}, hands))`,
371
+ ` ${all}.push(await ${each}(${item}, opened))`,
357
372
  '}',
358
373
  `const ${name}: unknown = ${all}`,
359
374
  ],
@@ -371,7 +386,7 @@ const SHAPES: Readonly<Record<string, (name: string, said: readonly string[], sh
371
386
  for (const [order, one] of every.entries()) {
372
387
  const each = spliced(one, shape.names, shape.mine, ROLES.block)
373
388
  if (typeof each === 'string') return `runs a block at position ${String(order + 1)} that ${each}`
374
- calls.push(each.form === 'expression' ? `(async () => ${each.text})()` : `${asFn(each.whole, shape.all)}(hands)`)
389
+ calls.push(each.form === 'expression' ? `(async () => ${each.text})()` : `${asFn(each.whole, shape.all)}(opened)`)
375
390
  }
376
391
  return { runs: [`const ${name}: unknown = await Promise.all([${calls.join(', ')}])`] }
377
392
  },
@@ -390,11 +405,11 @@ const SHAPES: Readonly<Record<string, (name: string, said: readonly string[], sh
390
405
  runs: [
391
406
  `let ${name}: unknown`,
392
407
  `const ${ceiling}: number = ${said[0] ?? ''}`,
393
- `const ${again} = (${block.whole}) as (pass: number, carried: unknown, hands: ${shape.all}) => Promise<{ readonly done: boolean; readonly value: unknown }>`,
408
+ `const ${again} = (${block.whole}) as (pass: number, carried: unknown, opened: ${shape.all}) => Promise<{ readonly done: boolean; readonly value: unknown }>`,
394
409
  `let ${carried}: unknown`,
395
410
  `let ${done} = false`,
396
411
  `for (let ${pass} = 0; ${pass} < ${ceiling}; ${pass} += 1) {`,
397
- ` const ${answer} = await ${again}(${pass}, ${carried}, hands)`,
412
+ ` const ${answer} = await ${again}(${pass}, ${carried}, opened)`,
398
413
  ` if (${answer}.done) { ${name} = ${answer}.value; ${done} = true; break }`,
399
414
  ` ${carried} = ${answer}.value`,
400
415
  '}',
@@ -408,20 +423,24 @@ const SHAPES: Readonly<Record<string, (name: string, said: readonly string[], sh
408
423
 
409
424
  const STOPS = "Symbol.for('thread.operation.stopped')"
410
425
 
411
- function plainly(name: string, said: readonly string[], shape: Shape, hands: string, ends: boolean): Made | string {
426
+ function plainly(name: string, said: readonly string[], shape: Shape, opened: string, ends: boolean): Made | string {
412
427
  if (said.length !== 1) return `takes one block, and was handed ${String(said.length)} thing(s)`
413
428
  const one = spliced(said[0] ?? '', shape.names, shape.mine, ROLES.block)
414
429
  if (typeof one === 'string') return one
415
430
 
416
- if (!ends) return { runs: answered(name, one, hands, 'const') }
431
+ if (!ends) return { runs: answered(name, one, opened, 'const') }
417
432
 
418
433
  return {
419
434
  runs: [
420
- ...answered(name, one, hands, 'const'),
435
+ ...answered(name, one, opened, 'const'),
421
436
  `throw Object.assign(new Error(${quoted(`${name} ended the operation`)}), { [${STOPS}]: true, value: ${name} })`,
422
437
  ],
423
438
  }
424
439
  }
440
+ const saidIn = (held: ts.Expression | undefined): string | undefined =>
441
+ held !== undefined && ts.isStringLiteral(held) ? held.text : undefined
442
+
443
+ const sourceIn = (held: ts.Expression | undefined): string | undefined => held?.getText()
425
444
 
426
445
  function compiled(
427
446
  at: string,
@@ -435,6 +454,21 @@ function compiled(
435
454
  const takes = one.takes[0]?.at
436
455
  if (takes === undefined) return { because: `\`${id}\` seeds what it takes and states no file for it` }
437
456
 
457
+ const { timeout } = one
458
+
459
+ const fields = descend().stated.get(id)?.fields
460
+ const entitled = saidIn(fields?.get('entitled'))
461
+ const rate = sourceIn(fields?.get('rate'))
462
+ const quota = sourceIn(fields?.get('quota'))
463
+ if (timeout === undefined) {
464
+ return {
465
+ because:
466
+ `\`${id}\` states no \`timeout\`, and an operation says how long it waits. Add \`timeout: 10_000\` to its row in ` +
467
+ '_threads/operations.ts, or change it with `thread edit ' + id + ' --timeout <milliseconds>`. How long a call may ' +
468
+ 'run is part of the operation, not something the place it reaches decides',
469
+ }
470
+ }
471
+
438
472
  const only = one.requires.length === 0 ? 'never' : one.requires.map((each) => quoted(each)).join(' | ')
439
473
  const mine = new Set<string>(['input', ...one.nodes.map((row) => String(row.id))])
440
474
 
@@ -466,7 +500,7 @@ function compiled(
466
500
  return { because: `the node \`${name}\` states no block this can read in ${row.at} — run \`thread seed\` and write it again` }
467
501
  }
468
502
 
469
- const shape: Shape = { all: `Handed<${only}>`, reads: `Reads<Handed<${only}>>`, names, mine }
503
+ const shape: Shape = { all: `Opened<${only}>`, reads: `Reads<Opened<${only}>>`, names, mine }
470
504
  const made = (SHAPES[from] ?? ownType)(name, parts(held), shape)
471
505
  if (typeof made === 'string') return { because: `the node \`${name}\` ${made}` }
472
506
 
@@ -481,18 +515,21 @@ function compiled(
481
515
  "import type { z } from 'zod'",
482
516
  '',
483
517
  `import type { Operation } from ${quoted(runtime(at, '../operations.ts'))}`,
484
- `import type { Handed, Reads } from ${quoted(runtime(at, '../seams.ts'))}`,
518
+ 'import type { Opened, Reads } from ' + quoted(runtime(at, '../operations.ts')),
485
519
  '',
486
- `import { estimate, input, resource } from ${quoted(beside(at, takes))}`,
520
+ `import { input, resource } from ${quoted(beside(at, takes))}`,
487
521
  '',
488
522
  `export const operation: Operation<z.infer<typeof input>, ${only}> = {`,
489
523
  ` id: ${quoted(id)},`,
490
524
  ' input,',
491
- ' estimate,',
525
+ ` timeout: ${String(timeout)},`,
492
526
  ' resource,',
493
527
  ` requires: [${one.requires.map((each) => quoted(each)).join(', ')}],`,
528
+ ...(entitled === undefined ? [] : [` entitled: ${quoted(entitled)},`]),
529
+ ...(rate === undefined ? [] : [` rate: ${rate},`]),
530
+ ...(quota === undefined ? [] : [` quota: ${quota},`]),
494
531
  '',
495
- ' run: async (hands, held) => {',
532
+ ' run: async (opened, held) => {',
496
533
  ' const input = held.input',
497
534
  ` let ${ENTERED} = ''`,
498
535
  ' try {',
@@ -524,8 +561,10 @@ async function planned(): Promise<readonly Wanted[]> {
524
561
  const reach = await reaching()
525
562
  const found: Wanted[] = []
526
563
 
527
- const answers = Object.keys(reach).filter((one) => Object.keys(reach[one]?.calls ?? {}).length > 0)
528
- const may = [...SUPPLIES, ...answers]
564
+ const answers = Object.keys(reach).filter(
565
+ (one) => Object.keys(reach[one]?.calls ?? {}).length > 0 || holdsOf(one)?.takes !== 'calls',
566
+ )
567
+ const may = [...answers]
529
568
  for (const [id, one] of operations(pass, known)) {
530
569
  if (one.body === undefined) continue
531
570
  const silent = one.requires.filter((each) => reach[each] !== undefined && !answers.includes(each))
@@ -535,13 +574,13 @@ async function planned(): Promise<readonly Wanted[]> {
535
574
  because: silent
536
575
  .map((each) => {
537
576
  const how = reach[each]?.reach ?? 'nothing known'
538
- const instead =
539
- how === 'module' || how === 'cli'
540
- ? 'run it with `thread run ' + each.replace(/^[a-z]+_/, '') + '`'
541
- : 'reach the rows it keeps with `sm_store`'
577
+ const instead = 'declare what it answers with `thread create target call ' + each + ' <name>`'
578
+
579
+
580
+
542
581
  return (
543
582
  '`' + id + '` requires `' + each + '`, which is reached over ' + how + ' and answers no call, so there ' +
544
- 'is nothing for a node to be handed. ' + instead + ', give it a call with `thread create target call`, ' +
583
+ 'is nothing for a node to be handed. ' + instead + ', ' +
545
584
  'or take the word off that operation\'s row'
546
585
  )
547
586
  })
@@ -1,15 +1,14 @@
1
- import { existsSync, readFileSync, writeFileSync } from "../../core/files.js";
2
- import { valuesIn } from "../../core/rows.js";
1
+ import { existsSync, readFileSync, writeFileSync } from '../../integrations/disk.js';
2
+ import { valuesIn } from '../../core/rows.js';
3
3
  import { resolve } from 'node:path';
4
4
  import { argv, stderr, stdout } from 'node:process';
5
- import { exit } from "../../core/invoked.js";
6
- import { PUBLIC_ROLE as PUBLIC } from "../../core/actor.js";
7
- import { ROOT, descend } from "../../core/descend.js";
8
- import { forbids, runChecker } from "../../core/finding.js";
9
- import { findTree, inTree } from "../../core/tree.js";
10
- import { PERMITS_AT, grantedTwice, opensToEverybody, unanswerable } from "../access.js";
11
- import { DECLARED_SEAMS_AT } from "../capabilities.js";
12
- import { operations as woven, runtime, types } from "./seed.js";
5
+ import { exit } from '../../core/invoked.js';
6
+ import { PUBLIC_ROLE as PUBLIC } from '../../core/actor.js';
7
+ import { ROOT, descend } from '../../core/descend.js';
8
+ import { forbids, runChecker } from '../../core/finding.js';
9
+ import { findTree, inTree } from '../../core/tree.js';
10
+ import { PERMITS_AT, grantedTwice, opensToEverybody, unanswerable } from '../access.js';
11
+ import { operations as woven, runtime, types } from './seed.js';
13
12
  function stop(why) {
14
13
  stderr.write(`permits: ${why}\n`);
15
14
  exit(1);
@@ -153,7 +152,7 @@ function permitting() {
153
152
  ];
154
153
  return [
155
154
  `import type { Actor } from '${runtime(PERMITS_AT, '../../core/actor.ts')}'`,
156
- `import type { Row } from '${runtime(PERMITS_AT, '../seams.ts')}'`,
155
+ "import type { Row } from '" + runtime(PERMITS_AT, '../../integrations/target.ts') + "'",
157
156
  '',
158
157
  ...(grants.some((one) => one.when !== undefined) ? [...READS, ''] : []),
159
158
  ...(grants.some((one) => one.to !== undefined) ? [...WEARS, ''] : []),
@@ -183,5 +182,5 @@ if (CHECKING) {
183
182
  exit(findings.length === 0 ? 0 : 1);
184
183
  }
185
184
  writeFileSync(permitted, content);
186
- stdout.write(`permits: wrote ${PERMITS_AT} — ${count}. ${DECLARED_SEAMS_AT} hands it to dispatch as the gate every operation passes; ` +
185
+ stdout.write(`permits: wrote ${PERMITS_AT} — ${count}. Dispatch imports this check itself, so every operation passes it; ` +
187
186
  '`thread grant` adds a grant, and a refusal no grant can say is an invariant on the entity, or a rule from `thread create rule`.\n');
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync, writeFileSync } from '../../core/files.ts'
1
+ import { existsSync, readFileSync, writeFileSync } from '../../integrations/disk.ts'
2
2
  import { valuesIn } from '../../core/rows.ts'
3
3
  import { dirname, resolve } from 'node:path'
4
4
  import { argv, stderr, stdout } from 'node:process'
@@ -12,7 +12,6 @@ import type { Condition, Operand } from '../../core/condition.ts'
12
12
  import { findTree, inTree } from '../../core/tree.ts'
13
13
 
14
14
  import { PERMITS_AT, grantedTwice, opensToEverybody, unanswerable, type Grant } from '../access.ts'
15
- import { DECLARED_SEAMS_AT } from '../capabilities.ts'
16
15
  import { operations as woven, runtime, types } from './seed.ts'
17
16
 
18
17
  function stop(why: string): never {
@@ -180,7 +179,7 @@ function permitting(): string {
180
179
 
181
180
  return [
182
181
  `import type { Actor } from '${runtime(PERMITS_AT, '../../core/actor.ts')}'`,
183
- `import type { Row } from '${runtime(PERMITS_AT, '../seams.ts')}'`,
182
+ "import type { Row } from '" + runtime(PERMITS_AT, '../../integrations/target.ts') + "'",
184
183
  '',
185
184
  ...(grants.some((one) => one.when !== undefined) ? [...READS, ''] : []),
186
185
  ...(grants.some((one) => one.to !== undefined) ? [...WEARS, ''] : []),
@@ -218,6 +217,6 @@ if (CHECKING) {
218
217
 
219
218
  writeFileSync(permitted, content)
220
219
  stdout.write(
221
- `permits: wrote ${PERMITS_AT} — ${count}. ${DECLARED_SEAMS_AT} hands it to dispatch as the gate every operation passes; ` +
220
+ `permits: wrote ${PERMITS_AT} — ${count}. Dispatch imports this check itself, so every operation passes it; ` +
222
221
  '`thread grant` adds a grant, and a refusal no grant can say is an invariant on the entity, or a rule from `thread create rule`.\n',
223
222
  )
@@ -11,6 +11,7 @@ interface Woven {
11
11
  readonly body?: string;
12
12
  readonly requires: readonly string[];
13
13
  readonly stray: readonly string[];
14
+ readonly timeout?: number;
14
15
  }
15
16
  export declare function operations(pass: Pass, known: ReadonlySet<string>): ReadonlyMap<string, Woven>;
16
17
  export declare const problem: (id: string, one: Woven) => string | undefined;