@athrio/loom 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.
package/dist/main.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env bun
2
2
  import { t as __commonJSMin } from "./rolldown-runtime-yvBN9yY6.js";
3
- import { $ as get, $n as filter, $t as ignore, A as Boolean, An as mergeAll, Ar as identity, At as makeUnsafe, B as make$8, Bn as fail$2, Bt as catchTag, C as errorReported, Cn as try_, Cr as format, Ct as endUnsafe, D as make$9, Dr as isNullish, Dt as offerUnsafe, E as Crypto$1, En as catchDone, Er as isNotUndefined, Et as offer, F as FileDescriptor, Fn as MinimumLogLevel, Ft as as, G as isStream, Gn as fail$3, Gt as ensuring, H as decodeText, Hn as Done, Ht as catch_, I as FileSystem, In as _await, It as asVoid, J as run$2, Jn as empty, Jt as fnUntraced, K as merge, Kn as Reference, Kt as fail, L as FileTypeId, Ln as doneUnsafe, Lt as callback, M as TrueValues, Mn as provideMerge, Mr as pipeArguments, Mt as acquireRelease, N as Path$1, Nn as succeed$3, Nt as addFinalizer$1, O as error, On as taggedEnum, Or as isUndefined, Ot as take, P as TypeId$5, Pn as addFinalizer, Pt as andThen, Q as unwrap, Qn as dedupe, Qt as gen, R as Size, Rn as isDone, S as errorExitCode, Sn as tryPromise, Sr as BaseProto, St as mapDone, Tn as void_, Tr as isNotNull, Tt as make$12, U as empty$1, Un as UnknownError, V as callback$1, Vn as succeed$2, Vt as catchTags, W as fromChannel$1, Wn as done, Wt as effectify, X as splitLines, Xn as make$6, Xt as forever, Y as runCollect, Yn as getUnsafe, Yt as forEach, Z as transduce, Zn as Prototype, Zt as forkScoped, _ as Terminal, _n as succeed, _r as map$4, _t as tag, a as storeDir, an as match$1, ar as of, at as badArgument, b as Stdio, br as some, c as LoomCompiler, cn as orElseSucceed, cr as fail$1, ct as Defect, d as PackageConfig, dn as provideService, dr as fromNullishOr, dt as String$1, en as interrupt, et as make$11, f as LoomConfig, fn as raceFirst, fr as fromUndefinedOr, ft as Struct, g as QuitError, gn as serviceOption, gr as isSome, gt as optional$3, hn as scoped, hr as isNone, ht as is, i as servicePackage, in as mapError, ir as match, it as BadArgument, j as FalseValues, jn as provide, jr as pipe, jt as nominal, k as log, kn as effect, kr as dual, kt as make$7, ln as provide$1, lr as succeed$1, lt as ErrorClass, mn as runFork, mr as getOrUndefined, mt as decodeUnknownEffect, n as installedServices, nt as fromChannel, o as workspaceRoot, on as matchEffect, or as reduce, ot as systemError, pn as result, pr as getOrElse, pt as Union, q as mkString, qn as Service, qt as flatMap, r as removeService, rn as map$2, rr as map$3, rt as isSink, s as DocumentSource, sn as orDie, sr as sort, st as ArraySchema, t as addService, tn as isEffect, tt as drain, un as provideContext, ur as flatMap$1, ut as Literal, v as isQuitError, vn as suspend, vr as match$2, vt as toCodecStringTree, w as makeRunMain, wn as uninterruptible, wr as hasProperty, wt as failCauseUnsafe, x as make$10, xn as timeoutOrElse, xr as String$2, xt as fromTransform, y as make$13, yn as sync, yr as none, z as WatchBackend, zn as makeUnsafe$1, zt as catchFilter } from "./LoomStore-DPhVqYEz.js";
3
+ import { $ as mkString, $n as done, $t as ensuring, A as log, An as timeoutOrElse, Ar as none, At as mapDone, B as WatchBackend, Bn as provide, Br as dual, Bt as acquireRelease, C as errorExitCode, Cn as runFork, Cr as fromUndefinedOr, Ct as is, D as Crypto$1, Dn as suspend, Dr as isSome, En as succeed, Er as isNone, Et as toCodecStringTree, F as TypeId$5, Fn as catchDone, Fr as hasProperty, Ft as offerUnsafe, G as empty$1, Gn as _await, Gt as callback, H as callback$1, Hn as succeed$3, Hr as pipe, Ht as andThen, I as FileDescriptor, Ir as isNotNull, It as take, J as fromEffect, Jn as makeUnsafe$1, Jt as catchTag, K as filter$1, Kn as doneUnsafe, L as FileSystem, Ln as taggedEnum, Lr as isNotUndefined, Lt as make$7, M as FalseValues, Mn as try_, Mr as String$2, Mt as failCauseUnsafe, N as TrueValues, Nn as uninterruptible, Nr as BaseProto, Nt as make$12, O as make$9, On as sync, Or as map$4, P as Path$1, Pn as void_, Pr as format, Pt as offer, Q as merge, Qn as UnknownError, Qt as effectify, R as FileTypeId, Rn as effect, Rr as isNullish, Rt as makeUnsafe, S as make$10, Sn as result, Sr as fromNullishOr, St as decodeUnknownEffect, T as makeRunMain, Tn as serviceOption, Tr as getOrUndefined, Tt as tag, U as concat, Un as addFinalizer, Ur as pipeArguments, Ut as as, V as make$8, Vn as provideMerge, Vr as identity, Vt as addFinalizer$1, W as decodeText, Wn as MinimumLogLevel, Wt as asVoid, X as isStream, Xn as succeed$2, Xt as catch_, Y as groupedWithin, Yn as fail$2, Yt as catchTags, Z as mapEffect, Zn as Done, _ as QuitError, _n as orElseSucceed, _r as fail$1, _t as ErrorClass, a as storeDir, an as forkScoped, ar as make$6, at as transduce, b as make$13, bn as provideService, br as contains, bt as Struct, c as LoomCompiler, cn as interrupt, cr as filter, ct as make$11, dn as map$2, dt as isSink, en as fail, er as fail$3, et as orDie$1, f as PackageConfig, fn as mapError, fr as map$3, ft as BadArgument, gn as orDie, gr as sort, gt as Defect, hn as option, hr as reduce, ht as ArraySchema, i as servicePackage, in as forever, ir as getUnsafe, it as splitLines, j as Boolean, jn as tryPromise, jr as some, jt as endUnsafe, k as error, kr as match$2, kt as fromTransform, l as ignoredDirs, ln as isEffect, lt as drain, mn as matchEffect, mr as of, mt as systemError, n as installedServices, nn as fnUntraced, nr as Service, nt as runCollect, o as workspaceRoot, on as gen, or as Prototype, ot as unwrap, p as LoomConfig, pn as match$1, pr as match, pt as badArgument, q as fromChannel$1, qn as isDone, qt as catchFilter, r as removeService, rn as forEach, rr as empty, rt as runForEach, s as DocumentSource, sn as ignore, sr as dedupe, st as get, t as addService, tn as flatMap, tr as Reference, tt as run$2, ut as fromChannel, v as Terminal, vn as provide$1, vr as match$3, vt as Literal, w as errorReported, wn as scoped, wr as getOrElse, wt as optional$3, x as Stdio, xn as raceFirst, xr as flatMap$1, xt as Union, y as isQuitError, yn as provideContext, yr as succeed$1, yt as String$1, z as Size, zn as mergeAll, zr as isUndefined, zt as nominal } from "./LoomStore-CxUQqaPK.js";
4
4
  import * as NodeChildProcess from "node:child_process";
