@athrio/loom 0.0.12 → 0.0.13

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 (31) hide show
  1. package/dist/LanguageLoader-DJGDopcP.js +3 -0
  2. package/dist/{LanguageLoader-BzlRnQhO.js → LanguageLoader-kZ-5Qbwr.js} +19 -11
  3. package/dist/{LanguageLoader-BzlRnQhO.js.map → LanguageLoader-kZ-5Qbwr.js.map} +1 -1
  4. package/dist/{LanguageService-BTCvgdWm.js → LanguageService-CcElIYBZ.js} +2 -2
  5. package/dist/{LanguageService-BTCvgdWm.js.map → LanguageService-CcElIYBZ.js.map} +1 -1
  6. package/dist/{LoomFormatter-Bu8L8cdR.js → LoomFormatter-D6wh-SLN.js} +11 -3
  7. package/dist/{LoomFormatter-Bu8L8cdR.js.map → LoomFormatter-D6wh-SLN.js.map} +1 -1
  8. package/dist/{LoomServer-DXIree_1.js → LoomServer-C54yIIo1.js} +28 -12
  9. package/dist/{LoomServer-DXIree_1.js.map → LoomServer-C54yIIo1.js.map} +1 -1
  10. package/dist/{LoomStore-pA-ohGNX.js → LoomStore-axDgE8RF.js} +103 -21
  11. package/dist/LoomStore-axDgE8RF.js.map +1 -0
  12. package/dist/{Runtime-XT-nb-2w.js → Runtime-Cj1Rsxs1.js} +1 -1
  13. package/dist/{Runtime-Byw6clui.js → Runtime-D4WijrpR.js} +3 -3
  14. package/dist/{Runtime-Byw6clui.js.map → Runtime-D4WijrpR.js.map} +1 -1
  15. package/dist/_virtual_tree-sitter-loom-CFLf84Ng.js +15 -0
  16. package/dist/{dist-D3YSXNOO.js → dist-LBqwqmSY.js} +2 -2
  17. package/dist/{dist-D3YSXNOO.js.map → dist-LBqwqmSY.js.map} +1 -1
  18. package/dist/main.js +224 -49
  19. package/dist/main.js.map +1 -1
  20. package/package.json +3 -1
  21. package/dist/LanguageLoader-DJZBFaqF.js +0 -3
  22. package/dist/LoomStore-pA-ohGNX.js.map +0 -1
  23. package/dist/tree-sitter-loom/editors/helix/queries/loom/highlights.scm +0 -120
  24. package/dist/tree-sitter-loom/editors/helix/queries/loom/injections.scm +0 -413
  25. package/dist/tree-sitter-loom/queries/highlights.scm +0 -120
  26. package/dist/tree-sitter-loom/queries/injections.scm +0 -85
  27. package/dist/tree-sitter-loom/src/parser.c +0 -4689
  28. package/dist/tree-sitter-loom/src/scanner.c +0 -293
  29. package/dist/tree-sitter-loom/src/tree_sitter/alloc.h +0 -54
  30. package/dist/tree-sitter-loom/src/tree_sitter/array.h +0 -330
  31. package/dist/tree-sitter-loom/src/tree_sitter/parser.h +0 -286
package/dist/main.js CHANGED
@@ -1,16 +1,18 @@
1
1
  #!/usr/bin/env node
