cssints 0.2.0 → 0.3.1

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 (50) hide show
  1. package/README.md +88 -44
  2. package/dist/check.mjs +2 -2
  3. package/dist/{contrast-DhK69Xak.mjs → contrast-B49XCnVX.mjs} +2 -2
  4. package/dist/devtools-link-D2YxsJKZ.mjs +94 -0
  5. package/dist/devtools-link.d.mts +55 -0
  6. package/dist/devtools-link.mjs +2 -0
  7. package/dist/groups/baseline-2015/with-downstream.d.mts +81 -0
  8. package/dist/groups/baseline-2015.d.mts +291 -0
  9. package/dist/groups/baseline-2016/with-downstream.d.mts +86 -0
  10. package/dist/groups/baseline-2016.d.mts +310 -0
  11. package/dist/groups/baseline-2017/with-downstream.d.mts +94 -0
  12. package/dist/groups/baseline-2017.d.mts +365 -0
  13. package/dist/groups/baseline-2018/with-downstream.d.mts +94 -0
  14. package/dist/groups/baseline-2018.d.mts +368 -0
  15. package/dist/groups/baseline-2019/with-downstream.d.mts +97 -0
  16. package/dist/groups/baseline-2019.d.mts +375 -0
  17. package/dist/groups/baseline-2020/with-downstream.d.mts +112 -0
  18. package/dist/groups/baseline-2020.d.mts +480 -0
  19. package/dist/groups/baseline-2021/with-downstream.d.mts +125 -0
  20. package/dist/groups/baseline-2021.d.mts +536 -0
  21. package/dist/groups/baseline-2022/with-downstream.d.mts +126 -0
  22. package/dist/groups/baseline-2022.d.mts +562 -0
  23. package/dist/groups/baseline-2023/with-downstream.d.mts +120 -0
  24. package/dist/groups/baseline-2023.d.mts +606 -0
  25. package/dist/groups/baseline-2024/with-downstream.d.mts +627 -0
  26. package/dist/groups/baseline-2024.d.mts +632 -0
  27. package/dist/groups/baseline-2025/with-downstream.d.mts +628 -0
  28. package/dist/groups/baseline-2025.d.mts +640 -0
  29. package/dist/groups/baseline-2026/with-downstream.d.mts +3 -0
  30. package/dist/groups/baseline-2026.d.mts +3 -0
  31. package/dist/groups/newly-available/with-downstream.d.mts +632 -0
  32. package/dist/groups/widely-available/with-downstream.d.mts +121 -0
  33. package/dist/index.mjs +22 -7
  34. package/dist/instrument-BqIZpbIU.mjs +3956 -0
  35. package/dist/{lowered-D2KusPLp.mjs → lowered-aJVapQT6.mjs} +1 -1
  36. package/dist/plugin-types.d.mts +7 -0
  37. package/dist/plugin.d.mts +2 -2
  38. package/dist/plugin.mjs +8 -1
  39. package/dist/{registry-CTumHB8p.mjs → registry-BUSEO32-.mjs} +7 -1
  40. package/dist/{scope-ZVhUxQH1.d.mts → scope-INuJD4RT.d.mts} +8 -1
  41. package/dist/{sheet-BKsMTa0c.mjs → sheet-BeHdq4xt.mjs} +1 -1
  42. package/dist/surface.d.mts +1 -1
  43. package/dist/{theme-BsP2E4LB.mjs → theme-SlQ73rFL.mjs} +3 -3
  44. package/dist/tui.mjs +4 -4
  45. package/dist/vite.d.mts +3 -1
  46. package/dist/vite.mjs +92 -39
  47. package/docs/API.md +458 -231
  48. package/package.json +6 -2
  49. package/skills/cssints-plugin/SKILL.md +2 -0
  50. package/dist/instrument-gCazujmb.mjs +0 -1624
@@ -1,4 +1,4 @@
1
- import { a as registry } from "./registry-CTumHB8p.mjs";
1
+ import { a as registry } from "./registry-BUSEO32-.mjs";
2
2
  import { Result } from "effect";
3
3
  import { browserslistToTargets, transform } from "lightningcss";
4
4
  //#region src/lowered.ts
@@ -373,5 +373,12 @@ export declare const lacking: (...keys: BcdKey[]) => string[];
373
373
  * file. Build time, like `scope()`: in a member's functions or in the plugin's own.
