@mirrowel/opencode-openshare 0.3.0-dev.1 → 0.3.0-dev.3

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/ci/openshare.js CHANGED
@@ -2482,6 +2482,32 @@ function createEngine(deps) {
2482
2482
  svelte: "svelte"
2483
2483
  };
2484
2484
  const FILE_TOOLS = new Set(["read", "write", "edit", "patch"]);
2485
+ const refineEmbeddedLanguage = (meta, text) => {
2486
+ if (meta.language !== "html")
2487
+ return false;
2488
+ const head = text.slice(0, 4000);
2489
+ if (/<[a-zA-Z][^>\n]*>/.test(head))
2490
+ return false;
2491
+ let refined;
2492
+ if (/^[ \t]*[.#][A-Za-z][\w-]*[^\n{]*\{/m.test(head) && !/\b(function|=>|return)\b/.test(head)) {
2493
+ refined = "css";
2494
+ } else if (/\b(function|const|let|var|return|if|for|while|=>|addEventListener|document\.|window\.)\b/.test(head) || /[;{}]\s*$/m.test(head)) {
2495
+ refined = "javascript";
2496
+ }
2497
+ if (!refined || meta.language === refined)
2498
+ return false;
2499
+ meta.language = refined;
2500
+ return true;
2501
+ };
2502
+ const refinePatchLanguage = (meta, patchText) => {
2503
+ const at = patchText.indexOf("@@");
2504
+ if (at < 0)
2505
+ return false;
2506
+ const body = patchText.slice(at).split(`
2507
+ `).map((l) => /^[ +\\]/.test(l) ? l.slice(1) : l.startsWith("-") ? l.slice(1) : "").join(`
2508
+ `);
2509
+ return refineEmbeddedLanguage(meta, body);
2510
+ };
2485
2511
  const stampFileLanguages = () => {
2486
2512
  for (const m of msgIndex.values()) {
2487
2513
  if (m.role !== "assistant")
@@ -2508,6 +2534,15 @@ function createEngine(deps) {
2508
2534
  mutated = true;
2509
2535
  }
2510
2536
  }
2537
+ if (part.name === "read" && typeof state.output === "string" && state.output.length > 0) {
2538
+ if (refineEmbeddedLanguage(meta, state.output))
2539
+ mutated = true;
2540
+ }
2541
+ if ((part.name === "edit" || part.name === "patch") && typeof meta.language === "string") {
2542
+ const pt = typeof meta.diff === "string" ? meta.diff : typeof meta.filediff?.patch === "string" ? meta.filediff.patch : undefined;
2543
+ if (pt && refinePatchLanguage(meta, pt))
2544
+ mutated = true;
2545
+ }
2511
2546
  if (typeof meta.lineStart !== "number" && part.name === "read") {
2512
2547
  const off = state.input?.offset;
2513
2548
  if (typeof off === "number" && off >= 0 && off > 0) {
package/dist/core.js CHANGED
@@ -2209,6 +2209,44 @@ export function createEngine(deps) {
2209
2209
  swift: "swift", kt: "kotlin", php: "php", lua: "lua", vue: "vue", svelte: "svelte",
2210
2210
  };
2211
2211
  const FILE_TOOLS = new Set(["read", "write", "edit", "patch"]);
2212
+ /** A read that returns lines from inside an html file's <script>/<style>
2213
+ * block gets tokenized as html by the viewer, and a snippet with no tag
2214
+ * context tokenizes as untyped soup (one default span per line). The
2215
+ * viewer only sees the snippet, so the stamp carries the language that is
2216
+ * true for the RETURNED RANGE: no tags plus code shape means the range sat
2217
+ * inside an embedded script or style block. */
2218
+ const refineEmbeddedLanguage = (meta, text) => {
2219
+ if (meta.language !== "html")
2220
+ return false;
2221
+ const head = text.slice(0, 4000);
2222
+ if (/<[a-zA-Z][^>\n]*>/.test(head))
2223
+ return false;
2224
+ let refined;
2225
+ if (/^[ \t]*[.#][A-Za-z][\w-]*[^\n{]*\{/m.test(head) && !/\b(function|=>|return)\b/.test(head)) {
2226
+ refined = "css";
2227
+ }
2228
+ else if (/\b(function|const|let|var|return|if|for|while|=>|addEventListener|document\.|window\.)\b/.test(head) || /[;{}]\s*$/m.test(head)) {
2229
+ refined = "javascript";
2230
+ }
2231
+ if (!refined || meta.language === refined)
2232
+ return false;
2233
+ meta.language = refined;
2234
+ return true;
2235
+ };
2236
+ /** Sniff the CODE CONTENT of a unified patch: drop everything before the
2237
+ * first hunk header and strip each line's diff marker, so the same
2238
+ * tag/shape checks as reads run over clean source lines. */
2239
+ const refinePatchLanguage = (meta, patchText) => {
2240
+ const at = patchText.indexOf("@@");
2241
+ if (at < 0)
2242
+ return false;
2243
+ const body = patchText
2244
+ .slice(at)
2245
+ .split("\n")
2246
+ .map((l) => (/^[ +\\]/.test(l) ? l.slice(1) : l.startsWith("-") ? l.slice(1) : ""))
2247
+ .join("\n");
2248
+ return refineEmbeddedLanguage(meta, body);
2249
+ };
2212
2250
  const stampFileLanguages = () => {
2213
2251
  for (const m of msgIndex.values()) {
2214
2252
  if (m.role !== "assistant")
@@ -2240,6 +2278,18 @@ export function createEngine(deps) {
2240
2278
  mutated = true;
2241
2279
  }
2242
2280
  }
2281
+ // range refinement: html-stamped reads inside script/style blocks
2282
+ if (part.name === "read" && typeof state.output === "string" && state.output.length > 0) {
2283
+ if (refineEmbeddedLanguage(meta, state.output))
2284
+ mutated = true;
2285
+ }
2286
+ // same refinement for edit hunks: a mid-script html diff tokenizes
2287
+ // untyped without the range language
2288
+ if ((part.name === "edit" || part.name === "patch") && typeof meta.language === "string") {
2289
+ const pt = typeof meta.diff === "string" ? meta.diff : typeof meta.filediff?.patch === "string" ? meta.filediff.patch : undefined;
2290
+ if (pt && refinePatchLanguage(meta, pt))
2291
+ mutated = true;
2292
+ }
2243
2293
  // lineStart stamp: reads sliced from an offset keep REAL file line
2244
2294
  // numbers in the viewer's unified file card (pierre numbers from 1;
2245
2295
  // the viewer shifts by this stamp, authoritatively)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mirrowel/opencode-openshare",
3
- "version": "0.3.0-dev.1",
3
+ "version": "0.3.0-dev.3",
4
4
  "type": "module",
5
5
  "description": "Open(code)Share — re:share: self-hosted session sharing for opencode. Server plugin (single file or package), optional TUI for interactive opt-in sharing.",
6
6
  "license": "MIT",
package/src/core.ts CHANGED
@@ -2263,6 +2263,41 @@ export function createEngine(deps: EngineDeps): Engine {
2263
2263
 
2264
2264
  const FILE_TOOLS = new Set(["read", "write", "edit", "patch"])
2265
2265
 
2266
+ /** A read that returns lines from inside an html file's <script>/<style>
2267
+ * block gets tokenized as html by the viewer, and a snippet with no tag
2268
+ * context tokenizes as untyped soup (one default span per line). The
2269
+ * viewer only sees the snippet, so the stamp carries the language that is
2270
+ * true for the RETURNED RANGE: no tags plus code shape means the range sat
2271
+ * inside an embedded script or style block. */
2272
+ const refineEmbeddedLanguage = (meta: { language?: unknown }, text: string): boolean => {
2273
+ if (meta.language !== "html") return false
2274
+ const head = text.slice(0, 4000)
2275
+ if (/<[a-zA-Z][^>\n]*>/.test(head)) return false
2276
+ let refined: string | undefined
2277
+ if (/^[ \t]*[.#][A-Za-z][\w-]*[^\n{]*\{/m.test(head) && !/\b(function|=>|return)\b/.test(head)) {
2278
+ refined = "css"
2279
+ } else if (/\b(function|const|let|var|return|if|for|while|=>|addEventListener|document\.|window\.)\b/.test(head) || /[;{}]\s*$/m.test(head)) {
2280
+ refined = "javascript"
2281
+ }
2282
+ if (!refined || meta.language === refined) return false
2283
+ meta.language = refined
2284
+ return true
2285
+ }
2286
+
2287
+ /** Sniff the CODE CONTENT of a unified patch: drop everything before the
2288
+ * first hunk header and strip each line's diff marker, so the same
2289
+ * tag/shape checks as reads run over clean source lines. */
2290
+ const refinePatchLanguage = (meta: { language?: unknown }, patchText: string): boolean => {
2291
+ const at = patchText.indexOf("@@")
2292
+ if (at < 0) return false
2293
+ const body = patchText
2294
+ .slice(at)
2295
+ .split("\n")
2296
+ .map((l) => (/^[ +\\]/.test(l) ? l.slice(1) : l.startsWith("-") ? l.slice(1) : ""))
2297
+ .join("\n")
2298
+ return refineEmbeddedLanguage(meta, body)
2299
+ }
2300
+
2266
2301
  const stampFileLanguages = () => {
2267
2302
  for (const m of msgIndex.values()) {
2268
2303
  if (m.role !== "assistant") continue
@@ -2289,6 +2324,16 @@ export function createEngine(deps: EngineDeps): Engine {
2289
2324
  mutated = true
2290
2325
  }
2291
2326
  }
2327
+ // range refinement: html-stamped reads inside script/style blocks
2328
+ if (part.name === "read" && typeof state.output === "string" && state.output.length > 0) {
2329
+ if (refineEmbeddedLanguage(meta, state.output)) mutated = true
2330
+ }
2331
+ // same refinement for edit hunks: a mid-script html diff tokenizes
2332
+ // untyped without the range language
2333
+ if ((part.name === "edit" || part.name === "patch") && typeof meta.language === "string") {
2334
+ const pt = typeof (meta as any).diff === "string" ? (meta as any).diff : typeof (meta as any).filediff?.patch === "string" ? (meta as any).filediff.patch : undefined
2335
+ if (pt && refinePatchLanguage(meta, pt)) mutated = true
2336
+ }
2292
2337
  // lineStart stamp: reads sliced from an offset keep REAL file line
2293
2338
  // numbers in the viewer's unified file card (pierre numbers from 1;
2294
2339
  // the viewer shifts by this stamp, authoritatively)