@automaton-labs/aib 0.0.3 → 0.0.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 (134) hide show
  1. package/dist/bin/cli.js +2 -2
  2. package/dist/commands/config-command.js +1 -3
  3. package/dist/commands/config-output.js +8 -0
  4. package/dist/commands/help-command.js +7 -3
  5. package/dist/commands/init-workspace.js +1 -3
  6. package/dist/commands/inspect-tree.js +3 -3
  7. package/dist/commands/reveal-command.js +5 -0
  8. package/dist/commands/session-workspace.js +4 -4
  9. package/dist/commands/sync-command.js +2 -2
  10. package/dist/config/local-config.js +3 -3
  11. package/dist/config/resolve-command-alias.js +1 -1
  12. package/dist/config/tsconfig-discovery.js +1 -0
  13. package/dist/config/workspace-root.js +3 -3
  14. package/dist/config/workspace-state.js +1 -1
  15. package/dist/dsl/aib-dsl.js +1 -1
  16. package/dist/help/bootstrap.md +108 -94
  17. package/dist/help/docs/config-setup.aliases.md +56 -0
  18. package/dist/help/docs/config-setup.excludes.md +45 -0
  19. package/dist/help/docs/config-setup.import-normalize.md +86 -0
  20. package/dist/help/docs/config-setup.import-rules.md +96 -0
  21. package/dist/help/docs/config-setup.tsconfigs.md +33 -0
  22. package/dist/help/docs/first-setup.md +292 -0
  23. package/dist/help/docs/help-protocol.md +26 -0
  24. package/dist/help/docs/inspect.cycles.md +38 -0
  25. package/dist/help/docs/inspect.md +1 -0
  26. package/dist/help/docs/inspect.tree.md +8 -6
  27. package/dist/help/docs/modulePlan.md +3 -0
  28. package/dist/help/docs/move.md +3 -0
  29. package/dist/help/docs/mutation.md +3 -0
  30. package/dist/help/docs/patterns.md +16 -118
  31. package/dist/help/docs/qr.md +6 -2
  32. package/dist/help/docs/quick-map.md +30 -0
  33. package/dist/help/docs/reveal.md +30 -0
  34. package/dist/help/dsl/bootstrap.md +108 -94
  35. package/dist/help/dsl/docs/config-setup.aliases.md +56 -0
  36. package/dist/help/dsl/docs/config-setup.excludes.md +45 -0
  37. package/dist/help/dsl/docs/config-setup.import-normalize.md +86 -0
  38. package/dist/help/dsl/docs/config-setup.import-rules.md +96 -0
  39. package/dist/help/dsl/docs/config-setup.tsconfigs.md +33 -0
  40. package/dist/help/dsl/docs/first-setup.md +292 -0
  41. package/dist/help/dsl/docs/help-protocol.md +26 -0
  42. package/dist/help/dsl/docs/inspect.cycles.md +38 -0
  43. package/dist/help/dsl/docs/inspect.md +1 -0
  44. package/dist/help/dsl/docs/inspect.tree.md +8 -6
  45. package/dist/help/dsl/docs/modulePlan.md +3 -0
  46. package/dist/help/dsl/docs/move.md +3 -0
  47. package/dist/help/dsl/docs/mutation.md +3 -0
  48. package/dist/help/dsl/docs/patterns.md +16 -118
  49. package/dist/help/dsl/docs/qr.md +6 -2
  50. package/dist/help/dsl/docs/quick-map.md +30 -0
  51. package/dist/help/dsl/docs/reveal.md +30 -0
  52. package/dist/help/dsl/full.md +108 -94
  53. package/dist/help/dsl/topics/config-setup.aliases.md +54 -0
  54. package/dist/help/dsl/topics/config-setup.excludes.md +43 -0
  55. package/dist/help/dsl/topics/config-setup.import-normalize.md +84 -0
  56. package/dist/help/dsl/topics/config-setup.import-rules.md +94 -0
  57. package/dist/help/dsl/topics/config-setup.tsconfigs.md +31 -0
  58. package/dist/help/dsl/topics/first-setup.md +290 -0
  59. package/dist/help/dsl/topics/help-protocol.md +24 -0
  60. package/dist/help/dsl/topics/inspect.cycles.md +36 -0
  61. package/dist/help/dsl/topics/inspect.md +1 -0
  62. package/dist/help/dsl/topics/inspect.tree.md +8 -6
  63. package/dist/help/dsl/topics/modulePlan.md +3 -0
  64. package/dist/help/dsl/topics/move.md +3 -0
  65. package/dist/help/dsl/topics/mutation.md +3 -0
  66. package/dist/help/dsl/topics/patterns.md +16 -118
  67. package/dist/help/dsl/topics/qr.md +6 -2
  68. package/dist/help/dsl/topics/quick-map.md +28 -0
  69. package/dist/help/dsl/topics/reveal.md +28 -0
  70. package/dist/help/full.md +108 -94
  71. package/dist/help/help-meta.json +57 -17
  72. package/dist/help/index.md +60 -0
  73. package/dist/help/json/bootstrap.md +108 -94
  74. package/dist/help/json/docs/config-setup.aliases.md +56 -0
  75. package/dist/help/json/docs/config-setup.excludes.md +45 -0
  76. package/dist/help/json/docs/config-setup.import-normalize.md +86 -0
  77. package/dist/help/json/docs/config-setup.import-rules.md +96 -0
  78. package/dist/help/json/docs/config-setup.tsconfigs.md +33 -0
  79. package/dist/help/json/docs/first-setup.md +292 -0
  80. package/dist/help/json/docs/help-protocol.md +26 -0
  81. package/dist/help/json/docs/inspect.cycles.md +38 -0
  82. package/dist/help/json/docs/inspect.md +1 -0
  83. package/dist/help/json/docs/inspect.tree.md +8 -6
  84. package/dist/help/json/docs/modulePlan.md +3 -0
  85. package/dist/help/json/docs/move.md +3 -0
  86. package/dist/help/json/docs/mutation.md +3 -0
  87. package/dist/help/json/docs/patterns.md +16 -118
  88. package/dist/help/json/docs/qr.md +6 -2
  89. package/dist/help/json/docs/quick-map.md +30 -0
  90. package/dist/help/json/docs/reveal.md +30 -0
  91. package/dist/help/json/full.md +108 -94
  92. package/dist/help/json/topics/config-setup.aliases.md +54 -0
  93. package/dist/help/json/topics/config-setup.excludes.md +43 -0
  94. package/dist/help/json/topics/config-setup.import-normalize.md +84 -0
  95. package/dist/help/json/topics/config-setup.import-rules.md +94 -0
  96. package/dist/help/json/topics/config-setup.tsconfigs.md +31 -0
  97. package/dist/help/json/topics/first-setup.md +290 -0
  98. package/dist/help/json/topics/help-protocol.md +24 -0
  99. package/dist/help/json/topics/inspect.cycles.md +36 -0
  100. package/dist/help/json/topics/inspect.md +1 -0
  101. package/dist/help/json/topics/inspect.tree.md +8 -6
  102. package/dist/help/json/topics/modulePlan.md +3 -0
  103. package/dist/help/json/topics/move.md +3 -0
  104. package/dist/help/json/topics/mutation.md +3 -0
  105. package/dist/help/json/topics/patterns.md +16 -118
  106. package/dist/help/json/topics/qr.md +6 -2
  107. package/dist/help/json/topics/quick-map.md +28 -0
  108. package/dist/help/json/topics/reveal.md +28 -0
  109. package/dist/help/topics/config-setup.aliases.md +54 -0
  110. package/dist/help/topics/config-setup.excludes.md +43 -0
  111. package/dist/help/topics/config-setup.import-normalize.md +84 -0
  112. package/dist/help/topics/config-setup.import-rules.md +94 -0
  113. package/dist/help/topics/config-setup.tsconfigs.md +31 -0
  114. package/dist/help/topics/first-setup.md +290 -0
  115. package/dist/help/topics/help-protocol.md +24 -0
  116. package/dist/help/topics/inspect.cycles.md +36 -0
  117. package/dist/help/topics/inspect.md +1 -0
  118. package/dist/help/topics/inspect.tree.md +8 -6
  119. package/dist/help/topics/modulePlan.md +3 -0
  120. package/dist/help/topics/move.md +3 -0
  121. package/dist/help/topics/mutation.md +3 -0
  122. package/dist/help/topics/patterns.md +16 -118
  123. package/dist/help/topics/qr.md +6 -2
  124. package/dist/help/topics/quick-map.md +28 -0
  125. package/dist/help/topics/reveal.md +28 -0
  126. package/dist/runtime/run-command.js +1 -1
  127. package/dist/session/server.js +3 -3
  128. package/dist/shared/diagnostic-catalog.js +1 -1
  129. package/dist/shared/errors.js +6 -5
  130. package/extension/vscode-refactor-bridge-extension.vsix +0 -0
  131. package/package.json +1 -1
  132. package/runtimes/launcher/win-x64/aib.exe +0 -0
  133. package/scripts/install-windows-launcher.cjs +1 -0
  134. package/scripts/provision-runtime.cjs +99 -41
