@prestack/thread 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/dist/core/{asking.d.ts → answers.d.ts} +6 -14
  3. package/dist/core/{asking.js → answers.js} +13 -332
  4. package/dist/core/{asking.ts → answers.ts} +14 -357
  5. package/dist/core/attach.js +2 -2
  6. package/dist/core/attach.ts +2 -3
  7. package/dist/core/chain.js +4 -11
  8. package/dist/core/chain.ts +4 -3
  9. package/dist/core/client.d.ts +57 -0
  10. package/dist/core/client.js +186 -0
  11. package/dist/core/client.ts +227 -0
  12. package/dist/core/descend.d.ts +2 -0
  13. package/dist/core/descend.js +109 -16
  14. package/dist/core/descend.ts +120 -16
  15. package/dist/core/files.d.ts +45 -0
  16. package/dist/core/files.js +95 -0
  17. package/dist/core/files.ts +137 -0
  18. package/dist/core/init.d.ts +1 -0
  19. package/dist/core/init.js +10 -2
  20. package/dist/core/init.ts +8 -2
  21. package/dist/core/invoked.js +1 -1
  22. package/dist/core/invoked.ts +1 -1
  23. package/dist/core/rows.d.ts +2 -0
  24. package/dist/core/rows.js +65 -0
  25. package/dist/core/rows.ts +58 -0
  26. package/dist/core/tree.js +1 -1
  27. package/dist/core/tree.ts +1 -1
  28. package/dist/derivation/attach.js +0 -12
  29. package/dist/derivation/attach.ts +0 -12
  30. package/dist/derivation/generators/build.js +8 -7
  31. package/dist/derivation/generators/build.ts +8 -7
  32. package/dist/derivation/generators/release.d.ts +1 -1
  33. package/dist/derivation/generators/release.js +15 -23
  34. package/dist/derivation/generators/release.ts +15 -15
  35. package/dist/integrations/attach.js +1 -19
  36. package/dist/integrations/attach.ts +1 -19
  37. package/dist/integrations/generators/read.js +2 -2
  38. package/dist/integrations/generators/read.ts +4 -4
  39. package/dist/integrations/generators/vault.js +4 -12
  40. package/dist/integrations/generators/vault.ts +4 -4
  41. package/dist/integrations/module.js +5 -3
  42. package/dist/integrations/module.ts +5 -3
  43. package/dist/integrations/vault.js +5 -5
  44. package/dist/integrations/vault.ts +5 -5
  45. package/dist/integrity/attach.js +0 -12
  46. package/dist/integrity/attach.ts +0 -12
  47. package/dist/integrity/check-threads.js +1 -1
  48. package/dist/integrity/check-threads.ts +1 -1
  49. package/dist/integrity/constraint.d.ts +11 -2
  50. package/dist/integrity/constraint.js +163 -20
  51. package/dist/integrity/constraint.ts +174 -22
  52. package/dist/integrity/generators/compiler.js +1 -1
  53. package/dist/integrity/generators/compiler.ts +1 -1
  54. package/dist/integrity/generators/gate.js +8 -16
  55. package/dist/integrity/generators/gate.ts +8 -7
  56. package/dist/integrity/generators/publish.js +14 -26
  57. package/dist/integrity/generators/publish.ts +14 -17
  58. package/dist/integrity/generators/trial.d.ts +2 -2
  59. package/dist/integrity/generators/trial.js +108 -50
  60. package/dist/integrity/generators/trial.ts +107 -48
  61. package/dist/integrity/lint.js +3 -3
  62. package/dist/integrity/lint.ts +3 -3
  63. package/dist/integrity/lsp/diagnostics.js +1 -1
  64. package/dist/integrity/lsp/diagnostics.ts +1 -1
  65. package/dist/integrity/lsp/lint.js +1 -1
  66. package/dist/integrity/lsp/lint.ts +1 -1
  67. package/dist/integrity/slopnator.d.ts +1 -14
  68. package/dist/integrity/slopnator.js +8 -40
  69. package/dist/integrity/slopnator.ts +9 -51
  70. package/dist/integrity/slopnators/sl_broken_lineage.js +4 -2
  71. package/dist/integrity/slopnators/sl_broken_lineage.ts +4 -2
  72. package/dist/integrity/slopnators/sl_declared_elsewhere.js +24 -3
  73. package/dist/integrity/slopnators/sl_declared_elsewhere.ts +24 -3
  74. package/dist/integrity/slopnators/sl_derived_drift.js +10 -4
  75. package/dist/integrity/slopnators/sl_derived_drift.ts +10 -4
  76. package/dist/integrity/slopnators/sl_inert_island.js +7 -13
  77. package/dist/integrity/slopnators/sl_inert_island.ts +7 -16
  78. package/dist/integrity/slopnators/sl_inert_slopnator.js +8 -8
  79. package/dist/integrity/slopnators/sl_inert_slopnator.ts +8 -8
  80. package/dist/integrity/slopnators/sl_missing_row.js +14 -9
  81. package/dist/integrity/slopnators/sl_missing_row.ts +14 -10
  82. package/dist/integrity/slopnators/sl_no_child_process.js +8 -8
  83. package/dist/integrity/slopnators/sl_no_child_process.ts +8 -8
  84. package/dist/integrity/slopnators/sl_no_import_cycle.js +1 -1
  85. package/dist/integrity/slopnators/sl_no_import_cycle.ts +1 -1
  86. package/dist/integrity/slopnators/sl_no_such_command.js +20 -5
  87. package/dist/integrity/slopnators/sl_no_such_command.ts +22 -5
  88. package/dist/integrity/slopnators/sl_only_takes_a_literal.js +8 -8
  89. package/dist/integrity/slopnators/sl_only_takes_a_literal.ts +8 -8
  90. package/dist/integrity/slopnators/sl_stale_path.js +91 -18
  91. package/dist/integrity/slopnators/sl_stale_path.ts +97 -18
  92. package/dist/integrity/slopnators/sl_twice_meant.js +25 -2
  93. package/dist/integrity/slopnators/sl_twice_meant.ts +28 -2
  94. package/dist/integrity/slopnators/sl_twice_parented.js +26 -5
  95. package/dist/integrity/slopnators/sl_twice_parented.ts +26 -5
  96. package/dist/integrity/slopnators/sl_undeclared_node.js +18 -2
  97. package/dist/integrity/slopnators/sl_undeclared_node.ts +18 -2
  98. package/dist/integrity/slopnators/sl_undeclared_operation.js +3 -1
  99. package/dist/integrity/slopnators/sl_undeclared_operation.ts +3 -1
  100. package/dist/integrity/slopnators/sl_undeclared_variant.js +6 -2
  101. package/dist/integrity/slopnators/sl_undeclared_variant.ts +6 -2
  102. package/dist/integrity/slopnators/sl_ungoverned_island.js +3 -4
  103. package/dist/integrity/slopnators/sl_ungoverned_island.ts +3 -4
  104. package/dist/integrity/slopnators/sl_unkept_rows.js +1 -1
  105. package/dist/integrity/slopnators/sl_unkept_rows.ts +1 -1
  106. package/dist/integrity/slopnators/sl_unpaired_member.js +13 -8
  107. package/dist/integrity/slopnators/sl_unpaired_member.ts +16 -8
  108. package/dist/integrity/slopnators/sl_unpaired_slopnator.js +16 -3
  109. package/dist/integrity/slopnators/sl_unpaired_slopnator.ts +16 -3
  110. package/dist/integrity/slopnators/sl_unthreaded.d.ts +1 -0
  111. package/dist/integrity/slopnators/sl_unthreaded.js +18 -10
  112. package/dist/integrity/slopnators/sl_unthreaded.ts +19 -11
  113. package/dist/integrity/slopnators/sl_untranslated_key.js +1 -1
  114. package/dist/integrity/slopnators/sl_untranslated_key.ts +1 -1
  115. package/dist/integrity/slopnators/sl_unversioned.js +16 -2
  116. package/dist/integrity/slopnators/sl_unversioned.ts +16 -2
  117. package/dist/integrity/sweep.js +17 -3
  118. package/dist/integrity/sweep.ts +20 -3
  119. package/dist/knowledge/attach.js +0 -6
  120. package/dist/knowledge/attach.ts +0 -6
  121. package/dist/knowledge/generators/docsgen.js +12 -3
  122. package/dist/knowledge/generators/docsgen.ts +12 -2
  123. package/dist/knowledge/generators/glossary.js +1 -1
  124. package/dist/knowledge/generators/glossary.ts +1 -1
  125. package/dist/operations/attach.js +2 -26
  126. package/dist/operations/attach.ts +2 -27
  127. package/dist/operations/dispatch.js +2 -3
  128. package/dist/operations/dispatch.ts +2 -3
  129. package/dist/operations/generators/capability.js +4 -7
  130. package/dist/operations/generators/capability.ts +3 -6
  131. package/dist/operations/generators/compile.js +8 -13
  132. package/dist/operations/generators/compile.ts +8 -4
  133. package/dist/operations/generators/permits.js +4 -13
  134. package/dist/operations/generators/permits.ts +3 -3
  135. package/dist/operations/generators/seed.js +5 -2
  136. package/dist/operations/generators/seed.ts +6 -2
  137. package/dist/operations/generators/trial.js +10 -10
  138. package/dist/operations/generators/trial.ts +10 -10
  139. package/dist/operations/http.js +4 -1
  140. package/dist/operations/http.ts +6 -1
  141. package/package.json +2 -2
  142. package/dist/core/cli.d.ts +0 -2
  143. package/dist/core/cli.js +0 -1761
  144. package/dist/core/cli.ts +0 -2004
  145. package/dist/core/generators/meta.d.ts +0 -2
  146. package/dist/core/generators/meta.js +0 -829
  147. package/dist/core/generators/meta.ts +0 -1006
  148. package/dist/derivation/generators/derivation.d.ts +0 -3
  149. package/dist/derivation/generators/derivation.js +0 -273
  150. package/dist/derivation/generators/derivation.ts +0 -347
  151. package/dist/derivation/makers/release.d.ts +0 -1
  152. package/dist/derivation/makers/release.js +0 -107
  153. package/dist/derivation/makers/release.ts +0 -135
  154. package/dist/integrations/generators/secret.d.ts +0 -1
  155. package/dist/integrations/generators/secret.js +0 -233
  156. package/dist/integrations/generators/secret.ts +0 -289
  157. package/dist/integrations/generators/target.d.ts +0 -1
  158. package/dist/integrations/generators/target.js +0 -775
  159. package/dist/integrations/generators/target.ts +0 -944
  160. package/dist/integrity/generators/rule.d.ts +0 -2
  161. package/dist/integrity/generators/rule.js +0 -213
  162. package/dist/integrity/generators/rule.ts +0 -271
  163. package/dist/integrity/generators/seal.d.ts +0 -4
  164. package/dist/integrity/generators/seal.js +0 -101
  165. package/dist/integrity/generators/seal.ts +0 -117
  166. package/dist/integrity/sealed.d.ts +0 -1
  167. package/dist/integrity/sealed.js +0 -56
  168. package/dist/integrity/sealed.ts +0 -56
  169. package/dist/knowledge/generators/skills.d.ts +0 -1
  170. package/dist/knowledge/generators/skills.js +0 -222
  171. package/dist/knowledge/generators/skills.ts +0 -263
  172. package/dist/operations/generators/grant.d.ts +0 -1
  173. package/dist/operations/generators/grant.js +0 -267
  174. package/dist/operations/generators/grant.ts +0 -336
  175. package/dist/operations/generators/operation.d.ts +0 -1
  176. package/dist/operations/generators/operation.js +0 -811
  177. package/dist/operations/generators/operation.ts +0 -972
  178. package/dist/operations/makers/capability.d.ts +0 -1
  179. package/dist/operations/makers/capability.js +0 -117
  180. package/dist/operations/makers/capability.ts +0 -166
  181. package/dist/operations/makers/trial.d.ts +0 -1
  182. package/dist/operations/makers/trial.js +0 -413
  183. package/dist/operations/makers/trial.ts +0 -520