374
374
  */
375
375
  export declare const dependsOn: (path: string) => void;
376
+ /**
377
+ * Whether a declaration is in an export group (`cssints/widely-available`, `baseline-2022/with-downstream`, ...): the group
378
+ * has the property and the value holds no word the group bans. A property cssints has no member for (a custom property, a
379
+ * vendor-prefixed one) is in every group. A plugin that has a variant per group emits only what passes. Build time, like
380
+ * `scope()`; an unknown group is an error.
381
+ */
382
+ export declare const inGroup: (group: string, property: string, value: string) => boolean;
376
383
  //#endregion
377
384
  export type { ArgsDef, Chain, Conflict, Css, Decl, Entry, GlobalRule, Impl, Kernel, KernelDef, Made, Members, Part, Pending, Runtime, Scope, Style, Table, ThemeRule, Typed };
package/dist/plugin.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { _ as lacking, a as Entry, b as Style, c as Made, d as Scope, f as Table, g as fn, h as dependsOn, i as Css, l as Members, m as arg, n as ArgsDef, o as Impl, p as Typed, r as Chain, s as KernelDef, u as Pending, v as scope, y as Part } from "./scope-ZVhUxQH1.mjs";
1
+ import { _ as inGroup, a as Entry, b as Part, c as Made, d as Scope, f as Table, g as fn, h as dependsOn, i as Css, l as Members, m as arg, n as ArgsDef, o as Impl, p as Typed, r as Chain, s as KernelDef, u as Pending, v as lacking, x as Style, y as scope } from "./scope-INuJD4RT.mjs";
2
2
  import { a as Kernel, i as GlobalRule, n as Conflict, o as Runtime, r as Decl, s as ThemeRule } from "./author-types-C1AhsnrT.mjs";
3
- export { type ArgsDef, type Chain, type Conflict, type Css, type Decl, type Entry, type GlobalRule, type Impl, type Kernel, type KernelDef, type Made, type Members, type Part, type Pending, type Runtime, type Scope, type Style, type Table, type ThemeRule, type Typed, arg, dependsOn, fn, lacking, scope };
3
+ export { type ArgsDef, type Chain, type Conflict, type Css, type Decl, type Entry, type GlobalRule, type Impl, type Kernel, type KernelDef, type Made, type Members, type Part, type Pending, type Runtime, type Scope, type Style, type Table, type ThemeRule, type Typed, arg, dependsOn, fn, inGroup, lacking, scope };
package/dist/plugin.mjs CHANGED
@@ -26,5 +26,12 @@ const lacking = (...keys) => engine().lacking(keys);
26
26
  * file. Build time, like `scope()`: in a member's functions or in the plugin's own.
27
27
  */
28
28
  const dependsOn = (path) => engine().dependsOn(path);
29
+ /**
30
+ * Whether a declaration is in an export group (`cssints/widely-available`, `baseline-2022/with-downstream`, ...): the group
31
+ * has the property and the value holds no word the group bans. A property cssints has no member for (a custom property, a
32
+ * vendor-prefixed one) is in every group. A plugin that has a variant per group emits only what passes. Build time, like
33
+ * `scope()`; an unknown group is an error.
34
+ */
35
+ const inGroup = (group, property, value) => engine().inGroup(group, property, value);
29
36
  //#endregion
30
- export { arg, dependsOn, fn, lacking, scope };
37
+ export { arg, dependsOn, fn, inGroup, lacking, scope };
@@ -66,7 +66,13 @@ const forgetKernels = (file) => {
66
66
  };
67
67
  const forget = (file) => {
68
68
  forgetKernels(file);
69
- for (const themed of [registry.themed, registry.terminal?.themed ?? /* @__PURE__ */ new Map()]) for (const [k, t] of themed) if (t.file === file) themed.delete(k);
69
+ for (const s of [registry, registry.terminal ?? registry]) {
70
+ for (const [k, p] of s.properties) if (p.file === file) {
71
+ s.properties.delete(k);
72
+ s.defs.delete(k);
73
+ }
74
+ for (const [k, t] of s.themed) if (t.file === file) s.themed.delete(k);
75
+ }
70
76
  for (const [k, c] of registry.checks) if (c.at.file === file) registry.checks.delete(k);
71
77
  };
72
78
  //#endregion