2
- import { $ as transduce, $n as scoped, $t as optionalKey, A as FileSystem, Ai as exists, An as forever, Ar as TaggedError$1, At as Defect, B as fromEffect, Bi as isNone, Bn as mapError, Bt as Struct, Ci as Reference, Cn as effectify, Cr as fail$2, D as log, Di as make$7, Dn as flatMap$1, Dr as done, Dt as ArraySchema, E as error, Ei as getUnsafe, En as filter$2, Er as UnknownError, Et as nominal, F as concat, Fi as fromUndefinedOr, Fn as interrupt, G as mapEffect$1, Gi as none, Gn as orElseSucceed, H as isStream, Hi as liftThrowable, Hn as matchEffect, Hr as findFirst, Ht as TrueLiterals, I as decodeText, Ii as getOrElse, In as isEffect, J as orDie$1, Jn as provideContext, K as merge, Ki as orElse, Kn as promise, Kt as decodeUnknownEffect, L as empty$2, M as WatchBackend, Mi as flatMap$2, Mr as toMillis, Mt as Int$4, N as make$10, Nn as gen, Nt as Literal, O as Path$3, On as fnUntraced, Or as fail$3, P as callback$1, Pi as fromNullishOr, Pn as ignore, Pr as dedupe, Q as splitLines, Qn as runFork, Qt as optional$3, R as filter$1, Rr as empty, Si as succeed$2, Sr as makeUnsafe$1, T as make$9, Ti as empty$1, Tn as fail, Tr as Done, Ui as map$4, Un as option, Ur as findFirstIndex, V as groupedWithin, Vi as isSome, Vn as match$2, Vr as filter, Vt as TaggedError, Wi as match$1, Wn as orDie, Wr as findLast, Wt as Union, X as runCollect, Xi as String$6, Xn as raceFirst, Y as run$3, Yn as provideService, Yt as is, Z as runForEach, Zn as result, _n as catchCause, _r as MinimumLogLevel, _t as poll, a as make$15, aa as hasProperty, ar as tryPromise, at as fromChannel, bn as catchTags, br as isDone, bt as makeUnsafe, c as errorExitCode, ca as isNullish, ci as match, cn as toNumber, cr as void_, ct as badArgument, da as identity, dn as all, dr as effect, dt as mapDone, er as serviceOption, fa as pipe, fi as reduce, fn as andThen, fr as mergeAll, ft as endUnsafe, gn as callback, gr as addFinalizer, gt as offerUnsafe, hi as sort, hn as cached, hr as succeed$4, ht as offer, i as isQuitError, ia as format$1, in as value, ir as tap, it as drain, j as FileTypeId, jn as forkScoped, jr as taggedEnum, jt as FalseLiterals, k as make$11, ki as contains, kn as forEach, kr as pretty, kt as BooleanLiterals, l as errorReported, la as isUndefined, ln as acquireRelease, lr as catchDone, lt as systemError, mr as provideMerge, mt as make$13, n as QuitError, na as assignProperty, ni as isReadonlyArrayNonEmpty, nr as suspend, nt as get, o as Stdio, oa as isNotNull, oi as map$3, or as try_, ot as isSink, pa as pipeArguments, pn as as, pr as provide, pt as failCauseUnsafe, q as mkString, qi as some, qn as provide$1, r as Terminal, ra as BaseProto, rn as make$6, rr as sync, rt as make$14, s as make$12, sa as isNotUndefined, sn as bytes, sr as uninterruptible, st as BadArgument, ta as Prototype, tn as toCodecStringTree, tr as succeed$1, tt as unwrap, u as makeRunMain, ua as dual, ui as of, un as addFinalizer$1, ur as round, ut as fromTransform, vn as catchFilter, vr as _await, vt as take, w as Crypto, wi as Service, wn as ensuring, wr as succeed$3, xi as match$3, xn as catch_, xr as isDoneUnsafe, yi as fail$1, yn as catchTag, yr as doneUnsafe, yt as make$8, z as fromChannel$1, zi as getOrUndefined, zn as map$2, zt as String$5 } from "./dist-D3YSXNOO.js";
3
- import { a as holds, c as storeDirs, l as PackageConfig, n as DocumentSource, o as loomsIn, r as LoomCompiler, s as projectIn, t as LoomFormatter, u as LoomConfig } from "./LoomFormatter-Bu8L8cdR.js";
4
- import { a as servicePackage, i as removeService, l as workspaceRoot, n as addService, o as serviceVersion, r as installedVersion, s as storeDir, t as ServiceInstall } from "./LoomStore-pA-ohGNX.js";
2
+ import { $ as transduce, $i as Number$2, $n as result, $t as optionalKey, A as FileSystem, Ai as make$7, An as forEach, Ar as done, At as Defect, B as fromEffect, Bt as Struct, Cn as effectify, Cr as isDone, D as log, Di as Service, Dn as filterOrFail, Dr as succeed$3, Dt as ArraySchema, E as error, Ei as Reference, En as filter$2, Er as fail$2, Et as nominal, F as concat, Fi as flatMap$2, Fn as ignore, Fr as toMillis, G as mapEffect$1, Gi as liftThrowable, Gn as option, Gr as findFirst, H as isStream, Hi as getOrUndefined, Hn as mapError, Ht as TrueLiterals, I as decodeText, In as interrupt, J as orDie$1, Ji as none, Jn as promise, K as merge, Ki as map$4, Kn as orDie, Kr as findFirstIndex, Kt as decodeUnknownEffect, L as empty$2, Li as fromNullishOr, Ln as isEffect, Lr as dedupe, M as WatchBackend, Mi as contains, Mn as forkScoped, Mr as pretty, Mt as Int$4, N as make$10, Ni as exists, Nr as TaggedError$1, Nt as Literal, O as Path$3, Oi as empty$1, On as flatMap$1, Or as Done, P as callback$1, Pn as gen, Pr as taggedEnum, Q as splitLines, Qi as Array_, Qn as raceFirst, Qt as optional$3, R as filter$1, Ri as fromUndefinedOr, Si as fail$1, Sr as doneUnsafe, T as make$9, Ti as succeed$2, Tn as fail, Tr as makeUnsafe$1, Ui as isNone, Un as match$2, V as groupedWithin, Vn as map$2, Vr as empty, Vt as TaggedError, Wi as isSome, Wn as matchEffect, Wr as filter, Wt as Union, X as runCollect, Xi as some, Xn as provideContext, Y as run$3, Yi as orElse, Yn as provide$1, Yt as is, Z as runForEach, Zn as provideService, _ as orElse$1, _a as pipe, _n as catchCause, _r as provideMerge, _t as poll, a as make$15, aa as mapInput, ai as isReadonlyArrayNonEmpty, ar as sync, at as fromChannel, b as when, bn as catchTags, br as MinimumLogLevel, bt as makeUnsafe, c as errorExitCode, ca as BaseProto, cn as toNumber, cr as tryPromise, ct as badArgument, da as isNotNull, di as match, dn as all, dr as void_, dt as mapDone, ea as String$6, er as runFork, fa as isNotUndefined, fn as andThen, fr as catchDone, ft as endUnsafe, ga as identity, gn as callback, gr as provide, gt as offerUnsafe, ha as dual, hi as reduce, hn as cached, hr as mergeAll, ht as offer, i as isQuitError, ia as isGreaterThan, in as value, ir as suspend, it as drain, j as FileTypeId, jn as forever, jr as fail$3, jt as FalseLiterals, k as make$11, ki as getUnsafe, kn as fnUntraced, kr as UnknownError, kt as BooleanLiterals, l as errorReported, la as format$1, li as map$3, ln as acquireRelease, lr as try_, lt as systemError, ma as isUndefined, mr as effect, mt as make$13, n as QuitError, nr as serviceOption, nt as get, o as Stdio, oa as Prototype, or as tap, ot as isSink, pa as isNullish, pi as of, pn as as, pr as round, pt as failCauseUnsafe, q as mkString, qi as match$1, qn as orElseSucceed, qr as findLast, r as Terminal, rn as make$6, rr as succeed$1, rt as make$14, s as make$12, sa as assignProperty, sn as bytes, sr as tapError, st as BadArgument, tn as toCodecStringTree, tr as scoped, tt as unwrap, u as makeRunMain, ua as hasProperty, un as addFinalizer$1, ur as uninterruptible, ut as fromTransform, va as pipeArguments, vi as sort, vn as catchFilter, vr as succeed$4, vt as take, w as Crypto, wi as match$3, wn as ensuring, wr as isDoneUnsafe, xn as catch_, xr as _await, y as value$1, yn as catchTag, yr as addFinalizer, yt as make$8, z as fromChannel$1, zi as getOrElse, zt as String$5 } from "./dist-LBqwqmSY.js";
3
+ import { a as holds, c as storeDirs, l as PackageConfig, n as DocumentSource, o as loomsIn, r as LoomCompiler, s as projectIn, t as LoomFormatter, u as LoomConfig } from "./LoomFormatter-D6wh-SLN.js";
4
+ import { a as installedVersion, d as standalone, f as storeDir, h as workspaceRoot, i as installTypeScript, l as servicePackage, n as embeddedFile, o as removeService, p as storeTypeScript, r as installService, t as ServiceInstall, u as serviceVersion } from "./LoomStore-axDgE8RF.js";
5
5
  import * as OS from "node:os";