package/dist/core/rows.ts CHANGED
@@ -252,6 +252,64 @@ function stated(node: ts.ObjectLiteralExpression, field: string): Bounds | undef
252
252
 
253
253
  export const quoted = (one: string): string => `'${one.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\n/g, '\\n')}'`
254
254
 
255
+ const UNREAD = Symbol.for('thread.unread')
256
+
257
+ function valued(node: ts.Expression): unknown {
258
+ if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) return node.text
259
+ if (ts.isNumericLiteral(node)) return Number(node.text)
260
+ if (node.kind === ts.SyntaxKind.TrueKeyword) return true
261
+ if (node.kind === ts.SyntaxKind.FalseKeyword) return false
262
+ if (node.kind === ts.SyntaxKind.NullKeyword) return null
263
+ if (ts.isAsExpression(node) || ts.isSatisfiesExpression(node) || ts.isParenthesizedExpression(node)) return valued(node.expression)
264
+ if (ts.isPrefixUnaryExpression(node) && node.operator === ts.SyntaxKind.MinusToken) {
265
+ const held = valued(node.operand)
266
+ return typeof held === 'number' ? -held : UNREAD
267
+ }
268
+ if (ts.isArrayLiteralExpression(node)) {
269
+ const held: unknown[] = []
270
+ for (const one of node.elements) {
271
+ const each = valued(one)
272
+ if (each === UNREAD) return UNREAD
273
+ held.push(each)
274
+ }
275
+ return held
276
+ }
277
+ if (ts.isObjectLiteralExpression(node)) {
278
+ const held: Record<string, unknown> = {}
279
+ for (const one of node.properties) {
280
+ if (!ts.isPropertyAssignment(one)) return UNREAD
281
+ const key = keyed(one)
282
+ if (key === undefined) return UNREAD
283
+ const each = valued(one.initializer)
284
+ if (each === UNREAD) return UNREAD
285
+ held[key] = each
286
+ }
287
+ return held
288
+ }
289
+ return UNREAD
290
+ }
291
+
292
+ function taken(text: string): readonly (readonly [string, unknown])[] {
293
+ const found: (readonly [string, unknown])[] = []
294
+ walk(tree(text), (node) => {
295
+ if (!ts.isVariableDeclaration(node) || node.initializer === undefined || !ts.isIdentifier(node.name)) return
296
+ found.push([node.name.text, valued(node.initializer)])
297
+ })
298
+ return found
299
+ }
300
+
301
+ export function valuesIn(text: string): Readonly<Record<string, unknown>> {
302
+ const found: Record<string, unknown> = {}
303
+ for (const [name, held] of taken(text)) {
304
+ if (held !== UNREAD) found[name] = held
305
+ }
306
+ return found
307
+ }
308
+
309
+ export function unread(text: string): readonly string[] {
310
+ return taken(text).filter(([, held]) => held === UNREAD).map(([name]) => name)
311
+ }
312
+
255
313
  export const STATED = ['at', 'describes', 'version']