@@ -24,6 +24,8 @@ main().catch((error) => {
24
24
  });
25
25
 
26
26
  async function main() {
27
+ cleanupOldTempDownloads();
28
+
27
29
  if (runtimeComplete()) {
28
30
  if (!options.quiet) {
29
31
  reporter.info(`aib runtime ready: ${path.relative(process.cwd(), runtimesDir) || runtimesDir}`);
@@ -57,27 +59,31 @@ async function main() {
57
59
 
58
60
  reporter.info(`aib runtime: provisioning ${platformKey}`);
59
61
  const resolution = source || url
60
- ? { archivePath: source ? path.resolve(source) : await downloadRuntimeArchive(url, "runtime archive"), expectedSha256: options.sha256 ?? process.env.AIB_RUNTIME_SHA256 ?? null }
62
+ ? { ...(source ? { archivePath: path.resolve(source), tempDir: null } : await downloadRuntimeArchive(url, "runtime archive")), expectedSha256: options.sha256 ?? process.env.AIB_RUNTIME_SHA256 ?? null }
61
63
  : await resolveFromManifest(manifestSource, manifestUrl);
62
64
  const archivePath = resolution.archivePath;
63
- if (!fs.existsSync(archivePath)) {
64
- throw new Error(`Runtime archive not found: ${archivePath}`);
65
- }
66
- if (resolution.expectedSha256) {
67
- reporter.info("aib runtime: verifying checksum");
68
- assertSha256(archivePath, resolution.expectedSha256);
69
- }
65
+ try {
66
+ if (!fs.existsSync(archivePath)) {
67
+ throw new Error(`Runtime archive not found: ${archivePath}`);
68
+ }
69
+ if (resolution.expectedSha256) {
70
+ reporter.info("aib runtime: verifying checksum");
71
+ assertSha256(archivePath, resolution.expectedSha256);
72
+ }
70
73
 
71
- fs.mkdirSync(runtimesDir, { recursive: true });
72
- reporter.info("aib runtime: extracting archive");
73
- extractRuntimeArchive(archivePath);
74
+ fs.mkdirSync(runtimesDir, { recursive: true });
75
+ reporter.info("aib runtime: extracting archive");
76
+ extractRuntimeArchive(archivePath);
74
77
 
75
- if (!runtimeComplete()) {
76
- throw new Error(`Runtime archive did not provision a complete runtime under ${runtimesDir}`);
78
+ if (!runtimeComplete()) {
79
+ throw new Error(`Runtime archive did not provision a complete runtime under ${runtimesDir}`);
80
+ }
81
+ } finally {
82
+ cleanupOwnedTempDownload(resolution.tempDir);
77
83
  }
78
84
 
79
85
  if (!options.quiet) {
80
- reporter.info(`aib runtime provisioned: ${path.relative(process.cwd(), runtimesDir) || runtimesDir}`);
86
+ reporter.info("aib runtime: ready");
81
87
  }
82
88
  }
83
89
 
@@ -138,21 +144,72 @@ async function resolveFromManifest(manifestSource, manifestUrl) {
138
144
  }
139
145
  const archivePath = artifact.file && manifestSource
140
146
  ? path.resolve(path.dirname(path.resolve(manifestSource)), String(artifact.file))
141
- : artifact.url
142
- ? await downloadRuntimeArchive(String(artifact.url))
143
- : null;
144
- if (!archivePath) {
147
+ : null;
148
+ const downloaded = !archivePath && artifact.url
149
+ ? await downloadRuntimeArchive(String(artifact.url))
150
+ : null;
151
+ const resolvedArchivePath = archivePath ?? downloaded?.archivePath ?? null;
152
+ const tempDir = downloaded?.tempDir ?? null;
153
+ if (!resolvedArchivePath) {
145
154
  throw new Error(`Runtime manifest artifact for ${platformKey} has no url or local file.`);
146
155
  }
147
156
  return {
148
- archivePath,
157
+ archivePath: resolvedArchivePath,
158
+ tempDir,
149
159
  expectedSha256: typeof artifact.sha256 === "string" ? artifact.sha256 : null
150
160
  };
151
161
  }
152
162
 
153
163
  async function downloadJson(url) {
154
- const filePath = await downloadRuntimeArchive(url, "runtime manifest");
155
- return JSON.parse(fs.readFileSync(filePath, "utf8"));
164
+ const download = await downloadRuntimeArchive(url, "runtime manifest");
165
+ try {
166
+ return JSON.parse(fs.readFileSync(download.archivePath, "utf8"));
167
+ } finally {
168
+ cleanupOwnedTempDownload(download.tempDir);
169
+ }
170
+ }
171
+
172
+ function cleanupOldTempDownloads() {
173
+ const cutoffMs = Date.now() - 24 * 60 * 60 * 1000;
174
+ let entries = [];
175
+ try {
176
+ entries = fs.readdirSync(os.tmpdir(), { withFileTypes: true });
177
+ } catch {
178
+ return;
179
+ }
180
+ for (const entry of entries) {
181
+ if (!entry.isDirectory() || !entry.name.startsWith("aib-runtime-")) {
182
+ continue;
183
+ }
184
+ const tempDir = path.join(os.tmpdir(), entry.name);
185
+ try {
186
+ const stat = fs.statSync(tempDir);
187
+ if (stat.mtimeMs < cutoffMs) {
188
+ fs.rmSync(tempDir, { recursive: true, force: true });
189
+ }
190
+ } catch {
191
+ // Best-effort cleanup only.
192
+ }
193
+ }
194
+ }
195
+
196
+ function cleanupOwnedTempDownload(tempDir) {
197
+ if (!tempDir) {
198
+ return;
199
+ }
200
+ try {
201
+ const resolvedTemp = path.resolve(tempDir);
202
+ const resolvedOsTemp = path.resolve(os.tmpdir());
203
+ const relative = path.relative(resolvedOsTemp, resolvedTemp);
204
+ if (path.basename(resolvedTemp).startsWith("aib-runtime-")
205
+ && relative
206
+ && !relative.startsWith("..")
207
+ && !path.isAbsolute(relative)) {
208
+ fs.rmSync(resolvedTemp, { recursive: true, force: true });
209
+ }
210
+ } catch {
211
+ // Best-effort cleanup only.
212
+ }
156
213
  }
157
214
 
158
215
  function defaultManifestUrl() {
@@ -281,12 +338,14 @@ function downloadRuntimeArchive(url, label = "runtime archive") {
281
338
  if (response.statusCode && response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
282
339
  file.close();
283
340
  fs.rmSync(targetPath, { force: true });
341
+ cleanupOwnedTempDownload(tempDir);
284
342
  downloadRuntimeArchive(new URL(response.headers.location, url).toString(), label).then(resolve, reject);
285
343
  return;
286
344
  }
287
345
  if (response.statusCode !== 200) {
288
346
  file.close();
289
347
  fs.rmSync(targetPath, { force: true });
348
+ cleanupOwnedTempDownload(tempDir);
290
349
  reject(new Error(`Runtime download failed with HTTP ${response.statusCode}: ${url}`));
291
350
  return;
292
351
  }
@@ -297,13 +356,14 @@ function downloadRuntimeArchive(url, label = "runtime archive") {
297
356
  file.on("finish", () => {
298
357
  file.close(() => {
299
358
  progress.done();
300
- resolve(targetPath);
359
+ resolve({ archivePath: targetPath, tempDir });
301
360
  });
302
361
  });
303
362
  });
304
363
  request.on("error", (error) => {
305
364
  file.close();
306
365
  fs.rmSync(targetPath, { force: true });
366
+ cleanupOwnedTempDownload(tempDir);
307
367
  reject(error);
308
368
  });
309
369
  });
@@ -311,7 +371,6 @@ function downloadRuntimeArchive(url, label = "runtime archive") {
311
371
 
312
372
  function createReporter(enabled) {
313
373
  const stream = process.stderr;
314
- const useCarriageReturn = Boolean(stream.isTTY);
315
374
  return {
316
375
  info(message) {
317
376
  if (!enabled) {
@@ -324,37 +383,36 @@ function createReporter(enabled) {
324
383
  return { add() {}, done() {} };
325
384
  }
326
385
  let downloadedBytes = 0;
327
- let lastWriteMs = 0;
328
386
  let ended = false;
329
- const startedMs = Date.now();
330
- const minIntervalMs = useCarriageReturn ? 750 : 5000;
331
- const write = (force = false) => {
332
- const now = Date.now();
333
- if (!force && now - lastWriteMs < minIntervalMs) {
387
+ let nextPercent = 10;
388
+ const totalKnown = Number.isFinite(totalBytes) && totalBytes > 0;
389
+ const showPercentProgress = totalKnown && totalBytes >= 1024 * 1024;
390
+ stream.write(totalKnown
391
+ ? `${label} ${formatBytes(totalBytes)}\n`
392
+ : `${label}\n`);
393
+ const writeProgress = () => {
394
+ if (!showPercentProgress) {
334
395
  return;
335
396
  }
336
- lastWriteMs = now;
337
- const percent = totalBytes ? Math.min(100, (downloadedBytes / totalBytes) * 100) : null;
338
- const elapsedSeconds = Math.max(0.001, (now - startedMs) / 1000);
339
- const rateBytes = downloadedBytes / elapsedSeconds;
340
- const text = percent === null
341
- ? `${label}: ${formatBytes(downloadedBytes)} downloaded (${formatBytes(rateBytes)}/s)`
342
- : `${label}: ${percent.toFixed(1)}% ${formatBytes(downloadedBytes)} / ${formatBytes(totalBytes)} (${formatBytes(rateBytes)}/s)`;
343
- stream.write(useCarriageReturn ? `\r${text}` : `${text}\n`);
397
+ const percent = Math.floor(Math.min(100, (downloadedBytes / totalBytes) * 100));
398
+ while (percent >= nextPercent && nextPercent <= 100) {
399
+ const thresholdBytes = Math.min(totalBytes, Math.round((totalBytes * nextPercent) / 100));
400
+ stream.write(`aib runtime: ${nextPercent}% ${formatBytes(thresholdBytes)} / ${formatBytes(totalBytes)}\n`);
401
+ nextPercent += 10;
402
+ }
344
403
  };
345
- write(true);
346
404
  return {
347
405
  add(byteCount) {
348
406
  downloadedBytes += byteCount;
349
- write(false);
407
+ writeProgress();
350
408
  },
351
409
  done() {
352
410
  if (ended) {
353
411
  return;
354
412
  }
355
413
  ended = true;
356
- write(true);
357
- stream.write(useCarriageReturn ? "\n" : "");
414
+ downloadedBytes = Math.max(downloadedBytes, totalBytes ?? downloadedBytes);
415
+ writeProgress();
358
416
  }
359
417
  };
360
418
  }