@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
@@ -16,3 +16,5 @@ export const idOf = (name: string): string | undefined => {
16
16
  }
17
17
 
18
18
  export const ours = (name: string): boolean => idOf(name) !== undefined
19
+
20
+ export const installed = (at: string): boolean => at.startsWith('node_modules/') && ours(at.split('/').slice(1, 3).join('/'))
@@ -20,7 +20,7 @@ export interface Member extends Threaded {
20
20
  readonly version: number;
21
21
  }
22
22
  export declare const PREFIXES: {
23
- readonly workflow: "wf_";
24
- readonly view: "vw_";
25
- readonly agent: "agt_";
23
+ readonly workflow: 'wf_';
24
+ readonly view: 'vw_';
25
+ readonly agent: 'agt_';
26
26
  };
@@ -1,3 +1,5 @@
1
+ import { FOLDER } from '../integrations/disk.ts';
2
+ export { FOLDER };
1
3
  export interface Tree {
2
4
  readonly at: string;
3
5
  readonly dir: string;
@@ -5,8 +7,9 @@ export interface Tree {
5
7
  readonly root: string;
6
8
  }
7
9
  export declare class UnthreadedRepositoryError extends Error {
8
- constructor(from: string);
10
+ constructor(from: string, floor?: string);
9
11
  }
12
+ export declare function folder(): string;
10
13
  export declare function findTree(from?: string): Tree;
11
14
  export declare function strayFiles(root: string, prefix: string, ends: string): readonly string[];
12
15
  export declare function inTree(tree: Tree, file: string): string;
package/dist/core/tree.js CHANGED
@@ -1,16 +1,34 @@
1
- import { existsSync, readdirSync, statSync } from "./files.js";
1
+ import { FOLDER, attached, existsSync, readdirSync, statSync } from '../integrations/disk.js';
2
2
  import { dirname, join, relative, resolve } from 'node:path';
3
- import { cwd } from 'node:process';
3
+ import { cwd, env } from 'node:process';
4
+ export { FOLDER };
4
5
  const NAMES = ['_threads', 'threads'];
5
6
  const ROOT = 'thread.ts';
6
7
  export class UnthreadedRepositoryError extends Error {
7
- constructor(from) {
8
- super(`no tree above ${from} — looked for a ${NAMES.map((one) => `${one}/`).join(' or ')} directory in every directory up to the filesystem root. ` +
8
+ constructor(from, floor) {
9
+ super('no tree above ' + from + ' — looked for a ' + NAMES.map((one) => one + '/').join(' or ') + ' directory in every directory up to ' + (floor === undefined ? 'the filesystem root' : floor + ', the folder this was pointed at') + '. ' +
9
10
  'Run `thread init` to write one.');
10
11
  this.name = 'UnthreadedRepositoryError';
11
12
  }
12
13
  }
13
- export function findTree(from = cwd()) {
14
+ function given() {
15
+ const named = env[FOLDER];
16
+ return named === undefined ? '' : named;
17
+ }
18
+ export function folder() {
19
+ const named = given();
20
+ if (named !== '')
21
+ return resolve(named);
22
+ if (attached())
23
+ throw new Error('this is answering for a tree on another machine and nothing said which folder that is. ' +
24
+ FOLDER +
25
+ ' carries it and is not set here. Falling back to the folder this process was started in would read ' +
26
+ 'the wrong tree and report it as yours, so it stopped instead.');
27
+ return cwd();
28
+ }
29
+ export function findTree(from = folder()) {
30
+ const named = given();
31
+ const floor = attached() && named !== '' ? resolve(named) : undefined;
14
32
  let at = resolve(from);
15
33
  for (;;) {
16
34
  for (const name of NAMES) {
@@ -20,7 +38,9 @@ export function findTree(from = cwd()) {
20
38
  }
21
39
  const up = dirname(at);
22
40
  if (up === at)
23
- throw new UnthreadedRepositoryError(from);
41
+ throw new UnthreadedRepositoryError(from, floor);
42
+ if (at === floor)
43
+ throw new UnthreadedRepositoryError(from, floor);
24
44
  at = up;
25
45
  }
26
46
  }
package/dist/core/tree.ts CHANGED
@@ -1,6 +1,8 @@
1
- import { existsSync, readdirSync, statSync } from './files.ts'
1
+ import { FOLDER, attached, existsSync, readdirSync, statSync } from '../integrations/disk.ts'
2
2
  import { dirname, join, relative, resolve } from 'node:path'
3
- import { cwd } from 'node:process'
3
+ import { cwd, env } from 'node:process'
4
+
5
+ export { FOLDER }
4
6
 
5
7
  const NAMES = ['_threads', 'threads'] as const
6
8
  const ROOT = 'thread.ts'
@@ -13,16 +15,36 @@ export interface Tree {
13
15
  }
14
16
 
15
17
  export class UnthreadedRepositoryError extends Error {
16
- constructor(from: string) {
18
+ constructor(from: string, floor?: string) {
17
19
  super(
18
- `no tree above ${from} — looked for a ${NAMES.map((one) => `${one}/`).join(' or ')} directory in every directory up to the filesystem root. ` +
20
+ 'no tree above ' + from + ' — looked for a ' + NAMES.map((one) => one + '/').join(' or ') + ' directory in every directory up to ' + (floor === undefined ? 'the filesystem root' : floor + ', the folder this was pointed at') + '. ' +
19
21
  'Run `thread init` to write one.',
20
22
  )
21
23
  this.name = 'UnthreadedRepositoryError'
22
24
  }
23
25
  }
24
26
 
25
- export function findTree(from: string = cwd()): Tree {
27
+ function given(): string {
28
+ const named = env[FOLDER]
29
+ return named === undefined ? '' : named
30
+ }
31
+
32
+ export function folder(): string {
33
+ const named = given()
34
+ if (named !== '') return resolve(named)
35
+ if (attached())
36
+ throw new Error(
37
+ 'this is answering for a tree on another machine and nothing said which folder that is. ' +
38
+ FOLDER +
39
+ ' carries it and is not set here. Falling back to the folder this process was started in would read ' +
40
+ 'the wrong tree and report it as yours, so it stopped instead.',
41
+ )
42
+ return cwd()
43
+ }
44
+
45
+ export function findTree(from: string = folder()): Tree {
46
+ const named = given()
47
+ const floor = attached() && named !== '' ? resolve(named) : undefined
26
48
  let at = resolve(from)
27
49
  for (;;) {
28
50
  for (const name of NAMES) {
@@ -30,7 +52,8 @@ export function findTree(from: string = cwd()): Tree {
30
52
  if (existsSync(dir) && statSync(dir).isDirectory()) return { at, dir, name, root: join(dir, ROOT) }
31
53
  }
32
54
  const up = dirname(at)
33
- if (up === at) throw new UnthreadedRepositoryError(from)
55
+ if (up === at) throw new UnthreadedRepositoryError(from, floor)
56
+ if (at === floor) throw new UnthreadedRepositoryError(from, floor)
34
57
  at = up
35
58
  }
36
59
  }
@@ -1,8 +1,8 @@
1
- export declare const VALUE_TYPES: readonly ["text", "number", "boolean", "date", "timestamp", "json"];
1
+ export declare const VALUE_TYPES: readonly ['text', 'number', 'boolean', 'date', 'timestamp', 'json'];
2
2
  export type ValueType = (typeof VALUE_TYPES)[number];
3
- export declare const KEYBOARDS: readonly ["text", "numeric", "decimal", "tel", "email", "url", "search"];
3
+ export declare const KEYBOARDS: readonly ['text', 'numeric', 'decimal', 'tel', 'email', 'url', 'search'];
4
4
  export type Keyboard = (typeof KEYBOARDS)[number];
5
- export declare const ENTRY_MODES: readonly ["plain", "calculator", "masked"];
5
+ export declare const ENTRY_MODES: readonly ['plain', 'calculator', 'masked'];
6
6
  export type EntryMode = (typeof ENTRY_MODES)[number];
7
7
  export type Checked = {
8
8
  readonly ok: true;
@@ -233,7 +233,9 @@ export const FORMATS = [
233
233
  check: instant,
234
234
  requires: ['now'],
235
235
  shown: (value, facts) => {
236
- const now = facts.now ?? Date.parse(new Date().toISOString());
236
+ const now = facts.now;
237
+ if (now === undefined)
238
+ return String(value);
237
239
  const gap = Date.parse(String(value)) - now;
238
240
  const UNITS = [
239
241
  ['year', 31_536_000_000],
@@ -270,7 +270,8 @@ export const FORMATS: readonly Format[] = [
270
270
  check: instant,
271
271
  requires: ['now'],
272
272
  shown: (value, facts) => {
273
- const now = facts.now ?? Date.parse(new Date().toISOString())
273
+ const now = facts.now
274
+ if (now === undefined) return String(value)
274
275
  const gap = Date.parse(String(value)) - now
275
276
  const UNITS: readonly (readonly [Intl.RelativeTimeFormatUnit, number])[] = [
276
277
  ['year', 31_536_000_000],
@@ -1,7 +1,8 @@
1
- import { quoted } from "../core/rows.js";
1
+ import { SHAPED } from '../core/init.js';
2
+ import { quoted } from '../core/rows.js';
2
3
  const DESCRIBES = 'What turns a declaration into a file: the rows that state something is to be made, and the generators that make it. They are kept apart so you can read what an app declares without opening the machinery that builds it.';
3
4
  const DERIVATION_SOURCE = [
4
- "import type { Threaded } from '../core/thread.ts'",
5
+ `import type { Threaded } from '${SHAPED}'`,
5
6
  '',
6
7
  'export const DERIVATION: Threaded = {',
7
8
  " id: 'derivation',",
@@ -1,12 +1,13 @@
1
1
  import type { Attaching } from '../core/attach.ts'
2
2
 
3
+ import { SHAPED } from '../core/init.ts'
3
4
  import { quoted } from '../core/rows.ts'
4
5
 
5
6
  const DESCRIBES =
6
7
  'What turns a declaration into a file: the rows that state something is to be made, and the generators that make it. They are kept apart so you can read what an app declares without opening the machinery that builds it.'
7
8
 
8
9
  const DERIVATION_SOURCE = [
9
- "import type { Threaded } from '../core/thread.ts'",
10
+ `import type { Threaded } from '${SHAPED}'`,
10
11
  '',
11
12
  'export const DERIVATION: Threaded = {',
12
13
  " id: 'derivation',",
@@ -10,12 +10,12 @@ import { relative, resolve } from 'node:path';
10
10
  import { argv, stderr, stdout } from 'node:process';
11
11
  import { pathToFileURL } from 'node:url';
12
12
  import { build } from 'esbuild';
13
- import { descend, reached } from "../../core/descend.js";
14
- import { existsSync, readFileSync } from "../../core/files.js";
15
- import { exit, invoked } from "../../core/invoked.js";
16
- import { valuesIn } from "../../core/rows.js";
17
- import { findTree } from "../../core/tree.js";
18
- import { servesBrowser } from "../../integrations/target.js";
13
+ import { descend, reached } from '../../core/descend.js';
14
+ import { existsSync, readFileSync } from '../../integrations/disk.js';
15
+ import { exit, invoked } from '../../core/invoked.js';
16
+ import { valuesIn } from '../../core/rows.js';
17
+ import { findTree } from '../../core/tree.js';
18
+ import { servesBrowser } from '../../integrations/target.js';
19
19
  const TREE = findTree();
20
20
  const ROOT = TREE.at;
21
21
  const OUTSIDE = /(^|\/)node_modules(\/|$)/;
@@ -5,7 +5,7 @@ import { pathToFileURL } from 'node:url'
5
5
  import { build } from 'esbuild'
6
6
 
7
7
  import { descend, reached, type Pass } from '../../core/descend.ts'
8
- import { existsSync, readFileSync } from '../../core/files.ts'
8
+ import { existsSync, readFileSync } from '../../integrations/disk.ts'
9
9
  import { exit, invoked } from '../../core/invoked.ts'
10
10
  import { valuesIn } from '../../core/rows.ts'
11
11
  import { findTree } from '../../core/tree.ts'
@@ -1,4 +1,4 @@
1
- import { bodyHash, parseGenerated } from "./determinism.js";
1
+ import { bodyHash, parseGenerated } from './determinism.js';
2
2
  export function checkGenerated(expected, read, options = {}) {
3
3
  const checks = [];
4
4
  const expectedPaths = new Set(expected.map((file) => file.path));
@@ -1,5 +1,5 @@
1
1
  import { createHash } from 'node:crypto';
2
- import { named } from "../../core/scope.js";
2
+ import { named } from '../../core/scope.js';
3
3
  export function sortedBy(items, key) {
4
4
  return [...items].sort((a, b) => compare(key(a), key(b)));
5
5
  }
@@ -1,14 +1,14 @@
1
1
  import { join } from 'node:path';
2
2
  import { argv, stderr, stdout } from 'node:process';
3
- import { marked, wordsIn } from "../../core/answers.js";
4
- import { existsSync, readFileSync, writeFileSync } from "../../core/files.js";
5
- import { exit, invoked } from "../../core/invoked.js";
6
- import { valuesIn } from "../../core/rows.js";
7
- import { ours } from "../../core/scope.js";
8
- import { findTree, inTree } from "../../core/tree.js";
9
- import { CHECKED_BY, KINDS, LISTENS, SAID, WRITES, WRITTEN_BY, kindOf } from "../release.js";
3
+ import { existsSync, readFileSync, writeFileSync } from '../../integrations/disk.js';
4
+ import { exit, invoked } from '../../core/invoked.js';
5
+ import { marked, valuesIn } from '../../core/rows.js';
6
+ import { ours } from '../../core/scope.js';
7
+ import { findTree, inTree } from '../../core/tree.js';
8
+ import { CHECKED_BY, KINDS, LISTENS, SAID, WRITES, WRITTEN_BY, kindOf } from '../release.js';
10
9
  const TREE = findTree();
11
10
  const MANIFEST = 'package.json';
11
+ const addressed = (rows) => rows.flatMap((one) => [...(one.at === undefined ? [] : [one.at]), ...addressed(one.derives ?? [])]);
12
12
  const mark = (one) => marked([one.id ?? '', one.at ?? '']);
13
13
  function releases() {
14
14
  const at = inTree(TREE, 'derivation.ts');
@@ -22,45 +22,41 @@ function releases() {
22
22
  return [];
23
23
  }
24
24
  }
25
- function named() {
26
- const at = inTree(TREE, 'secrets.ts');
27
- if (!existsSync(at))
28
- return [];
25
+ function manager() {
29
26
  try {
30
- const held = valuesIn(readFileSync(at, 'utf8'));
31
- return (held.SECRETS ?? []).map((one) => one.id.toUpperCase()).sort();
27
+ const held = JSON.parse(readFileSync(join(TREE.at, MANIFEST), 'utf8'));
28
+ const said = typeof held.packageManager === 'string' ? held.packageManager.split('@')[0] : undefined;
29
+ return said === undefined || said === '' ? 'npm' : said;
32
30
  }
33
31
  catch {
34
- return [];
32
+ return 'npm';
35
33
  }
36
34
  }
37
35
  function scripted() {
38
- try {
39
- const held = JSON.parse(readFileSync(join(TREE.at, MANIFEST), 'utf8'));
40
- const scripts = held.scripts ?? {};
41
- return {
42
- build: scripts['build'] === undefined ? 'npm run build' : 'npm run build',
43
- start: scripts['start'] === undefined ? 'npm start' : 'npm start',
44
- };
45
- }
46
- catch {
47
- return { build: 'npm run build', start: 'npm start' };
48
- }
36
+ const tool = manager();
37
+ return { build: `${tool} run build`, start: tool === 'npm' ? 'npm start' : `${tool} start` };
49
38
  }
50
39
  function dockerfile(build, start) {
40
+ const tool = manager();
41
+ const corepack = tool === 'npm' ? [] : ['RUN corepack enable'];
42
+ const lock = tool === 'npm' ? 'package-lock.json*' : `${tool}-lock.yaml*`;
43
+ const first = tool === 'npm'
44
+ ? 'RUN npm ci --omit=dev --ignore-scripts || npm install --omit=dev --ignore-scripts'
45
+ : `RUN ${tool} install --prod --frozen-lockfile --ignore-scripts || ${tool} install --prod --ignore-scripts`;
46
+ const all = tool === 'npm' ? 'RUN npm install --ignore-scripts' : `RUN ${tool} install --ignore-scripts`;
51
47
  return [
52
- '# GENERATED by thread — do not edit. It is derived from what this app declares.',
53
- '',
54
48
  'FROM node:22-slim AS build',
55
49
  'WORKDIR /app',
56
- 'COPY package.json package-lock.json* ./',
57
- 'RUN npm ci --omit=dev --ignore-scripts || npm install --omit=dev --ignore-scripts',
50
+ ...corepack,
51
+ `COPY package.json ${lock} ./`,
52
+ first,
58
53
  'COPY . .',
59
- 'RUN npm install --ignore-scripts',
54
+ all,
60
55
  `RUN ${build}`,
61
56
  '',
62
57
  'FROM node:22-slim',
63
58
  'WORKDIR /app',
59
+ ...corepack,
64
60
  'ENV NODE_ENV=production',
65
61
  'COPY --from=build /app ./',
66
62
  `EXPOSE ${String(LISTENS)}`,
@@ -68,28 +64,27 @@ function dockerfile(build, start) {
68
64
  '',
69
65
  ].join('\n');
70
66
  }
71
- function compose(id, secrets) {
67
+ function compose(id) {
72
68
  return [
73
- '# GENERATED by thread — do not edit. It is derived from what this app declares.',
74
- '',
75
69
  'services:',
76
70
  ` ${id}:`,
77
71
  ' build: .',
78
72
  ' ports:',
79
73
  ` - "${String(LISTENS)}:${String(LISTENS)}"`,
80
- ...(secrets.length === 0
81
- ? []
82
- : [
83
- ' environment:',
84
- ...secrets.map((one) => ` ${one}: \${${one}}`),
85
- ]),
74
+ '',
75
+ ].join('\n');
76
+ }
77
+ function withheld() {
78
+ return [
79
+ '.thread',
80
+ 'node_modules',
81
+ '.git',
86
82
  '',
87
83
  ].join('\n');
88
84
  }
89
85
  function made() {
90
86
  const found = new Map();
91
87
  const rows = releases();
92
- const secrets = named();
93
88
  const { build, start } = scripted();
94
89
  for (const one of rows) {
95
90
  const id = one.id;
@@ -100,7 +95,8 @@ function made() {
100
95
  continue;
101
96
  if (kind === 'docker') {
102
97
  found.set('Dockerfile', dockerfile(build, start));
103
- found.set('compose.yaml', compose(id, secrets));
98
+ found.set('compose.yaml', compose(id));
99
+ found.set('.dockerignore', withheld());
104
100
  }
105
101
  }
106
102
  return found;
@@ -120,7 +116,12 @@ function run() {
120
116
  `\`thread create release\` — it is ${KINDS.join(' or ')}, and the prefix on its id says which.\n`);
121
117
  return 0;
122
118
  }
123
- const words = wordsIn(['read']);
119
+ const words = argv.slice(2).filter((one) => !one.startsWith('-'));
120
+ if (words[0] !== undefined && words[0] !== 'read') {
121
+ stderr.write('release: `' + words[0] + '` is not something this command does. `thread release` writes the release, and ' +
122
+ '`thread release read <mark>` prints one. Nothing was written.\n');
123
+ return 1;
124
+ }
124
125
  if (words[0] === 'read') {
125
126
  const which = words[1];
126
127
  const one = rows.find((row) => mark(row) === which);
@@ -132,10 +133,10 @@ function run() {
132
133
  }
133
134
  const kind = kindOf(one.id ?? '');
134
135
  stdout.write(`${String(one.id)} — ${kind === undefined ? 'a release of a kind this generator does not recognise' : SAID[kind]}\n`);
135
- for (const file of kind === undefined ? [] : WRITES[kind]) {
136
- stdout.write(`\n${file}\n`);
136
+ for (const one of kind === undefined ? [] : WRITES[kind]) {
137
+ stdout.write(`\n${one.at} — ${one.describes}\n`);
137
138
  try {
138
- stdout.write(readFileSync(join(TREE.at, file), 'utf8'));
139
+ stdout.write(readFileSync(join(TREE.at, one.at), 'utf8'));
139
140
  }
140
141
  catch {
141
142
  stdout.write('(nothing is there)\n');
@@ -145,6 +146,16 @@ function run() {
145
146
  }
146
147
  const files = made();
147
148
  const checking = argv.includes('--check');
149
+ const stated = new Set(addressed(rows));
150
+ const stray = [...files.keys()].filter((one) => !stated.has(one));
151
+ if (stray.length > 0) {
152
+ stderr.write(`release: this release produces ${stray.join(', ')}, and no row names ${stray.length === 1 ? 'it' : 'them'}. ` +
153
+ `Writing ${stray.length === 1 ? 'it' : 'them'} would leave a file this tree does not declare, and the descent ` +
154
+ 'reports that three steps later as a file nobody can account for. Take the release out with `thread remove ' +
155
+ '<its id>` and declare it again — the maker writes one row per file this kind produces, so all of them arrive ' +
156
+ 'together. Nothing was written.\n');
157
+ return 1;
158
+ }
148
159
  const shipped = installed();
149
160
  if (shipped.length > 0) {
150
161
  stderr.write(`release: this app installs ${shipped.join(', ')} as a dependency, and what a host runs may hold ` +
@@ -176,8 +187,10 @@ function run() {
176
187
  }
177
188
  for (const [at, text] of files)
178
189
  writeFileSync(join(TREE.at, at), text, 'utf8');
179
- stdout.write(`release: wrote ${[...files.keys()].join(', ')} — built and started by what this app's own manifest ` +
180
- `declares, listening on ${String(LISTENS)}, naming ${String(named().length)} secret(s) and holding none of them.\n`);
190
+ stdout.write('release: wrote ' + [...files.keys()].join(', ') + ' — built and started by what this app\'s own manifest ' +
191
+ 'declares, listening on ' + String(LISTENS) + '.\n' +
192
+ 'release: no secret is named there. A secret is read from the sealed store at the moment it is used, and ' +
193
+ 'naming it here would be telling whoever deploys this to put a credential in the environment instead.\n');
181
194
  return 0;
182
195
  }
183
196
  if (invoked(import.meta.url))