boxglow 0.6.4 → 0.6.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/bin/boxglow.js CHANGED
@@ -1135,7 +1135,11 @@ var parts = {
1135
1135
  "\u3002\u3046\u3061\u672A\u7740\u624B\u306E {n} \u7BB1\u306F\u6C7A\u307E\u308B\u307E\u3067\u5F85\u3061\u307E\u3059": "; {n} not-started boxes wait until it is decided",
1136
1136
  "\u672A\u6C7A\u5B9A": "Undecided",
1137
1137
  "\u6E08\u3093\u3060\u4F5C\u696D\u304C\u3053\u306E\u65B9\u91DD\u306B\u5408\u3063\u3066\u3044\u308B\u3053\u3068\u3092\u78BA\u304B\u3081\u305F (\u78BA\u304B\u3081\u76F4\u3057\u306E\u672D\u3092\u6D88\u3059)": "The finished work matches this policy (clears the check-again mark)",
1138
- "\u78BA\u304B\u3081\u305F": "Checked"
1138
+ "\u78BA\u304B\u3081\u305F": "Checked",
1139
+ "\u30A8\u30C7\u30A3\u30BF\u3067\u958B\u304F: {path}": "Open in the editor: {path}",
1140
+ "\u65B0\u3057\u3044\u30BF\u30D6\u3067\u958B\u304F: {path}": "Open in a new tab: {path}",
1141
+ "\u30D1\u30B9\u3092\u30B3\u30D4\u30FC: {path}": "Copy the path: {path}",
1142
+ "\u8A18\u9332\u3057\u305F\u3068\u304D\u306E\u7248\u3092\u30D6\u30E9\u30A6\u30B6\u3067\u898B\u308B": "See the recorded version in the browser"
1139
1143
  };
1140
1144
 
1141
1145
  // src/i18n/en/canvas.ts
@@ -1652,7 +1656,10 @@ var app = {
1652
1656
  "\u300C{name}\u300D\u3092\u524A\u9664\u3057\u307E\u3057\u305F (Undo \u3067\u623B\u305B\u307E\u3059)": 'Removed "{name}" (Undo brings it back)',
1653
1657
  "\u81EA\u52D5\u4FDD\u5B58: \u30AA\u30F3 (\u5909\u66F4\u306E\u305F\u3073\u306B\u66F8\u304D\u8FBC\u307F\u307E\u3059\u3002\u62BC\u3059\u3068\u30AA\u30D5)": "Auto save: on (every change is written; click to turn off)",
1654
1658
  "\u81EA\u52D5\u4FDD\u5B58: \u30AA\u30D5 (Save \u304B Ctrl+S \u3067\u66F8\u304D\u8FBC\u307F\u307E\u3059\u3002\u62BC\u3059\u3068\u30AA\u30F3)": "Auto save: off (Save or Ctrl+S writes; click to turn on)",
1655
- "{file} \u306B\u4FDD\u5B58\u3057\u307E\u3059 (\u81EA\u52D5\u4FDD\u5B58\u306F\u30AA\u30D5: Save \u304B Ctrl+S \u3067\u66F8\u304D\u307E\u3059)": "Saves to {file} (auto save is off: Save or Ctrl+S writes)"
1659
+ "{file} \u306B\u4FDD\u5B58\u3057\u307E\u3059 (\u81EA\u52D5\u4FDD\u5B58\u306F\u30AA\u30D5: Save \u304B Ctrl+S \u3067\u66F8\u304D\u307E\u3059)": "Saves to {file} (auto save is off: Save or Ctrl+S writes)",
1660
+ "\u30D1\u30B9\u3092\u30B3\u30D4\u30FC\u3057\u307E\u3057\u305F: {path} (\u30D6\u30E9\u30A6\u30B6\u304B\u3089\u306F\u624B\u5143\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u958B\u3051\u307E\u305B\u3093\u3002VS Code \u62E1\u5F35\u304B serve \u3067\u958B\u304F\u3068\u3001\u62BC\u3059\u3060\u3051\u3067\u958B\u3051\u307E\u3059)": "Copied the path: {path} (a browser cannot open files on this computer; in the VS Code extension or serve, clicking opens the file)",
1661
+ "\u3053\u306E\u30D5\u30A1\u30A4\u30EB\u306F\u30D6\u30E9\u30A6\u30B6\u304B\u3089\u306F\u958B\u3051\u307E\u305B\u3093: {path}": "This file cannot be opened from the browser: {path}",
1662
+ "\u30D5\u30A1\u30A4\u30EB\u3092\u958B\u3051\u307E\u305B\u3093\u3067\u3057\u305F: {path}": "Could not open the file: {path}"
1656
1663
  };
1657
1664
 
1658
1665
  // src/i18n/en/cli.ts
@@ -2014,7 +2021,10 @@ var cli = {
2014
2021
  "\u65B9\u91DD\u306E\u7BC4\u56F2: all = \u8A08\u753B\u5168\u4F53\u3001<block> = \u305D\u306E\u7BB1\u306E\u4E2D\u3001\u7701\u7565 = \u540C\u3058\u89AA\u306E\u4E2D": "Policy scope: all = the whole plan, <block> = inside that box, omitted = within the same parent",
2015
2022
  "\u65B9\u91DD\u3092\u53C2\u8003\u306B\u3059\u308B (\u6C7A\u307E\u3063\u3066\u3044\u306A\u304F\u3066\u3082\u7740\u624B\u3092\u5F85\u305F\u305B\u306A\u3044)": "Make the policy advisory (boxes can start before it is decided)",
2016
2023
  "\u65B9\u91DD\u3092\u3084\u3081\u308B\u51FA\u529B\u306E\u540D\u524D": "Outputs that are no longer policies",
2017
- "\u3053\u306E\u7BB1\u3067\u306F\u53D7\u3051\u53D6\u3089\u306A\u3044\u65B9\u91DD (<\u7BB1>.<\u51FA\u529B\u540D>)": "Policies this box does not take (<box>.<output>)"
2024
+ "\u3053\u306E\u7BB1\u3067\u306F\u53D7\u3051\u53D6\u3089\u306A\u3044\u65B9\u91DD (<\u7BB1>.<\u51FA\u529B\u540D>)": "Policies this box does not take (<box>.<output>)",
2025
+ "\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {path}": "File not found: {path}",
2026
+ "\u8A08\u753B\u306E\u30D5\u30A9\u30EB\u30C0\u306E\u5916\u306E\u30D5\u30A1\u30A4\u30EB\u306F\u8868\u793A\u3067\u304D\u307E\u305B\u3093: {path}": "Files outside the plan's folder cannot be shown: {path}",
2027
+ "\u30D5\u30A1\u30A4\u30EB\u304C\u5927\u304D\u3059\u304E\u3066\u8868\u793A\u3067\u304D\u307E\u305B\u3093: {path}": "The file is too large to show: {path}"
2018
2028
  };
2019
2029
 
2020
2030
  // src/i18n/en/model.ts
@@ -4209,7 +4219,7 @@ function splitBlock(p, parentId, spec, actor, makers) {
4209
4219
  if (Object.keys(scope2).length) q.blocks[r.blockId].scope = scope2;
4210
4220
  for (const name of b.inputs ?? []) q = addPort(q, { blockId: r.blockId, direction: "in", name }).project;
4211
4221
  }