256
314
 
257
315
  export function reconciled(held: string, source: string, fields: readonly string[]): string {
package/dist/core/tree.js CHANGED
@@ -1,4 +1,4 @@
1
- import { existsSync, readdirSync, statSync } from 'node:fs';
1
+ import { existsSync, readdirSync, statSync } from "./files.js";
2
2
  import { dirname, join, relative, resolve } from 'node:path';
3
3
  import { cwd } from 'node:process';
4
4
  const NAMES = ['_threads', 'threads'];
package/dist/core/tree.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { existsSync, readdirSync, statSync } from 'node:fs'
1
+ import { existsSync, readdirSync, statSync } from './files.ts'
2
2
  import { dirname, join, relative, resolve } from 'node:path'
3
3
  import { cwd } from 'node:process'
4
4
 
@@ -39,18 +39,6 @@ const SHIPPED = [
39
39
  id: 'release-generator',
40
40
  source: " {\n id: 'release-generator',\n at: 'node_modules/@prestack/thread/dist/derivation/generators/release.js',\n describes: 'The writer of what a host reads to run this app — it derives the config from what the app already declares, its own build and start commands and the names of every secret it says it must be given, and refuses to write while this app installs a package of this framework as a dependency, because what a host runs may hold nothing of the scaffolding that assembled it.',\n version: 1,\n by: 'thread release',\n runs: 'thread release --check',\n },",
41
41
  },
42
- {
43
- into: 'derivation.ts',
44
- list: 'GENERATORS',
45
- id: 'release-noun',
46
- source: " {\n id: 'release-noun',\n at: 'node_modules/@prestack/thread/dist/derivation/makers/release.js',\n describes: 'The command that declares where this app goes when it leaves your machine. It writes the row saying where this app goes and nothing else, because everything the config needs is already declared somewhere and asking for it again would be the app’s own facts typed a second time.',\n version: 1,\n by: 'thread create release',\n },",
47
- },
48
- {
49
- into: 'derivation.ts',
50
- list: 'GENERATORS',
51
- id: 'generator-noun',
52
- source: " {\n id: 'generator-noun',\n at: 'node_modules/@prestack/thread/dist/derivation/generators/derivation.js',\n describes: 'Declares a generator this app derives a file with. `thread create generator` asks what it is, where its file goes and the command that writes it, then writes the row and seeds the file beside it — so a generator arrives through the same wizard as everything else, and the command it names exists from that moment because the CLI reads every `by:` the tree states.',\n version: 1,\n by: 'thread create generator',\n },",
53
- },
54
42
  ];