@@ -2097,5 +2097,12 @@ declare const lacking: (...keys: BcdKey[]) => string[];
2097
2097
  * file. Build time, like `scope()`: in a member's functions or in the plugin's own.
2098
2098
  */
2099
2099
  declare const dependsOn: (path: string) => void;
2100
+ /**
2101
+ * Whether a declaration is in an export group (`cssints/widely-available`, `baseline-2022/with-downstream`, ...): the group
2102
+ * has the property and the value holds no word the group bans. A property cssints has no member for (a custom property, a
2103
+ * vendor-prefixed one) is in every group. A plugin that has a variant per group emits only what passes. Build time, like
2104
+ * `scope()`; an unknown group is an error.
2105
+ */
2106
+ declare const inGroup: (group: string, property: string, value: string) => boolean;
2100
2107
  //#endregion
2101
- export { lacking as _, Entry as a, Style as b, Made as c, Scope as d, Table as f, fn as g, dependsOn as h, Css as i, Members as l, arg as m, ArgsDef as n, Impl as o, Typed as p, Chain as r, KernelDef as s, AliasesOf as t, Pending as u, scope as v, Part as y };
2108
+ export { inGroup as _, Entry as a, Part as b, Made as c, Scope as d, Table as f, fn as g, dependsOn as h, Css as i, Members as l, arg as m, ArgsDef as n, Impl as o, Typed as p, Chain as r, KernelDef as s, AliasesOf as t, Pending as u, lacking as v, Style as x, scope as y };
@@ -1,4 +1,4 @@
1
- import { d as MacroError, f as MemberError, o as warn, t as Registry } from "./registry-CTumHB8p.mjs";
1
+ import { d as MacroError, f as MemberError, o as warn, t as Registry } from "./registry-BUSEO32-.mjs";
2
2
  import { browsers, lacking, messageOf, supportOf } from "@cssints/css-grammar/support";
3
3
  import { Effect, Formatter, Result, Schema } from "effect";
4
4
  import { longhands } from "@cssints/css-grammar/longhands";
@@ -1,4 +1,4 @@
1
- import { t as AliasesOf } from "./scope-ZVhUxQH1.mjs";
1
+ import { t as AliasesOf } from "./scope-INuJD4RT.mjs";
2
2
  //#region src/surface.d.ts
3
3
  /**
4
4
  * `surface().color(t.color.canvas).lighten(0.06).ink()`: a background that follows from the surface around it, however
@@ -1,6 +1,6 @@
1
- import { a as registry, d as MacroError, f as MemberError, o as warn } from "./registry-CTumHB8p.mjs";
2
- import { D as relation, E as covers, d as requireLayer, p as standIn } from "./sheet-BKsMTa0c.mjs";
3
- import { t as fallbackOf } from "./lowered-D2KusPLp.mjs";
1
+ import { a as registry, d as MacroError, f as MemberError, o as warn } from "./registry-BUSEO32-.mjs";
2
+ import { D as relation, E as covers, d as requireLayer, p as standIn } from "./sheet-BeHdq4xt.mjs";
3
+ import { t as fallbackOf } from "./lowered-aJVapQT6.mjs";
4
4
  import { createRequire } from "node:module";
5
5
  import { checkSelector } from "@cssints/css-grammar/check";
6
6
  import { browsers, supportOf } from "@cssints/css-grammar/support";
package/dist/tui.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { a as registry } from "./registry-CTumHB8p.mjs";
2
- import { a as createTokens$1, i as createGlobalTheme$1, j as fail, s as sets } from "./theme-BsP2E4LB.mjs";
3
- import { g as evaluate, h as css } from "./sheet-BKsMTa0c.mjs";
4
- import { n as valueOf, t as together } from "./contrast-DhK69Xak.mjs";
1
+ import { a as registry } from "./registry-BUSEO32-.mjs";
2
+ import { a as createTokens$1, i as createGlobalTheme$1, j as fail, s as sets } from "./theme-SlQ73rFL.mjs";
3
+ import { g as evaluate, h as css } from "./sheet-BeHdq4xt.mjs";
4
+ import { n as valueOf, t as together } from "./contrast-B49XCnVX.mjs";
5
5
  import { n as parseColor } from "./color-BYIxVLlS.mjs";
6
6
  import { Formatter } from "effect";
7
7
  import { clampRgb, formatHex, formatHex8 } from "culori/fn";
package/dist/vite.d.mts CHANGED
@@ -76,6 +76,8 @@ interface Site {
76
76
  start: number;
77
77
  end: number;
78
78
  inFn: boolean;
79
+ /** dev with devtools: the readable class of a cn() or cv() site (`cs-Landing-logo`), see `tagged` */
80
+ name: string | undefined;
79
81
  locals: Set<string>;