4212
- const resolve7 = (ref, dir2) => {
4222
+ const resolve8 = (ref, dir2) => {
4213
4223
  let why = t("\u30DC\u30C3\u30AF\u30B9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093");
4214
4224
  for (const { title, portName } of refSplits(ref)) {
4215
4225
  const isParent = title === "parent" || title === parent.title || title === parentId;
@@ -4226,8 +4236,8 @@ function splitBlock(p, parentId, spec, actor, makers) {
4226
4236
  return { ep: null, why };
4227
4237
  };
4228
4238
  for (const c of spec.connections ?? []) {
4229
- const from = resolve7(c.from, "out");
4230
- let to = resolve7(c.to, "in");
4239
+ const from = resolve8(c.from, "out");
4240
+ let to = resolve8(c.to, "in");
4231
4241
  if (!to.ep && from.ep && !c.to.includes(".")) {
4232
4242
  const tid = c.to === "parent" || c.to === parent.title || c.to === parentId ? null : made[c.to] ?? findBlock(q, c.to).block?.id;
4233
4243
  if (tid) {
@@ -4334,7 +4344,7 @@ function instantiateNode(p, parentId, node, origin, position) {
4334
4344
  made[c.title] = rc.blockId;
4335
4345
  y += 120;
4336
4346
  }
4337
- const resolve7 = (ref, dir2) => {
4347
+ const resolve8 = (ref, dir2) => {
4338
4348
  for (const { title, portName } of refSplits(ref)) {
4339
4349
  const isParent = title === "parent";
4340
4350
  const blockId = isParent ? id : made[title];
@@ -4346,8 +4356,8 @@ function instantiateNode(p, parentId, node, origin, position) {
4346
4356
  return null;
4347
4357
  };
4348
4358
  for (const c of node.connections) {
4349
- const from = resolve7(c.from, "out");
4350
- const to = resolve7(c.to, "in");
4359
+ const from = resolve8(c.from, "out");
4360
+ const to = resolve8(c.to, "in");
4351
4361
  if (from && to) q = connect(q, from, to).project;
4352
4362
  }
4353
4363
  }
@@ -6019,7 +6029,7 @@ function resolveToken(server, allowEnvironmentToken = true) {
6019
6029
  import { hostname as hostname2 } from "node:os";
6020
6030
 
6021
6031
  // package.json
6022
- var version = "0.6.4";
6032
+ var version = "0.6.5";
6023
6033
 
6024
6034
  // src/model/version.ts
6025
6035
  var APP_VERSION = version;
@@ -6994,7 +7004,7 @@ function groupConflicts(base, local, remote, conflicts2) {
6994
7004
  parents.set(key, root);
6995
7005
  return root;
6996
7006
  };
6997
- const join13 = (keys) => {
7007
+ const join14 = (keys) => {
6998
7008
  const sorted = [...new Set(keys.length ? keys : [SETTINGS])].sort();
6999
7009
  const first = find(sorted[0]);
7000
7010
  for (const key of sorted.slice(1)) parents.set(find(key), first);
@@ -7032,9 +7042,9 @@ function groupConflicts(base, local, remote, conflicts2) {
7032
7042
  return [SETTINGS];
7033
7043
  };
7034
7044
  const items = conflicts2.filter((c) => !c.automatic);
7035
- for (const c of items) join13(owners(c));
7045
+ for (const c of items) join14(owners(c));
7036
7046
  for (const p of projects) for (const port2 of Object.values(p.ports)) {
7037
- if (port2.promotedFrom) join13(portOwners(port2.id));
7047
+ if (port2.promotedFrom) join14(portOwners(port2.id));
7038
7048
  }
7039
7049
  const ids = new Set(projects.flatMap((p) => Object.keys(p.blocks)));
7040
7050
  for (const id of ids) {
@@ -7066,7 +7076,7 @@ function groupConflicts(base, local, remote, conflicts2) {
7066
7076
  ))
7067
7077
  keys.push(...edgeOwners(e.id));
7068
7078
  }
7069
- join13(keys);
7079
+ join14(keys);
7070
7080
  keys.forEach((key) => structural.add(key));
7071
7081
  }
7072
7082
  const grouped = /* @__PURE__ */ new Map();
@@ -8577,13 +8587,46 @@ async function startMcp(run2) {
8577
8587
 
8578
8588
  // cli/serve.ts
8579
8589
  import { createServer } from "node:http";
8580
- import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync10, realpathSync as realpathSync3, statSync as statSync5, watch, writeFileSync as writeFileSync5 } from "node:fs";
8581
- import { basename as basename3, dirname as dirname6, extname, join as join8, relative, resolve as resolve3 } from "node:path";
8590
+ import { existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync10, realpathSync as realpathSync3, statSync as statSync6, watch, writeFileSync as writeFileSync5 } from "node:fs";
8591
+ import { basename as basename3, dirname as dirname7, extname, isAbsolute as isAbsolute2, join as join9, relative, resolve as resolve4 } from "node:path";
8582
8592
  import { spawn } from "node:child_process";
8583
8593
 
8594
+ // cli/attached-file.ts
8595
+ import { existsSync as existsSync5, statSync as statSync3 } from "node:fs";
8596
+ import { dirname as dirname4, isAbsolute, join as join6, resolve as resolve3 } from "node:path";
8597
+ function gitRootOf(dir2) {
8598
+ let cur = resolve3(dir2);
8599
+ for (let i = 0; i < 64; i++) {
8600
+ if (existsSync5(join6(cur, ".git"))) return cur;
8601
+ const up = dirname4(cur);
8602
+ if (up === cur) return null;
8603
+ cur = up;
8604
+ }
8605
+ return null;
8606
+ }
8607
+ function attachedFileBases(planFile) {
8608
+ const planDir = dirname4(resolve3(planFile));
8609
+ const root = gitRootOf(planDir);
8610
+ return [.../* @__PURE__ */ new Set([planDir, ...root ? [root] : []])];
8611
+ }
8612
+ function resolveAttachedFile(planFile, path) {
8613
+ let p = path.trim();
8614
+ if (p.startsWith("file://")) p = decodeURIComponent(p.slice("file://".length));
8615
+ p = p.replace(/[?#].*$/, "");
8616
+ if (!p) return null;
8617
+ const candidates = isAbsolute(p) ? [p] : attachedFileBases(planFile).map((base) => resolve3(base, p));
8618
+ for (const c of candidates) {
8619
+ try {
8620
+ if (existsSync5(c) && statSync3(c).isFile()) return c;
8621
+ } catch {
8622
+ }
8623
+ }
8624
+ return null;
8625
+ }
8626
+
8584
8627
  // cli/sync/host.ts
8585
8628
  import { randomUUID as randomUUID7 } from "node:crypto";
8586
- import { existsSync as existsSync7, readFileSync as readFileSync9, statSync as statSync4 } from "node:fs";
8629
+ import { existsSync as existsSync8, readFileSync as readFileSync9, statSync as statSync5 } from "node:fs";
8587
8630
 
8588
8631
  // src/sync/billing.ts
8589
8632
  function parseBilling2(value) {
@@ -8670,9 +8713,9 @@ function parseSummary(v) {
8670
8713
  }
8671
8714
 
8672
8715
  // cli/sync/agent-config.ts
8673
- import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "node:fs";
8716
+ import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "node:fs";
8674
8717
  import { homedir as homedir2 } from "node:os";
8675
- import { dirname as dirname4, join as join6 } from "node:path";
8718
+ import { dirname as dirname5, join as join7 } from "node:path";
8676
8719
 
8677
8720
  // node_modules/smol-toml/dist/error.js
8678
8721
  function getLineColFromPtr(string, ptr) {
@@ -9602,29 +9645,29 @@ function mergeCodexConfig(existing, server, token) {
9602
9645
  // cli/sync/agent-config.ts
9603
9646
  function writeAgentConfig(target, server, token, dir2) {
9604
9647
  if (target === "codex") {
9605
- const path2 = join6(homedir2(), ".codex", "config.toml");
9606
- mkdirSync5(dirname4(path2), { recursive: true });
9607
- writeFileSync4(path2, mergeCodexConfig(existsSync5(path2) ? readFileSync6(path2, "utf8") : null, server, token), { mode: 384 });
9648
+ const path2 = join7(homedir2(), ".codex", "config.toml");
9649
+ mkdirSync5(dirname5(path2), { recursive: true });
9650
+ writeFileSync4(path2, mergeCodexConfig(existsSync6(path2) ? readFileSync6(path2, "utf8") : null, server, token), { mode: 384 });
9608
9651
  return { path: path2, gitignored: true };
9609
9652
  }
9610
- const path = join6(dir2, ".mcp.json");
9611
- writeFileSync4(path, mergeMcpJson(existsSync5(path) ? readFileSync6(path, "utf8") : null, server, token));
9612
- const gi = join6(dir2, ".gitignore");
9613
- if (!existsSync5(gi)) return { path, gitignored: false };
9653
+ const path = join7(dir2, ".mcp.json");
9654
+ writeFileSync4(path, mergeMcpJson(existsSync6(path) ? readFileSync6(path, "utf8") : null, server, token));
9655
+ const gi = join7(dir2, ".gitignore");
9656
+ if (!existsSync6(gi)) return { path, gitignored: false };
9614
9657
  const next = gitignoreWithMcpJson(readFileSync6(gi, "utf8"));
9615
9658
  if (next !== null) writeFileSync4(gi, next);
9616
9659
  return { path, gitignored: true };
9617
9660
  }
9618
9661
 
9619
9662
  // cli/sync/host.ts
9620
- import { dirname as dirname5 } from "node:path";
9663
+ import { dirname as dirname6 } from "node:path";
9621
9664
 
9622
9665
  // cli/sync/command.ts
9623
9666
  import { readFileSync as readFileSync8 } from "node:fs";
9624
9667
 
9625
9668
  // cli/sync/watch.ts
9626
- import { existsSync as existsSync6, mkdirSync as mkdirSync6, readdirSync as readdirSync3, readFileSync as readFileSync7, statSync as statSync3 } from "node:fs";
9627
- import { join as join7 } from "node:path";
9669
+ import { existsSync as existsSync7, mkdirSync as mkdirSync6, readdirSync as readdirSync3, readFileSync as readFileSync7, statSync as statSync4 } from "node:fs";
9670
+ import { join as join8 } from "node:path";
9628
9671
  var DEBOUNCE_MS = 2e3;
9629
9672
  var MAX_WAIT_MS = 1e4;
9630
9673
  var POLL_MS = 3e4;
@@ -9634,7 +9677,7 @@ var RETRY_MS = 5e3;
9634
9677
  var RETRY_MAX_MS = 6e4;
9635
9678
  function signature(file) {
9636
9679
  try {
9637
- const st = statSync3(file);
9680
+ const st = statSync4(file);
9638
9681
  return `${st.mtimeMs}:${st.size}`;
9639
9682
  } catch {
9640
9683
  return "none";
@@ -9648,7 +9691,7 @@ function contentHash(file) {
9648
9691
  }
9649
9692
  }
9650
9693
  function bindingsFor(server) {
9651
- const root = join7(configDir(), "sync");
9694
+ const root = join8(configDir(), "sync");
9652
9695
  let names = [];
9653
9696
  try {
9654
9697
  names = readdirSync3(root);
@@ -9657,8 +9700,8 @@ function bindingsFor(server) {
9657
9700
  }
9658
9701
  const states = [], unreadable = [];
9659
9702
  for (const name of names) {
9660
- const dir2 = join7(root, name);
9661
- if (!existsSync6(join7(dir2, "state.json"))) continue;
9703
+ const dir2 = join8(root, name);
9704
+ if (!existsSync7(join8(dir2, "state.json"))) continue;
9662
9705
  try {
9663
9706
  const state = new StateStore(dir2).read();
9664
9707
  if (state && state.binding.server === normalizeServer(server)) states.push({ dir: dir2, state });
@@ -9669,9 +9712,9 @@ function bindingsFor(server) {
9669
9712
  return { states, unreadable };
9670
9713
  }
9671
9714
  function lockWatch(server) {
9672
- const root = join7(configDir(), "sync");
9715
+ const root = join8(configDir(), "sync");
9673
9716
  mkdirSync6(root, { recursive: true, mode: 448 });
9674
- const path = join7(root, `watch-${hashOf(normalizeServer(server)).slice(0, 16)}`);
9717
+ const path = join8(root, `watch-${hashOf(normalizeServer(server)).slice(0, 16)}`);
9675
9718
  try {
9676
9719
  return { unlock: lockFile(path, { waitMs: 0 }), path };
9677
9720
  } catch (e) {
@@ -10511,7 +10554,7 @@ var SyncHost = class {
10511
10554
  if (resolved?.source === "env") return "env:" + hashOf(resolved.token).slice(0, 16);
10512
10555
  const path = credentialsPath(this.server);
10513
10556
  try {
10514
- const st = statSync4(path);
10557
+ const st = statSync5(path);
10515
10558
  return `stored:${st.mtimeMs}:${st.size}:${hashOf(readFileSync9(path, "utf8")).slice(0, 16)}`;
10516
10559
  } catch {
10517
10560
  return "none";
@@ -10989,7 +11032,7 @@ var SyncHost = class {
10989
11032
  state.connected = void 0;
10990
11033
  if (action.kind === "connectAgent") {
10991
11034
  try {
10992
- const written2 = writeAgentConfig(action.target, this.server, created.token, file ? dirname5(file) : process.cwd());
11035
+ const written2 = writeAgentConfig(action.target, this.server, created.token, file ? dirname6(file) : process.cwd());
10993
11036
  state.newToken = void 0;
10994
11037
  state.connected = { target: action.target, wrote: true, path: written2.path, gitignored: written2.gitignored };
10995
11038
  } catch (e) {
@@ -11271,7 +11314,7 @@ var SyncHost = class {
11271
11314
  return;
11272
11315
  }
11273
11316
  const target = realFile(destination);
11274
- if (action.destination === "new" && (existsSync7(target) || bindingsOf(target).bindings.length))
11317
+ if (action.destination === "new" && (existsSync8(target) || bindingsOf(target).bindings.length))
11275
11318
  throw new SyncDestinationError(t("\u4FDD\u5B58\u5148\u306B\u306F\u65E2\u306B\u30D5\u30A1\u30A4\u30EB\u304C\u3042\u308A\u307E\u3059\u3002\u5225\u306E\u540D\u524D\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\u3002"));
11276
11319
  if (this.startups.get(file) !== op || this.stopping || this.stopped) return;
11277
11320
  if (op.credentials !== this.credentialsGeneration()) throw new Error("Credentials changed");
@@ -11809,6 +11852,8 @@ var HttpError = class extends Error {
11809
11852
  status;
11810
11853
  };
11811
11854
  var ASSETS_DIR = "boxglow.assets";
11855
+ var ATTACHED_MIME = { ".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".gif": "image/gif", ".webp": "image/webp", ".pdf": "application/pdf", ".mp4": "video/mp4", ".webm": "video/webm", ".mp3": "audio/mpeg", ".wav": "audio/wav" };
11856
+ var MAX_ATTACHED = 50 * 1024 * 1024;
11812
11857
  var ASSET_MIME = { ".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".gif": "image/gif", ".webp": "image/webp", ".svg": "image/svg+xml" };
11813
11858
  var MAX_ASSET = 10 * 1024 * 1024;
11814
11859
  function readRawBody(req, limit) {
@@ -11845,9 +11890,9 @@ function readBody(req, limit = MAX_BODY) {
11845
11890
  }
11846
11891
  function startServe(opts) {
11847
11892
  const { file, dist, log } = opts;
11848
- if (!existsSync8(join8(dist, "index.html"))) throw new Error(t("Web \u30A2\u30D7\u30EA\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {dist} (npm run build \u3067 dist/ \u3092\u4F5C\u3063\u3066\u304F\u3060\u3055\u3044)", { dist }));
11849
- if (!existsSync8(file)) {
11850
- if (!existsSync8(dirname6(file))) throw new Error(t("\u30D5\u30A9\u30EB\u30C0\u304C\u3042\u308A\u307E\u305B\u3093: {dir}", { dir: dirname6(file) }));
11893
+ if (!existsSync9(join9(dist, "index.html"))) throw new Error(t("Web \u30A2\u30D7\u30EA\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {dist} (npm run build \u3067 dist/ \u3092\u4F5C\u3063\u3066\u304F\u3060\u3055\u3044)", { dist }));
11894
+ if (!existsSync9(file)) {
11895
+ if (!existsSync9(dirname7(file))) throw new Error(t("\u30D5\u30A9\u30EB\u30C0\u304C\u3042\u308A\u307E\u305B\u3093: {dir}", { dir: dirname7(file) }));
11851
11896
  log(t("\u30D5\u30A1\u30A4\u30EB\u306F\u307E\u3060\u3042\u308A\u307E\u305B\u3093: {file} (\u753B\u9762\u304B\u3089\u8A08\u753B\u3092\u4F5C\u308B\u304B\u3001\u30B5\u30FC\u30D0\u30FC\u306E\u8A08\u753B\u3092\u53D7\u3051\u53D6\u308B\u3068\u3001\u3053\u3053\u306B\u4FDD\u5B58\u3057\u307E\u3059)", { file }));
11852
11897
  }
11853
11898
  const children = [];
@@ -11873,7 +11918,7 @@ data: ${data}
11873
11918
  destinationPicker: "sibling",
11874
11919
  chooseDestination: async (source, name) => {
11875
11920
  if (!name || !/^[^./\\][^/\\:<>"|?*]*\.json$/.test(name) || /[\x00-\x1f]/.test(name) || /^(con|prn|aux|nul|com[1-9]|lpt[1-9])\./i.test(name)) throw new SyncDestinationError(t("\u4FDD\u5B58\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30D5\u30A9\u30EB\u30C0\u3092\u542B\u3081\u305A\u3001.json\u3067\u7D42\u308F\u308B\u540D\u524D\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002"));
11876
- return join8(dirname6(source), name);
11921
+ return join9(dirname7(source), name);
11877
11922
  },
11878
11923
  onOpened: async (target) => {
11879
11924
  const child = startServe({ file: target, port: 0, dist, open: false, log, sync: { server: opts.sync.server, allowEnvironmentToken: opts.sync.allowEnvironmentToken, autoEnable: false } });
@@ -11893,7 +11938,7 @@ data: ${data}
11893
11938
  let timer;
11894
11939
  let watcher;
11895
11940
  try {
11896
- watcher = watch(dirname6(file), (_ev, name) => {
11941
+ watcher = watch(dirname7(file), (_ev, name) => {
11897
11942
  if (name && String(name) !== basename3(file)) return;
11898
11943
  clearTimeout(timer);
11899
11944
  timer = setTimeout(broadcast, 80);
@@ -11916,7 +11961,7 @@ data: ${data}
11916
11961
  const url = new URL(req.url ?? "/", `http://${req.headers.host}`);
11917
11962
  if (url.pathname === "/api/project") {
11918
11963
  if (req.method === "GET") {
11919
- if (!existsSync8(file)) {
11964
+ if (!existsSync9(file)) {
11920
11965
  send(404, JSON.stringify({ code: "no-file", file: basename3(file) }), "application/json; charset=utf-8", { "x-boxglow-file": encodeURIComponent(basename3(file)), "x-boxglow-version": APP_VERSION, "x-boxglow-protocol": String(SAVE_PROTOCOL) });
11921
11966
  return;
11922
11967
  }
@@ -11978,20 +12023,36 @@ data: ${JSON.stringify(lastSync ?? syncHost.status(file))}
11978
12023
  });
11979
12024
  return;
11980
12025
  }
12026
+ if (url.pathname === "/api/file") {
12027
+ if (req.method !== "GET" && req.method !== "HEAD") throw new HttpError(405, t("\u3053\u306E\u30E1\u30BD\u30C3\u30C9\u306F\u4F7F\u3048\u307E\u305B\u3093"));
12028
+ const asked = url.searchParams.get("path") ?? "";
12029
+ const found = resolveAttachedFile(file, asked);
12030
+ if (!found) throw new HttpError(404, t("\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {path}", { path: asked }));
12031
+ const real = realpathSync3(found);
12032
+ const inside2 = attachedFileBases(file).some((base2) => {
12033
+ const rel = relative(realpathSync3(base2), real);
12034
+ return rel !== "" && !rel.startsWith("..") && !isAbsolute2(rel);
12035
+ });
12036
+ if (!inside2) throw new HttpError(403, t("\u8A08\u753B\u306E\u30D5\u30A9\u30EB\u30C0\u306E\u5916\u306E\u30D5\u30A1\u30A4\u30EB\u306F\u8868\u793A\u3067\u304D\u307E\u305B\u3093: {path}", { path: asked }));
12037
+ if (statSync6(real).size > MAX_ATTACHED) throw new HttpError(413, t("\u30D5\u30A1\u30A4\u30EB\u304C\u5927\u304D\u3059\u304E\u3066\u8868\u793A\u3067\u304D\u307E\u305B\u3093: {path}", { path: asked }));
12038
+ const type = ATTACHED_MIME[extname(real).toLowerCase()] ?? "text/plain; charset=utf-8";
12039
+ send(200, req.method === "HEAD" ? "" : readFileSync10(real), type, type === "application/pdf" ? {} : { "content-security-policy": "sandbox; default-src 'none'; img-src 'self'; media-src 'self'; style-src 'unsafe-inline'" });
12040
+ return;
12041
+ }
11981
12042
  if (url.pathname.startsWith("/api/assets/")) {
11982
- const assetsDir = join8(dirname6(file), ASSETS_DIR);
12043
+ const assetsDir = join9(dirname7(file), ASSETS_DIR);
11983
12044
  const name = decodeURIComponent(url.pathname.slice("/api/assets/".length)).replace(/^boxglow\.assets\//, "");
11984
12045
  if (!/^[^/\\]+$/.test(name) || name.startsWith(".") || !ASSET_MIME[extname(name).toLowerCase()]) throw new HttpError(400, t("\u3053\u306E\u540D\u524D\u306E\u753B\u50CF\u306F\u6271\u3048\u307E\u305B\u3093: {name}", { name }));
11985
- const target2 = join8(assetsDir, name);
12046
+ const target2 = join9(assetsDir, name);
11986
12047
  if (req.method === "GET" || req.method === "HEAD") {
11987
- if (!existsSync8(target2) || !statSync5(target2).isFile()) throw new HttpError(404, t("\u753B\u50CF\u304C\u3042\u308A\u307E\u305B\u3093: {name}", { name }));
12048
+ if (!existsSync9(target2) || !statSync6(target2).isFile()) throw new HttpError(404, t("\u753B\u50CF\u304C\u3042\u308A\u307E\u305B\u3093: {name}", { name }));
11988
12049
  send(200, req.method === "HEAD" ? "" : readFileSync10(target2), ASSET_MIME[extname(name).toLowerCase()], { "cache-control": "no-cache" });
11989
12050
  return;
11990
12051
  }
11991
12052
  if (req.method === "PUT") {
11992
12053
  const bytes = await readRawBody(req, MAX_ASSET);
11993
12054
  mkdirSync7(assetsDir, { recursive: true });
11994
- if (existsSync8(target2)) throw new HttpError(409, t("\u540C\u3058\u540D\u524D\u306E\u753B\u50CF\u304C\u3042\u308A\u307E\u3059: {name}", { name }));
12055
+ if (existsSync9(target2)) throw new HttpError(409, t("\u540C\u3058\u540D\u524D\u306E\u753B\u50CF\u304C\u3042\u308A\u307E\u3059: {name}", { name }));
11995
12056
  writeFileSync5(target2, bytes);
11996
12057
  send(200, JSON.stringify({ ok: true, path: `${ASSETS_DIR}/${name}` }));
11997
12058
  return;
@@ -12000,13 +12061,13 @@ data: ${JSON.stringify(lastSync ?? syncHost.status(file))}
12000
12061
  }
12001
12062
  if (req.method !== "GET" && req.method !== "HEAD") throw new HttpError(405, t("\u3053\u306E\u30E1\u30BD\u30C3\u30C9\u306F\u4F7F\u3048\u307E\u305B\u3093"));
12002
12063
  const base = realpathSync3(dist);
12003
- const target = resolve3(base, "." + decodeURIComponent(url.pathname));
12064
+ const target = resolve4(base, "." + decodeURIComponent(url.pathname));
12004
12065
  const inside = (path2) => {
12005
12066
  const rel = relative(base, path2);
12006
12067
  return rel !== ".." && !rel.startsWith("../") && !rel.startsWith("..\\");
12007
12068
  };
12008
12069
  if (!inside(target)) throw new HttpError(403, t("\u3053\u306E\u30D1\u30B9\u306F\u914D\u4FE1\u3067\u304D\u307E\u305B\u3093"));
12009
- const path = existsSync8(target) && statSync5(target).isFile() ? realpathSync3(target) : join8(base, "index.html");
12070
+ const path = existsSync9(target) && statSync6(target).isFile() ? realpathSync3(target) : join9(base, "index.html");
12010
12071
  if (!inside(path)) throw new HttpError(403, t("\u3053\u306E\u30D1\u30B9\u306F\u914D\u4FE1\u3067\u304D\u307E\u305B\u3093"));
12011
12072
  send(200, req.method === "HEAD" ? "" : readFileSync10(path), MIME[extname(path)] ?? "application/octet-stream");
12012
12073
  } catch (e) {
@@ -12042,24 +12103,24 @@ data: ${JSON.stringify(lastSync ?? syncHost.status(file))}
12042
12103
  }
12043
12104
 
12044
12105
  // cli/plan-io.ts
12045
- import { existsSync as existsSync9, readFileSync as readFileSync11 } from "node:fs";
12046
- import { dirname as dirname7, join as join9, resolve as resolve4 } from "node:path";
12106
+ import { existsSync as existsSync10, readFileSync as readFileSync11 } from "node:fs";
12107
+ import { dirname as dirname8, join as join10, resolve as resolve5 } from "node:path";
12047
12108
  var filePlanIO = {
12048
12109
  locate(opt2, forInit) {
12049
- if (opt2) return resolve4(opt2);
12050
- if (process.env.BOXGLOW_FILE) return resolve4(process.env.BOXGLOW_FILE);
12110
+ if (opt2) return resolve5(opt2);
12111
+ if (process.env.BOXGLOW_FILE) return resolve5(process.env.BOXGLOW_FILE);
12051
12112
  let dir2 = process.cwd();
12052
12113
  for (let i = 0; i < 12; i++) {
12053
- const candidate = join9(dir2, "boxglow.json");
12054
- if (existsSync9(candidate)) return candidate;
12055
- const parent = dirname7(dir2);
12114
+ const candidate = join10(dir2, "boxglow.json");
12115
+ if (existsSync10(candidate)) return candidate;
12116
+ const parent = dirname8(dir2);
12056
12117
  if (parent === dir2) break;
12057
12118
  dir2 = parent;
12058
12119
  }
12059
- if (forInit) return join9(process.cwd(), "boxglow.json");
12120
+ if (forInit) return join10(process.cwd(), "boxglow.json");
12060
12121
  throw new Error(t("boxglow.json \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (--file \u3067\u6307\u5B9A\u3059\u308B\u304B\u3001`boxglow init` \u3067\u4F5C\u3063\u3066\u304F\u3060\u3055\u3044)"));
12061
12122
  },
12062
- exists: (path) => existsSync9(path),
12123
+ exists: (path) => existsSync10(path),
12063
12124
  read: (path) => readFileSync11(path, "utf8"),
12064
12125
  commit: (path, text2, expected, opts) => commitFile(path, text2, expected, opts)
12065
12126
  };
@@ -12311,12 +12372,12 @@ function isCurrentToken(p, token) {
12311
12372
  }
12312
12373
 
12313
12374
  // cli/setup-agent.ts
12314
- import { existsSync as existsSync10, mkdirSync as mkdirSync8, readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "node:fs";
12315
- import { dirname as dirname8, join as join10 } from "node:path";
12375
+ import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "node:fs";
12376
+ import { dirname as dirname9, join as join11 } from "node:path";
12316
12377
  var BEGIN = "<!-- boxglow:begin -->";
12317
12378
  var END = "<!-- boxglow:end -->";
12318
12379
  function readObject(path) {
12319
- if (!existsSync10(path)) return {};
12380
+ if (!existsSync11(path)) return {};
12320
12381
  const value = JSON.parse(readFileSync12(path, "utf8"));
12321
12382
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(t("\u8A2D\u5B9A\u306E\u5F62\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093: {where}", { where: path }));
12322
12383
  return value;
@@ -12399,8 +12460,8 @@ ${body}
12399
12460
  ${identity}
12400
12461
  ${END}
12401
12462
  `;
12402
- const path = join10(root, name);
12403
- const cur = existsSync10(path) ? readFileSync12(path, "utf8") : "";
12463
+ const path = join11(root, name);
12464
+ const cur = existsSync11(path) ? readFileSync12(path, "utf8") : "";
12404
12465
  const begin = cur.indexOf(BEGIN);
12405
12466
  const end = cur.indexOf(END);
12406
12467
  if (begin < 0 !== end < 0 || begin >= 0 && end < begin) throw new Error(t("Boxglow \u306E\u5370 (boxglow:begin / boxglow:end) \u304C\u6B63\u3057\u304F\u5BFE\u306B\u306A\u3063\u3066\u3044\u307E\u305B\u3093: {path}", { path }));
@@ -12420,8 +12481,8 @@ dependencies:
12420
12481
  value: boxglow
12421
12482
  transport: stdio
12422
12483
  `);
12423
- const tomlPath = join10(root, ".codex/config.toml");
12424
- const toml = existsSync10(tomlPath) ? readFileSync12(tomlPath, "utf8") : "";
12484
+ const tomlPath = join11(root, ".codex/config.toml");
12485
+ const toml = existsSync11(tomlPath) ? readFileSync12(tomlPath, "utf8") : "";
12425
12486
  let parsed;
12426
12487
  try {
12427
12488
  parsed = parse(toml);
@@ -12443,7 +12504,7 @@ default_tools_approval_mode = "auto"
12443
12504
  }
12444
12505
  files.set(".codex/config.toml", candidate);
12445
12506
  }
12446
- const hooksFile = readObject(join10(root, ".codex/hooks.json"));
12507
+ const hooksFile = readObject(join11(root, ".codex/hooks.json"));
12447
12508
  const hooks = object(hooksFile.hooks, "hooks");
12448
12509
  if (mergeHooks(hooks, "codex")) {
12449
12510
  hooksFile.hooks = hooks;
@@ -12459,7 +12520,7 @@ ${r.body.replace(/"""/g, '\\"\\"\\"')}
12459
12520
  }
12460
12521
  if (claude) {
12461
12522
  files.set(".claude/skills/boxglow/SKILL.md", skill);
12462
- const settings = readObject(join10(root, ".claude/settings.json"));
12523
+ const settings = readObject(join11(root, ".claude/settings.json"));
12463
12524
  const hooks = object(settings.hooks, "hooks");
12464
12525
  let changed2 = mergeHooks(hooks, "claude-code");
12465
12526
  if (changed2) settings.hooks = hooks;
@@ -12488,7 +12549,7 @@ tools: Bash, Read
12488
12549
 
12489
12550
  ${r.body}
12490
12551
  `);
12491
- const mcp = readObject(join10(root, ".mcp.json"));
12552
+ const mcp = readObject(join11(root, ".mcp.json"));
12492
12553
  const servers = object(mcp.mcpServers, "mcpServers");
12493
12554
  if (!servers.boxglow) {
12494
12555
  servers.boxglow = { command: "npx", args: ["-y", "boxglow", "mcp", "--actor", "claude-code"] };
@@ -12498,9 +12559,9 @@ ${r.body}
12498
12559
  }
12499
12560
  const changed = [];
12500
12561
  for (const [name, text2] of files) {
12501
- const path = join10(root, name);
12502
- if (existsSync10(path) && readFileSync12(path, "utf8") === text2) continue;
12503
- mkdirSync8(dirname8(path), { recursive: true });
12562
+ const path = join11(root, name);
12563
+ if (existsSync11(path) && readFileSync12(path, "utf8") === text2) continue;
12564
+ mkdirSync8(dirname9(path), { recursive: true });
12504
12565
  writeFileSync6(path, text2, "utf8");
12505
12566
  changed.push(name);
12506
12567
  }
@@ -12511,8 +12572,8 @@ function checkAgentSetup(root, agent) {
12511
12572
  const claude = agent !== "codex";
12512
12573
  const lines = [];
12513
12574
  const has = (rel, test) => {
12514
- const p = join10(root, rel);
12515
- if (!existsSync10(p)) return false;
12575
+ const p = join11(root, rel);
12576
+ if (!existsSync11(p)) return false;
12516
12577
  return test ? test(readFileSync12(p, "utf8")) : true;
12517
12578
  };
12518
12579
  const hooksOk = (rel, actor) => has(rel, (text2) => {
@@ -12730,16 +12791,16 @@ function resumeReport(project, options = {}) {
12730
12791
  }
12731
12792
 
12732
12793
  // cli/hooks.ts
12733
- import { appendFileSync, existsSync as existsSync11, mkdirSync as mkdirSync9, readFileSync as readFileSync13, writeFileSync as writeFileSync7 } from "node:fs";
12734
- import { join as join11 } from "node:path";
12794
+ import { appendFileSync, existsSync as existsSync12, mkdirSync as mkdirSync9, readFileSync as readFileSync13, writeFileSync as writeFileSync7 } from "node:fs";
12795
+ import { join as join12 } from "node:path";
12735
12796
  import { createHash as createHash4 } from "node:crypto";
12736
12797
  var sessionMark = (id) => id ? createHash4("sha256").update(id).digest("hex").slice(0, 8) : "";
12737
- var hookLogPath = () => join11(configDir(), "hooks.log");
12798
+ var hookLogPath = () => join12(configDir(), "hooks.log");
12738
12799
  function recordHook(entry) {
12739
12800
  try {
12740
12801
  const path = hookLogPath();
12741
12802
  mkdirSync9(configDir(), { recursive: true });
12742
- const lines = existsSync11(path) ? readFileSync13(path, "utf8").split("\n").filter(Boolean) : [];
12803
+ const lines = existsSync12(path) ? readFileSync13(path, "utf8").split("\n").filter(Boolean) : [];
12743
12804
  lines.push(JSON.stringify(entry));
12744
12805
  writeFileSync7(path, lines.slice(-200).join("\n") + "\n");
12745
12806
  } catch {
@@ -12748,7 +12809,7 @@ function recordHook(entry) {
12748
12809
  function readHookLog(cwd) {
12749
12810
  try {
12750
12811
  const path = hookLogPath();
12751
- if (!existsSync11(path)) return [];
12812
+ if (!existsSync12(path)) return [];
12752
12813
  const all = readFileSync13(path, "utf8").split("\n").filter(Boolean).map((l) => {
12753
12814
  try {
12754
12815
  return JSON.parse(l);
@@ -13413,7 +13474,7 @@ function reviewable(p, blockId) {
13413
13474
  }
13414
13475
 
13415
13476
  // cli/main.ts
13416
- import { existsSync as existsSync13, readFileSync as readFileSync14, writeFileSync as writeFileSync8 } from "node:fs";
13477
+ import { existsSync as existsSync14, readFileSync as readFileSync14, writeFileSync as writeFileSync8 } from "node:fs";
13417
13478
  import { execFileSync as execFileSync3 } from "node:child_process";
13418
13479
 
13419
13480
  // docs/AGENTS_SNIPPET.md
@@ -13719,7 +13780,7 @@ function terminalHeight(p, which) {
13719
13780
  }
13720
13781
 
13721
13782
  // cli/main.ts
13722
- import { dirname as dirname10, join as join12, resolve as resolve6 } from "node:path";
13783
+ import { dirname as dirname11, join as join13, resolve as resolve7 } from "node:path";
13723
13784
 
13724
13785
  // src/model/report.ts
13725
13786
  var quoted = (title) => t("\u300C{title}\u300D", { title });
@@ -13937,8 +13998,8 @@ var STATUS_LABEL2 = {
13937
13998
 
13938
13999
  // cli/git.ts
13939
14000
  import { execFileSync as execFileSync2 } from "node:child_process";
13940
- import { existsSync as existsSync12, statSync as statSync6 } from "node:fs";
13941
- import { dirname as dirname9, relative as relative2, resolve as resolve5 } from "node:path";
14001
+ import { existsSync as existsSync13, statSync as statSync7 } from "node:fs";
14002
+ import { dirname as dirname10, relative as relative2, resolve as resolve6 } from "node:path";
13942
14003
  function git(args, cwd) {
13943
14004
  try {
13944
14005
  return execFileSync2("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
@@ -13956,9 +14017,9 @@ function remoteToWeb(remote) {
13956
14017
  return null;
13957
14018
  }
13958
14019
  function gitRefFor(filePath) {
13959
- const abs = resolve5(filePath);
13960
- if (!existsSync12(abs) || !statSync6(abs).isFile()) return null;
13961
- const root = git(["rev-parse", "--show-toplevel"], dirname9(abs));
14020
+ const abs = resolve6(filePath);
14021
+ if (!existsSync13(abs) || !statSync7(abs).isFile()) return null;
14022
+ const root = git(["rev-parse", "--show-toplevel"], dirname10(abs));
13962
14023
  if (!root) return null;
13963
14024
  const rel = relative2(root, abs).replace(/\\/g, "/");
13964
14025
  const commit = git(["rev-parse", "HEAD"], root) ?? "";
@@ -13972,14 +14033,14 @@ function gitRefFor(filePath) {
13972
14033
  }
13973
14034
  function findGitRef(recorded, bases) {
13974
14035
  for (const base of bases) {
13975
- const ref = gitRefFor(resolve5(base, recorded));
14036
+ const ref = gitRefFor(resolve6(base, recorded));
13976
14037
  if (ref) return ref;
13977
14038
  }
13978
14039
  return null;
13979
14040
  }
13980
14041
  function currentRef(root, rel) {
13981
14042
  const commit = git(["rev-parse", "HEAD"], root) ?? "";
13982
- const blob = git(["hash-object", "--path", rel, "--", resolve5(root, rel)], root) ?? "";
14043
+ const blob = git(["hash-object", "--path", rel, "--", resolve6(root, rel)], root) ?? "";
13983
14044
  const repo = git(["config", "--get", "remote.origin.url"], root) ?? "";
13984
14045
  const web = repo ? remoteToWeb(repo) : null;
13985
14046
  return { path: rel, commit, blob, url: web && commit ? `${web}/blob/${commit}/${rel}` : "" };
@@ -13987,7 +14048,7 @@ function currentRef(root, rel) {
13987
14048
  function checkGitRef(ref, cwd) {
13988
14049
  const root = git(["rev-parse", "--show-toplevel"], cwd);
13989
14050
  if (!root || !ref.path) return { state: "missing" };
13990
- if (existsSync12(resolve5(root, ref.path))) return { state: "ok", path: ref.path };
14051
+ if (existsSync13(resolve6(root, ref.path))) return { state: "ok", path: ref.path };
13991
14052
  if (ref.blob) {
13992
14053
  const tree = git(["ls-tree", "-r", "HEAD"], root) ?? "";
13993
14054
  for (const line of tree.split("\n")) {
@@ -14005,7 +14066,7 @@ function checkGitRef(ref, cwd) {
14005
14066
  if (m && m[1] === cur) cur = m[2];
14006
14067
  }
14007
14068
  }
14008
- if (cur !== ref.path && existsSync12(resolve5(root, cur))) return { state: "moved", ...currentRef(root, cur) };
14069
+ if (cur !== ref.path && existsSync13(resolve6(root, cur))) return { state: "moved", ...currentRef(root, cur) };
14009
14070
  }
14010
14071
  return { state: "missing" };
14011
14072
  }
@@ -14244,11 +14305,11 @@ var claimRequest;
14244
14305
  var CONFLICT_RETRIES = 8;
14245
14306
  function load(path) {
14246
14307
  const text2 = planIO().read(path);
14247
- readRevisions.set(resolve6(path), revisionOf(text2));
14308
+ readRevisions.set(resolve7(path), revisionOf(text2));
14248
14309
  return fromJSON(text2);
14249
14310
  }
14250
14311
  function save(path, p) {
14251
- const expected = readRevisions.has(resolve6(path)) ? readRevisions.get(resolve6(path)) : null;
14312
+ const expected = readRevisions.has(resolve7(path)) ? readRevisions.get(resolve7(path)) : null;
14252
14313
  const normalized = normalizePortNames(p).project;
14253
14314
  let text2 = toJSON(normalized) + "\n";
14254
14315
  const warnings = [];
@@ -14258,12 +14319,12 @@ function save(path, p) {
14258
14319
  return text2;
14259
14320
  } });
14260
14321
  for (const warning of warnings) out(warning);
14261
- readRevisions.set(resolve6(path), revision);
14322
+ readRevisions.set(resolve7(path), revision);
14262
14323
  lastSavedText = text2;
14263
14324
  }
14264
14325
  function writeExport(target, text2) {
14265
14326
  let guarded = false;
14266
- if (existsSync13(target)) {
14327
+ if (existsSync14(target)) {
14267
14328
  try {
14268
14329
  guarded = claimsEnabled(fromJSON(readFileSync14(target, "utf8")));
14269
14330
  } catch {
@@ -14731,7 +14792,7 @@ function main(argv) {
14731
14792
  if (cmd === "init") {
14732
14793
  const path2 = locateFile(str2(options.file), true);
14733
14794
  if (planIO().exists(path2) && !options.force) throw new Error(t("{path} \u306F\u65E2\u306B\u3042\u308A\u307E\u3059 (--force \u3067\u4E0A\u66F8\u304D)", { path: path2 }));
14734
- readRevisions.set(resolve6(path2), existsSync13(path2) ? revisionOf(readFileSync14(path2, "utf8")) : null);
14795
+ readRevisions.set(resolve7(path2), existsSync14(path2) ? revisionOf(readFileSync14(path2, "utf8")) : null);
14735
14796
  const lang = explicitLang(options) ?? envLang();
14736
14797
  setLang(lang);
14737
14798
  const from = str2(options.from);
@@ -14746,7 +14807,7 @@ function main(argv) {
14746
14807
  if (!basePath || !oursPath || !theirsPath) throw new Error(t("merge <base> <ours> <theirs> \u306E 3 \u3064\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"));
14747
14808
  const read2 = (f) => {
14748
14809
  const text2 = readFileSync14(f, "utf8");
14749
- readRevisions.set(resolve6(f), revisionOf(text2));
14810
+ readRevisions.set(resolve7(f), revisionOf(text2));
14750
14811
  return text2.trim() ? fromJSON(text2) : null;
14751
14812
  };
14752
14813
  const base = read2(basePath);
@@ -14763,7 +14824,7 @@ function main(argv) {
14763
14824
  const message = kept.includes(c) ? t("\u30DE\u30FC\u30B8\u3067\u7247\u65B9\u304C\u524A\u9664\u30FB\u7247\u65B9\u304C\u5909\u66F4: {path} (\u5909\u66F4\u3055\u308C\u305F\u5074\u3092\u6B8B\u3057\u307E\u3057\u305F\u3002\u524A\u9664\u3057\u305F\u5074: {side})", { path: c.path, side: c.ours === void 0 ? t("\u81EA\u5206") : t("\u76F8\u624B") }) : t("\u30DE\u30FC\u30B8\u3067\u4E21\u5074\u304C\u5909\u66F4: {path} (\u63A1\u7528: {ours} / \u76F8\u624B: {theirs})", { path: c.path, ours: JSON.stringify(c.ours), theirs: JSON.stringify(c.theirs) });
14764
14825
  q = { ...q, log: [...q.log, { id: `m${Math.random().toString(36).slice(2, 10)}`, at: (/* @__PURE__ */ new Date()).toISOString(), actor: "merge", kind: "note", message }] };
14765
14826
  }
14766
- commitFile(oursPath, toJSON(q) + "\n", readRevisions.get(resolve6(oursPath)));
14827
+ commitFile(oursPath, toJSON(q) + "\n", readRevisions.get(resolve7(oursPath)));
14767
14828
  const both = r.conflicts.length - kept.length;
14768
14829
  out(
14769
14830
  t("\u30DE\u30FC\u30B8: \u76F8\u624B\u306E\u5909\u66F4 {count} \u4EF6\u3092\u53D6\u308A\u8FBC\u307F", { count: r.merged }) + (both ? t("\u3001\u4E21\u5074\u3067\u5909\u66F4\u304C {count} \u4EF6 (\u81EA\u5206\u306E\u5024\u3092\u63A1\u7528\u3057\u3001\u76F8\u624B\u306E\u5024\u306F\u30ED\u30B0\u306B\u8A18\u9332)", { count: both }) : "") + (kept.length ? t("\u3001\u524A\u9664\u3068\u5909\u66F4\u306E\u7AF6\u5408\u304C {count} \u4EF6 (\u5909\u66F4\u3055\u308C\u305F\u5074\u3092\u6B8B\u3057\u3001\u30ED\u30B0\u306B\u8A18\u9332)", { count: kept.length }) : "")
@@ -15021,7 +15082,7 @@ function runCommand(cmd, rest, options, actor, path, p, AGENTS_SNIPPET, SKILL_MD
15021
15082
  return;
15022
15083
  }
15023
15084
  case "setup-agent": {
15024
- const root = str2(options.dir) ? resolve6(str2(options.dir)) : dirname10(path);
15085
+ const root = str2(options.dir) ? resolve7(str2(options.dir)) : dirname11(path);
15025
15086
  const agent = str2(options.agent) ?? "all";
15026
15087
  if (options.check) {
15027
15088
  out(checkAgentSetup(root, agent).join("\n"));
@@ -15154,10 +15215,10 @@ function runCommand(cmd, rest, options, actor, path, p, AGENTS_SNIPPET, SKILL_MD
15154
15215
  return;
15155
15216
  }
15156
15217
  case "git-setup": {
15157
- const root = dirname10(path);
15158
- const attrs = join12(root, ".gitattributes");
15218
+ const root = dirname11(path);
15219
+ const attrs = join13(root, ".gitattributes");
15159
15220
  const line = "boxglow.json merge=boxglow";
15160
- const cur = existsSync13(attrs) ? readFileSync14(attrs, "utf8") : "";
15221
+ const cur = existsSync14(attrs) ? readFileSync14(attrs, "utf8") : "";
15161
15222
  if (!cur.split(/\r?\n/).includes(line)) writeFileSync8(attrs, (cur && !cur.endsWith("\n") ? cur + "\n" : cur) + line + "\n", "utf8");
15162
15223
  execFileSync3("git", ["config", "merge.boxglow.name", "Boxglow plan merge (box level)"], { cwd: root });
15163
15224
  execFileSync3("git", ["config", "merge.boxglow.driver", "npx boxglow merge %O %A %B"], { cwd: root });
@@ -15566,7 +15627,7 @@ function runCommand(cmd, rest, options, actor, path, p, AGENTS_SNIPPET, SKILL_MD
15566
15627
  for (const a of port2.artifacts) {
15567
15628
  const owner = p.blocks[port2.blockId]?.title ?? "?";
15568
15629
  if (a.kind === "file" && a.path) {
15569
- const ref = findGitRef(a.path, [dirname10(path), process.cwd()]);
15630
+ const ref = findGitRef(a.path, [dirname11(path), process.cwd()]);
15570
15631
  if (ref) {
15571
15632
  a.kind = "git";
15572
15633
  a.repo = ref.repo;
@@ -15583,7 +15644,7 @@ function runCommand(cmd, rest, options, actor, path, p, AGENTS_SNIPPET, SKILL_MD
15583
15644
  }
15584
15645
  if (a.kind !== "git") continue;
15585
15646
  if (!a.commit && a.path) {
15586
- const ref = gitRefFor(resolve6(dirname10(path), a.path));
15647
+ const ref = gitRefFor(resolve7(dirname11(path), a.path));
15587
15648
  if (ref?.commit) {
15588
15649
  a.commit = ref.commit;
15589
15650
  a.blob = ref.blob;
@@ -15595,7 +15656,7 @@ function runCommand(cmd, rest, options, actor, path, p, AGENTS_SNIPPET, SKILL_MD
15595
15656
  continue;
15596
15657
  }
15597
15658
  }
15598
- const r = checkGitRef(a, dirname10(path));
15659
+ const r = checkGitRef(a, dirname11(path));
15599
15660
  if (r.state === "moved" && r.path) {
15600
15661
  lines.push(t("- [\u79FB\u52D5] {owner}.{port} \u300C{title}\u300D {from} -> {to}", { owner, port: port2.name, title: a.title, from: String(a.path), to: r.path }));
15601
15662
  a.path = r.path;
@@ -15759,7 +15820,7 @@ function runCommand(cmd, rest, options, actor, path, p, AGENTS_SNIPPET, SKILL_MD
15759
15820
  function cliMain(argv) {
15760
15821
  if (argv[0] === "mcp") {
15761
15822
  const { options } = parseArgs(argv.slice(1));
15762
- if (str2(options.file)) process.env.BOXGLOW_FILE = resolve6(str2(options.file));
15823
+ if (str2(options.file)) process.env.BOXGLOW_FILE = resolve7(str2(options.file));
15763
15824
  if (str2(options.actor)) process.env.BOXGLOW_ACTOR = str2(options.actor);
15764
15825
  if (str2(options.lang)) process.env.BOXGLOW_LANG = str2(options.lang);
15765
15826
  const mcpFile = locateFile(str2(options.file));
@@ -15814,10 +15875,10 @@ function cliMain(argv) {
15814
15875
  claimRequest = claimCommand("combine", void 0, options, actorOf(str2(options.actor), process.env));
15815
15876
  const outPath = str2(options.out);
15816
15877
  if (positional.length < 2 || !outPath) throw new Error("boxglow combine <\u8A08\u753B\u30D5\u30A1\u30A4\u30EB> <\u8A08\u753B\u30D5\u30A1\u30A4\u30EB>... --out <path>");
15817
- if (existsSync13(outPath) && !options.force) throw new Error(t("{path} \u306F\u65E2\u306B\u3042\u308A\u307E\u3059 (--force \u3067\u4E0A\u66F8\u304D)", { path: outPath }));
15878
+ if (existsSync14(outPath) && !options.force) throw new Error(t("{path} \u306F\u65E2\u306B\u3042\u308A\u307E\u3059 (--force \u3067\u4E0A\u66F8\u304D)", { path: outPath }));
15818
15879
  let merged = load(positional[0]);
15819
15880
  for (const file of positional.slice(1)) merged = combineProjects(merged, load(file), basename4(file));
15820
- readRevisions.set(resolve6(outPath), existsSync13(outPath) ? revisionOf(readFileSync14(outPath, "utf8")) : null);
15881
+ readRevisions.set(resolve7(outPath), existsSync14(outPath) ? revisionOf(readFileSync14(outPath, "utf8")) : null);
15821
15882
  save(outPath, merged);
15822
15883
  console.log(t("\u7D50\u5408: {n} \u500B\u306E\u8A08\u753B\u3092 {path} \u306B\u307E\u3068\u3081\u307E\u3057\u305F (\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u7BB1 {m} \u500B)", { n: String(positional.length), path: outPath, m: String(projectBlocks(merged).length) }));
15823
15884
  } catch (e) {
@@ -15831,14 +15892,14 @@ function cliMain(argv) {
15831
15892
  claimRequest = claimCommand("split-file", void 0, options, actorOf(str2(options.actor), process.env));
15832
15893
  const outPath = str2(options.out);
15833
15894
  if (!positional[0] || !outPath) throw new Error("boxglow split-file <\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u7BB1> --out <path> [--file <\u8A08\u753B>]");
15834
- if (existsSync13(outPath) && !options.force) throw new Error(t("{path} \u306F\u65E2\u306B\u3042\u308A\u307E\u3059 (--force \u3067\u4E0A\u66F8\u304D)", { path: outPath }));
15895
+ if (existsSync14(outPath) && !options.force) throw new Error(t("{path} \u306F\u65E2\u306B\u3042\u308A\u307E\u3059 (--force \u3067\u4E0A\u66F8\u304D)", { path: outPath }));
15835
15896
  const path = locateFile(str2(options.file));
15836
15897
  const p = load(path);
15837
15898
  const found = findBlock(p, positional[0]);
15838
15899
  if (!found.block) throw new Error(t("\u30D6\u30ED\u30C3\u30AF\u300C{ref}\u300D\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002", { ref: positional[0] }));
15839
15900
  const box = found.block;
15840
15901
  const { remaining, extracted } = splitProject(p, box.id, str2(options.name));
15841
- readRevisions.set(resolve6(outPath), existsSync13(outPath) ? revisionOf(readFileSync14(outPath, "utf8")) : null);
15902
+ readRevisions.set(resolve7(outPath), existsSync14(outPath) ? revisionOf(readFileSync14(outPath, "utf8")) : null);
15842
15903
  save(outPath, extracted);
15843
15904
  save(path, remaining);
15844
15905
  console.log(t("\u5206\u5272: \u300C{title}\u300D\u3092 {out} \u306B\u5207\u308A\u51FA\u3057\u307E\u3057\u305F ({path} \u306B\u306F\u6B8B\u308A {m} \u500B\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u7BB1)", { title: box.title, out: outPath, path, m: String(projectBlocks(remaining).length) }));
@@ -15904,7 +15965,7 @@ function cliMain(argv) {
15904
15965
  }
15905
15966
  const command = positional[0] ?? "list";
15906
15967
  const write = command === "connect" ? !(options["read-only"] === true || options["read-only"] === "true") : options.write === true || options.write === "true";
15907
- process.exitCode = await runAgentToken({ server, out: (line) => console.log(line), command, name: str2(options.name), write, id: positional[1], target: command === "connect" ? positional[1] : void 0, projectId, dir: file ? dirname10(file) : process.cwd() });
15968
+ process.exitCode = await runAgentToken({ server, out: (line) => console.log(line), command, name: str2(options.name), write, id: positional[1], target: command === "connect" ? positional[1] : void 0, projectId, dir: file ? dirname11(file) : process.cwd() });
15908
15969
  })().catch((e) => {
15909
15970
  console.error(`[boxglow agent-token] ${e instanceof Error ? e.message : String(e)}`);
15910
15971
  process.exitCode = 1;