55
43
  export const ATTACH = {
56
44
  attaches: SEEDED.attaches,
@@ -46,18 +46,6 @@ const SHIPPED: readonly { readonly into: string; readonly list: string; readonly
46
46
  id: 'release-generator',
47
47
  source: " {\n id: 'release-generator',\n at: 'node_modules/@prestack/thread/dist/derivation/generators/release.js',\n describes: 'The writer of what a host reads to run this app — it derives the config from what the app already declares, its own build and start commands and the names of every secret it says it must be given, and refuses to write while this app installs a package of this framework as a dependency, because what a host runs may hold nothing of the scaffolding that assembled it.',\n version: 1,\n by: 'thread release',\n runs: 'thread release --check',\n },",
48
48
  },
49
- {
50
- into: 'derivation.ts',
51
- list: 'GENERATORS',
52
- id: 'release-noun',
53
- source: " {\n id: 'release-noun',\n at: 'node_modules/@prestack/thread/dist/derivation/makers/release.js',\n describes: 'The command that declares where this app goes when it leaves your machine. It writes the row saying where this app goes and nothing else, because everything the config needs is already declared somewhere and asking for it again would be the app’s own facts typed a second time.',\n version: 1,\n by: 'thread create release',\n },",
54
- },
55
- {
56
- into: 'derivation.ts',
57
- list: 'GENERATORS',
58
- id: 'generator-noun',
59
- source: " {\n id: 'generator-noun',\n at: 'node_modules/@prestack/thread/dist/derivation/generators/derivation.js',\n describes: 'Declares a generator this app derives a file with. `thread create generator` asks what it is, where its file goes and the command that writes it, then writes the row and seeds the file beside it — so a generator arrives through the same wizard as everything else, and the command it names exists from that moment because the CLI reads every `by:` the tree states.',\n version: 1,\n by: 'thread create generator',\n },",
60
- },
61
49
  ]
62
50
  export const ATTACH: Attaching = {
63
51
  attaches: SEEDED.attaches,
@@ -6,13 +6,14 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
6
6
  }
7
7
  return path;
8
8
  };
9
- import { existsSync, readFileSync } from 'node:fs';
10
9
  import { relative, resolve } from 'node:path';
11
10
  import { argv, stderr, stdout } from 'node:process';
12
11
  import { pathToFileURL } from 'node:url';
13
12
  import { build } from 'esbuild';
14
13
  import { descend, reached } from "../../core/descend.js";
14
+ import { existsSync, readFileSync } from "../../core/files.js";
15
15
  import { exit, invoked } from "../../core/invoked.js";
16
+ import { valuesIn } from "../../core/rows.js";
16
17
  import { findTree } from "../../core/tree.js";
17
18
  import { servesBrowser } from "../../integrations/target.js";
18
19
  const TREE = findTree();
@@ -57,23 +58,23 @@ const JSX = /\.(c|m)?(t|j)sx$/;
57
58
  function browsing(entry) {
58
59
  return JSX.test(entry);
59
60
  }