6
- import { homedir } from "node:os";
6
+ import { homedir, tmpdir } from "node:os";
7
7
  import * as NodeChildProcess from "node:child_process";
8
8
  import { PassThrough } from "node:stream";
9
9
  import * as NodeCrypto from "node:crypto";
10
+ import { createHash } from "node:crypto";
10
11
  import * as NFS from "node:fs";
11
- import { cpSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
12
+ import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
12
13
  import * as Path from "node:path";
13
14
  import { dirname, relative, resolve } from "node:path";
15
+ import { gunzipSync } from "node:zlib";
14
16
  import * as NodeUrl from "node:url";
15
17
  import { fileURLToPath, pathToFileURL } from "node:url";
16
18
  import * as readline from "node:readline";
@@ -3038,7 +3040,7 @@ var withDefault$1 = /*#__PURE__*/ dual(2, (self, defaultValue) => {
3038
3040
  * @category combinators
3039
3041
  * @since 4.0.0
3040
3042
  */
3041
- var variadic = (self, options) => {
3043
+ var variadic$1 = (self, options) => {
3042
3044
  const single = getUnderlyingSingleOrThrow(self);
3043
3045
  const parse = (args) => {
3044
3046
  if (single.kind === "argument") return parsePositionalVariadic(self, single, args, options);
@@ -3180,7 +3182,7 @@ var transformSingle = (param, f) => {
3180
3182
  Map: (mapped) => map(transformSingle(mapped.param, f), mapped.f),
3181
3183
  Transform: (mapped) => transform(transformSingle(mapped.param, f), mapped.f, mapped.alternatives.map((alternative) => () => transformSingle(alternative(), f))),
3182
3184
  Optional: (p) => optional$2(transformSingle(p.param, f)),
3183
- Variadic: (p) => variadic(transformSingle(p.param, f), {
3185
+ Variadic: (p) => variadic$1(transformSingle(p.param, f), {
3184
3186
  min: getOrUndefined(p.min),
3185
3187
  max: getOrUndefined(p.max)
3186
3188
  })
@@ -3293,6 +3295,35 @@ var Directory = (name, options) => Directory$1(argumentKind, name, options);
3293
3295
  * @since 4.0.0
3294
3296
  */
3295
3297
  var optional$1 = (arg) => optional$2(arg);
3298
+ /**
3299
+ * Creates a variadic positional argument that accepts multiple values.
3300
+ *
3301
+ * **Example** (Accepting multiple values)
3302
+ *
3303
+ * ```ts import.meta.vitest
3304
+ * import { Argument } from "effect/cli"
3305
+ *
3306
+ * // Accept any number of files
3307
+ * const anyFiles = Argument.String("files").pipe(Argument.variadic)
3308
+ *
3309
+ * // Accept at least 1 file
3310
+ * const atLeastOneFile = Argument.String("files").pipe(
3311
+ * Argument.variadic({ min: 1 })
3312
+ * )
3313
+ *
3314
+ * // Accept between 1 and 5 files
3315
+ * const limitedFiles = Argument.String("files").pipe(
3316
+ * Argument.variadic({ min: 1, max: 5 })
3317
+ * )
3318
+ *
3319
+ * const kinds = [anyFiles.kind, atLeastOneFile.kind, limitedFiles.kind] // => ["argument", "argument", "argument"]
3320
+ * ```
3321
+ *
3322
+ * @stability unstable
3323
+ * @category combinators
3324
+ * @since 4.0.0
3325
+ */
3326
+ var variadic = /*#__PURE__*/ dual((args) => isParam(args[0]), (self, options) => variadic$1(self, options));
3296
3327
  //#endregion
3297
3328
  //#region ../../node_modules/effect/dist/cli/CliOutput.js
3298
3329
  /**
@@ -6165,7 +6196,7 @@ var promptSingle = (single) => {
6165
6196
  case "Date": return map$2(run$2(Date$1({ message })), (date) => commandLineArg(date.toISOString()));
6166
6197
  case "Finite": return map$2(run$2(Number$1({ message })), (value) => commandLineArg(String(value)));
6167
6198
  case "Int": return map$2(run$2(Int$2({ message })), (value) => commandLineArg(String(value)));
6168
- case "Redacted": return map$2(run$2(Password({ message })), (value$1) => commandLineArg(value(value$1), "<redacted>"));
6199
+ case "Redacted": return map$2(run$2(Password({ message })), (value$2) => commandLineArg(value(value$2), "<redacted>"));
6169
6200
  default: return map$2(run$2(String$3({ message })), commandLineArg);
6170
6201
  }
6171
6202
  };
@@ -8621,7 +8652,7 @@ var tangleWatch = (file) => gen(function* () {
8621
8652
  yield* log(`loom: watching ${file} — re-tangling on change`);
8622
8653
  yield* runForEach(tangler.watch(resolve(process.cwd(), file)), match$3({
8623
8654
  onSuccess: reportWritten,
8624
- onFailure: (error$1) => error(error$1.message)
8655
+ onFailure: (error$2) => error(error$2.message)
8625
8656
  }));
8626
8657
  });
8627
8658
  var tangle = (file, watch) => watch ? tangleWatch(file) : tangleOnce(file);
@@ -8653,10 +8684,12 @@ var format = (path, check) => gen(function* () {
8653
8684
  if (check && changed.length > 0) yield* sync(() => void (process.exitCode = 1));
8654
8685
  });
8655
8686
  var typeScriptFrom = (from) => liftThrowable(() => createRequire(from).resolve("typescript/lib/typescript.js"))();
8656
- var projectTypeScript = (root) => match$1(orElse(typeScriptFrom(resolve(root, "package.json")), () => typeScriptFrom(import.meta.url)), {
8657
- onNone: () => succeed$1(none()),
8658
- onSome: (file) => tryPromise(() => import(pathToFileURL(file).href)).pipe(map$2((module) => some(module.default ?? module)), orElseSucceed(() => none()))
8659
- });
8687
+ var foundTypeScript = (root) => pipe(typeScriptFrom(resolve(root, "package.json")), orElse(() => standalone ? none() : typeScriptFrom(import.meta.url)), orElse(() => storeTypeScript(root)));
8688
+ var storedTypeScript = (root) => error(`loom: installing TypeScript ^6 into ${storeDir(root)}`).pipe(andThen(installTypeScript(root)), tapError((error$1) => error(`loom: could not install TypeScript — ${String(error$1.cause)}`)));
8689
+ var projectTypeScript = (root) => match$1(foundTypeScript(root), {
8690
+ onNone: () => storedTypeScript(root),
8691
+ onSome: succeed$1
8692
+ }).pipe(flatMap$1((file) => tryPromise(() => import(pathToFileURL(file).href))), map$2((module) => some(module.default ?? module)), orElseSucceed(() => none()));
8660
8693
  var formatLanguages = (target) => gen(function* () {
8661
8694
  const config = yield* LoomConfig;
8662
8695
  const root = workspaceRoot(dirname(target));
@@ -8669,8 +8702,8 @@ var formatLanguages = (target) => gen(function* () {
8669
8702
  yield* sync(() => {
8670
8703
  globalThis.require ??= createRequire(import.meta.url);
8671
8704
  });
8672
- const { installHostRuntime } = yield* promise(() => import("./Runtime-XT-nb-2w.js"));
8673
- const { loadActive } = yield* promise(() => import("./LanguageLoader-DJZBFaqF.js"));
8705
+ const { installHostRuntime } = yield* promise(() => import("./Runtime-Cj1Rsxs1.js"));
8706
+ const { loadActive } = yield* promise(() => import("./LanguageLoader-DJGDopcP.js"));
8674
8707
  yield* sync(() => installHostRuntime(ts));
8675
8708
  return yield* loadActive(ids, root);
8676
8709
  })
@@ -8752,24 +8785,27 @@ var updateLanguages = (config, dir, change) => gen(function* () {
8752
8785
  const current = yield* config.manifest(workspace);
8753
8786
  const ids = change(Object.keys(current?.languages ?? {}));
8754
8787
  const languages = Object.fromEntries(ids.map((id) => [id, current?.languages?.[id] ?? {}]));
8755
- yield* config.materialize(workspace, {
8756
- ...current ?? {},
8757
- languages
8758
- });
8788
+ yield* config.edit(workspace, ["languages"], languages);
8759
8789
  });
8790
+ var activatedLanguages = (config, dir) => config.manifest(workspaceRoot(dir)).pipe(map$2((manifest) => Object.keys(manifest?.languages ?? {})));
8791
+ var installNote = (language, change) => ServiceInstall.$match(change, {
8792
+ Current: () => `${servicePackage(language)} ${serviceVersion} is already in the store`,
8793
+ Installed: () => `installed ${servicePackage(language)} ${serviceVersion}`,
8794
+ Updated: ({ from }) => `updated ${servicePackage(language)} from ${from} to ${serviceVersion}`
8795
+ });
8796
+ var failedInstall = (error) => refuse(`loom: could not install ${error.packageName} — ${String(error.cause)}`);
8797
+ var alreadyActive = (language, dir) => log(`\n ${teal("✓")} ${language} is already activated\n` + match$1(installedVersion(language, dir), {
8798
+ onNone: () => ` ${dim(`its service is not in the store; \`loom update ${language}\` installs it`)}\n`,
8799
+ onSome: (version) => version === "0.0.13" ? "" : ` ${dim(`the store holds its service at ${version}; \`loom update ${language}\` brings it to ${serviceVersion}`)}\n`
8800
+ }));
8760
8801
  var add = (language) => gen(function* () {
8761
8802
  const config = yield* LoomConfig;
8762
8803
  const dir = process.cwd();
8763
- const change = yield* addService(language, dir);
8764
- yield* updateLanguages(config, dir, (ids) => [.../* @__PURE__ */ new Set([...ids, language])]);
8765
- const service = `${servicePackage(language)} ${serviceVersion}`;
8766
- const done = ServiceInstall.$match(change, {
8767
- Current: () => `${service} is already in the store`,
8768
- Installed: () => `installed ${service}`,
8769
- Updated: ({ from }) => `updated ${servicePackage(language)} from ${from} to ${serviceVersion}`
8770
- });
8771
- yield* log(`\n ${teal("✓")} activated ${language}\n ${dim(done)}\n ${dim(`store: ${storeDir(dir)}`)}\n`);
8772
- }).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))))));
8804
+ if ((yield* activatedLanguages(config, dir)).includes(language)) return yield* alreadyActive(language, dir);
8805
+ const change = yield* installService(language, dir);
8806
+ yield* updateLanguages(config, dir, (ids) => [...ids, language]);
8807
+ yield* log(`\n ${teal("✓")} activated ${language}\n ${dim(installNote(language, change))}\n ${dim(`store: ${storeDir(dir)}`)}\n`);
8808
+ }).pipe(catchTag("StoreError", failedInstall));
8773
8809
  var remove = (language) => gen(function* () {
8774
8810
  const config = yield* LoomConfig;
8775
8811
  const dir = process.cwd();
@@ -8777,6 +8813,123 @@ var remove = (language) => gen(function* () {
8777
8813
  yield* updateLanguages(config, dir, (ids) => ids.filter((id) => id !== language));
8778
8814
  yield* log(`\n ${teal("✓")} removed ${language}\n`);
8779
8815
  });
8816
+ var updateUsage = "usage: loom update <language>… | loom update --all";
8817
+ var update = (languages, all) => gen(function* () {
8818
+ if (languages.length === 0 && !all) return yield* refuse(`loom: name the languages to update, or use --all — ${updateUsage}\n To upgrade Loom itself, run \`loom upgrade\`.`);
8819
+ if (languages.length > 0 && all) return yield* refuse(`loom: name languages or use --all, not both — ${updateUsage}`);
8820
+ const config = yield* LoomConfig;
8821
+ const dir = process.cwd();
8822
+ const activated = yield* activatedLanguages(config, dir);
8823
+ const inactive = languages.filter((id) => !activated.includes(id));
8824
+ if (inactive.length > 0) return yield* forEach(inactive, (id) => refuse(`loom: ${id} is not activated; \`loom add ${id}\` turns it on`), { discard: true });
8825
+ const ids = all ? activated : languages;
8826
+ if (ids.length === 0) return yield* log(`\n ${dim("no languages are activated")}\n`);
8827
+ yield* log("");
8828
+ yield* forEach(ids, (id) => installService(id, dir).pipe(flatMap$1((change) => log(` ${teal("✓")} ${dim(installNote(id, change))}`))));
8829
+ yield* log(` ${dim(`store: ${storeDir(dir)}`)}\n`);
8830
+ }).pipe(catchTag("StoreError", failedInstall));
8831
+ var packageManagerUpgrade = (bundle) => value$1(bundle).pipe(when((path) => /[\\/]\.bun[\\/]/.test(path), () => "bun add -g @athrio/loom@latest"), when((path) => /[\\/]pnpm[\\/]/.test(path), () => "pnpm add -g @athrio/loom@latest"), orElse$1(() => "npm install -g @athrio/loom@latest"));
8832
+ var loomVersion = "0.0.13";
8833
+ var releases = process.env.LOOM_RELEASES ?? "https://api.github.com/repos/athrio-com/loom/releases";
8834
+ var ReleaseSchema = Struct({
8835
+ tag_name: String$5,
8836
+ assets: ArraySchema(Struct({
8837
+ name: String$5,
8838
+ browser_download_url: String$5
8839
+ }))
8840
+ });
8841
+ var versionOrder = mapInput(Array_(Number$2), (version) => version.split(".").map(Number));
8842
+ var ReleaseUnreachable = class extends TaggedError$1("ReleaseUnreachable") {};
8843
+ var fetched = (url) => tryPromise({
8844
+ try: () => fetch(url, { headers: { "user-agent": "loom" } }),
8845
+ catch: (cause) => new ReleaseUnreachable({
8846
+ url,
8847
+ cause
8848
+ })
8849
+ }).pipe(filterOrFail((response) => response.ok, (response) => new ReleaseUnreachable({
8850
+ url,
8851
+ cause: `${response.status} ${response.statusText}`
8852
+ })));
8853
+ var latestRelease = gen(function* () {
8854
+ const url = `${releases}/latest`;
8855
+ const response = yield* fetched(url);
8856
+ const body = yield* tryPromise({
8857
+ try: () => response.json(),
8858
+ catch: (cause) => new ReleaseUnreachable({
8859
+ url,
8860
+ cause
8861
+ })
8862
+ });
8863
+ return yield* decodeUnknownEffect(ReleaseSchema)(body).pipe(mapError((cause) => new ReleaseUnreachable({
8864
+ url,
8865
+ cause
8866
+ })));
8867
+ });
8868
+ var bytesAt = (url) => fetched(url).pipe(flatMap$1((response) => tryPromise({
8869
+ try: async () => new Uint8Array(await response.arrayBuffer()),
8870
+ catch: (cause) => new ReleaseUnreachable({
8871
+ url,
8872
+ cause
8873
+ })
8874
+ })));
8875
+ var assetName = `${process.platform === "win32" ? `loom-windows-${process.arch}.exe` : `loom-${process.platform}-${process.arch}`}.gz`;
8876
+ var ReleaseLacksAsset = class extends TaggedError$1("ReleaseLacksAsset") {};
8877
+ var ChecksumMismatch = class extends TaggedError$1("ChecksumMismatch") {};
8878
+ var assetUrl = (release, asset) => match$1(findFirst(release.assets, (candidate) => candidate.name === asset), {
8879
+ onNone: () => fail(new ReleaseLacksAsset({
8880
+ version: release.tag_name,
8881
+ asset
8882
+ })),
8883
+ onSome: (found) => succeed$1(found.browser_download_url)
8884
+ });
8885
+ var listedChecksum = (sums, asset) => pipe(sums.split("\n"), map$3((line) => line.trim().split(/\s+/)), findFirst((fields) => fields[1] === asset || fields[1] === `*${asset}`), flatMap$2((fields) => fromNullishOr(fields[0])));
8886
+ var verified = (bytes, sums, asset) => contains(listedChecksum(sums, asset), createHash("sha256").update(bytes).digest("hex")) ? succeed$1(bytes) : fail(new ChecksumMismatch({ asset }));
8887
+ var UnpackFailed = class extends TaggedError$1("UnpackFailed") {};
8888
+ var unpacked = (archive) => try_({
8889
+ try: () => new Uint8Array(gunzipSync(archive)),
8890
+ catch: (cause) => new UnpackFailed({
8891
+ asset: assetName,
8892
+ cause
8893
+ })
8894
+ });
8895
+ var ReplaceFailed = class extends TaggedError$1("ReplaceFailed") {};
8896
+ var moveAside = (target) => {
8897
+ if (process.platform !== "win32") return;
8898
+ rmSync(`${target}.old`, { force: true });
8899
+ renameSync(target, `${target}.old`);
8900
+ };
8901
+ var replaceExecutable = (bytes) => {
8902
+ const target = process.execPath;
8903
+ const partial = `${target}.${process.pid}`;
8904
+ return try_({
8905
+ try: () => {
8906
+ writeFileSync(partial, bytes, { mode: 493 });
8907
+ moveAside(target);
8908
+ renameSync(partial, target);
8909
+ },
8910
+ catch: (cause) => new ReplaceFailed({
8911
+ path: target,
8912
+ cause
8913
+ })
8914
+ }).pipe(tapError(() => sync(() => rmSync(partial, { force: true }))));
8915
+ };
8916
+ var upgradeStandalone = gen(function* () {
8917
+ const release = yield* latestRelease;
8918
+ const latest = release.tag_name.replace(/^v/, "");
8919
+ if (!isGreaterThan(versionOrder)(latest, loomVersion)) return yield* log(`\n ${teal("✓")} Loom ${loomVersion} is up to date; the latest release is ${latest}\n`);
8920
+ yield* verified(yield* assetUrl(release, assetName).pipe(flatMap$1(bytesAt)), yield* assetUrl(release, "SHA256SUMS").pipe(flatMap$1(bytesAt), map$2((bytes) => new TextDecoder().decode(bytes))), assetName).pipe(flatMap$1(unpacked), flatMap$1(replaceExecutable));
8921
+ yield* log(`\n ${teal("✓")} upgraded Loom from ${loomVersion} to ${latest}\n ${dim("run `loom update --all` in each workspace to bring its services along")}\n`);
8922
+ });
8923
+ var upgrade = gen(function* () {
8924
+ if (standalone) return yield* upgradeStandalone;
8925
+ yield* log(`\n Loom was installed by a package manager, which upgrades it:\n\n ${packageManagerUpgrade(fileURLToPath(import.meta.url))}\n`);
8926
+ }).pipe(catchTags({
8927
+ ReleaseUnreachable: (error) => refuse(`loom: could not reach the latest release at ${error.url} — ${String(error.cause)}`),
8928
+ ReleaseLacksAsset: (error) => refuse(`loom: release ${error.version} carries no ${error.asset}`),
8929
+ ChecksumMismatch: (error) => refuse(`loom: the checksum of the downloaded ${error.asset} does not match the release's list, so Loom was left as it was`),
8930
+ UnpackFailed: (error) => refuse(`loom: could not unpack ${error.asset} — ${String(error.cause)}`),
8931
+ ReplaceFailed: (error) => refuse(`loom: could not replace ${error.path} — ${String(error.cause)}\n Run the install script again, or move Loom somewhere you can write to.`)
8932
+ }));
8780
8933
  var status = gen(function* () {
8781
8934
  const config = yield* LoomConfig;
8782
8935
  const dir = process.cwd();
@@ -8784,8 +8937,8 @@ var status = gen(function* () {
8784
8937
  const primary = manifest?.primary;
8785
8938
  const languages = Object.keys(manifest?.languages ?? {});
8786
8939
  const mark = (id) => match$1(installedVersion(id, dir), {
8787
- onNone: () => ` ${dim("○")} ${id}${dim(` — run \`loom add ${id}\``)}`,
8788
- onSome: (version) => version === "0.0.12" ? ` ${teal("●")} ${id}` : ` ${dim("◐")} ${id}${dim(` — ${version} is installed; run \`loom add ${id}\` for ${serviceVersion}`)}`
8940
+ onNone: () => ` ${dim("○")} ${id}${dim(` — run \`loom update ${id}\``)}`,
8941
+ onSome: (version) => version === "0.0.13" ? ` ${teal("●")} ${id}` : ` ${dim("◐")} ${id}${dim(` — ${version} is installed; run \`loom update ${id}\` for ${serviceVersion}`)}`
8789
8942
  });
8790
8943
  yield* log(`\n ${dim("store")} ${storeDir(dir)}\n ${dim("primary")} ${primary ?? dim("(none)")}\n ${dim("activated")} ${languages.length === 0 ? dim("(none)") : languages.join(", ")}\n`);
8791
8944
  if (languages.length > 0) yield* log(`${languages.map(mark).join("\n")}\n`);
@@ -8806,13 +8959,7 @@ var set = (name, value) => gen(function* () {
8806
8959
  return;
8807
8960
  }
8808
8961
  const current = yield* config.manifest(workspace);
8809
- yield* config.materialize(workspace, {
8810
- ...current ?? {},
8811
- variables: {
8812
- ...current?.variables ?? {},
8813
- [name]: value
8814
- }
8815
- });
8962
+ yield* config.edit(workspace, ["variables", name], value);
8816
8963
  const corpus = resolve(workspace, current?.corpus ?? "corpus");
8817
8964
  yield* log(`loom: set ${name} = ${value} (re-tangled ${(yield* tangler.tangle(corpus)).length} files)`);
8818
8965
  }).pipe(catchTag("TangleError", (e) => error(e.message).pipe(andThen(sync(() => void (process.exitCode = 1))))));
@@ -8835,12 +8982,24 @@ var design = (project, application, port) => gen(function* () {
8835
8982
  }), (running) => running.exitCode));
8836
8983
  yield* sync(() => void (process.exitCode = code));
8837
8984
  }).pipe(catchTag("DesignMissing", () => error("loom: Loom Design is not installed.\n Add it with `bun add -d @athrio/loom-design`, then run this again.").pipe(andThen(sync(() => void (process.exitCode = 1))))), catchCause((cause) => error(`loom: Loom Design could not start\n${pretty(cause)}`).pipe(andThen(sync(() => void (process.exitCode = 1))))));
8985
+ var embeddedGrammar = tryPromise(() => import("./_virtual_tree-sitter-loom-CFLf84Ng.js")).pipe(map$2((module) => some(module.default)), orElseSucceed(() => none()));
8986
+ var unpackedGrammar = (files) => acquireRelease(sync(() => mkdtempSync(resolve(tmpdir(), "loom-grammar-"))), (dir) => sync(() => rmSync(dir, {
8987
+ recursive: true,
8988
+ force: true
8989
+ }))).pipe(tap((dir) => forEach(Object.entries(files), ([path, text]) => sync(() => {
8990
+ mkdirSync(dirname(resolve(dir, path)), { recursive: true });
8991
+ writeFileSync(resolve(dir, path), text);
8992
+ }), { discard: true })));
8838
8993
  var GrammarMissing = class extends TaggedError$1("GrammarMissing") {};
8839
8994
  var grammarIn = (dir) => existsSync(resolve(dir, "src", "parser.c")) ? some(dir) : none();
8840
- var shippedGrammar = pipe(grammarIn(resolve(dirname(fileURLToPath(import.meta.url)), "tree-sitter-loom")), orElse(() => flatMap$2(liftThrowable(() => createRequire(import.meta.url).resolve("tree-sitter-loom/package.json"))(), (manifest) => grammarIn(dirname(manifest)))), match$1({
8841
- onNone: () => fail(new GrammarMissing()),
8842
- onSome: (dir) => succeed$1(dir)
8843
- }));
8995
+ var workspaceGrammar = () => flatMap$2(liftThrowable(() => createRequire(import.meta.url).resolve("tree-sitter-loom/package.json"))(), (manifest) => grammarIn(dirname(manifest)));
8996
+ var shippedGrammar = embeddedGrammar.pipe(flatMap$1(match$1({
8997
+ onSome: unpackedGrammar,
8998
+ onNone: () => match$1(workspaceGrammar(), {
8999
+ onNone: () => fail(new GrammarMissing()),
9000
+ onSome: (dir) => succeed$1(dir)
9001
+ })
9002
+ })));
8844
9003
  var GrammarCompileFailed = class extends TaggedError$1("GrammarCompileFailed") {};
8845
9004
  var compileGrammar = (grammar, library) => gen(function* () {
8846
9005
  const compiler = process.env.CC ?? "cc";
@@ -8863,10 +9022,19 @@ var compileGrammar = (grammar, library) => gen(function* () {
8863
9022
  }), (running) => running.exitCode)).pipe(catchCause(() => succeed$1(-1)))) !== 0) return yield* fail(new GrammarCompileFailed({ compiler }));
8864
9023
  yield* sync(() => renameSync(partial, library));
8865
9024
  });
9025
+ var grammarLibrary = process.platform === "win32" ? "loom.dll" : "loom.so";
9026
+ var writeLibrary = (prebuilt, library) => promise(() => prebuilt.arrayBuffer()).pipe(flatMap$1((bytes) => sync(() => {
9027
+ const partial = `${library}.${process.pid}`;
9028
+ writeFileSync(partial, new Uint8Array(bytes), { mode: 493 });
9029
+ renameSync(partial, library);
9030
+ })));
9031
+ var buildGrammar = (grammar, library) => match$1(embeddedFile(grammarLibrary), {
9032
+ onSome: (prebuilt) => writeLibrary(prebuilt, library),
9033
+ onNone: () => compileGrammar(grammar, library)
9034
+ });
8866
9035
  var refuse = (message) => error(message).pipe(andThen(sync(() => void (process.exitCode = 1))));
8867
9036
  var cannotCompile = (error) => refuse(`loom: could not compile the grammar with \`${error.compiler}\`.\n Install a C compiler, or name one in the CC variable, then run this again.`);
8868
9037
  var helixConfigDir = () => process.platform === "win32" ? resolve(process.env.APPDATA ?? homedir(), "helix") : resolve(process.env.XDG_CONFIG_HOME ?? resolve(homedir(), ".config"), "helix");
8869
- var grammarLibrary = process.platform === "win32" ? "loom.dll" : "loom.so";
8870
9038
  var helixBlock = {
8871
9039
  begin: "# Loom: written by `loom helix`, which replaces this block on every run",
8872
9040
  end: "# Loom: end",
@@ -8899,14 +9067,14 @@ var helix = gen(function* () {
8899
9067
  const languages = yield* withLoomLanguages(languagesFile, yield* sync(() => existsSync(languagesFile) ? readFileSync(languagesFile, "utf8") : ""));
8900
9068
  const library = resolve(config, "runtime", "grammars", grammarLibrary);
8901
9069
  yield* sync(() => mkdirSync(dirname(library), { recursive: true }));
8902
- yield* compileGrammar(grammar, library);
9070
+ yield* buildGrammar(grammar, library);
8903
9071
  yield* log(`\n ${teal("✓")} built the grammar into ${library}`);
8904
9072
  const queries = resolve(config, "runtime", "queries", "loom");
8905
9073
  yield* sync(() => cpSync(resolve(grammar, "editors", "helix", "queries", "loom"), queries, { recursive: true }));
8906
9074
  yield* log(` ${teal("✓")} copied the queries into ${queries}`);
8907
9075
  yield* sync(() => writeFileSync(languagesFile, languages));
8908
9076
  yield* log(` ${teal("✓")} added Loom to ${languagesFile}\n ${dim("check it with `hx --health loom`")}\n`);
8909
- }).pipe(catchTags({
9077
+ }).pipe(scoped, catchTags({
8910
9078
  GrammarMissing: () => refuse("loom: this installation of Loom carries no grammar for Helix."),
8911
9079
  GrammarCompileFailed: cannotCompile,
8912
9080
  HelixConfigClash: (error) => refuse(`loom: ${error.file} already sets up Loom.\n Remove its Loom entries, then run this again to replace them with the managed block.`)
@@ -8944,7 +9112,7 @@ var nvim = gen(function* () {
8944
9112
  if (exists(yield* sync(() => existsSync(pluginFile) ? some(readFileSync(pluginFile, "utf8")) : none()), (text) => !text.startsWith(nvimHeader))) return yield* fail(new NvimConfigClash({ file: pluginFile }));
8945
9113
  const parser = resolve(site, "parser", "loom.so");
8946
9114
  yield* sync(() => mkdirSync(dirname(parser), { recursive: true }));
8947
- yield* compileGrammar(grammar, parser);
9115
+ yield* buildGrammar(grammar, parser);
8948
9116
  yield* log(`\n ${teal("✓")} built the grammar into ${parser}`);
8949
9117
  const queries = resolve(site, "queries", "loom");
8950
9118
  yield* sync(() => cpSync(resolve(grammar, "queries"), queries, { recursive: true }));
@@ -8954,7 +9122,7 @@ var nvim = gen(function* () {
8954
9122
  writeFileSync(pluginFile, nvimPlugin);
8955
9123
  });
8956
9124
  yield* log(` ${teal("✓")} added Loom to ${pluginFile}\n ${dim("check it with `:checkhealth vim.treesitter` in Neovim")}\n`);
8957
- }).pipe(catchTags({
9125
+ }).pipe(scoped, catchTags({
8958
9126
  GrammarMissing: () => refuse("loom: this installation of Loom carries no grammar for Neovim."),
8959
9127
  GrammarCompileFailed: cannotCompile,
8960
9128
  NvimConfigClash: (error) => refuse(`loom: ${error.file} was not written by \`loom nvim\`.\n Move it aside, then run this again.`)
@@ -8976,6 +9144,11 @@ var tocCommand = make$5("toc", { path: String$1("path") }, ({ path }) => toc(pat
8976
9144
  var initCommand = make$5("init", { dir: optional$1(Directory("dir")) }, ({ dir }) => init(dir));
8977
9145
  var addCommand = make$5("add", { language: String$1("language") }, ({ language }) => add(language));
8978
9146
  var removeCommand = make$5("remove", { language: String$1("language") }, ({ language }) => remove(language));
9147
+ var updateCommand = make$5("update", {
9148
+ languages: String$1("language").pipe(variadic()),
9149
+ all: Boolean("all").pipe(withDefault(false))
9150
+ }, ({ languages, all }) => update(languages, all));
9151
+ var upgradeCommand = make$5("upgrade", {}, () => upgrade);
8979
9152
  var statusCommand = make$5("status", {}, () => status);
8980
9153
  var setCommand = make$5("set", {
8981
9154
  name: String$1("name"),
@@ -8997,15 +9170,17 @@ var program = run(make$5("loom").pipe(withSubcommands([
8997
9170
  initCommand,
8998
9171
  addCommand,
8999
9172
  removeCommand,
9173
+ updateCommand,
9174
+ upgradeCommand,
9000
9175
  statusCommand,
9001
9176
  setCommand,
9002
9177
  designCommand,
9003
9178
  helixCommand,
9004
9179
  nvimCommand
9005
- ])), { version: "0.0.12" }).pipe(provide$1(LoomTangler.layer), provide$1(LoomWeaver.layer), provide$1(LoomContents.layer), provide$1(LoomFormatter.layer), provide$1(DocumentSource.layer), provide$1(PackageConfig.layer), provide$1(LoomConfig.layer), provide$1(layer));
9180
+ ])), { version: loomVersion }).pipe(provide$1(LoomTangler.layer), provide$1(LoomWeaver.layer), provide$1(LoomContents.layer), provide$1(LoomFormatter.layer), provide$1(DocumentSource.layer), provide$1(PackageConfig.layer), provide$1(LoomConfig.layer), provide$1(layer));
9006
9181
  if (process.argv[2] === "lsp") {
9007
9182
  globalThis.require = createRequire(import.meta.url);
9008
- const { startLanguageServer } = await import("./LoomServer-DXIree_1.js");
9183
+ const { startLanguageServer } = await import("./LoomServer-C54yIIo1.js");
9009
9184
  startLanguageServer();
9010
9185
  } else runMain(program);
9011
9186
  //#endregion