80
82
  group?: SiteGroup;
81
83
  }
@@ -84,7 +86,7 @@ interface Instrumented {
84
86
  sites: Site[];
85
87
  imp: CssImports;
86
88
  }
87
- export declare const instrument: (code: string, id: string, client?: boolean | undefined) => Effect.Effect<Instrumented | null, ImportError, never>;
89
+ export declare const instrument: (code: string, id: string, client?: boolean | undefined, named?: boolean | undefined) => Effect.Effect<Instrumented | null, ImportError, never>;
88
90
  //#endregion
89
91
  //#region src/sheet.d.ts
90
92
  /** Adds a global rule (`*{box-sizing:border-box}`) of a plugin member, by its content, to the sheet of the module at `at`. `layer` names a declared top-level layer to wrap it in, no layer puts it in `_.k`. */
package/dist/vite.mjs CHANGED
@@ -1,15 +1,16 @@
1
- import { c as EvalError, d as MacroError, f as MemberError, i as forgetWarnings, l as HookError, n as forget, p as SiteMissingError, t as Registry } from "./registry-CTumHB8p.mjs";
2
- import { C as fallbackEntries, T as runtimeNames, a as closeNames, b as DERIVED, c as layerEntries, f as themedEntries, l as layerStatements, m as usesDerived, n as addGlobal, o as globalEntries, r as addLayers, s as globalNames, t as LAYERS, u as renderSheet, v as kernelEntries, w as runtimeModule, x as RUNTIME_ID } from "./sheet-BKsMTa0c.mjs";
3
- import { a as runtimeImport, i as instrument, o as writeSite } from "./instrument-gCazujmb.mjs";
4
- import { r as verifyChecks } from "./contrast-DhK69Xak.mjs";
1
+ import { c as EvalError, d as MacroError, f as MemberError, i as forgetWarnings, l as HookError, n as forget, p as SiteMissingError, t as Registry } from "./registry-BUSEO32-.mjs";
2
+ import { C as fallbackEntries, T as runtimeNames, a as closeNames, b as DERIVED, c as layerEntries, f as themedEntries, l as layerStatements, m as usesDerived, n as addGlobal, o as globalEntries, r as addLayers, s as globalNames, t as LAYERS, u as renderSheet, v as kernelEntries, w as runtimeModule, x as RUNTIME_ID } from "./sheet-BeHdq4xt.mjs";
3
+ import { a as runtimeImport, i as instrument, o as tagged, s as writeSite } from "./instrument-BqIZpbIU.mjs";
4
+ import { r as verifyChecks } from "./contrast-B49XCnVX.mjs";
5
+ import { i as serverId, n as gitRoot, o as sessionOf, r as register } from "./devtools-link-D2YxsJKZ.mjs";
5
6
  import { createRequire } from "node:module";
6
7
  import { targets as targets$1, useTargets } from "@cssints/css-grammar/support";
7
8
  import { Cause, Clock, Config, Data, Effect, Exit, Formatter, Option, Predicate, Result, Schema, Semaphore } from "effect";
8
9
  import { createHash } from "node:crypto";
9
- import { basename, join, relative, resolve, sep } from "node:path";
10
+ import { basename, join, relative, resolve } from "node:path";
10
11
  import { browserslistToTargets } from "lightningcss";
11
12
  import MagicString from "magic-string";
12
- import { existsSync, readFileSync } from "node:fs";
13
+ import { readFileSync } from "node:fs";
13
14
  import { readFile } from "node:fs/promises";
14
15
  import { browsers as browsers$1 } from "@cssints/css-grammar/browsers";
15
16
  import { createFilter, createServer, createServerModuleRunner, normalizePath, transformWithOxc } from "vite";
@@ -31,6 +32,7 @@ var DomEvaluator = class extends ESModulesEvaluator {
31
32
  }
32
33
  };
33
34
  const evalLock = Semaphore.makeUnsafe(1);