60
- async function sheet(file, list) {
61
+ function sheet(file, list) {
61
62
  const path = resolve(ROOT, `${TREE.name}/${file}`);
62
63
  if (!existsSync(path))
63
64
  return [];
64
65
  try {
65
- const held = (await import(__rewriteRelativeImportExtension(pathToFileURL(path).href)));
66
+ const held = valuesIn(readFileSync(path, 'utf8'));
66
67
  return held[list] ?? [];
67
68
  }
68
69
  catch {
69
70
  return [];
70
71
  }
71
72
  }
72
- async function withheld(pass) {
73
- const targets = await sheet('targets.ts', 'TARGETS');
73
+ function withheld(pass) {
74
+ const targets = sheet('targets.ts', 'TARGETS');
74
75
  if (targets.length === 0)
75
76
  return new Map();
76
- const secrets = await sheet('secrets.ts', 'SECRETS');
77
+ const secrets = sheet('secrets.ts', 'SECRETS');
77
78
  const because = new Map();
78
79
  for (const one of targets) {
79
80
  const said = servesBrowser(one, secrets);
@@ -184,7 +185,7 @@ async function main() {
184
185
  exit(1);
185
186
  }
186
187
  const forBrowser = browsing(entry);
187
- const refusals = forBrowser ? await withheld(pass) : new Map();
188
+ const refusals = forBrowser ? withheld(pass) : new Map();
188
189
  const held = await build({
189
190
  entryPoints: [resolve(ROOT, entry)],
190
191
  bundle: true,
@@ -1,4 +1,3 @@
1
- import { existsSync, readFileSync } from 'node:fs'
2
1
  import { relative, resolve } from 'node:path'
3
2
  import { argv, stderr, stdout } from 'node:process'
4
3
  import { pathToFileURL } from 'node:url'
@@ -6,7 +5,9 @@ import { pathToFileURL } from 'node:url'
6
5
  import { build } from 'esbuild'
7
6
 
8
7
  import { descend, reached, type Pass } from '../../core/descend.ts'
8
+ import { existsSync, readFileSync } from '../../core/files.ts'
9
9
  import { exit, invoked } from '../../core/invoked.ts'
10
+ import { valuesIn } from '../../core/rows.ts'
10
11
  import { findTree } from '../../core/tree.ts'
11
12
  import type { Secret } from '../../integrations/secret.ts'
12
13
  import { servesBrowser, type Target } from '../../integrations/target.ts'
@@ -59,21 +60,21 @@ function browsing(entry: string): boolean {
59
60
  return JSX.test(entry)
60
61
  }
61
62
 
62
- async function sheet<T>(file: string, list: string): Promise<readonly T[]> {
63
+ function sheet<T>(file: string, list: string): readonly T[] {
63
64
  const path = resolve(ROOT, `${TREE.name}/${file}`)
64
65
  if (!existsSync(path)) return []
65
66
  try {
66
- const held = (await import(pathToFileURL(path).href)) as Record<string, readonly T[] | undefined>
67
+ const held = valuesIn(readFileSync(path, 'utf8')) as Record<string, readonly T[] | undefined>
67
68
  return held[list] ?? []
68
69
  } catch {
69
70
  return []
70
71
  }
71
72
  }
72
73
 
73
- async function withheld(pass: Pass): Promise<ReadonlyMap<string, string>> {
74
- const targets = await sheet<Target>('targets.ts', 'TARGETS')
74
+ function withheld(pass: Pass): ReadonlyMap<string, string> {
75
+ const targets = sheet<Target>('targets.ts', 'TARGETS')
75
76
  if (targets.length === 0) return new Map()
76
- const secrets = await sheet<Secret>('secrets.ts', 'SECRETS')
77
+ const secrets = sheet<Secret>('secrets.ts', 'SECRETS')
77
78
 
78
79
  const because = new Map<string, string>()
79
80
  for (const one of targets) {
@@ -193,7 +194,7 @@ async function main(): Promise<void> {
193
194
  }
194
195
 
195
196
  const forBrowser = browsing(entry)
196
- const refusals = forBrowser ? await withheld(pass) : new Map<string, string>()
197
+ const refusals = forBrowser ? withheld(pass) : new Map<string, string>()
197
198
 
198
199
  const held = await build({
199
200
  entryPoints: [resolve(ROOT, entry)],
@@ -1,3 +1,3 @@
1
1
  import { CHECKED_BY, WRITES } from '../release.ts';
2
- declare function made(): Promise<ReadonlyMap<string, string>>;
2
+ declare function made(): ReadonlyMap<string, string>;
3
3
  export { CHECKED_BY, WRITES, made };
@@ -1,41 +1,33 @@
1
- var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
- if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
- return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
- return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
- });
6
- }
7
- return path;
8
- };
9
- import { existsSync, readFileSync, writeFileSync } from 'node:fs';
10
1
  import { join } from 'node:path';
11
2
  import { argv, stderr, stdout } from 'node:process';
12
- import { pathToFileURL } from 'node:url';
13
- import { marked, wordsIn } from "../../core/asking.js";
3
+ import { marked, wordsIn } from "../../core/answers.js";
4
+ import { existsSync, readFileSync, writeFileSync } from "../../core/files.js";
14
5
  import { exit, invoked } from "../../core/invoked.js";
6
+ import { valuesIn } from "../../core/rows.js";
15
7
  import { ours } from "../../core/scope.js";
16
8
  import { findTree, inTree } from "../../core/tree.js";
17
9
  import { CHECKED_BY, KINDS, LISTENS, SAID, WRITES, WRITTEN_BY, kindOf } from "../release.js";
18
10
  const TREE = findTree();
19
11
  const MANIFEST = 'package.json';
20
12
  const mark = (one) => marked([one.id ?? '', one.at ?? '']);
21
- async function releases() {
13
+ function releases() {
22
14
  const at = inTree(TREE, 'derivation.ts');
23
15
  if (!existsSync(at))
24
16
  return [];
25
17
  try {
26
- const held = (await import(__rewriteRelativeImportExtension(pathToFileURL(at).href)));
18
+ const held = valuesIn(readFileSync(at, 'utf8'));
27
19
  return held.DERIVATION?.derives ?? [];
28
20
  }
29
21
  catch {
30
22
  return [];
31
23
  }
32
24
  }
33
- async function named() {
25
+ function named() {
34
26
  const at = inTree(TREE, 'secrets.ts');
35
27
  if (!existsSync(at))
36
28
  return [];
37
29
  try {
38
- const held = (await import(__rewriteRelativeImportExtension(pathToFileURL(at).href)));
30
+ const held = valuesIn(readFileSync(at, 'utf8'));
39
31
  return (held.SECRETS ?? []).map((one) => one.id.toUpperCase()).sort();
40
32
  }
41
33
  catch {
@@ -94,10 +86,10 @@ function compose(id, secrets) {
94
86
  '',
95
87
  ].join('\n');
96
88
  }
97
- async function made() {
89
+ function made() {
98
90
  const found = new Map();
99
- const rows = await releases();
100
- const secrets = await named();
91
+ const rows = releases();
92
+ const secrets = named();
101
93
  const { build, start } = scripted();
102
94
  for (const one of rows) {
103
95
  const id = one.id;
@@ -121,8 +113,8 @@ function installed() {
121
113
  const held = JSON.parse(readFileSync(at, 'utf8'));
122
114
  return Object.keys(held.dependencies ?? {}).filter((one) => ours(one)).sort();
123
115
  }
124
- async function run() {
125
- const rows = await releases();
116
+ function run() {
117
+ const rows = releases();
126
118
  if (rows.length === 0) {
127
119
  stdout.write(`release: this app declares no release, so there is nowhere for it to go yet. Declare one with ` +
128
120
  `\`thread create release\` — it is ${KINDS.join(' or ')}, and the prefix on its id says which.\n`);
@@ -151,7 +143,7 @@ async function run() {
151
143
  }
152
144
  return 0;
153
145
  }
154
- const files = await made();
146
+ const files = made();
155
147
  const checking = argv.includes('--check');
156
148
  const shipped = installed();
157
149
  if (shipped.length > 0) {
@@ -185,9 +177,9 @@ async function run() {
185
177
  for (const [at, text] of files)
186
178
  writeFileSync(join(TREE.at, at), text, 'utf8');
187
179
  stdout.write(`release: wrote ${[...files.keys()].join(', ')} — built and started by what this app's own manifest ` +
188
- `declares, listening on ${String(LISTENS)}, naming ${String((await named()).length)} secret(s) and holding none of them.\n`);
180
+ `declares, listening on ${String(LISTENS)}, naming ${String(named().length)} secret(s) and holding none of them.\n`);
189
181
  return 0;
190
182
  }
191
183
  if (invoked(import.meta.url))
192
- exit(await run());
184
+ exit(run());
193
185
  export { CHECKED_BY, WRITES, made };
@@ -1,10 +1,10 @@
1
- import { existsSync, readFileSync, writeFileSync } from 'node:fs'
2
1
  import { join } from 'node:path'
3
2
  import { argv, stderr, stdout } from 'node:process'
4
- import { pathToFileURL } from 'node:url'
5
3
 
6
- import { marked, wordsIn } from '../../core/asking.ts'
4
+ import { marked, wordsIn } from '../../core/answers.ts'
5
+ import { existsSync, readFileSync, writeFileSync } from '../../core/files.ts'
7
6
  import { exit, invoked } from '../../core/invoked.ts'
7
+ import { valuesIn } from '../../core/rows.ts'
8
8
  import { ours } from '../../core/scope.ts'
9
9
  import { findTree, inTree } from '../../core/tree.ts'
10
10
 
@@ -21,22 +21,22 @@ interface Row {
21
21
 
22
22
  const mark = (one: Row): string => marked([one.id ?? '', one.at ?? ''])
23
23
 
24
- async function releases(): Promise<readonly Row[]> {
24
+ function releases(): readonly Row[] {
25
25
  const at = inTree(TREE, 'derivation.ts')
26
26
  if (!existsSync(at)) return []
27
27
  try {
28
- const held = (await import(pathToFileURL(at).href)) as { DERIVATION?: { readonly derives?: readonly Row[] } }
28
+ const held = valuesIn(readFileSync(at, 'utf8')) as { DERIVATION?: { readonly derives?: readonly Row[] } }
29
29
  return held.DERIVATION?.derives ?? []
30
30
  } catch {
31
31
  return []
32
32
  }
33
33
  }
34
34
 
35
- async function named(): Promise<readonly string[]> {
35
+ function named(): readonly string[] {
36
36
  const at = inTree(TREE, 'secrets.ts')
37
37
  if (!existsSync(at)) return []
38
38
  try {
39
- const held = (await import(pathToFileURL(at).href)) as { SECRETS?: readonly { readonly id: string }[] }
39
+ const held = valuesIn(readFileSync(at, 'utf8')) as { SECRETS?: readonly { readonly id: string }[] }
40
40
  return (held.SECRETS ?? []).map((one) => one.id.toUpperCase()).sort()
41
41
  } catch {
42
42
  return []
@@ -100,10 +100,10 @@ function compose(id: string, secrets: readonly string[]): string {
100
100
  ].join('\n')
101
101
  }
102
102
 
103
- async function made(): Promise<ReadonlyMap<string, string>> {
103
+ function made(): ReadonlyMap<string, string> {
104
104
  const found = new Map<string, string>()
105
- const rows = await releases()
106
- const secrets = await named()
105
+ const rows = releases()
106
+ const secrets = named()
107
107
  const { build, start } = scripted()
108
108
 
109
109
  for (const one of rows) {
@@ -128,8 +128,8 @@ function installed(): readonly string[] {
128
128
  return Object.keys(held.dependencies ?? {}).filter((one) => ours(one)).sort()
129
129
  }
130
130
 
131
- async function run(): Promise<number> {
132
- const rows = await releases()
131
+ function run(): number {
132
+ const rows = releases()
133
133
  if (rows.length === 0) {
134
134
  stdout.write(
135
135
  `release: this app declares no release, so there is nowhere for it to go yet. Declare one with ` +
@@ -164,7 +164,7 @@ async function run(): Promise<number> {
164
164
  return 0
165
165
  }
166
166
 
167
- const files = await made()
167
+ const files = made()
168
168
  const checking = argv.includes('--check')
169
169
 
170
170
  const shipped = installed()
@@ -203,11 +203,11 @@ async function run(): Promise<number> {
203
203
  for (const [at, text] of files) writeFileSync(join(TREE.at, at), text, 'utf8')
204
204
  stdout.write(
205
205
  `release: wrote ${[...files.keys()].join(', ')} — built and started by what this app's own manifest ` +
206
- `declares, listening on ${String(LISTENS)}, naming ${String((await named()).length)} secret(s) and holding none of them.\n`,
206
+ `declares, listening on ${String(LISTENS)}, naming ${String(named().length)} secret(s) and holding none of them.\n`,
207
207
  )
208
208
  return 0
209
209
  }
210
210
 
211
- if (invoked(import.meta.url)) exit(await run())
211
+ if (invoked(import.meta.url)) exit(run())
212
212
 
213
213
  export { CHECKED_BY, WRITES, made }
@@ -82,7 +82,7 @@ const OWN = [
82
82
  },
83
83
  ];
84
84
  const SEEDED = {
85
- attaches: ['@prestack/thread/derivation/attach'],
85
+ attaches: ['@prestack/thread/derivation/attach', '@prestack/thread/knowledge/attach'],
86
86
  id: 'integrations',
87
87
  declares: [
88
88
  ' {',
@@ -94,18 +94,6 @@ const SEEDED = {
94
94
  ].join('\n'),
95
95
  };
96
96
  const SHIPPED = [
97
- {
98
- into: 'derivation.ts',
99
- list: 'GENERATORS',
100
- id: 'target-generator',
101
- source: " {\n id: 'target-generator',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/target.js',\n describes: 'The command that declares a place this app reaches. Asked for nothing it lists every target already here with what it accepts and what it requires, every way a target may be reached and what each way can hold, and every secret this app declares. It then asks what the place is called and how it is reached, puts the prefix on the id, asks which secret is its address and which go into a header, and writes the row — so a target arrives declared with its credential named rather than with an environment variable typed into whatever needed it.',\n version: 1,\n by: 'thread create target',\n },",
102
- },
103
- {
104
- into: 'derivation.ts',
105
- list: 'GENERATORS',
106
- id: 'secret-generator',
107
- source: " {\n id: 'secret-generator',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/secret.js',\n describes: 'The command that declares a value this app must be given, and the only thing that ever takes one. It asks what the secret is for and who may hold it, puts `sec_` or `pub_` on the id accordingly, and writes the row. Then it asks a person for the value, with the terminal\\'s echo off, and seals it into the store beside the tree under a key it generates and never prints. The value goes from the keyboard into the sealed store and nowhere else: not into the row, not into the output, not into whatever transcript is being kept of the session that ran it.',\n version: 1,\n by: 'thread create secret',\n },",
108
- },
109
97
  {
110
98
  into: 'derivation.ts',
111
99
  list: 'GENERATORS',
@@ -118,12 +106,6 @@ const SHIPPED = [
118
106
  id: 'inspect-generator',
119
107
  source: " {\n id: 'inspect-generator',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/read.js',\n describes: 'The one command for reading what this app declares. Asked for nothing it prints every sheet and what each holds; asked for a word it prints every row whose id or sentence carries it. It reads the tree rather than the files, which is the whole reason it exists: a row is a nested TypeScript literal and a search over lines answers questions about text while the questions people actually ask are about rows.',\n version: 1,\n by: 'thread inspect',\n },",
120
108
  },
121
- {
122
- into: 'derivation.ts',
123
- list: 'GENERATORS',
124
- id: 'call-noun',
125
- source: " {\n id: 'call-noun',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/target.js',\n describes: 'The command that makes an already-declared call happen. `thread run call <id>` asks for whatever its path leaves to be filled in — `{like_this}` — by name, and for a call that writes (POST, PUT, PATCH) a JSON body, then resolves the target\\'s address and every credential it requires through the vault at the moment of the call and never before. Nothing here ever names a vendor: a call already states its target, its method and its path, and which one runs is read off its own id, exactly as `thread run trial` reads an operation\\'s.',\n version: 1,\n by: 'thread run call',\n },",
126
- },
127
109
  ];
128
110
  export const ATTACH = {
129
111
  attaches: SEEDED.attaches,
@@ -107,7 +107,7 @@ const OWN: readonly { readonly into: string; readonly list: string; readonly id:
107
107
  ]
108
108
 
109
109
  const SEEDED = {
110
- attaches: ['@prestack/thread/derivation/attach'] as const,
110
+ attaches: ['@prestack/thread/derivation/attach', '@prestack/thread/knowledge/attach'] as const,
111
111
  id: 'integrations',
112
112
  declares: [
113
113
  ' {',
@@ -120,18 +120,6 @@ const SEEDED = {
120
120
  }
121
121
 
122
122
  const SHIPPED: readonly { readonly into: string; readonly list: string; readonly id: string; readonly source: string }[] = [
123
- {
124
- into: 'derivation.ts',
125
- list: 'GENERATORS',
126
- id: 'target-generator',
127
- source: " {\n id: 'target-generator',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/target.js',\n describes: 'The command that declares a place this app reaches. Asked for nothing it lists every target already here with what it accepts and what it requires, every way a target may be reached and what each way can hold, and every secret this app declares. It then asks what the place is called and how it is reached, puts the prefix on the id, asks which secret is its address and which go into a header, and writes the row — so a target arrives declared with its credential named rather than with an environment variable typed into whatever needed it.',\n version: 1,\n by: 'thread create target',\n },",
128
- },
129
- {
130
- into: 'derivation.ts',
131
- list: 'GENERATORS',
132
- id: 'secret-generator',
133
- source: " {\n id: 'secret-generator',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/secret.js',\n describes: 'The command that declares a value this app must be given, and the only thing that ever takes one. It asks what the secret is for and who may hold it, puts `sec_` or `pub_` on the id accordingly, and writes the row. Then it asks a person for the value, with the terminal\\'s echo off, and seals it into the store beside the tree under a key it generates and never prints. The value goes from the keyboard into the sealed store and nowhere else: not into the row, not into the output, not into whatever transcript is being kept of the session that ran it.',\n version: 1,\n by: 'thread create secret',\n },",
134
- },
135
123
  {
136
124
  into: 'derivation.ts',
137
125
  list: 'GENERATORS',
@@ -144,12 +132,6 @@ const SHIPPED: readonly { readonly into: string; readonly list: string; readonly
144
132
  id: 'inspect-generator',
145
133
  source: " {\n id: 'inspect-generator',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/read.js',\n describes: 'The one command for reading what this app declares. Asked for nothing it prints every sheet and what each holds; asked for a word it prints every row whose id or sentence carries it. It reads the tree rather than the files, which is the whole reason it exists: a row is a nested TypeScript literal and a search over lines answers questions about text while the questions people actually ask are about rows.',\n version: 1,\n by: 'thread inspect',\n },",
146
134
  },
147
- {
148
- into: 'derivation.ts',
149
- list: 'GENERATORS',
150
- id: 'call-noun',
151
- source: " {\n id: 'call-noun',\n at: 'node_modules/@prestack/thread/dist/integrations/generators/target.js',\n describes: 'The command that makes an already-declared call happen. `thread run call <id>` asks for whatever its path leaves to be filled in — `{like_this}` — by name, and for a call that writes (POST, PUT, PATCH) a JSON body, then resolves the target\\'s address and every credential it requires through the vault at the moment of the call and never before. Nothing here ever names a vendor: a call already states its target, its method and its path, and which one runs is read off its own id, exactly as `thread run trial` reads an operation\\'s.',\n version: 1,\n by: 'thread run call',\n },",
152
- },
153
135
  ]
154
136
  export const ATTACH: Attaching = {
155
137
  attaches: SEEDED.attaches,
@@ -1,6 +1,6 @@
1
1
  import { stdout } from 'node:process';
2
2
  import { exit } from "../../core/invoked.js";
3
- import { wordsIn } from "../../core/asking.js";
3
+ import { TYPED, wordsIn } from "../../core/answers.js";
4
4
  import { descend } from "../../core/descend.js";
5
5
  const words = wordsIn([]);
6
6
  const looking = words.join(' ').trim().toLowerCase();
@@ -43,7 +43,7 @@ if (looking === '') {
43
43
  out.push(` ${String(held.length).padStart(4)} ${file}`);
44
44
  }
45
45
  out.unshift(`${String(files.length)} sheet(s) in this tree, and what each holds:`, '');
46
- out.push('', 'Name a word to read the rows themselves — every row whose id, sentence, path, command or', 'requirement carries it, each with what it means:', '', ' npx thread inspect element', ' npx thread inspect variant', ' npx thread inspect <any word above, or any word this tree coins>', '');
46
+ out.push('', 'Name a word to read the rows themselves — every row whose id, sentence, path, command or', 'requirement carries it, each with what it means:', '', ` ${TYPED} inspect element`, ` ${TYPED} inspect variant`, ` ${TYPED} inspect <any word above, or any word this tree coins>`, '');
47
47
  stdout.write(`${out.join('\n')}\n`);
48
48
  stdout.write(`read: ${String(rows)} row(s) across ${String(pass.declarations)} declaration(s), ` +
49
49
  `and ${String(pass.findings.length)} finding(s) the gate would report.\n`);
@@ -1,7 +1,7 @@
1
1
  import { stdout } from 'node:process'
2
2
 
3
3
  import { exit } from '../../core/invoked.ts'
4
- import { wordsIn } from '../../core/asking.ts'
4
+ import { TYPED, wordsIn } from '../../core/answers.ts'
5
5
  import { descend, type Row } from '../../core/descend.ts'
6
6
 
7
7
  const words = wordsIn([])
@@ -63,9 +63,9 @@ if (looking === '') {
63
63
  'Name a word to read the rows themselves — every row whose id, sentence, path, command or',
64
64
  'requirement carries it, each with what it means:',
65
65
  '',
66
- ' npx thread inspect element',
67
- ' npx thread inspect variant',
68
- ' npx thread inspect <any word above, or any word this tree coins>',
66
+ ` ${TYPED} inspect element`,
67
+ ` ${TYPED} inspect variant`,
68
+ ` ${TYPED} inspect <any word above, or any word this tree coins>`,
69
69
  '',
70
70
  )
71
71
  stdout.write(`${out.join('\n')}\n`)
@@ -1,12 +1,5 @@
1
- var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
- if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
- return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
- return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
- });
6
- }
7
- return path;
8
- };
9
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
1
+ import { existsSync, readFileSync, writeFileSync } from "../../core/files.js";
2
+ import { valuesIn } from "../../core/rows.js";
10
3
  import { dirname, join, relative } from 'node:path';
11
4
  import { argv, stderr, stdout } from 'node:process';
12
5
  import { fileURLToPath } from 'node:url';
@@ -31,7 +24,7 @@ function refuse(because) {
31
24
  }
32
25
  let secrets = [];
33
26
  try {
34
- const taken = (await import(__rewriteRelativeImportExtension(new URL(`file://${from}`).href)));
27
+ const taken = valuesIn(readFileSync(from));
35
28
  secrets = taken.SECRETS ?? [];
36
29
  }
37
30
  catch {
@@ -80,7 +73,7 @@ async function taken(file, list) {
80
73
  if (!existsSync(at))
81
74
  return [];
82
75
  try {
83
- const held = (await import(__rewriteRelativeImportExtension(new URL(`file://${at}`).href)));
76
+ const held = valuesIn(readFileSync(at));
84
77
  return held[list] ?? [];
85
78
  }
86
79
  catch {
@@ -187,7 +180,6 @@ if (existsSync(path) && readFileSync(path, 'utf8') === SOURCE) {
187
180
  stdout.write(`vault: ${AT} is already yours — it opens ${opening}, read off ${here(from)} as they are declared.\n`);
188
181
  exit(0);
189
182
  }
190
- mkdirSync(dirname(path), { recursive: true });
191
183
  writeFileSync(path, SOURCE, 'utf8');
192
184
  stdout.write(`vault: wrote ${AT} — what opens a secret's value at the moment of use.\n` +
193
185
  ` It opens the values sealed under ${SEALED_AT} for the secrets declared in ${here(from)}, and refuses every other name.\n` +
@@ -1,4 +1,5 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
1
+ import { existsSync, readFileSync, writeFileSync } from '../../core/files.ts'
2
+ import { valuesIn } from '../../core/rows.ts'
2
3
  import { dirname, join, relative } from 'node:path'
3
4
  import { argv, stderr, stdout } from 'node:process'
4
5
  import { fileURLToPath } from 'node:url'
@@ -36,7 +37,7 @@ function refuse(because: string): never {
36
37
 
37
38
  let secrets: readonly Secret[] = []
38
39
  try {
39
- const taken = (await import(new URL(`file://${from}`).href)) as { SECRETS?: readonly Secret[] }
40
+ const taken = valuesIn(readFileSync(from)) as { SECRETS?: readonly Secret[] }
40
41
  secrets = taken.SECRETS ?? []
41
42
  } catch {
42
43
  refuse(`${here(from)} could not be read. Attach \`${packageOf('integrations')}\` first — an app states its secrets there.`)
@@ -86,7 +87,7 @@ async function taken<T>(file: string, list: string): Promise<readonly T[]> {
86
87
  const at = inTree(TREE, file)
87
88
  if (!existsSync(at)) return []
88
89
  try {
89
- const held = (await import(new URL(`file://${at}`).href)) as Record<string, readonly T[] | undefined>
90
+ const held = valuesIn(readFileSync(at)) as Record<string, readonly T[] | undefined>
90
91
  return held[list] ?? []
91
92
  } catch {
92
93
  return []
@@ -201,7 +202,6 @@ if (existsSync(path) && readFileSync(path, 'utf8') === SOURCE) {
201
202
  exit(0)
202
203
  }
203
204
 
204
- mkdirSync(dirname(path), { recursive: true })
205
205
  writeFileSync(path, SOURCE, 'utf8')
206
206
  stdout.write(
207
207
  `vault: wrote ${AT} — what opens a secret's value at the moment of use.\n` +
@@ -8,8 +8,10 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
8
8
  };
9
9
  import { spawnSync } from 'node:child_process';
10
10
  import { argv, stderr, stdout } from 'node:process';
11
- import { answer, asking, given, only, wordsIn } from "../core/asking.js";
11
+ import { answer, asking, given, unasked, wordsIn } from "../core/answers.js";
12
+ import { readFileSync } from "../core/files.js";
12
13
  import { exit } from "../core/invoked.js";
14
+ import { valuesIn } from "../core/rows.js";
13
15
  import { findTree, inTree } from "../core/tree.js";
14
16
  import { REACH, reachOf } from "./target.js";
15
17
  import { opened } from "./vault.js";
@@ -34,7 +36,7 @@ export async function ran(name) {
34
36
  const tree = findTree();
35
37
  let targets = [];
36
38
  try {
37
- const taken = (await import(__rewriteRelativeImportExtension(new URL(`file://${inTree(tree, 'targets.ts')}`).href)));
39
+ const taken = valuesIn(readFileSync(inTree(tree, 'targets.ts')));
38
40
  targets = taken.TARGETS ?? [];
39
41
  }
40
42
  catch {
@@ -79,7 +81,7 @@ export async function run(declared) {
79
81
  return refuse(`\`${method}\` is not a method path — one name, or names joined by dots, e.g. \`customers.list\``);
80
82
  }
81
83
  const piped = given();
82
- only(piped, TAKES, `\`thread run ${declared.name} ${method}\``);
84
+ unasked(piped, TAKES, `\`thread run ${declared.name} ${method}\``);
83
85
  const { ask, shut } = asking(piped);
84
86
  const typed = (piped.length > 0
85
87
  ? (answer(piped, TAKES[0] ?? 'args') ?? '')