@prestack/thread 0.1.2 → 0.1.4

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 (265) hide show
  1. package/CHANGELOG.md +193 -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 +67 -58
  7. package/dist/core/attach.ts +61 -68
  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 +89 -21
  14. package/dist/core/descend.ts +86 -17
  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 +0 -2
  27. package/dist/core/init.js +51 -15
  28. package/dist/core/init.ts +58 -15
  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/thread.d.ts +3 -3
  38. package/dist/core/tree.d.ts +4 -1
  39. package/dist/core/tree.js +26 -6
  40. package/dist/core/tree.ts +29 -6
  41. package/dist/core/types.d.ts +3 -3
  42. package/dist/core/types.js +3 -1
  43. package/dist/core/types.ts +2 -1
  44. package/dist/derivation/attach.js +1 -1
  45. package/dist/derivation/generators/build.js +6 -6
  46. package/dist/derivation/generators/build.ts +1 -1
  47. package/dist/derivation/generators/check.js +1 -1
  48. package/dist/derivation/generators/determinism.js +1 -1
  49. package/dist/derivation/generators/release.js +60 -47
  50. package/dist/derivation/generators/release.ts +66 -43
  51. package/dist/derivation/release.d.ts +7 -3
  52. package/dist/derivation/release.js +14 -1
  53. package/dist/derivation/release.ts +22 -2
  54. package/dist/integrations/attach.d.ts +4 -0
  55. package/dist/integrations/attach.js +33 -54
  56. package/dist/integrations/attach.ts +50 -57
  57. package/dist/integrations/cli.d.ts +37 -0
  58. package/dist/integrations/cli.js +440 -0
  59. package/dist/integrations/cli.ts +543 -0
  60. package/dist/{core/files.d.ts → integrations/disk.d.ts} +16 -20
  61. package/dist/integrations/disk.js +435 -0
  62. package/dist/integrations/disk.ts +465 -0
  63. package/dist/integrations/generators/read.js +6 -6
  64. package/dist/integrations/generators/read.ts +4 -4
  65. package/dist/integrations/generators/vault.js +10 -11
  66. package/dist/integrations/generators/vault.ts +4 -5
  67. package/dist/{operations/http.d.ts → integrations/https.d.ts} +10 -6
  68. package/dist/integrations/https.js +170 -0
  69. package/dist/integrations/https.ts +216 -0
  70. package/dist/integrations/pglite.d.ts +26 -0
  71. package/dist/integrations/pglite.js +143 -0
  72. package/dist/integrations/pglite.ts +206 -0
  73. package/dist/integrations/secret.d.ts +8 -2
  74. package/dist/integrations/secret.js +3 -5
  75. package/dist/integrations/secret.ts +10 -6
  76. package/dist/integrations/target.d.ts +155 -14
  77. package/dist/integrations/target.js +171 -50
  78. package/dist/integrations/target.ts +377 -61
  79. package/dist/integrations/vault.d.ts +1 -0
  80. package/dist/integrations/vault.js +20 -5
  81. package/dist/integrations/vault.ts +17 -5
  82. package/dist/integrity/attach.js +3 -73
  83. package/dist/integrity/attach.ts +1 -71
  84. package/dist/integrity/check-threads.js +5 -5
  85. package/dist/integrity/check-threads.ts +2 -2
  86. package/dist/integrity/constraint.d.ts +0 -1
  87. package/dist/integrity/constraint.js +267 -366
  88. package/dist/integrity/constraint.ts +267 -375
  89. package/dist/integrity/generators/compiler.js +14 -17
  90. package/dist/integrity/generators/compiler.ts +10 -15
  91. package/dist/integrity/generators/gate.js +15 -15
  92. package/dist/integrity/generators/gate.ts +10 -10
  93. package/dist/integrity/generators/issues.js +7 -7
  94. package/dist/integrity/generators/publish.js +39 -57
  95. package/dist/integrity/generators/publish.ts +44 -55
  96. package/dist/integrity/generators/trial.d.ts +3 -3
  97. package/dist/integrity/generators/trial.js +133 -161
  98. package/dist/integrity/generators/trial.ts +145 -165
  99. package/dist/integrity/lint.js +9 -13
  100. package/dist/integrity/lint.ts +7 -10
  101. package/dist/integrity/lsp/bin.js +5 -4
  102. package/dist/integrity/lsp/bin.ts +3 -1
  103. package/dist/integrity/lsp/diagnostics.js +3 -3
  104. package/dist/integrity/lsp/diagnostics.ts +1 -1
  105. package/dist/integrity/lsp/lint.js +19 -30
  106. package/dist/integrity/lsp/lint.ts +16 -32
  107. package/dist/integrity/lsp/server.js +3 -3
  108. package/dist/integrity/slopnator.d.ts +3 -13
  109. package/dist/integrity/slopnator.js +58 -37
  110. package/dist/integrity/slopnator.ts +53 -37
  111. package/dist/integrity/slopnators/sl_broken_lineage.js +2 -2
  112. package/dist/integrity/slopnators/sl_declared_elsewhere.js +1 -1
  113. package/dist/integrity/slopnators/sl_derived_drift.js +4 -4
  114. package/dist/integrity/slopnators/sl_derived_drift.ts +1 -1
  115. package/dist/integrity/slopnators/sl_door_in_a_node.js +220 -0
  116. package/dist/integrity/slopnators/sl_door_in_a_node.ts +250 -0
  117. package/dist/integrity/slopnators/sl_inert_island.js +10 -8
  118. package/dist/integrity/slopnators/sl_inert_island.ts +8 -6
  119. package/dist/integrity/slopnators/sl_missing_row.js +6 -51
  120. package/dist/integrity/slopnators/sl_missing_row.ts +4 -50
  121. package/dist/integrity/slopnators/sl_no_barrel.js +1 -1
  122. package/dist/integrity/slopnators/sl_no_child_process.js +36 -18
  123. package/dist/integrity/slopnators/sl_no_child_process.ts +44 -18
  124. package/dist/integrity/slopnators/sl_no_dispatch_bypass.js +80 -149
  125. package/dist/integrity/slopnators/sl_no_dispatch_bypass.ts +95 -147
  126. package/dist/integrity/slopnators/sl_no_import_cycle.js +15 -4
  127. package/dist/integrity/slopnators/sl_no_import_cycle.ts +20 -4
  128. package/dist/integrity/slopnators/sl_no_such_command.js +2 -2
  129. package/dist/integrity/slopnators/sl_no_such_command.ts +1 -1
  130. package/dist/integrity/slopnators/sl_outside_an_operation.js +20 -0
  131. package/dist/integrity/slopnators/sl_outside_an_operation.ts +25 -0
  132. package/dist/integrity/slopnators/sl_screen_holds_only_declared.d.ts +2 -0
  133. package/dist/integrity/slopnators/sl_screen_holds_only_declared.js +61 -0
  134. package/dist/integrity/slopnators/sl_screen_holds_only_declared.ts +70 -0
  135. package/dist/integrity/slopnators/sl_secret_literal.js +1 -33
  136. package/dist/integrity/slopnators/sl_secret_literal.ts +1 -33
  137. package/dist/integrity/slopnators/sl_stale_path.js +5 -22
  138. package/dist/integrity/slopnators/sl_stale_path.ts +4 -20
  139. package/dist/integrity/slopnators/sl_twice_meant.js +1 -1
  140. package/dist/integrity/slopnators/sl_twice_parented.js +29 -5
  141. package/dist/integrity/slopnators/sl_twice_parented.ts +28 -4
  142. package/dist/integrity/slopnators/sl_undeclared_crossing.d.ts +4 -1
  143. package/dist/integrity/slopnators/sl_undeclared_crossing.js +426 -62
  144. package/dist/integrity/slopnators/sl_undeclared_crossing.ts +454 -70
  145. package/dist/integrity/slopnators/sl_undeclared_destination.js +59 -25
  146. package/dist/integrity/slopnators/sl_undeclared_destination.ts +69 -21
  147. package/dist/integrity/slopnators/sl_undeclared_list.d.ts +2 -0
  148. package/dist/integrity/slopnators/sl_undeclared_list.js +363 -0
  149. package/dist/integrity/slopnators/sl_undeclared_list.ts +358 -0
  150. package/dist/integrity/slopnators/sl_undeclared_node.js +1 -11
  151. package/dist/integrity/slopnators/sl_undeclared_node.ts +0 -10
  152. package/dist/integrity/slopnators/sl_undeclared_operation.js +111 -29
  153. package/dist/integrity/slopnators/sl_undeclared_operation.ts +134 -26
  154. package/dist/integrity/slopnators/sl_undeclared_variant.js +2 -2
  155. package/dist/integrity/slopnators/sl_undeclared_webhook.d.ts +2 -0
  156. package/dist/integrity/slopnators/sl_undeclared_webhook.js +90 -0
  157. package/dist/integrity/slopnators/sl_undeclared_webhook.ts +108 -0
  158. package/dist/integrity/slopnators/sl_underived_route.d.ts +2 -0
  159. package/dist/integrity/slopnators/sl_underived_route.js +61 -0
  160. package/dist/integrity/slopnators/sl_underived_route.ts +72 -0
  161. package/dist/integrity/slopnators/sl_ungoverned_island.js +3 -3
  162. package/dist/integrity/slopnators/sl_ungoverned_island.ts +1 -1
  163. package/dist/integrity/slopnators/sl_unlisted_program.d.ts +2 -0
  164. package/dist/integrity/slopnators/sl_unlisted_program.js +39 -0
  165. package/dist/integrity/slopnators/sl_unlisted_program.ts +40 -0
  166. package/dist/integrity/slopnators/sl_unnamed_island.js +1 -1
  167. package/dist/integrity/slopnators/sl_unpaired_member.js +3 -3
  168. package/dist/integrity/slopnators/sl_unpaired_member.ts +1 -1
  169. package/dist/integrity/slopnators/sl_unpaired_slopnator.js +4 -4
  170. package/dist/integrity/slopnators/sl_unpaired_slopnator.ts +1 -1
  171. package/dist/integrity/slopnators/sl_unprefixed_member.js +5 -31
  172. package/dist/integrity/slopnators/sl_unprefixed_member.ts +2 -28
  173. package/dist/integrity/slopnators/sl_unthreaded.js +11 -7
  174. package/dist/integrity/slopnators/sl_unthreaded.ts +6 -7
  175. package/dist/integrity/slopnators/sl_untranslated_key.js +2 -25
  176. package/dist/integrity/slopnators/sl_untranslated_key.ts +1 -25
  177. package/dist/integrity/slopnators/sl_unvaulted_secret.d.ts +2 -0
  178. package/dist/integrity/slopnators/sl_unvaulted_secret.js +107 -0
  179. package/dist/integrity/slopnators/sl_unvaulted_secret.ts +132 -0
  180. package/dist/integrity/slopnators/sl_unversioned.js +6 -4
  181. package/dist/integrity/slopnators/sl_unversioned.ts +5 -3
  182. package/dist/integrity/sweep.d.ts +1 -0
  183. package/dist/integrity/sweep.js +105 -42
  184. package/dist/integrity/sweep.ts +115 -42
  185. package/dist/knowledge/attach.js +1 -1
  186. package/dist/knowledge/generators/docsgen.js +8 -6
  187. package/dist/knowledge/generators/docsgen.ts +4 -2
  188. package/dist/knowledge/generators/glossary.js +4 -4
  189. package/dist/knowledge/generators/glossary.ts +1 -1
  190. package/dist/operations/access.d.ts +23 -0
  191. package/dist/operations/access.js +28 -1
  192. package/dist/operations/access.ts +43 -0
  193. package/dist/operations/attach.js +28 -109
  194. package/dist/operations/attach.ts +46 -113
  195. package/dist/operations/capabilities.d.ts +14 -5
  196. package/dist/operations/capabilities.js +13 -4
  197. package/dist/operations/capabilities.ts +27 -8
  198. package/dist/operations/dispatch.d.ts +8 -2
  199. package/dist/operations/dispatch.js +128 -185
  200. package/dist/operations/dispatch.ts +138 -191
  201. package/dist/operations/error-results.d.ts +1 -1
  202. package/dist/operations/error-results.js +2 -2
  203. package/dist/operations/error-results.ts +2 -2
  204. package/dist/operations/generators/capability.d.ts +11 -1
  205. package/dist/operations/generators/capability.js +481 -224
  206. package/dist/operations/generators/capability.ts +562 -233
  207. package/dist/operations/generators/compile.js +66 -39
  208. package/dist/operations/generators/compile.ts +78 -39
  209. package/dist/operations/generators/permits.js +11 -12
  210. package/dist/operations/generators/permits.ts +3 -4
  211. package/dist/operations/generators/seed.d.ts +1 -0
  212. package/dist/operations/generators/seed.js +19 -17
  213. package/dist/operations/generators/seed.ts +22 -14
  214. package/dist/operations/generators/trial.d.ts +6 -8
  215. package/dist/operations/generators/trial.js +200 -70
  216. package/dist/operations/generators/trial.ts +230 -93
  217. package/dist/operations/nodes.d.ts +15 -16
  218. package/dist/operations/nodes.ts +16 -17
  219. package/dist/operations/operations.d.ts +40 -4
  220. package/dist/operations/operations.js +1 -0
  221. package/dist/operations/operations.ts +61 -4
  222. package/dist/operations/result.d.ts +2 -2
  223. package/dist/operations/result.ts +2 -2
  224. package/package.json +1 -4
  225. package/dist/core/answers.d.ts +0 -171
  226. package/dist/core/answers.js +0 -789
  227. package/dist/core/answers.ts +0 -999
  228. package/dist/core/client.d.ts +0 -57
  229. package/dist/core/client.js +0 -247
  230. package/dist/core/client.ts +0 -286
  231. package/dist/core/files.js +0 -145
  232. package/dist/core/files.ts +0 -193
  233. package/dist/integrations/module.d.ts +0 -6
  234. package/dist/integrations/module.js +0 -153
  235. package/dist/integrations/module.ts +0 -191
  236. package/dist/integrity/slopnators/sl_unkept_rows.js +0 -104
  237. package/dist/integrity/slopnators/sl_unkept_rows.ts +0 -111
  238. package/dist/integrity/slopnators/sl_unseamed_reach.js +0 -73
  239. package/dist/integrity/slopnators/sl_unseamed_reach.ts +0 -79
  240. package/dist/operations/cost.d.ts +0 -14
  241. package/dist/operations/cost.js +0 -37
  242. package/dist/operations/cost.ts +0 -58
  243. package/dist/operations/errors/errors.d.ts +0 -52
  244. package/dist/operations/http.js +0 -124
  245. package/dist/operations/http.ts +0 -169
  246. package/dist/operations/memory.d.ts +0 -104
  247. package/dist/operations/memory.js +0 -365
  248. package/dist/operations/memory.ts +0 -470
  249. package/dist/operations/metering.d.ts +0 -55
  250. package/dist/operations/metering.js +0 -247
  251. package/dist/operations/metering.ts +0 -328
  252. package/dist/operations/queue-policy.d.ts +0 -3
  253. package/dist/operations/queue-policy.js +0 -8
  254. package/dist/operations/queue-policy.ts +0 -10
  255. package/dist/operations/seams.d.ts +0 -239
  256. package/dist/operations/seams.js +0 -45
  257. package/dist/operations/seams.ts +0 -364
  258. package/dist/operations/store.d.ts +0 -14
  259. package/dist/operations/store.js +0 -1
  260. package/dist/operations/store.ts +0 -29
  261. /package/dist/{operations → core}/errors/classes.d.ts +0 -0
  262. /package/dist/{operations → core}/errors/classes.js +0 -0
  263. /package/dist/{operations → core}/errors/classes.ts +0 -0
  264. /package/dist/integrity/slopnators/{sl_unkept_rows.d.ts → sl_door_in_a_node.d.ts} +0 -0
  265. /package/dist/integrity/slopnators/{sl_unseamed_reach.d.ts → sl_outside_an_operation.d.ts} +0 -0