35
+ const LIMIT = Effect.runSync(Config.Int("CSSINTS_EVAL_TIMEOUT").pipe(Config.withDefault(3e4)));
34
36
  const LIB = fileURLToPath(new URL("./index.ts", import.meta.url));
35
37
  const clearApp = ({ idToModuleMap, urlToIdModuleMap, fileToModulesMap }) => {
36
38
  const lib = /* @__PURE__ */ new Set();
@@ -90,11 +92,11 @@ const evaluateModule = Effect.fnUntraced(function* (runner, id, targets) {
90
92
  try: () => runner.import(id).then((m) => m.__cssints_hoisted?.()),
91
93
  catch: failureOf(id, registry)
92
94
  }).pipe(Effect.withSpan("cssints.runner.import", { attributes: { file: id } }), Effect.timeoutOrElse({
93
- duration: "30 seconds",
94
- orElse: () => Effect.fail(new EvalError({
95
+ duration: LIMIT,
96
+ orElse: () => Effect.promise(() => runner.close()).pipe(Effect.andThen(Effect.fail(new EvalError({
95
97
  file: id,
96
- message: `cssints: evaluating ${id} took more than 30 seconds`
97
- }))
98
+ message: `cssints: evaluating ${id} took more than ${LIMIT / 1e3} seconds`
99
+ }))))
98
100
  }));
99
101
  yield* verifyChecks((c) => c.gen === registry.gen);
100
102
  return registry.sites.get(id) ?? /* @__PURE__ */ new Map();
@@ -190,13 +192,30 @@ const table = Effect.fn("cssints.devtoolsTable")(function* (root, usedBy, callsO
190
192
  });
191
193
  const ASK = "cssints:devtools:ask";
192
194
  const ASKED = "cssints:devtools:asked";
195
+ const LINK = "cssints:devtools:link";
196
+ const LINKED = "cssints:devtools:linked";
193
197
  const MAX_PROMPT = 16e3;
194
198
  const Asking = Schema.Struct({
195
199
  ref: Schema.Finite,
196
200
  prompt: Schema.String
197
201
  });
198
202
  var OpenCodeError = class extends Data.TaggedError("OpenCodeError") {};
199
- const workspace = (root) => root.split(sep).map((_, i, parts) => parts.slice(0, parts.length - i).join(sep) || sep).find((dir) => existsSync(join(dir, ".git"))) ?? root;
203
+ const attachedTo = (root) => Effect.sync(() => {
204
+ const git = gitRoot(root);
205
+ return sessionOf(git, serverId(git, root));
206
+ });
207
+ const urlOf = (s) => {
208
+ const address = s.httpServer?.address();
209
+ return Predicate.hasProperty(address, "port") ? `${s.config.server.https ? "https" : "http"}://localhost:${address.port}/` : void 0;
210
+ };
211
+ const announce = (s) => Effect.try(() => {
212
+ const http = s.httpServer;
213
+ const url = urlOf(s);
214
+ if (!http || !url) return;
215
+ const remove = register(gitRoot(s.config.root), s.config.root, url);
216
+ http.once("close", remove);
217
+ process.once("exit", remove);
218
+ }).pipe(Effect.ignore);
200
219
  const connect = Effect.fn("cssints.opencodeConnect")(function* () {
201
220
  const unavailable = (message) => () => new OpenCodeError({
202
221
  status: "unavailable",
@@ -216,15 +235,36 @@ const connect = Effect.fn("cssints.opencodeConnect")(function* () {
216
235
  });
217
236
  if (!service) return yield* new OpenCodeError({
218
237
  status: "unavailable",
238
+ idle: true,
219
239
  message: "No OpenCode service is running. Start OpenCode (or `opencode serve --service`) and send again."
220
240
  });
221
- return OpenCode.make({
222
- baseUrl: service.url,
223
- headers: Service.headers(service)
224
- });
241
+ return {
242
+ url: service.url,
243
+ client: OpenCode.make({
244
+ baseUrl: service.url,
245
+ headers: Service.headers(service)
246
+ })
247
+ };
225
248
  });
226
- const ask = Effect.fn("cssints.opencodeAsk")(function* (root, options, ref, prompt, say) {
227
- const client = yield* connect();
249
+ const link = Effect.fn("cssints.opencodeLink")(function* (root) {
250
+ const directory = gitRoot(root);
251
+ const attached = yield* attachedTo(root);
252
+ const session = attached ? { session: attached } : {};
253
+ return yield* connect().pipe(Effect.map(({ url }) => ({
254
+ connected: true,
255
+ url,
256
+ directory,
257
+ ...session
258
+ })), Effect.catchTag("OpenCodeError", (e) => Effect.succeed({
259
+ connected: false,
260
+ directory,
261
+ ...session,
262
+ ...e.idle ? {} : { message: e.message }
263
+ })));
264
+ });
265
+ const appLine = (root, url) => `App: ${relative(gitRoot(root), root) || "."}${url ? ` (${url})` : ""}; file paths below are relative to it`;
266
+ const ask = Effect.fn("cssints.opencodeAsk")(function* (root, url, options, ref, prompt, say) {
267
+ const { client } = yield* connect();
228
268
  const call = (f) => Effect.tryPromise({
229
269
  try: f,
230
270
  catch: (e) => new OpenCodeError({
@@ -232,11 +272,16 @@ const ask = Effect.fn("cssints.opencodeAsk")(function* (root, options, ref, prom
232
272
  message: Predicate.isError(e) ? e.message : String(e)
233
273
  })
234
274
  });
235
- const { id } = yield* call(() => client.session.create({
275
+ const attached = yield* attachedTo(root);
276
+ if (attached) yield* call(() => client.session.get({ sessionID: attached })).pipe(Effect.mapError((e) => new OpenCodeError({
277
+ status: "failed",
278
+ message: `The attached session ${attached} is gone (${e.message}). Run /cssints-devtools in an OpenCode session to attach another.`
279
+ })));
280
+ const id = attached ?? (yield* call(() => client.session.create({
236
281
  title: "cssints devtools: UI change",
237
282
  ...options.agent ? { agent: options.agent } : {},
238
- location: { directory: workspace(root) }
239
- }));
283
+ location: { directory: gitRoot(root) }
284
+ }))).id;
240
285
  say({
241
286
  ref,
242
287
  status: "running",
@@ -244,7 +289,7 @@ const ask = Effect.fn("cssints.opencodeAsk")(function* (root, options, ref, prom
244
289
  });
245
290
  yield* call(() => client.session.prompt({
246
291
  sessionID: id,
247
- text: prompt.slice(0, MAX_PROMPT),
292
+ text: `${appLine(root, url)}\n${prompt}`.slice(0, MAX_PROMPT),
248
293
  ...options.skills?.length ? { skills: options.skills.map((s) => ({ id: s })) } : {}
249
294
  }));
250
295
  yield* call(() => client.session.wait({ sessionID: id }));
@@ -260,7 +305,7 @@ const hot = import.meta.hot;
260
305
  mount({
261
306
  root: ${Formatter.formatJson(root)},
262
307
  request: () => hot.send("cssints:devtools:get"),
263
- on: (event, listener) => hot.on(event, listener),${opencode ? `\n ask: (ref, prompt) => hot.send("${ASK}", { ref, prompt }),` : ""}
308
+ on: (event, listener) => hot.on(event, listener),${opencode ? `\n ask: (ref, prompt) => hot.send("${ASK}", { ref, prompt }),\n link: () => hot.send("${LINK}"),` : ""}
264
309
  });
265
310
  ` : `console.warn("cssints: devtools is on, but @cssints/devtools/overlay is not installed (or not built): add @cssints/devtools to the devDependencies of the app");\n`;
266
311
  /**
@@ -283,18 +328,22 @@ const devtoolsPlugin = (usedBy, callsOf, opencode) => {
283
328
  apply: "serve",
284
329
  configureServer(s) {
285
330
  server = s;
331
+ if (opencode) s.httpServer?.once("listening", () => Effect.runSync(announce(s)));
286
332
  s.environments.client.hot.on("cssints:devtools:get", (_, client) => client.send("cssints:devtools", Effect.runSync(table(s.config.root, usedBy, callsOf))));
287
- if (opencode) s.environments.client.hot.on(ASK, (data) => {
288
- const asking = Schema.decodeUnknownOption(Asking)(data);
289
- if (Option.isNone(asking)) return;
290
- const { ref, prompt } = asking.value;
291
- const say = (asked) => s.environments.client.hot.send(ASKED, asked);
292
- Effect.runFork(ask(s.config.root, opencode, ref, prompt, say).pipe(Effect.catchTag("OpenCodeError", (e) => Effect.sync(() => say({
293
- ref,
294
- status: e.status,
295
- message: e.message
296
- })))));
297
- });
333
+ if (opencode) {
334
+ s.environments.client.hot.on(LINK, () => Effect.runFork(link(s.config.root).pipe(Effect.map((linked) => s.environments.client.hot.send(LINKED, linked)))));
335
+ s.environments.client.hot.on(ASK, (data) => {
336
+ const asking = Schema.decodeUnknownOption(Asking)(data);
337
+ if (Option.isNone(asking)) return;
338
+ const { ref, prompt } = asking.value;
339
+ const say = (asked) => s.environments.client.hot.send(ASKED, asked);
340
+ Effect.runFork(ask(s.config.root, urlOf(s), opencode, ref, prompt, say).pipe(Effect.catchTag("OpenCodeError", (e) => Effect.sync(() => say({
341
+ ref,
342
+ status: e.status,
343
+ message: e.message
344
+ })))));
345
+ });
346
+ }
298
347
  },
299
348
  transformIndexHtml: () => [{
300
349
  tag: "script",
@@ -717,7 +766,7 @@ function cssints({ inner = false, exclude, devtools = false, opencode = false }
717
766
  site: n,
718
767
  offset: s.start
719
768
  });
720
- writeSite(ms, s, replacement);
769
+ writeSite(ms, s, s.name ? tagged(replacement, s.name) : replacement);
721
770
  }
722
771
  for (const decl of parsed.imp.decls) ms.remove(decl.start, decl.end);
723
772
  for (const dep of runnerDeps(env, id)) (depsOf.get(dep) ?? depsOf.set(dep, /* @__PURE__ */ new Set()).get(dep)).add(id);
@@ -762,10 +811,10 @@ function cssints({ inner = false, exclude, devtools = false, opencode = false }
762
811
  return out && /x$/.test(id) ? yield* inertJsx(out.code, id) : out?.code;
763
812
  }
764
813
  if (inner) return void 0;
765
- const parsed = yield* instrument(code, id);
814
+ const parsed = yield* instrument(code, id, true, !!devtools && !build);
766
815
  if (!parsed) return void 0;
767
816
  const env = server.environments.ssr;
768
- runner ??= createServerModuleRunner(env, {
817
+ if (!runner || runner.isClosed()) runner = createServerModuleRunner(env, {
769
818
  hmr: false,
770
819
  sourcemapInterceptor: "prepareStackTrace",
771
820
  evaluator: new DomEvaluator()
@@ -852,8 +901,12 @@ function cssints({ inner = false, exclude, devtools = false, opencode = false }
852
901
  const buildEnd = Effect.fn("cssints.buildEnd")(function* (warn) {
853
902
  yield* verifyChecks(() => true).pipe(Effect.catch((e) => locate(e, "", "")), Effect.ensuring(flushWarnings(warn)));
854
903
  });
855
- const hotUpdate = Effect.fn("cssints.hotUpdate")(function* (env, file, modules) {
904
+ const hotUpdate = Effect.fn("cssints.hotUpdate")(function* (env, file, modules, type) {
856
905
  if (env.name !== "client") return void 0;
906
+ if (type === "delete") {
907
+ yield* Effect.sync(() => forget(file));
908
+ yield* drop(file);
909
+ }
857
910
  yield* Effect.sync(() => forgetWarnings([file]));
858
911
  const graph = env.moduleGraph;
859
912
  const affected = [.../* @__PURE__ */ new Set([...depsOf.get(file) ?? [], ...inflight])].flatMap((id) => graph.getModuleById(id) ?? []);
@@ -941,8 +994,8 @@ function cssints({ inner = false, exclude, devtools = false, opencode = false }
941
994
  return run(hook("vite.transform", id, transform(this, code, id).pipe(Effect.catch((e) => locate(e, code, id))), this.environment.name));
942
995
  }
943
996
  },
944
- hotUpdate({ file, modules }) {
945
- return runSync(hook("vite.hotUpdate", file, hotUpdate(this.environment, file, modules)));
997
+ hotUpdate({ file, modules, type }) {
998
+ return runSync(hook("vite.hotUpdate", file, hotUpdate(this.environment, file, modules, type)));
946
999
  }
947
1000
  };
948
1001
  const version = {