5
- import "node:stream";
5
+ import { PassThrough } from "node:stream";
6
6
  import * as Crypto from "node:crypto";
7
7
  import * as NFS from "node:fs";
8
8
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
@@ -8525,11 +8525,11 @@ var getOutOfScopeGlobalFlagErrors = (allFlags, activeFlags, flagMap, commandPath
8525
8525
  }
8526
8526
  return errors;
8527
8527
  };
8528
- var showHelp = (command, error$2) => gen(function* () {
8528
+ var showHelp = (command, error$3) => gen(function* () {
8529
8529
  const formatter = yield* Formatter;
8530
- const helpDoc = yield* getHelpForCommandPath(command, error$2.commandPath, BuiltIns);
8530
+ const helpDoc = yield* getHelpForCommandPath(command, error$3.commandPath, BuiltIns);
8531
8531
  yield* log(formatter.formatHelpDoc(helpDoc));
8532
- if (error$2.errors.length > 0) yield* error(formatter.formatErrors(error$2.errors));
8532
+ if (error$3.errors.length > 0) yield* error(formatter.formatErrors(error$3.errors));
8533
8533
  });
8534
8534
  /**
8535
8535
  * Runs a command using the arguments supplied by the `Stdio` service.
@@ -9092,7 +9092,6 @@ var fromReadableChannel = (options) => fromTransform((_, scope) => readableToPul
9092
9092
  }));
9093
9093
  var readableToPullUnsafe = (options) => {
9094
9094
  const readable = options.readable;
9095
- if (readable.readableEnded) return succeed(done());
9096
9095
  const closeOnDone = options.closeOnDone ?? true;
9097
9096
  const exit = options.exit ?? make$7(void 0);
9098
9097
  const latch = makeUnsafe(false);
@@ -9114,6 +9113,7 @@ var readableToPullUnsafe = (options) => {
9114
9113
  let item = options.readable.read(options.chunkSize);
9115
9114
  if (item === null) {
9116
9115
  if (exit.current) return exit.current;
9116
+ if (readable.readableEnded) return fail(Done());
9117
9117
  latch.closeUnsafe();
9118
9118
  return flatMap(latch.await, loop);
9119
9119
  }
@@ -9240,10 +9240,15 @@ var layer$11 = /*#__PURE__*/ effect(ChildProcessSpawner, /* @__PURE__ */ gen(fun
9240
9240
  }
9241
9241
  case "output": {
9242
9242
  let stream = empty$1;
9243
- if (nodeStream && "read" in nodeStream) stream = fromReadable({
9244
- evaluate: () => nodeStream,
9245
- onError: (error) => toPlatformError(`fromReadable(fd${fd})`, toError(error), command)
9246
- });
9243
+ if (nodeStream && "read" in nodeStream) {
9244
+ const passThrough = new PassThrough();
9245
+ nodeStream.on("error", (error) => passThrough.destroy(error));
9246
+ nodeStream.pipe(passThrough);
9247
+ stream = fromReadable({
9248
+ evaluate: () => passThrough,
9249
+ onError: (error) => toPlatformError(`fromReadable(fd${fd})`, toError(error), command)
9250
+ });
9251
+ }
9247
9252
  if (config.sink) stream = transduce(stream, config.sink);
9248
9253
  outputStreams.set(fd, stream);
9249
9254
  break;
@@ -9267,14 +9272,24 @@ var layer$11 = /*#__PURE__*/ effect(ChildProcessSpawner, /* @__PURE__ */ gen(fun
9267
9272
  return succeed(sink);
9268
9273
  });
9269
9274
  const setupChildOutputStreams = (command, childProcess, stdoutConfig, stderrConfig) => {
9270
- let stdout = childProcess.stdout ? fromReadable({
9271
- evaluate: () => childProcess.stdout,
9272
- onError: (error) => toPlatformError("fromReadable(stdout)", toError(error), command)
9273
- }) : empty$1;
9274
- let stderr = childProcess.stderr ? fromReadable({
9275
- evaluate: () => childProcess.stderr,
9276
- onError: (error) => toPlatformError("fromReadable(stderr)", toError(error), command)
9277
- }) : empty$1;
9275
+ let stdout = childProcess.stdout ? (() => {
9276
+ const passThrough = new PassThrough();
9277
+ childProcess.stdout.on("error", (error) => passThrough.destroy(error));
9278
+ childProcess.stdout.pipe(passThrough);
9279
+ return fromReadable({
9280
+ evaluate: () => passThrough,
9281
+ onError: (error) => toPlatformError("fromReadable(stdout)", toError(error), command)
9282
+ });
9283
+ })() : empty$1;
9284
+ let stderr = childProcess.stderr ? (() => {
9285
+ const passThrough = new PassThrough();
9286
+ childProcess.stderr.on("error", (error) => passThrough.destroy(error));
9287
+ childProcess.stderr.pipe(passThrough);
9288
+ return fromReadable({
9289
+ evaluate: () => passThrough,
9290
+ onError: (error) => toPlatformError("fromReadable(stderr)", toError(error), command)
9291
+ });
9292
+ })() : empty$1;
9278
9293
  if (isSink(stdoutConfig.stream)) stdout = transduce(stdout, stdoutConfig.stream);
9279
9294
  if (isSink(stderrConfig.stream)) stderr = transduce(stderr, stderrConfig.stream);
9280
9295
  const all = merge(stdout, stderr);
@@ -9359,7 +9374,6 @@ var layer$11 = /*#__PURE__*/ effect(ChildProcessSpawner, /* @__PURE__ */ gen(fun
9359
9374
  const stderrConfig = resolveOutputOption(cmd.options, "stderr");
9360
9375
  const resolvedAdditionalFds = resolveAdditionalFds(cmd.options);
9361
9376
  let isReferenced = true;
9362
- let cleanupOnNonZeroExit = false;
9363
9377
  const cwd = yield* resolveWorkingDirectory(cmd.options);
9364
9378
  const env = resolveEnvironment(cmd.options);
9365
9379
  const stdio = buildStdioArray(stdinConfig, stdoutConfig, stderrConfig, resolvedAdditionalFds);
@@ -9382,20 +9396,18 @@ var layer$11 = /*#__PURE__*/ effect(ChildProcessSpawner, /* @__PURE__ */ gen(fun
9382
9396
  }));
9383
9397
  const pid = ProcessId(childProcess.pid);
9384
9398
  childProcess.on("exit", (code) => {
9385
- if (cleanupOnNonZeroExit && code !== 0 && isNotNull(code)) killProcessGroupOnExit(childProcess, cmd.options.killSignal ?? "SIGTERM");
9399
+ if (code !== 0 && isNotNull(code)) killProcessGroupOnExit(childProcess, cmd.options.killSignal ?? "SIGTERM");
9386
9400
  });
9387
9401
  const reref = sync(() => {
9388
9402
  if (!isReferenced) {
9389
9403
  childProcess.ref();
9390
9404
  isReferenced = true;
9391
- cleanupOnNonZeroExit = false;
9392
9405
  }
9393
9406
  });
9394
9407
  const unref = sync(() => {
9395
9408
  if (isReferenced) {
9396
9409
  childProcess.unref();
9397
9410
  isReferenced = false;
9398
- cleanupOnNonZeroExit = true;
9399
9411
  }
9400
9412
  return reref;
9401
9413
  });
@@ -9566,6 +9578,13 @@ var chown = /*#__PURE__*/ (() => {
9566
9578
  const nodeChown = /*#__PURE__*/ effectify(NFS.chown, /*#__PURE__*/ handleErrnoException("FileSystem", "chown"), /*#__PURE__*/ handleBadArgument("chown"));
9567
9579
  return (path, uid, gid) => nodeChown(path, uid, gid);
9568
9580
  })();
9581
+ var glob = /*#__PURE__*/ (() => {
9582
+ const nodeGlob = /*#__PURE__*/ effectify(NFS.glob, /*#__PURE__*/ handleErrnoException("FileSystem", "glob"), /*#__PURE__*/ handleBadArgument("glob"));
9583
+ return (pattern, options) => nodeGlob(pattern, {
9584
+ cwd: options?.root,
9585
+ exclude: options?.exclude
9586
+ });
9587
+ })();
9569
9588
  var link = /*#__PURE__*/ (() => {
9570
9589
  const nodeLink = /*#__PURE__*/ effectify(NFS.link, /*#__PURE__*/ handleErrnoException("FileSystem", "link"), /*#__PURE__*/ handleBadArgument("link"));
9571
9590
  return (existingPath, newPath) => nodeLink(existingPath, newPath);
@@ -9843,6 +9862,7 @@ var makeFileSystem = /*#__PURE__*/ map$2(/*#__PURE__*/ serviceOption(WatchBacken
9843
9862
  chown,
9844
9863
  copy,
9845
9864
  copyFile,
9865
+ glob,
9846
9866
  link,
9847
9867
  makeDirectory,
9848
9868
  makeTempDirectory,
@@ -10214,17 +10234,13 @@ var pruned = (produced) => ({
10214
10234
  });
10215
10235
  //#endregion
10216
10236
  //#region ../loom-lang/src/LoomTangler.ts
10217
- var ignoredSegment = /* @__PURE__ */ new Set([
10218
- "node_modules",
10219
- ".loom",
10220
- "dist",
10221
- ".git"
10222
- ]);
10223
- var isStorePath = (name) => name.split("/").some((segment) => ignoredSegment.has(segment));
10237
+ var isStorePath = (name) => name.split("/").some((segment) => ignoredDirs.has(segment));
10224
10238
  var LoomTangler = class extends Service()("LoomTangler", { make: gen(function* () {
10225
10239
  const compiler = yield* LoomCompiler;
10226
10240
  const fs = yield* FileSystem;
10227
- const writeFile = (file) => fs.makeDirectory(dirname(file.path), { recursive: true }).pipe(andThen(fs.writeFileString(file.path, file.content)), orDie, as(file));
10241
+ const config = yield* PackageConfig;
10242
+ const matchesDisk = (file) => fs.readFileString(file.path).pipe(option, map$2(contains(file.content)));
10243
+ const writeFile = (file) => matchesDisk(file).pipe(flatMap((same) => same ? void_ : fs.makeDirectory(dirname(file.path), { recursive: true }).pipe(andThen(fs.writeFileString(file.path, file.content)))), orDie, as(file));
10228
10244
  const tangleFile = (entry) => compiler.tangle(entry).pipe(flatMap((files) => forEach(files, writeFile)));
10229
10245
  const loomsUnder = (dir) => fs.readDirectory(dir, { recursive: true }).pipe(orDie, map$2((names) => pipe(names, filter((name) => name.endsWith(".loom") && !isStorePath(name)), map$3((name) => resolve(dir, name)))));
10230
10246
  const loomsOf = (path) => fs.stat(path).pipe(orDie, flatMap((info) => info.type === "Directory" ? loomsUnder(path) : succeed([path])));
@@ -10255,10 +10271,16 @@ var LoomTangler = class extends Service()("LoomTangler", { make: gen(function* (
10255
10271
  yield* writeLock(root, pruned(produced));
10256
10272
  return map$3(orphans, (rel) => resolve(root, rel));
10257
10273
  });
10274
+ const batchWindow = "50 millis";
10275
+ const batchLimit = 1e3;
10276
+ const isLoomEvent = (event) => event.path.endsWith(".loom") && !isStorePath(event.path);
10277
+ const watchRoot = (path) => fs.stat(path).pipe(orDie, flatMap((info) => info.type === "Directory" ? succeed(path) : config.resolve(path).pipe(map$2(({ corpusDir }) => getOrElse(fromNullishOr(corpusDir), () => dirname(path))))));
10278
+ const watch = (path) => unwrap(watchRoot(path).pipe(map$2((root) => concat(fromEffect(result(tangle(path))), fs.watch(root).pipe(filter$1(isLoomEvent), groupedWithin(batchLimit, batchWindow), mapEffect((events) => forEach(dedupe(map$3(events, (event) => resolve(root, event.path))), (changed) => compiler.invalidate(changed), { discard: true }).pipe(andThen(result(tangle(path))))), orDie$1)))));
10258
10279
  return {
10259
10280
  tangle,
10260
10281
  orphans,
10261
- prune
10282
+ prune,
10283
+ watch
10262
10284
  };
10263
10285
  }) }) {
10264
10286
  static {
@@ -10278,6 +10300,18 @@ var LoomWeaver = class extends Service()("LoomWeaver", { make: gen(function* ()
10278
10300
  }
10279
10301
  };
10280
10302
  //#endregion
10303
+ //#region ../loom-lang/src/weave/LoomContents.ts
10304
+ var LoomContents = class extends Service()("LoomContents", { make: gen(function* () {
10305
+ const compiler = yield* LoomCompiler;
10306
+ const fs = yield* FileSystem;
10307
+ const write = (entry) => compiler.contents(entry).pipe(flatMap((text) => fs.writeFileString(entry, text).pipe(orDie, as(entry))));
10308
+ return { write };
10309
+ }) }) {
10310
+ static {
10311
+ this.layer = effect(this, this.make).pipe(provide(LoomCompiler.layer));
10312
+ }
10313
+ };
10314
+ //#endregion
10281
10315
  //#region src/main.ts
10282
10316
  var reset = "\x1B[0m";
10283
10317
  var teal = (s) => `\x1b[38;5;44m${s}${reset}`;
@@ -10290,11 +10324,19 @@ var banner = log(`\n${teal([
10290
10324
  " ███████╗╚██████╔╝╚██████╔╝██║ ╚═╝ ██║",
10291
10325
  " ╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝"
10292
10326
  ].join("\n"))}\n ${dim("a literate framework")}\n`);
10293
- var tangle = (file) => gen(function* () {
10294
- const written = yield* (yield* LoomTangler).tangle(resolve(process.cwd(), file));
10295
- if (written.length === 0) yield* log("loom: no {path} sinks to tangle");
10296
- else yield* forEach(written, (f) => log(`loom: tangled ${f.section} → ${f.path}`));
10327
+ var reportWritten = (written) => written.length === 0 ? log("loom: no {path} sinks to tangle") : forEach(written, (f) => log(`loom: tangled ${f.section} → ${f.path}`), { discard: true });
10328
+ var tangleOnce = (file) => gen(function* () {
10329
+ yield* reportWritten(yield* (yield* LoomTangler).tangle(resolve(process.cwd(), file)));
10297
10330
  }).pipe(catchTag("TangleError", (e) => error(e.message).pipe(andThen(sync(() => void (process.exitCode = 1))))));
10331
+ var tangleWatch = (file) => gen(function* () {
10332
+ const tangler = yield* LoomTangler;
10333
+ yield* log(`loom: watching ${file} — re-tangling on change`);
10334
+ yield* runForEach(tangler.watch(resolve(process.cwd(), file)), match$3({
10335
+ onSuccess: reportWritten,
10336
+ onFailure: (error$1) => error(error$1.message)
10337
+ }));
10338
+ });
10339
+ var tangle = (file, watch) => watch ? tangleWatch(file) : tangleOnce(file);
10298
10340
  var orphans = (prune) => gen(function* () {
10299
10341
  const tangler = yield* LoomTangler;
10300
10342
  if (prune) {
@@ -10305,6 +10347,9 @@ var orphans = (prune) => gen(function* () {
10305
10347
  var weave = (file, out) => gen(function* () {
10306
10348
  yield* log(`loom: wove ${file} → ${yield* (yield* LoomWeaver).weave(resolve(process.cwd(), file), resolve(process.cwd(), out))}`);
10307
10349
  });
10350
+ var toc = (file) => gen(function* () {
10351
+ yield* log(`loom: wrote the table of contents into ${yield* (yield* LoomContents).write(resolve(process.cwd(), file))}`);
10352
+ });
10308
10353
  var mergeMcpConfig = (root) => {
10309
10354
  const path = resolve(root, ".mcp.json");
10310
10355
  const existing = existsSync(path) ? JSON.parse(readFileSync(path, "utf8")) : {};
@@ -10363,7 +10408,7 @@ var add = (language) => gen(function* () {
10363
10408
  yield* addService(language, dir);
10364
10409
  yield* updateLanguages(config, dir, (ids) => [.../* @__PURE__ */ new Set([...ids, language])]);
10365
10410
  yield* log(`\n ${teal("✓")} activated ${language}\n ${dim(`store: ${storeDir(dir)}`)}\n`);
10366
- }).pipe(catchTag("StoreError", (error$1) => error(`loom: could not install ${servicePackage(error$1.id)} — ${String(error$1.cause)}`).pipe(andThen(sync(() => void (process.exitCode = 1))))));
10411
+ }).pipe(catchTag("StoreError", (error$2) => error(`loom: could not install ${servicePackage(error$2.id)} — ${String(error$2.cause)}`).pipe(andThen(sync(() => void (process.exitCode = 1))))));
10367
10412
  var remove = (language) => gen(function* () {
10368
10413
  const config = yield* LoomConfig;
10369
10414
  const dir = process.cwd();
@@ -10382,29 +10427,65 @@ var status = gen(function* () {
10382
10427
  yield* log(`\n ${dim("store")} ${storeDir(dir)}\n ${dim("primary")} ${primary ?? dim("(none)")}\n ${dim("activated")} ${languages.length === 0 ? dim("(none)") : languages.join(", ")}\n`);
10383
10428
  if (languages.length > 0) yield* log(`${languages.map(mark).join("\n")}\n`);
10384
10429
  });
10385
- var tangleCommand = make$5("tangle", { path: string("path") }, ({ path }) => tangle(path));
10430
+ var set = (name, value) => gen(function* () {
10431
+ const config = yield* LoomConfig;
10432
+ const tangler = yield* LoomTangler;
10433
+ const workspace = workspaceRoot(process.cwd());
10434
+ const usage = "usage: loom set <name> <value>";
10435
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
10436
+ yield* error(`loom: \`${name}\` is not a variable name — ${usage}`);
10437
+ yield* sync(() => void (process.exitCode = 1));
10438
+ return;
10439
+ }
10440
+ if (value.startsWith("=")) {
10441
+ yield* error(`loom: a value cannot begin with \`=\`; give the name and value with a space, no \`=\` — ${usage}`);
10442
+ yield* sync(() => void (process.exitCode = 1));
10443
+ return;
10444
+ }
10445
+ const current = yield* config.manifest(workspace);
10446
+ yield* config.materialize(workspace, {
10447
+ ...current ?? {},
10448
+ variables: {
10449
+ ...current?.variables ?? {},
10450
+ [name]: value
10451
+ }
10452
+ });
10453
+ const corpus = resolve(workspace, current?.corpus ?? "corpus");
10454
+ yield* log(`loom: set ${name} = ${value} (re-tangled ${(yield* tangler.tangle(corpus)).length} files)`);
10455
+ }).pipe(catchTag("TangleError", (e) => error(e.message).pipe(andThen(sync(() => void (process.exitCode = 1))))));
10456
+ var tangleCommand = make$5("tangle", {
10457
+ path: string("path"),
10458
+ watch: boolean("watch")
10459
+ }, ({ path, watch }) => tangle(path, watch));
10386
10460
  var orphansCommand = make$5("orphans", { prune: boolean("prune") }, ({ prune }) => orphans(prune));
10387
10461
  var weaveCommand = make$5("weave", {
10388
10462
  path: string("path"),
10389
10463
  out: string("out")
10390
10464
  }, ({ path, out }) => weave(path, out));
10465
+ var tocCommand = make$5("toc", { path: string("path") }, ({ path }) => toc(path));
10391
10466
  var initCommand = make$5("init", { dir: optional$1(directory("dir")) }, ({ dir }) => init(dir));
10392
10467
  var addCommand = make$5("add", { language: string("language") }, ({ language }) => add(language));
10393
10468
  var removeCommand = make$5("remove", { language: string("language") }, ({ language }) => remove(language));
10394
10469
  var statusCommand = make$5("status", {}, () => status);
10470
+ var setCommand = make$5("set", {
10471
+ name: string("name"),
10472
+ value: string("value")
10473
+ }, ({ name, value }) => set(name, value));
10395
10474
  var program = run(make$5("loom").pipe(withSubcommands([
10396
10475
  tangleCommand,
10397
10476
  orphansCommand,
10398
10477
  weaveCommand,
10478
+ tocCommand,
10399
10479
  initCommand,
10400
10480
  addCommand,
10401
10481
  removeCommand,
10402
- statusCommand
10403
- ])), { version: "0.0.3" }).pipe(provide$1(LoomTangler.layer), provide$1(LoomWeaver.layer), provide$1(DocumentSource.layer), provide$1(PackageConfig.layer), provide$1(LoomConfig.layer), provide$1(layer));
10482
+ statusCommand,
10483
+ setCommand
10484
+ ])), { version: "0.0.5" }).pipe(provide$1(LoomTangler.layer), provide$1(LoomWeaver.layer), provide$1(LoomContents.layer), provide$1(DocumentSource.layer), provide$1(PackageConfig.layer), provide$1(LoomConfig.layer), provide$1(layer));
10404
10485
  if (process.argv[2] === "lsp") {
10405
10486
  const { createRequire } = await import("node:module");
10406
10487
  globalThis.require = createRequire(import.meta.url);
10407
- const { startLanguageServer } = await import("./LoomServer-3C83kvX5.js");
10488
+ const { startLanguageServer } = await import("./LoomServer-DdMrIE4N.js");
10408
10489
  startLanguageServer();
10409
10490
  } else runMain(program);
10410
10491
  //#endregion