@@ -1,5 +1,5 @@
1
- import { spawnSync } from 'node:child_process'
2
- import { attached, existsSync, kind, readdirSync, readFileSync, realpathSync, statSync, writeFileSync } from './files.ts'
1
+ import { starts } from '../integrations/cli.ts'
2
+ import { attached, beyond, existsSync, here as answering, kind, readdirSync, readFileSync, realpathSync, statSync, writeFileSync, type Kind } from '../integrations/disk.ts'
3
3
  import { dirname, join, relative, resolve } from 'node:path'
4
4
 
5
5
  import ts from 'typescript'
@@ -41,7 +41,7 @@ let readIgnores = false
41
41
  function ownIgnores(): readonly string[] | undefined {
42
42
  if (readIgnores) return ignores
43
43
  readIgnores = true
44
- if (!attached() && spawnSync('git', ['rev-parse', '--is-inside-work-tree'], { cwd: ROOT, stdio: 'ignore' }).status === 0) {
44
+ if (!attached() && starts('git', ['rev-parse', '--is-inside-work-tree'], { at: ROOT }).ok) {
45
45
  return ignores
46
46
  }
47
47
  try {
@@ -65,7 +65,7 @@ export function unkept(at: string): boolean {
65
65
  const own = ownIgnores()
66
66
  const found =
67
67
  own === undefined
68
- ? spawnSync('git', ['check-ignore', '-q', '--', at], { cwd: ROOT, stdio: 'ignore' }).status === 0
68
+ ? starts('git', ['check-ignore', '-q', '--', at], { at: ROOT }).ok
69
69
  : own.some((one) => at === one || at.startsWith(`${one}/`) || at.split('/').includes(one))
70
70
  asked.set(at, found)
71
71
  return found
@@ -252,7 +252,7 @@ function listing(at: string, take: readonly string[], skip: readonly string[], o
252
252
  function parsing(from: string): ts.ParseConfigHost {
253
253
  return {
254
254
  useCaseSensitiveFileNames: true,
255
- fileExists: (at) => existsSync(at),
255
+ fileExists: (at) => !beyond(at) && existsSync(at),
256
256
  readFile: (at) => {
257
257
  try {
258
258
  return readFileSync(at)
@@ -301,22 +301,35 @@ export function configured(): { readonly options: ts.CompilerOptions; readonly f
301
301
  return { options: { ...FALLBACK, ...INVARIANT }, from: '' }
302
302
  }
303
303
 
304
+ const libraries = new Map<string, ReturnType<ts.CompilerHost['getSourceFile']>>()
305
+
306
+ const DEPENDENCIES = '/node_' + 'modules/'
307
+
304
308
  export function hosting(options: ts.CompilerOptions): ts.CompilerHost {
305
309
  const host = ts.createCompilerHost(options, true)
306
310
  const lib = host.getDefaultLibLocation?.()
311
+ const settings = JSON.stringify(options)
307
312
  const toolchain = (at: string): boolean => lib !== undefined && (at === lib || at.startsWith(`${lib}/`))
313
+ const seen = (at: string): Kind => (beyond(at) ? 'none' : kind(at))
308
314
  return {
309
315
  ...host,
310
- fileExists: (at) => (toolchain(at) ? host.fileExists(at) : kind(at) === 'file'),
311
- directoryExists: (at) => (toolchain(at) ? (host.directoryExists?.(at) ?? false) : kind(at) === 'folder'),
312
- readFile: (at) => (toolchain(at) ? host.readFile(at) : kind(at) === 'file' ? readFileSync(at) : undefined),
316
+ fileExists: (at) => (toolchain(at) ? host.fileExists(at) : seen(at) === 'file'),
317
+ directoryExists: (at) => (toolchain(at) ? (host.directoryExists?.(at) ?? false) : seen(at) === 'folder'),
318
+ readFile: (at) => (toolchain(at) ? host.readFile(at) : seen(at) === 'file' ? readFileSync(at) : undefined),
313
319
  getSourceFile: (at, version) => {
314
- if (toolchain(at)) return host.getSourceFile(at, version)
315
- if (kind(at) !== 'file') return undefined
316
- return ts.createSourceFile(at, readFileSync(at), version, true)
320
+ const lasting = toolchain(at) ? true : at.includes(DEPENDENCIES)
321
+ const key = settings + at + JSON.stringify(version)
322
+ if (lasting && libraries.has(key)) return libraries.get(key)
323
+ const made = toolchain(at)
324
+ ? host.getSourceFile(at, version)
325
+ : seen(at) === 'file'
326
+ ? ts.createSourceFile(at, readFileSync(at), version, true)
327
+ : undefined
328
+ if (lasting) libraries.set(key, made)
329
+ return made
317
330
  },
318
331
  getDirectories: (at) =>
319
- kind(at) === 'folder' ? readdirSync(at, { withFileTypes: true }).filter((one) => one.isDirectory()).map((one) => one.name) : [],
332
+ seen(at) === 'folder' ? readdirSync(at, { withFileTypes: true }).filter((one) => one.isDirectory()).map((one) => one.name) : [],
320
333
  realpath: (at) => (toolchain(at) ? (host.realpath?.(at) ?? at) : realpathSync(at)),
321
334
  writeFile: (at, said) => {
322
335
  writeFileSync(at, said)
@@ -389,8 +402,13 @@ export function read(at: string): string | undefined {
389
402
  return text
390
403
  }
391
404
 
405
+ const shapes = new WeakMap<object, ReadonlyMap<string, readonly string[]>>()
406
+
392
407
  export function shapesNamed(): ReadonlyMap<string, readonly string[]> {
393
- const { program, checker } = compiled()
408
+ const held = compiled()
409
+ const known = shapes.get(held)
410
+ if (known !== undefined) return known
411
+ const { program, checker } = held
394
412
  const shape = threadedType(checker, program)
395
413
  const found = new Map<string, string[]>()
396
414
  if (shape === undefined) return found
@@ -419,6 +437,7 @@ export function shapesNamed(): ReadonlyMap<string, readonly string[]> {
419
437
  found.set(named, [...where, at])
420
438
  }
421
439
  }
440
+ shapes.set(held, found)
422
441
  return found
423
442
  }
424
443
 
@@ -429,7 +448,7 @@ export function threading(): ReadonlySet<string> {
429
448
  export function shapeFields(
430
449
  named: string,
431
450
  inside?: string,
432
- ): readonly { readonly name: string; readonly required: boolean; readonly list: boolean; readonly map: boolean; readonly worded: boolean; readonly guide: string }[] {
451
+ ): readonly { readonly name: string; readonly required: boolean; readonly list: boolean; readonly map: boolean; readonly worded: boolean; readonly guide: string; readonly record: readonly string[] }[] {
433
452
  const { program, checker } = compiled()
434
453
  for (const at of [...sources(), ...shipped()]) {
435
454
  if (!SOURCE.test(at)) continue
@@ -466,6 +485,7 @@ export function shapeFields(
466
485
  map: mapped(kind),
467
486
  worded: (kind.isUnion() ? kind.types : [kind]).some((each) => (each.flags & ts.TypeFlags.StringLike) !== 0),
468
487
  guide: ts.displayPartsToString(one.getDocumentationComment(checker)).trim(),
488
+ record: recordOf(checker, kind),
469
489
  }
470
490
  })
471
491
  }
@@ -481,9 +501,10 @@ export interface Field {
481
501
  readonly boolean: boolean
482
502
  readonly worded: boolean
483
503
  readonly guide: string
504
+ readonly record: readonly string[]
484
505
  }
485
506
 
486
- function elementAt(at: string, list: string): { readonly type: ts.Type; readonly node: ts.Node } | undefined {
507
+ function elementAt(at: string, list: string, within?: number): { readonly type: ts.Type; readonly node: ts.Node } | undefined {
487
508
  const { program, checker } = compiled()
488
509
  const file = program.getSourceFile(resolve(ROOT, at))
489
510
  if (file === undefined) return undefined
@@ -493,6 +514,7 @@ function elementAt(at: string, list: string): { readonly type: ts.Type; readonly
493
514
 
494
515
  const consider = (node: ts.ArrayLiteralExpression): void => {
495
516
  if (held !== undefined) return
517
+ if (within !== undefined && node.getStart() !== within) return
496
518
  const wanted = checker.getContextualType(node) ?? checker.getTypeAtLocation(node)
497
519
  const kinds = (wanted.isUnionOrIntersection() ? wanted.types : [wanted])
498
520
  .filter((one) => checker.getIndexTypeOfType(one, ts.IndexKind.Number) !== undefined)
@@ -525,8 +547,8 @@ export function listShape(at: string, list: string): string | undefined {
525
547
  return held === undefined ? undefined : compiled().checker.typeToString(held.type)
526
548
  }
527
549
 
528
- export function listFields(at: string, list: string): readonly Field[] {
529
- const held = elementAt(at, list)
550
+ export function listFields(at: string, list: string, within?: number): readonly Field[] {
551
+ const held = elementAt(at, list, within)
530
552
  if (held === undefined) return []
531
553
  const { checker } = compiled()
532
554
  const bare = (kind: ts.Type): readonly ts.Type[] =>
@@ -557,6 +579,7 @@ export function listFields(at: string, list: string): readonly Field[] {
557
579
  boolean: flagged(kind),
558
580
  worded: worded(kind),
559
581
  guide: ts.displayPartsToString(one.getDocumentationComment(checker)).trim(),
582
+ record: recordOf(checker, kind),
560
583
  }
561
584
  })
562
585
  }
@@ -565,6 +588,21 @@ function elementOf(checker: ts.TypeChecker, type: ts.Type): ts.Type {
565
588
  return checker.getIndexTypeOfType(type, ts.IndexKind.Number) ?? type
566
589
  }
567
590
 
591
+ function recordOf(checker: ts.TypeChecker, type: ts.Type): readonly string[] {
592
+ for (const each of type.isUnion() ? type.types : [type]) {
593
+ if ((each.flags & ts.TypeFlags.StringLike) !== 0 || checker.getIndexTypeOfType(each, ts.IndexKind.Number) === undefined) continue
594
+ const element = elementOf(checker, each)
595
+ if ((element.flags & ts.TypeFlags.Object) === 0) return []
596
+ const fields = checker.getPropertiesOfType(element)
597
+ const worded = fields.every((one) => {
598
+ const kind = checker.getNonNullableType(checker.getTypeOfSymbol(one))
599
+ return (kind.isUnion() ? kind.types : [kind]).every((part) => (part.flags & ts.TypeFlags.StringLike) !== 0)
600
+ })
601
+ return worded ? fields.map((one) => one.getName()) : []
602
+ }
603
+ return []
604
+ }
605
+
568
606
  export function rowShape(at: string, list: string): string | undefined {
569
607
  const { program, checker } = compiled()
570
608
  const file = program.getSourceFile(resolve(ROOT, at))
@@ -751,7 +789,38 @@ export function reached(): readonly string[] {
751
789
  return [THREAD_AT, ...descend().threaded.keys()]
752
790
  }
753
791
 
792
+ let world: object = answering()
793
+
794
+ const worlds = new WeakMap<object, () => void>()
795
+
796
+ function kept(): () => void {
797
+ const was = { passed, built, scanned, commands, ignores, readIgnores, source: new Map(source), asked: new Map(asked) }
798
+ return () => {
799
+ passed = was.passed
800
+ built = was.built
801
+ scanned = was.scanned
802
+ commands = was.commands
803
+ ignores = was.ignores
804
+ readIgnores = was.readIgnores
805
+ source.clear()
806
+ for (const [at, text] of was.source) source.set(at, text)
807
+ asked.clear()
808
+ for (const [at, ignore] of was.asked) asked.set(at, ignore)
809
+ }
810
+ }
811
+
754
812
  export function forget(): void {
813
+ const now = answering()
814
+ if (now === world) libraries.clear()
815
+ else {
816
+ worlds.set(world, kept())
817
+ world = now
818
+ const back = worlds.get(now)
819
+ if (back !== undefined) {
820
+ back()
821
+ return
822
+ }
823
+ }
755
824
  passed = undefined
756
825
  built = undefined
757
826
  scanned = undefined
@@ -0,0 +1,52 @@
1
+ export declare const AuthUnauthenticated: import("./error.ts").ErrorFactory<"auth.unauthenticated">;
2
+ export declare const AuthInvalidCredentials: import("./error.ts").ErrorFactory<"auth.invalid_credentials">;
3
+ export declare const AuthTokenExpired: import("./error.ts").ErrorFactory<"auth.token_expired">;
4
+ export declare const AuthTokenReused: import("./error.ts").ErrorFactory<"auth.token_reused">;
5
+ export declare const AuthSessionRevoked: import("./error.ts").ErrorFactory<"auth.session_revoked">;
6
+ export declare const AuthDenied: import("./error.ts").ErrorFactory<"auth.denied">;
7
+ export declare const QuotaExceeded: import("./error.ts").ErrorFactory<"quota.exceeded">;
8
+ export declare const QuotaReservationExpired: import("./error.ts").ErrorFactory<"quota.reservation_expired">;
9
+ export declare const RateLimitExceeded: import("./error.ts").ErrorFactory<"rate_limit.exceeded">;
10
+ export declare const FeatureNotInPlan: import("./error.ts").ErrorFactory<"feature.not_in_plan">;
11
+ export declare const DbNotFound: import("./error.ts").ErrorFactory<"db.not_found">;
12
+ export declare const DbConstraintViolation: import("./error.ts").ErrorFactory<"db.constraint_violation">;
13
+ export declare const DbAlreadyExists: import("./error.ts").ErrorFactory<"db.already_exists">;
14
+ export declare const DbConflict: import("./error.ts").ErrorFactory<"db.conflict">;
15
+ export declare const DbMigrationChecksumMismatch: import("./error.ts").ErrorFactory<"db.migration_checksum_mismatch">;
16
+ export declare const DbDestructiveWithoutDryRun: import("./error.ts").ErrorFactory<"db.destructive_without_dry_run">;
17
+ export declare const DbRoundTripBudgetExceeded: import("./error.ts").ErrorFactory<"db.round_trip_budget_exceeded">;
18
+ export declare const DbCursorInvalid: import("./error.ts").ErrorFactory<"db.cursor_invalid">;
19
+ export declare const DbCursorExpired: import("./error.ts").ErrorFactory<"db.cursor_expired">;
20
+ export declare const WorkflowNodeFailed: import("./error.ts").ErrorFactory<"workflow.node_failed">;
21
+ export declare const WorkflowInvalidTransition: import("./error.ts").ErrorFactory<"workflow.invalid_transition">;
22
+ export declare const WorkflowCompensationFailed: import("./error.ts").ErrorFactory<"workflow.compensation_failed">;
23
+ export declare const WorkflowAlreadyRunning: import("./error.ts").ErrorFactory<"workflow.already_running">;
24
+ export declare const QueueJobFailed: import("./error.ts").ErrorFactory<"queue.job_failed">;
25
+ export declare const QueueDlqExhausted: import("./error.ts").ErrorFactory<"queue.dlq_exhausted">;
26
+ export declare const AiProviderUnavailable: import("./error.ts").ErrorFactory<"ai.provider_unavailable">;
27
+ export declare const AiSchemaValidationFailed: import("./error.ts").ErrorFactory<"ai.schema_validation_failed">;
28
+ export declare const AiToolNotInMask: import("./error.ts").ErrorFactory<"ai.tool_not_in_mask">;
29
+ export declare const AiNodeCapExceeded: import("./error.ts").ErrorFactory<"ai.node_cap_exceeded">;
30
+ export declare const SearchIndexFailed: import("./error.ts").ErrorFactory<"search.index_failed">;
31
+ export declare const SearchQueryInvalid: import("./error.ts").ErrorFactory<"search.query_invalid">;
32
+ export declare const CommsChannelKindUndeclared: import("./error.ts").ErrorFactory<"comms.channel_kind_undeclared">;
33
+ export declare const CommsChannelKindUndescribed: import("./error.ts").ErrorFactory<"comms.channel_kind_undescribed">;
34
+ export declare const CommsChannelKindUnlabelled: import("./error.ts").ErrorFactory<"comms.channel_kind_unlabelled">;
35
+ export declare const CommsChannelKindUndocumented: import("./error.ts").ErrorFactory<"comms.channel_kind_undocumented">;
36
+ export declare const CommsChannelKindDuplicate: import("./error.ts").ErrorFactory<"comms.channel_kind_duplicate">;
37
+ export declare const ConfigInvalid: import("./error.ts").ErrorFactory<"config.invalid">;
38
+ export declare const ConfigMissingEnv: import("./error.ts").ErrorFactory<"config.missing_env">;
39
+ export declare const ConfigSecretInPublicVar: import("./error.ts").ErrorFactory<"config.secret_in_public_var">;
40
+ export declare const ConfigCredentialInvalid: import("./error.ts").ErrorFactory<"config.credential_invalid">;
41
+ export declare const ConfigScopeMissing: import("./error.ts").ErrorFactory<"config.scope_missing">;
42
+ export declare const ConfigResourceNotFound: import("./error.ts").ErrorFactory<"config.resource_not_found">;
43
+ export declare const ConfigDestinationIncompatible: import("./error.ts").ErrorFactory<"config.destination_incompatible">;
44
+ export declare const ConfigBlocksExit: import("./error.ts").ErrorFactory<"config.blocks_exit">;
45
+ export declare const NetTimeout: import("./error.ts").ErrorFactory<"net.timeout">;
46
+ export declare const NetUpstreamUnavailable: import("./error.ts").ErrorFactory<"net.upstream_unavailable">;
47
+ export declare const NetDestinationRefused: import("./error.ts").ErrorFactory<"net.destination_refused">;
48
+ export declare const InternalUnexpected: import("./error.ts").ErrorFactory<"internal.unexpected">;
49
+ export declare const InternalNotImplemented: import("./error.ts").ErrorFactory<"internal.not_implemented">;
50
+ export declare const InternalInvalidArgument: import("./error.ts").ErrorFactory<"internal.invalid_argument">;
51
+ export declare const PLATFORM_ERRORS: readonly [import("./error.ts").ErrorFactory<"auth.unauthenticated">, import("./error.ts").ErrorFactory<"auth.invalid_credentials">, import("./error.ts").ErrorFactory<"auth.token_expired">, import("./error.ts").ErrorFactory<"auth.token_reused">, import("./error.ts").ErrorFactory<"auth.session_revoked">, import("./error.ts").ErrorFactory<"auth.denied">, import("./error.ts").ErrorFactory<"quota.exceeded">, import("./error.ts").ErrorFactory<"quota.reservation_expired">, import("./error.ts").ErrorFactory<"rate_limit.exceeded">, import("./error.ts").ErrorFactory<"feature.not_in_plan">, import("./error.ts").ErrorFactory<"db.not_found">, import("./error.ts").ErrorFactory<"db.constraint_violation">, import("./error.ts").ErrorFactory<"db.already_exists">, import("./error.ts").ErrorFactory<"db.conflict">, import("./error.ts").ErrorFactory<"db.migration_checksum_mismatch">, import("./error.ts").ErrorFactory<"db.destructive_without_dry_run">, import("./error.ts").ErrorFactory<"db.round_trip_budget_exceeded">, import("./error.ts").ErrorFactory<"db.cursor_invalid">, import("./error.ts").ErrorFactory<"db.cursor_expired">, import("./error.ts").ErrorFactory<"workflow.node_failed">, import("./error.ts").ErrorFactory<"workflow.invalid_transition">, import("./error.ts").ErrorFactory<"workflow.compensation_failed">, import("./error.ts").ErrorFactory<"workflow.already_running">, import("./error.ts").ErrorFactory<"queue.job_failed">, import("./error.ts").ErrorFactory<"queue.dlq_exhausted">, import("./error.ts").ErrorFactory<"ai.provider_unavailable">, import("./error.ts").ErrorFactory<"ai.schema_validation_failed">, import("./error.ts").ErrorFactory<"ai.tool_not_in_mask">, import("./error.ts").ErrorFactory<"ai.node_cap_exceeded">, import("./error.ts").ErrorFactory<"search.index_failed">, import("./error.ts").ErrorFactory<"search.query_invalid">, import("./error.ts").ErrorFactory<"comms.channel_kind_undeclared">, import("./error.ts").ErrorFactory<"comms.channel_kind_undescribed">, import("./error.ts").ErrorFactory<"comms.channel_kind_unlabelled">, import("./error.ts").ErrorFactory<"comms.channel_kind_undocumented">, import("./error.ts").ErrorFactory<"comms.channel_kind_duplicate">, import("./error.ts").ErrorFactory<"config.invalid">, import("./error.ts").ErrorFactory<"config.missing_env">, import("./error.ts").ErrorFactory<"config.secret_in_public_var">, import("./error.ts").ErrorFactory<"config.credential_invalid">, import("./error.ts").ErrorFactory<"config.scope_missing">, import("./error.ts").ErrorFactory<"config.resource_not_found">, import("./error.ts").ErrorFactory<"config.destination_incompatible">, import("./error.ts").ErrorFactory<"config.blocks_exit">, import("./error.ts").ErrorFactory<"net.timeout">, import("./error.ts").ErrorFactory<"net.upstream_unavailable">, import("./error.ts").ErrorFactory<"net.destination_refused">, import("./error.ts").ErrorFactory<"internal.unexpected">, import("./error.ts").ErrorFactory<"internal.not_implemented">, import("./error.ts").ErrorFactory<"internal.invalid_argument">];
52
+ export type PlatformErrorCode = (typeof PLATFORM_ERRORS)[number]['def']['code'];
@@ -1,4 +1,4 @@
1
- import { defineError } from "./catalog.js";
1
+ import { defineError } from './error.js';
2
2
  export const AuthUnauthenticated = defineError({
3
3
  code: 'auth.unauthenticated',
4
4
  class: 'UNAUTHENTICATED',
@@ -1,6 +1,6 @@
1
1
 
2
2
 
3
- import { defineError } from './catalog.ts'
3
+ import { defineError } from './error.ts'
4
4
 
5
5
  export const AuthUnauthenticated = defineError({
6
6
  code: 'auth.unauthenticated',
@@ -1,7 +1,6 @@
1
1
  import { type ErrorClass } from './classes.ts';
2
- export declare const NAMESPACES: readonly ["auth", "quota", "rate_limit", "feature", "db", "workflow", "queue", "ai", "search", "comms", "config", "net", "internal"];
3
- export type Namespace = (typeof NAMESPACES)[number];
4
- export type ErrorCode = `${Namespace}.${string}`;
2
+ import type { ErrorCode } from './namespaces.ts';
3
+ export type { ErrorCode } from './namespaces.ts';
5
4
  export interface ErrorDef<C extends ErrorCode = ErrorCode> {
6
5
  readonly code: C;
7
6
  readonly class: ErrorClass;
@@ -1,19 +1,4 @@
1
- import { classDef } from "./classes.js";
2
- export const NAMESPACES = [
3
- 'auth',
4
- 'quota',
5
- 'rate_limit',
6
- 'feature',
7
- 'db',
8
- 'workflow',
9
- 'queue',
10
- 'ai',
11
- 'search',
12
- 'comms',
13
- 'config',
14
- 'net',
15
- 'internal',
16
- ];
1
+ import { classDef } from './classes.js';
17
2
  export class PlatformError extends Error {
18
3
  def;
19
4
  detail;
@@ -2,25 +2,9 @@
2
2
 
3
3
  import { classDef, type ErrorClass } from './classes.ts'
4
4
 
5
- export const NAMESPACES = [
6
- 'auth',
7
- 'quota',
8
- 'rate_limit',
9
- 'feature',
10
- 'db',
11
- 'workflow',
12
- 'queue',
13
- 'ai',
14
- 'search',
15
- 'comms',
16
- 'config',
17
- 'net',
18
- 'internal',
19
- ] as const
20
-
21
- export type Namespace = (typeof NAMESPACES)[number]
22
-
23
- export type ErrorCode = `${Namespace}.${string}`
5
+ import type { ErrorCode } from './namespaces.ts'
6
+
7
+ export type { ErrorCode } from './namespaces.ts'
24
8
 
25
9
  export interface ErrorDef<C extends ErrorCode = ErrorCode> {
26
10
  readonly code: C
@@ -0,0 +1,3 @@
1
+ export declare const NAMESPACES: readonly ['auth', 'quota', 'rate_limit', 'feature', 'db', 'workflow', 'queue', 'ai', 'search', 'comms', 'config', 'net', 'internal'];
2
+ export type Namespace = (typeof NAMESPACES)[number];
3
+ export type ErrorCode = `${Namespace}.${string}`;
@@ -0,0 +1,15 @@
1
+ export const NAMESPACES = [
2
+ 'auth',
3
+ 'quota',
4
+ 'rate_limit',
5
+ 'feature',
6
+ 'db',
7
+ 'workflow',
8
+ 'queue',
9
+ 'ai',
10
+ 'search',
11
+ 'comms',
12
+ 'config',
13
+ 'net',
14
+ 'internal',
15
+ ];
@@ -0,0 +1,19 @@
1
+ export const NAMESPACES = [
2
+ 'auth',
3
+ 'quota',
4
+ 'rate_limit',
5
+ 'feature',
6
+ 'db',
7
+ 'workflow',
8
+ 'queue',
9
+ 'ai',
10
+ 'search',
11
+ 'comms',
12
+ 'config',
13
+ 'net',
14
+ 'internal',
15
+ ] as const
16
+
17
+ export type Namespace = (typeof NAMESPACES)[number]
18
+
19
+ export type ErrorCode = `${Namespace}.${string}`
@@ -11,7 +11,6 @@ function locate(finding) {
11
11
  export function runChecker(name, findings, measured) {
12
12
  if (findings.length === 0) {
13
13
  stdout.write(`${name}: ${measured} — no findings.\n`);
14
- process.exitCode = 0;
15
14
  return;
16
15
  }
17
16
  const lines = findings.map((finding) => ` ${forbids(finding) ? '' : 'warning: '}${finding.detail}${locate(finding)}\n Instead: ${finding.instead}`);
@@ -19,5 +18,6 @@ export function runChecker(name, findings, measured) {
19
18
  stdout.write(`${name}: ${String(findings.length)} finding${findings.length === 1 ? '' : 's'}` +
20
19
  `${forbidding === findings.length ? '' : `, ${String(findings.length - forbidding)} of them warnings`} — ${measured}\n\n` +
21
20
  `${lines.join('\n')}\n`);
22
- process.exitCode = forbidding === 0 ? 0 : 1;
21
+ if (forbidding > 0)
22
+ process.exitCode = 1;
23
23
  }
@@ -21,7 +21,6 @@ function locate(finding: Finding): string {
21
21
  export function runChecker(name: string, findings: readonly Finding[], measured: string): void {
22
22
  if (findings.length === 0) {
23
23
  stdout.write(`${name}: ${measured} — no findings.\n`)
24
- process.exitCode = 0
25
24
  return
26
25
  }
27
26
 
@@ -34,5 +33,5 @@ export function runChecker(name: string, findings: readonly Finding[], measured:
34
33
  `${forbidding === findings.length ? '' : `, ${String(findings.length - forbidding)} of them warnings`} — ${measured}\n\n` +
35
34
  `${lines.join('\n')}\n`,
36
35
  )
37
- process.exitCode = forbidding === 0 ? 0 : 1
36
+ if (forbidding > 0) process.exitCode = 1
38
37
  }
@@ -5,8 +5,6 @@ export declare class AlreadyThreadedError extends Error {
5
5
  constructor(at: string);
6
6
  }
7
7
  export declare const COMPILER = "tsconfig.json";
8
- export declare const LOCKFILES: readonly ["package-lock.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb"];
9
- export declare function manager(into: string): readonly string[];
10
8
  export declare const MANIFEST = "package.json";
11
9
  export declare const REGISTRY: string;
12
10
  export declare const IGNORED: string;
package/dist/core/init.js CHANGED
@@ -1,6 +1,9 @@
1
- import { existsSync, readFileSync, writeFileSync } from "./files.js";
1
+ import { LOCKFILES, installing, manager } from '../integrations/cli.js';
2
+ import { existsSync, readFileSync, writeFileSync } from '../integrations/disk.js';
3
+ import { createRequire } from 'node:module';
2
4
  import { join, relative, resolve } from 'node:path';
3
- import { quoted } from "./rows.js";
5
+ import { fileURLToPath } from 'node:url';
6
+ import { quoted } from './rows.js';
4
7
  export const TREE = '_threads';
5
8
  export const ROOT = 'thread.ts';
6
9
  export class AlreadyThreadedError extends Error {
@@ -14,18 +17,11 @@ export class AlreadyThreadedError extends Error {
14
17
  }
15
18
  }
16
19
  export const COMPILER = 'tsconfig.json';
17
- export const LOCKFILES = ['package-lock.json', 'pnpm-lock.yaml', 'yarn.lock', 'bun.lockb'];
18
- export function manager(into) {
19
- if (existsSync(join(into, 'pnpm-lock.yaml')))
20
- return ['pnpm', 'add'];
21
- if (existsSync(join(into, 'yarn.lock')))
22
- return ['yarn', 'add'];
23
- if (existsSync(join(into, 'bun.lockb')))
24
- return ['bun', 'add'];
25
- return ['npm', 'install'];
26
- }
27
20
  export const MANIFEST = 'package.json';
21
+ const BUILT = '_gener' + 'ated/packages/core';
28
22
  const MODULE = 'module';
23
+ const NPM = 'npm';
24
+ const LATEST = 'latest';
29
25
  export const REGISTRY = '.npm' + 'rc';
30
26
  export const IGNORED = '.git' + 'ignore';
31
27
  export function ignored() {
@@ -55,7 +51,7 @@ export function compiler() {
55
51
  }, null, 2)}\n`;
56
52
  }
57
53
  function owned(into) {
58
- const held = LOCKFILES.filter((one) => existsSync(join(into, one)));
54
+ const held = Object.keys(LOCKFILES).filter((one) => existsSync(join(into, one)));
59
55
  return [
60
56
  {
61
57
  id: 'manifest',
@@ -108,6 +104,35 @@ export function root(into) {
108
104
  '',
109
105
  ].join('\n');
110
106
  }
107
+ const own = createRequire(import.meta.url);
108
+ function manifested(at) {
109
+ try {
110
+ return own(at);
111
+ }
112
+ catch {
113
+ return undefined;
114
+ }
115
+ }
116
+ function shipped() {
117
+ let at = fileURLToPath(new URL('.', import.meta.url));
118
+ for (;;) {
119
+ const read = manifested(join(at, MANIFEST));
120
+ if (read !== undefined) {
121
+ if (read.name !== undefined && read.version !== undefined)
122
+ return [read.name, read.version];
123
+ const core = manifested(join(at, BUILT, MANIFEST));
124
+ if (core?.name !== undefined && core.version !== undefined)
125
+ return [core.name, core.version];
126
+ }
127
+ const up = resolve(at, '..');
128
+ if (up === at) {
129
+ throw new Error('this framework cannot find the package it is running from, so it has no name to install into your project. ' +
130
+ 'That name is read off the manifest beside this code rather than written down anywhere, which is what keeps it ' +
131
+ 'right when the package is renamed.');
132
+ }
133
+ at = up;
134
+ }
135
+ }
111
136
  export function init(into) {
112
137
  const dir = resolve(into, TREE);
113
138
  const at = join(dir, ROOT);
@@ -121,19 +146,30 @@ export function init(into) {
121
146
  }
122
147
  const manifest = join(into, MANIFEST);
123
148
  if (!existsSync(manifest)) {
124
- throw new Error(`there is no ${MANIFEST} here, and a thread tree is source this package has to be able to load. ` +
125
- 'Run `npm init` first, then `thread init` — the tree is written beside a manifest, not instead of one.');
149
+ const called = (into.split('/').filter(Boolean).pop() ?? 'app').toLowerCase().replace(/[^a-z0-9-]+/g, '-');
150
+ writeFileSync(manifest, JSON.stringify({ name: called, version: '0.0.0', type: MODULE }, null, 2) + '\n', 'utf8');
151
+ written.push(MANIFEST);
126
152
  }
127
153
  const stated = JSON.parse(readFileSync(manifest, 'utf8'));
128
154
  if (stated.type !== MODULE) {
129
155
  writeFileSync(manifest, `${JSON.stringify({ ...stated, type: MODULE }, null, 2)}\n`, 'utf8');
130
156
  written.push(MANIFEST);
131
157
  }
158
+ const [from, version] = shipped();
159
+ const holds = JSON.parse(readFileSync(manifest, 'utf8'));
160
+ const dev = holds.devDependencies ?? {};
161
+ const wanted = { [from]: '^' + version, ...(manager(into) === NPM ? { [NPM]: LATEST } : {}) };
162
+ const missing = Object.entries(wanted).filter(([name]) => dev[name] === undefined);
163
+ if (missing.length > 0) {
164
+ writeFileSync(manifest, JSON.stringify({ ...holds, devDependencies: { ...dev, ...Object.fromEntries(missing) } }, null, 2) + '\n', 'utf8');
165
+ written.push(MANIFEST);
166
+ }
132
167
  const ignore = join(into, IGNORED);
133
168
  if (!existsSync(ignore)) {
134
169
  writeFileSync(ignore, ignored(), 'utf8');
135
170
  written.push(IGNORED);
136
171
  }
172
+ installing(into);
137
173
  for (const [name, text] of [[ROOT, root(into)]]) {
138
174
  writeFileSync(join(dir, name), text, 'utf8');
139
175
  written.push(relative(into, join(dir, name)));