@nuucognition/flint-cli 0.6.0-dev.6 → 0.6.0-dev.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -13756,7 +13756,7 @@ var init_installer_DWQPLLKD = __esm({
13756
13756
  // ../../packages/flint/dist/index.js
13757
13757
  var dist_exports = {};
13758
13758
  __export(dist_exports, {
13759
- DISCOVERY_FILE_PATH: () => DISCOVERY_FILE_PATH,
13759
+ DISCOVERY_DIR: () => DISCOVERY_DIR,
13760
13760
  EntityFrameSchema: () => EntityFrameSchema,
13761
13761
  FLINT_CONFIG_FILENAME: () => FLINT_CONFIG_FILENAME,
13762
13762
  FLINT_JSON_FILENAME: () => FLINT_JSON_FILENAME,
@@ -13824,6 +13824,7 @@ __export(dist_exports, {
13824
13824
  findFlintByName: () => findFlintByName,
13825
13825
  findFlintByPath: () => findFlintByPath,
13826
13826
  findFlintRoot: () => findFlintRoot,
13827
+ findLivePluginForVault: () => findLivePluginForVault,
13827
13828
  findShardEntry: () => findShardEntry,
13828
13829
  findTinderboxRoot: () => findTinderboxRoot,
13829
13830
  findVaultIdByPath: () => findVaultIdByPath,
@@ -13910,6 +13911,7 @@ __export(dist_exports, {
13910
13911
  healShard: () => healShard,
13911
13912
  healTinderbox: () => healTinderbox,
13912
13913
  identity: () => identity2,
13914
+ initEmptyTinderbox: () => initEmptyTinderbox,
13913
13915
  initGit: () => initGit,
13914
13916
  initPlateRepo: () => initPlateRepo,
13915
13917
  installInstalledShard: () => installInstalledShard,
@@ -13960,6 +13962,7 @@ __export(dist_exports, {
13960
13962
  pushWithTags: () => pushWithTags,
13961
13963
  queryArtifacts: () => queryArtifacts,
13962
13964
  queueMigration: () => queueMigration,
13965
+ readAllDiscoveries: () => readAllDiscoveries,
13963
13966
  readArtifactAtPath: () => readArtifactAtPath,
13964
13967
  readConfig: () => readConfig,
13965
13968
  readConfigSync: () => readConfigSync,
@@ -14100,34 +14103,34 @@ import { execFile as execFile7 } from "child_process";
14100
14103
  import { promisify as promisify32 } from "util";
14101
14104
  import { rm as rm32 } from "fs/promises";
14102
14105
  import { execFile as execFile22 } from "child_process";
14103
- import { cp as cp4, mkdir as mkdir82, readdir as readdir42, readFile as readFile52, rename as rename32, rm as rm42, stat as stat52, writeFile as writeFile62 } from "fs/promises";
14104
- import { homedir as homedir22 } from "os";
14105
- import { basename as basename32, dirname as dirname23, join as join92, resolve as resolve32 } from "path";
14106
+ import { cp as cp4, mkdir as mkdir92, readdir as readdir52, readFile as readFile72, rename as rename42, rm as rm42, stat as stat52, writeFile as writeFile72 } from "fs/promises";
14107
+ import { homedir as homedir4 } from "os";
14108
+ import { basename as basename32, dirname as dirname32, join as join112, resolve as resolve42 } from "path";
14106
14109
  import { promisify as promisify52 } from "util";
14107
14110
  import { exec as exec3 } from "child_process";
14108
14111
  import { promisify as promisify42 } from "util";
14109
14112
  import { promises as fs7 } from "fs";
14110
14113
  import path5 from "path";
14111
- import { extname, join as join102 } from "path";
14112
- import { readdir as readdir52, mkdir as mkdir92, readFile as readFile62, rename as rename42, writeFile as writeFile72 } from "fs/promises";
14113
- import { execSync } from "child_process";
14114
- import { parse as parseYaml32 } from "yaml";
14115
- import { spawn as spawn22 } from "child_process";
14116
- import { readdir as readdir62 } from "fs/promises";
14117
- import { join as join112, resolve as resolve42, sep as sep2 } from "path";
14118
- import { readdir as readdir72, rename as rename52, rm as rm52, stat as stat62, mkdir as mkdir10 } from "fs/promises";
14119
- import { basename as basename42, dirname as dirname32, join as join122 } from "path";
14120
- import { readFile as readFile72, writeFile as writeFile82, rename as rename62, mkdir as mkdir11 } from "fs/promises";
14114
+ import { readFile as readFile52, writeFile as writeFile62, rename as rename32, mkdir as mkdir82 } from "fs/promises";
14121
14115
  import { existsSync as existsSync3 } from "fs";
14122
- import { dirname as dirname42, join as join132, resolve as resolve5 } from "path";
14123
- import { homedir as homedir32, platform as platform22 } from "os";
14116
+ import { dirname as dirname23, join as join92, resolve as resolve32 } from "path";
14117
+ import { homedir as homedir22, platform as platform22 } from "os";
14124
14118
  import { randomBytes as randomBytes2 } from "crypto";
14125
- import { readFile as readFile82 } from "fs/promises";
14119
+ import { readFile as readFile62, readdir as readdir42, realpath } from "fs/promises";
14126
14120
  import { existsSync as existsSync22 } from "fs";
14127
- import { join as join142 } from "path";
14128
- import { homedir as homedir4 } from "os";
14121
+ import { join as join102 } from "path";
14122
+ import { homedir as homedir32 } from "os";
14129
14123
  import { request } from "http";
14130
- import { readdir as readdir82, readFile as readFile92, mkdir as mkdir12 } from "fs/promises";
14124
+ import { extname, join as join122 } from "path";
14125
+ import { readdir as readdir62, mkdir as mkdir10, readFile as readFile82, rename as rename52, writeFile as writeFile82 } from "fs/promises";
14126
+ import { execSync } from "child_process";
14127
+ import { parse as parseYaml32 } from "yaml";
14128
+ import { spawn as spawn22 } from "child_process";
14129
+ import { readdir as readdir72 } from "fs/promises";
14130
+ import { join as join132, resolve as resolve5, sep as sep2 } from "path";
14131
+ import { readdir as readdir82, rename as rename62, rm as rm52, stat as stat62, mkdir as mkdir11 } from "fs/promises";
14132
+ import { basename as basename42, dirname as dirname42, join as join142 } from "path";
14133
+ import { readdir as readdir92, readFile as readFile92, mkdir as mkdir12 } from "fs/promises";
14131
14134
  import { join as join152, dirname as dirname52, resolve as resolve6, sep as sep22 } from "path";
14132
14135
  import { randomUUID as randomUUID22 } from "crypto";
14133
14136
  import { fileURLToPath as fileURLToPath2 } from "url";
@@ -14135,7 +14138,7 @@ import { stat as stat82 } from "fs/promises";
14135
14138
  import { join as join16 } from "path";
14136
14139
  import path22 from "path";
14137
14140
  import { fileURLToPath as fileURLToPath22 } from "url";
14138
- import { readdir as readdir92, readFile as readFile102, mkdir as mkdir13, writeFile as writeFile9, rm as rm62, stat as stat92, copyFile as copyFile2 } from "fs/promises";
14141
+ import { readdir as readdir102, readFile as readFile102, mkdir as mkdir13, writeFile as writeFile9, rm as rm62, stat as stat92, copyFile as copyFile2 } from "fs/promises";
14139
14142
  import { join as join17, basename as basename5, dirname as dirname62, resolve as resolve7, relative as relative3, sep as sep3, extname as extname2 } from "path";
14140
14143
  import { promises as fs42 } from "fs";
14141
14144
  import path52 from "path";
@@ -16604,6 +16607,164 @@ async function resolveReference(root, type, name) {
16604
16607
  const hit = slice.find((f) => f.name.toLowerCase() === normalized);
16605
16608
  return hit ? { path: hit.path, type } : null;
16606
16609
  }
16610
+ function getObsidianConfigPath() {
16611
+ const p = platform22();
16612
+ if (p === "darwin") {
16613
+ return join92(homedir22(), "Library", "Application Support", "obsidian", "obsidian.json");
16614
+ }
16615
+ if (p === "win32") {
16616
+ const appData = process.env.APPDATA ?? join92(homedir22(), "AppData", "Roaming");
16617
+ return join92(appData, "obsidian", "obsidian.json");
16618
+ }
16619
+ return join92(homedir22(), ".config", "obsidian", "obsidian.json");
16620
+ }
16621
+ async function readObsidianConfig(configPath = getObsidianConfigPath()) {
16622
+ if (!existsSync3(configPath)) {
16623
+ return { vaults: {} };
16624
+ }
16625
+ const raw = await readFile52(configPath, "utf-8");
16626
+ const parsed = JSON.parse(raw);
16627
+ return {
16628
+ ...parsed,
16629
+ vaults: parsed.vaults ?? {}
16630
+ };
16631
+ }
16632
+ async function writeObsidianConfig(config, configPath = getObsidianConfigPath()) {
16633
+ await mkdir82(dirname23(configPath), { recursive: true });
16634
+ if (existsSync3(configPath)) {
16635
+ const current = await readFile52(configPath, "utf-8");
16636
+ await writeFile62(`${configPath}.backup`, current, "utf-8");
16637
+ }
16638
+ const tempPath = `${configPath}.tmp.${process.pid}.${Date.now()}`;
16639
+ await writeFile62(tempPath, JSON.stringify(config), "utf-8");
16640
+ await rename32(tempPath, configPath);
16641
+ }
16642
+ function findVaultIdByPath(config, absPath) {
16643
+ const target = resolve32(absPath);
16644
+ for (const [id, vault] of Object.entries(config.vaults)) {
16645
+ if (resolve32(vault.path) === target) return id;
16646
+ }
16647
+ return null;
16648
+ }
16649
+ function generateVaultId() {
16650
+ return randomBytes2(8).toString("hex");
16651
+ }
16652
+ async function registerVault(absPath, configPath = getObsidianConfigPath()) {
16653
+ const target = resolve32(absPath);
16654
+ const config = await readObsidianConfig(configPath);
16655
+ const existing = findVaultIdByPath(config, target);
16656
+ if (existing) {
16657
+ return { id: existing, alreadyRegistered: true };
16658
+ }
16659
+ const id = generateVaultId();
16660
+ config.vaults[id] = { path: target, ts: Date.now() };
16661
+ await writeObsidianConfig(config, configPath);
16662
+ return { id, alreadyRegistered: false };
16663
+ }
16664
+ async function readDiscovery(path202) {
16665
+ if (!existsSync22(path202)) return null;
16666
+ try {
16667
+ const raw = await readFile62(path202, "utf-8");
16668
+ const parsed = JSON.parse(raw);
16669
+ if (typeof parsed.port !== "number" || typeof parsed.pid !== "number") return null;
16670
+ return parsed;
16671
+ } catch {
16672
+ return null;
16673
+ }
16674
+ }
16675
+ async function readAllDiscoveries(dir = DISCOVERY_DIR) {
16676
+ let entries;
16677
+ try {
16678
+ entries = await readdir42(dir);
16679
+ } catch {
16680
+ return [];
16681
+ }
16682
+ const records = [];
16683
+ for (const name of entries) {
16684
+ if (!name.endsWith(".json")) continue;
16685
+ const record = await readDiscovery(join102(dir, name));
16686
+ if (record) records.push(record);
16687
+ }
16688
+ return records;
16689
+ }
16690
+ function isPidAlive(pid) {
16691
+ try {
16692
+ process.kill(pid, 0);
16693
+ return true;
16694
+ } catch (err) {
16695
+ if (err.code === "EPERM") return true;
16696
+ return false;
16697
+ }
16698
+ }
16699
+ async function getLivePlugin(dir = DISCOVERY_DIR) {
16700
+ for (const record of await readAllDiscoveries(dir)) {
16701
+ if (isPidAlive(record.pid)) return record;
16702
+ }
16703
+ return null;
16704
+ }
16705
+ async function samePath(a, b) {
16706
+ try {
16707
+ return await realpath(a) === await realpath(b);
16708
+ } catch {
16709
+ return a === b;
16710
+ }
16711
+ }
16712
+ async function findLivePluginForVault(vaultPath, dir = DISCOVERY_DIR) {
16713
+ for (const record of await readAllDiscoveries(dir)) {
16714
+ if (!record.vaultPath) continue;
16715
+ if (!isPidAlive(record.pid)) continue;
16716
+ if (await samePath(record.vaultPath, vaultPath)) return record;
16717
+ }
16718
+ return null;
16719
+ }
16720
+ async function postOpenVault(port, absPath, timeoutMs = 2e3) {
16721
+ return new Promise((resolvePromise) => {
16722
+ const body = JSON.stringify({ path: absPath });
16723
+ const req = request(
16724
+ {
16725
+ hostname: "127.0.0.1",
16726
+ port,
16727
+ path: "/vault/open",
16728
+ method: "POST",
16729
+ headers: {
16730
+ "Content-Type": "application/json",
16731
+ "Content-Length": Buffer.byteLength(body)
16732
+ },
16733
+ timeout: timeoutMs
16734
+ },
16735
+ (res) => {
16736
+ const chunks = [];
16737
+ res.on("data", (chunk) => chunks.push(chunk));
16738
+ res.on("end", () => {
16739
+ const text = Buffer.concat(chunks).toString("utf-8");
16740
+ try {
16741
+ const parsed = JSON.parse(text);
16742
+ if (parsed.ok === true && typeof parsed.id === "string") {
16743
+ resolvePromise({ ok: true, id: parsed.id, registered: Boolean(parsed.registered) });
16744
+ return;
16745
+ }
16746
+ const errorMessage = typeof parsed.error === "string" ? parsed.error : `unexpected response (status ${res.statusCode ?? "unknown"})`;
16747
+ resolvePromise({ ok: false, error: errorMessage });
16748
+ } catch {
16749
+ resolvePromise({ ok: false, error: `invalid JSON response (status ${res.statusCode ?? "unknown"})` });
16750
+ }
16751
+ });
16752
+ res.on("error", (err) => {
16753
+ resolvePromise({ ok: false, error: err.message });
16754
+ });
16755
+ }
16756
+ );
16757
+ req.on("timeout", () => {
16758
+ req.destroy();
16759
+ resolvePromise({ ok: false, error: `request timed out after ${timeoutMs}ms` });
16760
+ });
16761
+ req.on("error", (err) => {
16762
+ resolvePromise({ ok: false, error: err.message });
16763
+ });
16764
+ req.write(body);
16765
+ req.end();
16766
+ });
16767
+ }
16607
16768
  function isRecord3(value) {
16608
16769
  return !!value && typeof value === "object" && !Array.isArray(value);
16609
16770
  }
@@ -16620,7 +16781,7 @@ function isDirectionalConnection(value) {
16620
16781
  return "from" in value && "to" in value;
16621
16782
  }
16622
16783
  function getConfigPath2(root) {
16623
- return join92(root, TINDERBOX_CONFIG_FILENAME);
16784
+ return join112(root, TINDERBOX_CONFIG_FILENAME);
16624
16785
  }
16625
16786
  function getTinderboxFlintMode(declaration) {
16626
16787
  if (declaration.mode) {
@@ -16680,7 +16841,7 @@ function formatTinderboxToml(config) {
16680
16841
  `;
16681
16842
  }
16682
16843
  async function writeTinderboxToml(root, config) {
16683
- await writeFile62(getConfigPath2(root), formatTinderboxToml(config));
16844
+ await writeFile72(getConfigPath2(root), formatTinderboxToml(config));
16684
16845
  }
16685
16846
  function parseTinderboxToml(content) {
16686
16847
  const parsed = parse2(content);
@@ -16749,7 +16910,7 @@ function parseTinderboxToml(content) {
16749
16910
  };
16750
16911
  }
16751
16912
  async function readTinderboxToml(root) {
16752
- const content = await readFile52(getConfigPath2(root), "utf-8");
16913
+ const content = await readFile72(getConfigPath2(root), "utf-8");
16753
16914
  const config = parseTinderboxToml(content);
16754
16915
  await validateTinderboxToml(root, config);
16755
16916
  return config;
@@ -16758,12 +16919,9 @@ async function validateTinderboxToml(root, config) {
16758
16919
  if (!config.tinderbox.name.trim()) {
16759
16920
  throw new Error("Invalid tinderbox.toml: [tinderbox].name must be a non-empty string");
16760
16921
  }
16761
- if (await pathExists32(join92(root, "flint.toml"))) {
16922
+ if (await pathExists32(join112(root, "flint.toml"))) {
16762
16923
  throw new Error("Invalid tinderbox root: the tinderbox root must not also be a Flint");
16763
16924
  }
16764
- if (!config.flints.required.length) {
16765
- throw new Error("Invalid tinderbox.toml: [flints].required must contain at least one entry");
16766
- }
16767
16925
  const names = /* @__PURE__ */ new Set();
16768
16926
  for (const flint of config.flints.required) {
16769
16927
  if (!flint.name.trim()) {
@@ -16830,22 +16988,22 @@ function resolveTinderboxConnections(config) {
16830
16988
  return edges;
16831
16989
  }
16832
16990
  async function findTinderboxRoot(startPath) {
16833
- let current = resolve32(startPath);
16834
- const home = resolve32(homedir22());
16991
+ let current = resolve42(startPath);
16992
+ const home = resolve42(homedir4());
16835
16993
  try {
16836
16994
  const currentStat = await stat52(current);
16837
16995
  if (!currentStat.isDirectory()) {
16838
- current = dirname23(current);
16996
+ current = dirname32(current);
16839
16997
  }
16840
16998
  } catch {
16841
- current = dirname23(current);
16999
+ current = dirname32(current);
16842
17000
  }
16843
17001
  let currentDevice = (await stat52(current)).dev;
16844
17002
  while (true) {
16845
17003
  if (await pathExists32(getConfigPath2(current))) {
16846
17004
  return current;
16847
17005
  }
16848
- const parent = dirname23(current);
17006
+ const parent = dirname32(current);
16849
17007
  if (current === parent || current === home) {
16850
17008
  return null;
16851
17009
  }
@@ -16858,13 +17016,13 @@ async function findTinderboxRoot(startPath) {
16858
17016
  }
16859
17017
  }
16860
17018
  async function scanTinderboxFlints(root) {
16861
- const entries = await readdir42(root, { withFileTypes: true });
17019
+ const entries = await readdir52(root, { withFileTypes: true });
16862
17020
  const flints = [];
16863
17021
  for (const entry of entries) {
16864
17022
  if (!entry.isDirectory()) continue;
16865
17023
  if (entry.name.startsWith(".")) continue;
16866
- const flintPath = join92(root, entry.name);
16867
- if (!await pathExists32(join92(flintPath, "flint.toml"))) {
17024
+ const flintPath = join112(root, entry.name);
17025
+ if (!await pathExists32(join112(flintPath, "flint.toml"))) {
16868
17026
  continue;
16869
17027
  }
16870
17028
  const config = await readFlintToml(flintPath);
@@ -16894,8 +17052,8 @@ async function reconcileTinderbox(root, config) {
16894
17052
  matched.push({ declaration, actual });
16895
17053
  continue;
16896
17054
  }
16897
- const expectedPath = join92(root, getTinderboxFolderName(declaration.name));
16898
- if (await pathExists32(join92(expectedPath, "flint.toml"))) {
17055
+ const expectedPath = join112(root, getTinderboxFolderName(declaration.name));
17056
+ if (await pathExists32(join112(expectedPath, "flint.toml"))) {
16899
17057
  const expectedConfig = await readFlintToml(expectedPath);
16900
17058
  const actualName = expectedConfig?.flint?.name;
16901
17059
  if (actualName && actualName !== declaration.name) {
@@ -16907,7 +17065,7 @@ async function reconcileTinderbox(root, config) {
16907
17065
  folderName: basename32(expectedPath)
16908
17066
  }
16909
17067
  });
16910
- renamedPaths.add(resolve32(expectedPath));
17068
+ renamedPaths.add(resolve42(expectedPath));
16911
17069
  continue;
16912
17070
  }
16913
17071
  }
@@ -16920,14 +17078,14 @@ async function reconcileTinderbox(root, config) {
16920
17078
  if (ownedNames.has(flint.name)) {
16921
17079
  return false;
16922
17080
  }
16923
- return !renamedPaths.has(resolve32(flint.path));
17081
+ return !renamedPaths.has(resolve42(flint.path));
16924
17082
  });
16925
17083
  return { matched, undeclared, missing, renamed };
16926
17084
  }
16927
17085
  function buildFlintEntry(path202, name, toml) {
16928
17086
  const entry = {
16929
17087
  name,
16930
- path: resolve32(path202),
17088
+ path: resolve42(path202),
16931
17089
  source: "local"
16932
17090
  };
16933
17091
  if (toml?.flint.tags?.length) {
@@ -16943,7 +17101,7 @@ async function syncRegistryForFlint(flint) {
16943
17101
  const entry = buildFlintEntry(flint.path, flint.name, toml);
16944
17102
  const byPath = await findFlintByPath(flint.path);
16945
17103
  if (byPath) {
16946
- if (byPath.name === entry.name && resolve32(byPath.path) === entry.path) {
17104
+ if (byPath.name === entry.name && resolve42(byPath.path) === entry.path) {
16947
17105
  return false;
16948
17106
  }
16949
17107
  await updateFlintEntry(byPath.path, entry);
@@ -16951,7 +17109,7 @@ async function syncRegistryForFlint(flint) {
16951
17109
  }
16952
17110
  const byName = await findFlintByName(flint.name);
16953
17111
  if (byName) {
16954
- if (resolve32(byName.path) === entry.path) {
17112
+ if (resolve42(byName.path) === entry.path) {
16955
17113
  return false;
16956
17114
  }
16957
17115
  await updateFlintEntry(byName.path, entry);
@@ -16962,11 +17120,11 @@ async function syncRegistryForFlint(flint) {
16962
17120
  }
16963
17121
  async function ensureFlintStructure(flintPath) {
16964
17122
  for (const dir of REQUIRED_FLINT_DIRS) {
16965
- await mkdir82(join92(flintPath, dir), { recursive: true });
17123
+ await mkdir92(join112(flintPath, dir), { recursive: true });
16966
17124
  }
16967
17125
  }
16968
17126
  async function materializeGitFlint(root, declaration) {
16969
- const tempPath = join92(root, `.tinderbox-clone-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`);
17127
+ const tempPath = join112(root, `.tinderbox-clone-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`);
16970
17128
  try {
16971
17129
  await execFileAsync22("git", ["clone", declaration.source, tempPath]);
16972
17130
  const config = await readFlintToml(tempPath);
@@ -16977,11 +17135,11 @@ async function materializeGitFlint(root, declaration) {
16977
17135
  if (actualName !== declaration.name) {
16978
17136
  throw new Error(`Cloned Flint name "${actualName}" does not match declared name "${declaration.name}"`);
16979
17137
  }
16980
- const destination = join92(root, getTinderboxFolderName(actualName));
17138
+ const destination = join112(root, getTinderboxFolderName(actualName));
16981
17139
  if (await pathExists32(destination)) {
16982
17140
  throw new Error(`Destination already exists: ${destination}`);
16983
17141
  }
16984
- await rename32(tempPath, destination);
17142
+ await rename42(tempPath, destination);
16985
17143
  await ensureFlintStructure(destination);
16986
17144
  return {
16987
17145
  name: actualName,
@@ -17012,7 +17170,7 @@ async function resolveDeclaredFlints(root, config, reconciliation) {
17012
17170
  path: actual.path,
17013
17171
  available: true,
17014
17172
  presentInRoot: true,
17015
- registered: !!registryEntry && resolve32(registryEntry.path) === resolve32(actual.path)
17173
+ registered: !!registryEntry && resolve42(registryEntry.path) === resolve42(actual.path)
17016
17174
  });
17017
17175
  continue;
17018
17176
  }
@@ -17111,7 +17269,7 @@ async function wireTinderboxConnections(config, resolvedFlints) {
17111
17269
  }
17112
17270
  const local = await readReferencesLocal(from.path);
17113
17271
  const existing = local.flints.find((entry) => entry.name.toLowerCase() === edge.to.toLowerCase());
17114
- const isCurrent = !!existing && resolve32(existing.path) === resolve32(to.path) && await pathExists32(existing.path);
17272
+ const isCurrent = !!existing && resolve42(existing.path) === resolve42(to.path) && await pathExists32(existing.path);
17115
17273
  if (!isCurrent) {
17116
17274
  await upsertFulfillment(from.path, "flints", {
17117
17275
  name: edge.to,
@@ -17132,7 +17290,7 @@ async function wireTinderboxConnections(config, resolvedFlints) {
17132
17290
  }
17133
17291
  return { wired, warnings, errors };
17134
17292
  }
17135
- async function syncTinderbox(root) {
17293
+ async function syncTinderbox(root, options3 = {}) {
17136
17294
  const config = await readTinderboxToml(root);
17137
17295
  const initialReconciliation = await reconcileTinderbox(root, config);
17138
17296
  const cloned = [];
@@ -17146,7 +17304,7 @@ async function syncTinderbox(root) {
17146
17304
  try {
17147
17305
  const existingEntry = await findFlintByName(declaration.name);
17148
17306
  if (existingEntry && await pathExists32(existingEntry.path)) {
17149
- const destination = join92(root, getTinderboxFolderName(declaration.name));
17307
+ const destination = join112(root, getTinderboxFolderName(declaration.name));
17150
17308
  const moveResult = await moveFlint(existingEntry.path, destination);
17151
17309
  moved.push({ name: declaration.name, from: moveResult.from, to: moveResult.to });
17152
17310
  continue;
@@ -17183,6 +17341,55 @@ async function syncTinderbox(root) {
17183
17341
  const wireResult = await wireTinderboxConnections(config, resolved.flints);
17184
17342
  warnings.push(...wireResult.warnings);
17185
17343
  errors.push(...wireResult.errors);
17344
+ const registeredVaults = [];
17345
+ let focusSwitched;
17346
+ if (options3.obsidian !== false) {
17347
+ const obsidianTargets = resolved.flints.filter(
17348
+ (flint) => flint.available && typeof flint.path === "string" && flint.path.length > 0
17349
+ );
17350
+ for (const flint of obsidianTargets) {
17351
+ try {
17352
+ const result = await registerVault(flint.path);
17353
+ registeredVaults.push({
17354
+ name: flint.declaration.name,
17355
+ path: flint.path,
17356
+ id: result.id,
17357
+ alreadyRegistered: result.alreadyRegistered
17358
+ });
17359
+ } catch (error3) {
17360
+ warnings.push({
17361
+ scope: flint.declaration.name,
17362
+ message: `Could not register vault in obsidian.json: ${error3 instanceof Error ? error3.message : String(error3)}`
17363
+ });
17364
+ }
17365
+ }
17366
+ const focusTarget = obsidianTargets[0];
17367
+ if (focusTarget) {
17368
+ try {
17369
+ const plugin = await getLivePlugin();
17370
+ if (plugin) {
17371
+ const response = await postOpenVault(plugin.port, focusTarget.path);
17372
+ if (response.ok) {
17373
+ focusSwitched = {
17374
+ name: focusTarget.declaration.name,
17375
+ path: focusTarget.path,
17376
+ id: response.id
17377
+ };
17378
+ } else {
17379
+ warnings.push({
17380
+ scope: focusTarget.declaration.name,
17381
+ message: `NUU Obsidian plugin focus call failed: ${response.error}`
17382
+ });
17383
+ }
17384
+ }
17385
+ } catch (error3) {
17386
+ warnings.push({
17387
+ scope: focusTarget.declaration.name,
17388
+ message: `NUU Obsidian plugin focus call threw: ${error3 instanceof Error ? error3.message : String(error3)}`
17389
+ });
17390
+ }
17391
+ }
17392
+ }
17186
17393
  return {
17187
17394
  root,
17188
17395
  cloned,
@@ -17192,6 +17399,8 @@ async function syncTinderbox(root) {
17192
17399
  registryUpdated,
17193
17400
  connectionsWired: wireResult.wired,
17194
17401
  undeclared: reconciliation.undeclared,
17402
+ registeredVaults,
17403
+ focusSwitched,
17195
17404
  warnings,
17196
17405
  errors
17197
17406
  };
@@ -17209,7 +17418,7 @@ async function getConnectionDrift(config, resolvedFlints) {
17209
17418
  const local = await readReferencesLocal(from.path);
17210
17419
  const declarationExists = declarations.some((entry) => entry.name.toLowerCase() === edge.to.toLowerCase());
17211
17420
  const fulfillment = local.flints.find((entry) => entry.name.toLowerCase() === edge.to.toLowerCase());
17212
- const fulfillmentValid = !!fulfillment && resolve32(fulfillment.path) === resolve32(to.path) && await pathExists32(fulfillment.path);
17421
+ const fulfillmentValid = !!fulfillment && resolve42(fulfillment.path) === resolve42(to.path) && await pathExists32(fulfillment.path);
17213
17422
  if (!declarationExists || !fulfillmentValid) {
17214
17423
  drift.push({
17215
17424
  from: edge.from,
@@ -17229,7 +17438,7 @@ async function checkTinderbox(root) {
17229
17438
  const staleRegistry = [];
17230
17439
  for (const flint of discovered) {
17231
17440
  const entry = await findFlintByName(flint.name);
17232
- if (!entry || resolve32(entry.path) !== resolve32(flint.path)) {
17441
+ if (!entry || resolve42(entry.path) !== resolve42(flint.path)) {
17233
17442
  staleRegistry.push({
17234
17443
  name: flint.name,
17235
17444
  actualPath: flint.path,
@@ -17296,7 +17505,7 @@ async function getTinderboxStatus(root) {
17296
17505
  for (const edge of expectedEdges) {
17297
17506
  const target = resolvedByName.get(edge.to);
17298
17507
  const fulfillment = local.flints.find((entry) => entry.name.toLowerCase() === edge.to.toLowerCase());
17299
- if (target?.available && target.path && fulfillment && resolve32(fulfillment.path) === resolve32(target.path) && await pathExists32(fulfillment.path)) {
17508
+ if (target?.available && target.path && fulfillment && resolve42(fulfillment.path) === resolve42(target.path) && await pathExists32(fulfillment.path)) {
17300
17509
  connectionsFulfilled++;
17301
17510
  }
17302
17511
  }
@@ -17341,16 +17550,16 @@ async function countFiles(path202) {
17341
17550
  if (!stats.isDirectory()) {
17342
17551
  return 1;
17343
17552
  }
17344
- const entries = await readdir42(path202, { withFileTypes: true });
17553
+ const entries = await readdir52(path202, { withFileTypes: true });
17345
17554
  let count = 1;
17346
17555
  for (const entry of entries) {
17347
- count += await countFiles(join92(path202, entry.name));
17556
+ count += await countFiles(join112(path202, entry.name));
17348
17557
  }
17349
17558
  return count;
17350
17559
  }
17351
17560
  async function resolveMoveSource(nameOrPath) {
17352
- const directPath = resolve32(nameOrPath);
17353
- if (await pathExists32(join92(directPath, "flint.toml"))) {
17561
+ const directPath = resolve42(nameOrPath);
17562
+ if (await pathExists32(join112(directPath, "flint.toml"))) {
17354
17563
  const config = await readFlintToml(directPath);
17355
17564
  const name = config?.flint?.name;
17356
17565
  if (!name) {
@@ -17362,16 +17571,16 @@ async function resolveMoveSource(nameOrPath) {
17362
17571
  if (!entry) {
17363
17572
  throw new Error(`Flint not found: ${nameOrPath}`);
17364
17573
  }
17365
- return { path: resolve32(entry.path), name: entry.name };
17574
+ return { path: resolve42(entry.path), name: entry.name };
17366
17575
  }
17367
17576
  async function moveFlint(nameOrPath, destination, options3 = {}) {
17368
17577
  const source = await resolveMoveSource(nameOrPath);
17369
- const targetPath = resolve32(destination);
17370
- const targetParent = dirname23(targetPath);
17578
+ const targetPath = resolve42(destination);
17579
+ const targetParent = dirname32(targetPath);
17371
17580
  if (!await pathExists32(targetParent)) {
17372
17581
  throw new Error(`Destination parent does not exist: ${targetParent}`);
17373
17582
  }
17374
- if (resolve32(source.path) === targetPath) {
17583
+ if (resolve42(source.path) === targetPath) {
17375
17584
  throw new Error(`Destination is the same as source: ${targetPath}`);
17376
17585
  }
17377
17586
  if (await pathExists32(targetPath)) {
@@ -17382,7 +17591,7 @@ async function moveFlint(nameOrPath, destination, options3 = {}) {
17382
17591
  }
17383
17592
  let crossDevice = false;
17384
17593
  try {
17385
- await rename32(source.path, targetPath);
17594
+ await rename42(source.path, targetPath);
17386
17595
  } catch (error3) {
17387
17596
  const code = error3.code;
17388
17597
  if (code !== "EXDEV") {
@@ -17444,10 +17653,10 @@ async function ensureTinderboxGitRepo(root) {
17444
17653
  }
17445
17654
  initialized = true;
17446
17655
  }
17447
- const gitignorePath = join92(root, ".gitignore");
17656
+ const gitignorePath = join112(root, ".gitignore");
17448
17657
  let existing = "";
17449
17658
  try {
17450
- existing = await readFile52(gitignorePath, "utf-8");
17659
+ existing = await readFile72(gitignorePath, "utf-8");
17451
17660
  } catch {
17452
17661
  existing = "";
17453
17662
  }
@@ -17455,13 +17664,41 @@ async function ensureTinderboxGitRepo(root) {
17455
17664
  const block3 = [TINDERBOX_GITIGNORE_HEADER, TINDERBOX_GITIGNORE_PATTERN, ""].join("\n");
17456
17665
  const content = existing ? `${existing.replace(/\n*$/, "\n")}
17457
17666
  ${block3}` : `${block3}`;
17458
- await writeFile62(gitignorePath, content);
17667
+ await writeFile72(gitignorePath, content);
17459
17668
  }
17460
17669
  return { initialized };
17461
17670
  }
17671
+ async function initEmptyTinderbox(parentDir, name) {
17672
+ const trimmedName = name.trim();
17673
+ if (!trimmedName) {
17674
+ throw new Error("Tinderbox name must be non-empty");
17675
+ }
17676
+ const resolvedParent = resolve42(parentDir);
17677
+ if (!await pathExists32(resolvedParent)) {
17678
+ throw new Error(`Parent directory does not exist: ${resolvedParent}`);
17679
+ }
17680
+ if (await pathExists32(join112(resolvedParent, "flint.toml"))) {
17681
+ throw new Error(`Cannot create a Tinderbox inside a Flint: ${resolvedParent}`);
17682
+ }
17683
+ if (await pathExists32(join112(resolvedParent, TINDERBOX_CONFIG_FILENAME))) {
17684
+ throw new Error(`Cannot create a Tinderbox inside a Tinderbox: ${resolvedParent}`);
17685
+ }
17686
+ const tinderboxRoot = join112(resolvedParent, getTinderboxFolderNameForRoot(trimmedName));
17687
+ if (await pathExists32(tinderboxRoot)) {
17688
+ throw new Error(`Destination already exists: ${tinderboxRoot}`);
17689
+ }
17690
+ await mkdir92(tinderboxRoot, { recursive: true });
17691
+ const config = {
17692
+ tinderbox: { name: trimmedName },
17693
+ flints: { required: [] }
17694
+ };
17695
+ await writeTinderboxToml(tinderboxRoot, config);
17696
+ await ensureTinderboxGitRepo(tinderboxRoot);
17697
+ return { root: tinderboxRoot };
17698
+ }
17462
17699
  async function startTinderbox(currentFlintPath, name, parentDir) {
17463
- const flintPath = resolve32(currentFlintPath);
17464
- if (!await pathExists32(join92(flintPath, "flint.toml"))) {
17700
+ const flintPath = resolve42(currentFlintPath);
17701
+ if (!await pathExists32(join112(flintPath, "flint.toml"))) {
17465
17702
  throw new Error(`Not a Flint: ${flintPath} (missing flint.toml)`);
17466
17703
  }
17467
17704
  const flintToml = await readFlintToml(flintPath);
@@ -17479,22 +17716,22 @@ async function startTinderbox(currentFlintPath, name, parentDir) {
17479
17716
  if (!trimmedName) {
17480
17717
  throw new Error("Tinderbox name must be non-empty");
17481
17718
  }
17482
- const resolvedParent = resolve32(parentDir ? parentDir : dirname23(flintPath));
17719
+ const resolvedParent = resolve42(parentDir ? parentDir : dirname32(flintPath));
17483
17720
  if (!await pathExists32(resolvedParent)) {
17484
17721
  throw new Error(`Parent directory does not exist: ${resolvedParent}`);
17485
17722
  }
17486
- if (await pathExists32(join92(resolvedParent, "flint.toml"))) {
17723
+ if (await pathExists32(join112(resolvedParent, "flint.toml"))) {
17487
17724
  throw new Error(`Cannot create a Tinderbox inside a Flint: ${resolvedParent}`);
17488
17725
  }
17489
- const tinderboxRoot = join92(resolvedParent, getTinderboxFolderNameForRoot(trimmedName));
17726
+ const tinderboxRoot = join112(resolvedParent, getTinderboxFolderNameForRoot(trimmedName));
17490
17727
  if (await pathExists32(tinderboxRoot)) {
17491
17728
  throw new Error(`Destination already exists: ${tinderboxRoot}`);
17492
17729
  }
17493
- if (await pathExists32(join92(tinderboxRoot, TINDERBOX_CONFIG_FILENAME))) {
17730
+ if (await pathExists32(join112(tinderboxRoot, TINDERBOX_CONFIG_FILENAME))) {
17494
17731
  throw new Error(`tinderbox.toml already exists at ${tinderboxRoot}`);
17495
17732
  }
17496
- await mkdir82(tinderboxRoot, { recursive: true });
17497
- const destinationFlint = join92(tinderboxRoot, getTinderboxFolderName(flintName));
17733
+ await mkdir92(tinderboxRoot, { recursive: true });
17734
+ const destinationFlint = join112(tinderboxRoot, getTinderboxFolderName(flintName));
17498
17735
  let move;
17499
17736
  try {
17500
17737
  move = await moveFlint(flintPath, destinationFlint);
@@ -17531,7 +17768,7 @@ async function addFlintToTinderbox(root, flintName) {
17531
17768
  if (!registryEntry || !await pathExists32(registryEntry.path)) {
17532
17769
  throw new Error(`Flint "${flintName}" not found in the global registry`);
17533
17770
  }
17534
- if (resolve32(registryEntry.path).startsWith(`${resolve32(root)}/`) || resolve32(registryEntry.path) === resolve32(root)) {
17771
+ if (resolve42(registryEntry.path).startsWith(`${resolve42(root)}/`) || resolve42(registryEntry.path) === resolve42(root)) {
17535
17772
  throw new Error(`Flint "${flintName}" already lives inside this Tinderbox`);
17536
17773
  }
17537
17774
  const remote = await readGitRemoteUrl(registryEntry.path);
@@ -17540,7 +17777,7 @@ async function addFlintToTinderbox(root, flintName) {
17540
17777
  `Flint "${flintName}" has no git remote. Configure one with \`git remote add origin <url>\` before adding to a Tinderbox.`
17541
17778
  );
17542
17779
  }
17543
- const destination = join92(root, getTinderboxFolderName(flintName));
17780
+ const destination = join112(root, getTinderboxFolderName(flintName));
17544
17781
  if (await pathExists32(destination)) {
17545
17782
  throw new Error(`Destination already exists: ${destination}`);
17546
17783
  }
@@ -17652,9 +17889,9 @@ async function installDependency(flintPath, source, version) {
17652
17889
  }
17653
17890
  async function healShardScaffolding(folderPath, name) {
17654
17891
  for (const sub of SHARD_SPEC_DIRS_SOURCE) {
17655
- await mkdir92(join102(folderPath, sub), { recursive: true });
17892
+ await mkdir10(join122(folderPath, sub), { recursive: true });
17656
17893
  }
17657
- const yamlPath = join102(folderPath, "shard.yaml");
17894
+ const yamlPath = join122(folderPath, "shard.yaml");
17658
17895
  if (!await exists2(yamlPath)) {
17659
17896
  const stub = `shard-spec: "0.2.0"
17660
17897
  version: "0.1.0"
@@ -17662,20 +17899,20 @@ name: ${name}
17662
17899
  shorthand: ${name}
17663
17900
  description: ""
17664
17901
  `;
17665
- await writeFile72(yamlPath, stub, "utf-8");
17902
+ await writeFile82(yamlPath, stub, "utf-8");
17666
17903
  }
17667
- const readmePath = join102(folderPath, "README.md");
17904
+ const readmePath = join122(folderPath, "README.md");
17668
17905
  if (!await exists2(readmePath)) {
17669
- await writeFile72(readmePath, `# ${name}
17906
+ await writeFile82(readmePath, `# ${name}
17670
17907
  `, "utf-8");
17671
17908
  }
17672
- const releasePath = join102(folderPath, "RELEASE.md");
17909
+ const releasePath = join122(folderPath, "RELEASE.md");
17673
17910
  if (!await exists2(releasePath)) {
17674
- await writeFile72(releasePath, "# 0.1.0\n\n- Initial shard scaffold\n", "utf-8");
17911
+ await writeFile82(releasePath, "# 0.1.0\n\n- Initial shard scaffold\n", "utf-8");
17675
17912
  }
17676
- const migrationsPath = join102(folderPath, "MIGRATIONS.md");
17913
+ const migrationsPath = join122(folderPath, "MIGRATIONS.md");
17677
17914
  if (!await exists2(migrationsPath)) {
17678
- await writeFile72(
17915
+ await writeFile82(
17679
17916
  migrationsPath,
17680
17917
  `# Migrations
17681
17918
 
@@ -17714,7 +17951,7 @@ function filterManifestHealthErrors(manifest, errors) {
17714
17951
  }
17715
17952
  async function resolveExistingSystemFolder(flintPath, folder) {
17716
17953
  for (const candidate of [folder.canonical, ...folder.alternates]) {
17717
- if (await exists2(join102(flintPath, candidate))) {
17954
+ if (await exists2(join122(flintPath, candidate))) {
17718
17955
  return candidate;
17719
17956
  }
17720
17957
  }
@@ -17744,7 +17981,7 @@ function hasReadonlyTag(content) {
17744
17981
  }
17745
17982
  async function readGitignore(flintPath) {
17746
17983
  try {
17747
- return await readFile62(join102(flintPath, ".gitignore"), "utf-8");
17984
+ return await readFile82(join122(flintPath, ".gitignore"), "utf-8");
17748
17985
  } catch {
17749
17986
  return "";
17750
17987
  }
@@ -17765,13 +18002,13 @@ function declarationMatchesFolder(flintPath, declarationName, declaration, folde
17765
18002
  if (relativePath.startsWith("./")) {
17766
18003
  relativePath = relativePath.slice(2);
17767
18004
  }
17768
- return join102(flintPath, relativePath) === join102(flintPath, "Shards", folderName);
18005
+ return join122(flintPath, relativePath) === join122(flintPath, "Shards", folderName);
17769
18006
  }
17770
18007
  return false;
17771
18008
  }
17772
18009
  async function countFiles2(dirPath) {
17773
18010
  try {
17774
- const entries = await readdir52(dirPath, { withFileTypes: true });
18011
+ const entries = await readdir62(dirPath, { withFileTypes: true });
17775
18012
  return entries.filter((e) => e.isFile() && e.name.endsWith(".md")).length;
17776
18013
  } catch {
17777
18014
  return 0;
@@ -17789,12 +18026,12 @@ function stripShardFolderPrefix(folderName) {
17789
18026
  function buildRenameAction(shardPath, currentRelativePath, nextRelativePath) {
17790
18027
  return {
17791
18028
  action: async () => {
17792
- const currentPath = join102(shardPath, currentRelativePath);
17793
- const nextPath = join102(shardPath, nextRelativePath);
18029
+ const currentPath = join122(shardPath, currentRelativePath);
18030
+ const nextPath = join122(shardPath, nextRelativePath);
17794
18031
  if (await exists2(nextPath)) {
17795
18032
  throw new Error(`Cannot rename ${currentRelativePath} to ${nextRelativePath}: destination already exists`);
17796
18033
  }
17797
- await rename42(currentPath, nextPath);
18034
+ await rename52(currentPath, nextPath);
17798
18035
  },
17799
18036
  actionLabel: `Rename to ${nextRelativePath}`
17800
18037
  };
@@ -17976,10 +18213,10 @@ async function collectMarkdownBasenames(dirPath) {
17976
18213
  return basenames;
17977
18214
  }
17978
18215
  const visit = async (currentPath) => {
17979
- const entries = await readdir52(currentPath, { withFileTypes: true });
18216
+ const entries = await readdir62(currentPath, { withFileTypes: true });
17980
18217
  for (const entry of entries) {
17981
18218
  if (entry.name.startsWith(".")) continue;
17982
- const entryPath = join102(currentPath, entry.name);
18219
+ const entryPath = join122(currentPath, entry.name);
17983
18220
  if (entry.isDirectory()) {
17984
18221
  await visit(entryPath);
17985
18222
  continue;
@@ -17998,11 +18235,11 @@ async function collectMarkdownRelativePaths(dirPath) {
17998
18235
  return relativePaths;
17999
18236
  }
18000
18237
  const visit = async (currentPath, prefix = "") => {
18001
- const entries = await readdir52(currentPath, { withFileTypes: true });
18238
+ const entries = await readdir62(currentPath, { withFileTypes: true });
18002
18239
  for (const entry of entries) {
18003
18240
  if (entry.name.startsWith(".")) continue;
18004
18241
  const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
18005
- const entryPath = join102(currentPath, entry.name);
18242
+ const entryPath = join122(currentPath, entry.name);
18006
18243
  if (entry.isDirectory()) {
18007
18244
  await visit(entryPath, relativePath);
18008
18245
  continue;
@@ -18026,9 +18263,9 @@ function pushMissingReferences(results, check, references, existingFiles, label)
18026
18263
  }
18027
18264
  async function validateInitContent(shardPath, shorthand) {
18028
18265
  const relativePath = `init-${shorthand}.md`;
18029
- const filePath = join102(shardPath, relativePath);
18266
+ const filePath = join122(shardPath, relativePath);
18030
18267
  if (!await exists2(filePath)) return [];
18031
- const content = await readFile62(filePath, "utf-8");
18268
+ const content = await readFile82(filePath, "utf-8");
18032
18269
  const sections = parseMarkdownSections(content);
18033
18270
  const results = [];
18034
18271
  const intro = sections[0]?.body ?? "";
@@ -18061,7 +18298,7 @@ async function validateInitContent(shardPath, shorthand) {
18061
18298
  );
18062
18299
  }
18063
18300
  const references = getReferencedFiles(section3.body, spec.regex);
18064
- const existingFiles = await collectMarkdownBasenames(join102(shardPath, spec.dir));
18301
+ const existingFiles = await collectMarkdownBasenames(join122(shardPath, spec.dir));
18065
18302
  pushMissingReferences(results, relativePath, references, existingFiles, `Init ${spec.label} section`);
18066
18303
  }
18067
18304
  if (!findSection(sections, /\brequired reading\b/i)) {
@@ -18074,9 +18311,9 @@ async function validateInitContent(shardPath, shorthand) {
18074
18311
  }
18075
18312
  async function validateHeadlessInitContent(shardPath, shorthand) {
18076
18313
  const relativePath = `hinit-${shorthand}.md`;
18077
- const filePath = join102(shardPath, relativePath);
18314
+ const filePath = join122(shardPath, relativePath);
18078
18315
  if (!await exists2(filePath)) return [];
18079
- const content = await readFile62(filePath, "utf-8");
18316
+ const content = await readFile82(filePath, "utf-8");
18080
18317
  const sections = parseMarkdownSections(content);
18081
18318
  const results = [];
18082
18319
  const workflowsSection = findSection(sections, /\bheadless workflows\b/i);
@@ -18089,7 +18326,7 @@ async function validateHeadlessInitContent(shardPath, shorthand) {
18089
18326
  );
18090
18327
  }
18091
18328
  const references = getReferencedFiles(workflowsSection.body, WORKFLOW_REFERENCE_REGEX);
18092
- const existingFiles = await collectMarkdownBasenames(join102(shardPath, "workflows"));
18329
+ const existingFiles = await collectMarkdownBasenames(join122(shardPath, "workflows"));
18093
18330
  pushMissingReferences(results, relativePath, references, existingFiles, "Headless Workflows section");
18094
18331
  if (!references.some((reference) => reference.startsWith("hwkfl-")) || !/replaces/i.test(workflowsSection.body)) {
18095
18332
  results.push(
@@ -18123,10 +18360,10 @@ async function validateHeadlessInitContent(shardPath, shorthand) {
18123
18360
  }
18124
18361
  async function validateTemplateContent(shardPath) {
18125
18362
  const results = [];
18126
- const files = await collectMarkdownRelativePaths(join102(shardPath, "templates"));
18363
+ const files = await collectMarkdownRelativePaths(join122(shardPath, "templates"));
18127
18364
  for (const relativeFile of files) {
18128
18365
  const relativePath = `templates/${relativeFile}`;
18129
- const content = await readFile62(join102(shardPath, relativePath), "utf-8");
18366
+ const content = await readFile82(join122(shardPath, relativePath), "utf-8");
18130
18367
  if (!MARKDOWN_FILENAME_LINE_REGEX.test(content)) {
18131
18368
  results.push(
18132
18369
  createContentWarning(relativePath, 'Template should declare its output filename with a "# File:" header')
@@ -18156,10 +18393,10 @@ async function validateTemplateContent(shardPath) {
18156
18393
  }
18157
18394
  async function validateSkillContent(shardPath) {
18158
18395
  const results = [];
18159
- const files = await collectMarkdownRelativePaths(join102(shardPath, "skills"));
18396
+ const files = await collectMarkdownRelativePaths(join122(shardPath, "skills"));
18160
18397
  for (const relativeFile of files) {
18161
18398
  const relativePath = `skills/${relativeFile}`;
18162
- const content = await readFile62(join102(shardPath, relativePath), "utf-8");
18399
+ const content = await readFile82(join122(shardPath, relativePath), "utf-8");
18163
18400
  const sections = parseMarkdownSections(content);
18164
18401
  if (!findSection(sections, /\binput\b/i)) {
18165
18402
  results.push(createContentWarning(relativePath, "Skill is missing an Input section"));
@@ -18178,10 +18415,10 @@ async function validateSkillContent(shardPath) {
18178
18415
  }
18179
18416
  async function validateWorkflowContent(shardPath) {
18180
18417
  const results = [];
18181
- const files = await collectMarkdownRelativePaths(join102(shardPath, "workflows"));
18418
+ const files = await collectMarkdownRelativePaths(join122(shardPath, "workflows"));
18182
18419
  for (const relativeFile of files) {
18183
18420
  const relativePath = `workflows/${relativeFile}`;
18184
- const content = await readFile62(join102(shardPath, relativePath), "utf-8");
18421
+ const content = await readFile82(join122(shardPath, relativePath), "utf-8");
18185
18422
  const sections = parseMarkdownSections(content);
18186
18423
  const isHeadless = relativeFile.split("/").pop()?.startsWith("hwkfl-") ?? false;
18187
18424
  if (!findSection(sections, /\binput\b/i)) {
@@ -18227,10 +18464,10 @@ async function validateWorkflowContent(shardPath) {
18227
18464
  }
18228
18465
  async function validateKnowledgeContent(shardPath) {
18229
18466
  const results = [];
18230
- const files = await collectMarkdownRelativePaths(join102(shardPath, "knowledge"));
18467
+ const files = await collectMarkdownRelativePaths(join122(shardPath, "knowledge"));
18231
18468
  for (const relativeFile of files) {
18232
18469
  const relativePath = `knowledge/${relativeFile}`;
18233
- const content = await readFile62(join102(shardPath, relativePath), "utf-8");
18470
+ const content = await readFile82(join122(shardPath, relativePath), "utf-8");
18234
18471
  const sections = parseMarkdownSections(content);
18235
18472
  const lineCount = content.split(/\r?\n/).length;
18236
18473
  if (!sections[0]?.heading) {
@@ -18265,7 +18502,7 @@ async function validateTypeDefinitions(shardPath, shorthand, manifest) {
18265
18502
  }
18266
18503
  const expectedSource = resolveTypeSourceFilename(typeDecl, shorthand);
18267
18504
  const expectedDest = resolveTypeDestPath(typeDecl, manifest.name);
18268
- const sourceExists = await exists2(join102(shardPath, "install", expectedSource));
18505
+ const sourceExists = await exists2(join122(shardPath, "install", expectedSource));
18269
18506
  if (!sourceExists) {
18270
18507
  results.push(
18271
18508
  createContentWarning(
@@ -18275,7 +18512,7 @@ async function validateTypeDefinitions(shardPath, shorthand, manifest) {
18275
18512
  );
18276
18513
  } else {
18277
18514
  try {
18278
- const content = await readFile62(join102(shardPath, "install", expectedSource), "utf-8");
18515
+ const content = await readFile82(join122(shardPath, "install", expectedSource), "utf-8");
18279
18516
  const sections = parseMarkdownSections(content);
18280
18517
  const headings = new Set(sections.map((s) => s.heading));
18281
18518
  for (const property of TYPE_DEFINITION_PROPERTIES) {
@@ -18309,9 +18546,9 @@ async function validateTypeDefinitions(shardPath, shorthand, manifest) {
18309
18546
  }
18310
18547
  async function validateReleaseChangelog(shardPath) {
18311
18548
  const relativePath = "RELEASE.md";
18312
- const filePath = join102(shardPath, relativePath);
18549
+ const filePath = join122(shardPath, relativePath);
18313
18550
  if (!await exists2(filePath)) return [];
18314
- const content = await readFile62(filePath, "utf-8");
18551
+ const content = await readFile82(filePath, "utf-8");
18315
18552
  const results = [];
18316
18553
  const entries = content.split(/\n\s*---\s*\n/g).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
18317
18554
  if (entries.length === 0) {
@@ -18344,20 +18581,20 @@ async function validateRuntimeEnvironment(shardPath, folderName, manifest) {
18344
18581
  if (!manifest) return [];
18345
18582
  const results = [];
18346
18583
  const capabilityParts = [];
18347
- const scriptsDir = join102(shardPath, "scripts");
18348
- const workspaceReqsDir = join102(shardPath, "workspace-reqs");
18349
- const yamlPath = join102(shardPath, "shard.yaml");
18584
+ const scriptsDir = join122(shardPath, "scripts");
18585
+ const workspaceReqsDir = join122(shardPath, "workspace-reqs");
18586
+ const yamlPath = join122(shardPath, "shard.yaml");
18350
18587
  try {
18351
- const yamlContent = await readFile62(yamlPath, "utf-8");
18588
+ const yamlContent = await readFile82(yamlPath, "utf-8");
18352
18589
  if (/^scripts\s*:/m.test(yamlContent)) {
18353
18590
  results.push(withCategory({
18354
18591
  check: "shard.yaml/scripts",
18355
18592
  status: "warning",
18356
18593
  message: "scripts: field is deprecated \u2014 scripts are auto-discovered from scripts/*.js",
18357
18594
  action: async () => {
18358
- const content = await readFile62(yamlPath, "utf-8");
18595
+ const content = await readFile82(yamlPath, "utf-8");
18359
18596
  const cleaned = content.replace(/^scripts\s*:.*(?:\n(?:[ \t]+.*))*\n?/m, "");
18360
- await writeFile72(yamlPath, cleaned);
18597
+ await writeFile82(yamlPath, cleaned);
18361
18598
  },
18362
18599
  actionLabel: "Drop scripts: field \u2014 scripts are auto-discovered from scripts/*.js"
18363
18600
  }, "Runtime", folderName));
@@ -18366,7 +18603,7 @@ async function validateRuntimeEnvironment(shardPath, folderName, manifest) {
18366
18603
  }
18367
18604
  const discoveredScripts = [];
18368
18605
  try {
18369
- const entries = await readdir52(scriptsDir, { withFileTypes: true });
18606
+ const entries = await readdir62(scriptsDir, { withFileTypes: true });
18370
18607
  for (const entry of entries) {
18371
18608
  if (!entry.isFile() || !entry.name.endsWith(".js")) continue;
18372
18609
  discoveredScripts.push(entry.name.slice(0, -3));
@@ -18392,7 +18629,7 @@ async function validateRuntimeEnvironment(shardPath, folderName, manifest) {
18392
18629
  `Workspace: ${workspaceRequirements.map((requirement) => requirement.name).join(", ")}`
18393
18630
  );
18394
18631
  for (const requirement of workspaceRequirements) {
18395
- const requirementPath = join102(shardPath, requirement.source);
18632
+ const requirementPath = join122(shardPath, requirement.source);
18396
18633
  if (!await exists2(requirementPath)) {
18397
18634
  results.push(withCategory(
18398
18635
  createContentWarning(
@@ -18405,7 +18642,7 @@ async function validateRuntimeEnvironment(shardPath, folderName, manifest) {
18405
18642
  }
18406
18643
  }
18407
18644
  } else if (await exists2(workspaceReqsDir)) {
18408
- const entries = await readdir52(workspaceReqsDir, { withFileTypes: true });
18645
+ const entries = await readdir62(workspaceReqsDir, { withFileTypes: true });
18409
18646
  if (entries.some((entry) => entry.isFile() && entry.name.endsWith(".js"))) {
18410
18647
  results.push(withCategory(
18411
18648
  createContentWarning(
@@ -18457,7 +18694,7 @@ async function validateShardStateModel(flintPath, folderName, manifest) {
18457
18694
  }, "State", folderName));
18458
18695
  return;
18459
18696
  }
18460
- const content = await readFile62(filePath, "utf-8");
18697
+ const content = await readFile82(filePath, "utf-8");
18461
18698
  const parsed = parseFrontmatterRecord(content);
18462
18699
  if (!parsed) {
18463
18700
  results.push(withHealthMeta({
@@ -18493,11 +18730,11 @@ async function validateShardStateModel(flintPath, folderName, manifest) {
18493
18730
  if (requiresShardState) {
18494
18731
  const stateFolder = await resolveExistingSystemFolder(flintPath, SHARD_SYSTEM_FOLDERS[1]) ?? SHARD_SYSTEM_FOLDERS[1].canonical;
18495
18732
  const relativePath = `${stateFolder}/(Shard) ${manifest.name}.md`;
18496
- await validateStateFile(join102(flintPath, relativePath), relativePath);
18733
+ await validateStateFile(join122(flintPath, relativePath), relativePath);
18497
18734
  }
18498
18735
  if (requiresLocalState) {
18499
18736
  const relativePath = `${SHARD_SYSTEM_FOLDERS[2].canonical}/(Shard) ${manifest.name} (Local).md`;
18500
- await validateStateFile(join102(flintPath, relativePath), relativePath);
18737
+ await validateStateFile(join122(flintPath, relativePath), relativePath);
18501
18738
  }
18502
18739
  return results;
18503
18740
  }
@@ -18537,7 +18774,7 @@ async function collectShardStructureResults(shardPath, shorthand, shardName = sh
18537
18774
  const migrationPattern = new RegExp(`^mig-${escapedShorthand}-\\d+\\.\\d+\\.\\d+-to-\\d+\\.\\d+\\.\\d+\\.(?:md|js|mjs)$`);
18538
18775
  const devMigrationPattern = new RegExp(`^dev-mig-${escapedShorthand}-\\d+\\.\\d+\\.\\d+-to-\\d+\\.\\d+\\.\\d+\\.(?:md|js|mjs)$`);
18539
18776
  const expectedInitName = isDev ? `dev-init-${shorthand}.md` : `init-${shorthand}.md`;
18540
- if (!await exists2(join102(shardPath, expectedInitName))) {
18777
+ if (!await exists2(join122(shardPath, expectedInitName))) {
18541
18778
  results.push({
18542
18779
  check: expectedInitName,
18543
18780
  status: "warning",
@@ -18580,7 +18817,7 @@ async function collectShardStructureResults(shardPath, shorthand, shardName = sh
18580
18817
  };
18581
18818
  };
18582
18819
  try {
18583
- const rootEntries = await readdir52(shardPath, { withFileTypes: true });
18820
+ const rootEntries = await readdir62(shardPath, { withFileTypes: true });
18584
18821
  const allowedRootDirs = /* @__PURE__ */ new Set([...SHARD_SPEC_DIRS_SOURCE, ...OPTIONAL_SHARD_ROOT_DIRS]);
18585
18822
  for (const entry of rootEntries) {
18586
18823
  if (entry.name.startsWith(".")) continue;
@@ -18609,10 +18846,10 @@ async function collectShardStructureResults(shardPath, shorthand, shardName = sh
18609
18846
  return results;
18610
18847
  }
18611
18848
  const inspectDir = async (dir, validateFile) => {
18612
- const dirPath = join102(shardPath, dir);
18849
+ const dirPath = join122(shardPath, dir);
18613
18850
  if (!await exists2(dirPath)) return;
18614
18851
  const visit = async (currentPath, relativePrefix = "") => {
18615
- const entries = await readdir52(currentPath, { withFileTypes: true });
18852
+ const entries = await readdir62(currentPath, { withFileTypes: true });
18616
18853
  for (const entry of entries) {
18617
18854
  if (entry.name.startsWith(".")) continue;
18618
18855
  const relativeName = relativePrefix ? `${relativePrefix}/${entry.name}` : entry.name;
@@ -18626,7 +18863,7 @@ async function collectShardStructureResults(shardPath, shorthand, shardName = sh
18626
18863
  });
18627
18864
  continue;
18628
18865
  }
18629
- await visit(join102(currentPath, entry.name), relativeName);
18866
+ await visit(join122(currentPath, entry.name), relativeName);
18630
18867
  continue;
18631
18868
  }
18632
18869
  const issue = validateFile(shardRelativePath, entry.name);
@@ -18809,7 +19046,7 @@ async function checkShardHealth(flintPath, identifier) {
18809
19046
  const snapshotManifests = /* @__PURE__ */ new Map();
18810
19047
  const blockingManifestFolders = /* @__PURE__ */ new Set();
18811
19048
  for (const folder of targetFolders) {
18812
- const shardPath = join102(flintPath, "Shards", folder);
19049
+ const shardPath = join122(flintPath, "Shards", folder);
18813
19050
  const strictResult = await readShardManifest(shardPath);
18814
19051
  const snapshot = await readShardManifestSnapshot(shardPath);
18815
19052
  manifestResults.set(folder, strictResult);
@@ -18843,7 +19080,7 @@ async function checkShardHealth(flintPath, identifier) {
18843
19080
  status: "warning",
18844
19081
  message: "Missing shard system folder",
18845
19082
  action: async () => {
18846
- await mkdir92(join102(flintPath, folder.canonical), { recursive: true });
19083
+ await mkdir10(join122(flintPath, folder.canonical), { recursive: true });
18847
19084
  },
18848
19085
  actionLabel: `Create ${folder.canonical}`
18849
19086
  }, "State"));
@@ -18860,7 +19097,7 @@ async function checkShardHealth(flintPath, identifier) {
18860
19097
  for (const folder of targetFolders) {
18861
19098
  const kebab = toKebabCase3(folder);
18862
19099
  if (!declaredKebabNames.has(kebab)) {
18863
- const shardPath = join102(flintPath, "Shards", folder);
19100
+ const shardPath = join122(flintPath, "Shards", folder);
18864
19101
  const manifestResult = manifestResults.get(folder) ?? await readShardManifest(shardPath);
18865
19102
  const manifest = manifests.get(folder);
18866
19103
  if (manifest) {
@@ -18898,7 +19135,7 @@ async function checkShardHealth(flintPath, identifier) {
18898
19135
  }
18899
19136
  if (decl.source.startsWith("path:")) {
18900
19137
  const relativePath = decl.source.slice(5);
18901
- const fullPath = join102(flintPath, relativePath);
19138
+ const fullPath = join122(flintPath, relativePath);
18902
19139
  if (!await exists2(fullPath)) {
18903
19140
  results.push(withHealthMeta({
18904
19141
  check: `${name} (${decl.source})`,
@@ -18913,7 +19150,7 @@ async function checkShardHealth(flintPath, identifier) {
18913
19150
  }
18914
19151
  }
18915
19152
  for (const folder of targetFolders) {
18916
- const shardPath = join102(flintPath, "Shards", folder);
19153
+ const shardPath = join122(flintPath, "Shards", folder);
18917
19154
  const manifestResult = manifestResults.get(folder) ?? await readShardManifest(shardPath);
18918
19155
  const manifest = manifests.get(folder);
18919
19156
  if (!manifestResult) {
@@ -18931,7 +19168,7 @@ name: ${name}
18931
19168
  shorthand: ${shorthand}
18932
19169
  description: ${name} shard
18933
19170
  `;
18934
- await writeFile72(join102(shardPath, "shard.yaml"), yaml);
19171
+ await writeFile82(join122(shardPath, "shard.yaml"), yaml);
18935
19172
  },
18936
19173
  actionLabel: `Create minimal shard.yaml for ${folder}`
18937
19174
  }, "Manifest", folder));
@@ -18955,7 +19192,7 @@ description: ${name} shard
18955
19192
  }
18956
19193
  for (const folder of targetFolders) {
18957
19194
  if (blockingManifestFolders.has(folder)) continue;
18958
- const shardPath = join102(flintPath, "Shards", folder);
19195
+ const shardPath = join122(flintPath, "Shards", folder);
18959
19196
  const manifest = manifests.get(folder) ?? null;
18960
19197
  if (!manifest) continue;
18961
19198
  const kebab = toKebabCase3(folder);
@@ -18963,14 +19200,14 @@ description: ${name} shard
18963
19200
  const mode = decl ? decl.kind : folder.startsWith("(Dev Remote)") || folder.startsWith("(Dev)") ? "dev-remote" : folder.startsWith("(Dev Local)") || folder.startsWith("(Local)") ? "dev-local" : "installed";
18964
19201
  const expectedDirs = mode === "installed" ? SHARD_SPEC_DIRS_INSTALLED : SHARD_SPEC_DIRS_SOURCE;
18965
19202
  for (const dir of expectedDirs) {
18966
- const dirPath = join102(shardPath, dir);
19203
+ const dirPath = join122(shardPath, dir);
18967
19204
  if (!await exists2(dirPath)) {
18968
19205
  results.push(withHealthMeta({
18969
19206
  check: `Shards/${folder}/${dir}/`,
18970
19207
  status: "warning",
18971
19208
  message: "Missing shard-spec directory",
18972
19209
  action: async () => {
18973
- await mkdir92(dirPath, { recursive: true });
19210
+ await mkdir10(dirPath, { recursive: true });
18974
19211
  },
18975
19212
  actionLabel: `Create ${dir}/ in ${folder}`
18976
19213
  }, "Structure", folder));
@@ -18979,7 +19216,7 @@ description: ${name} shard
18979
19216
  }
18980
19217
  for (const folder of targetFolders) {
18981
19218
  if (blockingManifestFolders.has(folder)) continue;
18982
- const shardPath = join102(flintPath, "Shards", folder);
19219
+ const shardPath = join122(flintPath, "Shards", folder);
18983
19220
  const manifest = manifests.get(folder) ?? null;
18984
19221
  if (!manifest) continue;
18985
19222
  const shardName = manifest.name;
@@ -18999,16 +19236,16 @@ description: ${name} shard
18999
19236
  }
19000
19237
  for (const folder of targetFolders) {
19001
19238
  if (blockingManifestFolders.has(folder)) continue;
19002
- const shardPath = join102(flintPath, "Shards", folder);
19239
+ const shardPath = join122(flintPath, "Shards", folder);
19003
19240
  const manifest = manifests.get(folder) ?? null;
19004
19241
  if (!manifest?.install?.length) continue;
19005
19242
  const folderEntry = findShardEntry(config, toKebabCase3(folder));
19006
19243
  const mode = folderEntry ? folderEntry.kind : folder.startsWith("(Dev Remote)") || folder.startsWith("(Dev)") ? "dev-remote" : folder.startsWith("(Dev Local)") || folder.startsWith("(Local)") ? "dev-local" : "installed";
19007
19244
  if (mode !== "installed") continue;
19008
19245
  for (const entry of manifest.install) {
19009
- const installedPath = join102(flintPath, entry.dest);
19246
+ const installedPath = join122(flintPath, entry.dest);
19010
19247
  if (!await exists2(installedPath)) continue;
19011
- const content = await readFile62(installedPath, "utf-8");
19248
+ const content = await readFile82(installedPath, "utf-8");
19012
19249
  if (!hasReadonlyTag(content)) {
19013
19250
  results.push(withHealthMeta({
19014
19251
  check: entry.dest,
@@ -19080,7 +19317,7 @@ async function healShard(flintPath, folderName) {
19080
19317
  );
19081
19318
  }
19082
19319
  const results = [];
19083
- const shardPath = join102(flintPath, "Shards", folderName);
19320
+ const shardPath = join122(flintPath, "Shards", folderName);
19084
19321
  const kebab = toKebabCase3(folderName);
19085
19322
  const manifestResult = await readShardManifest(shardPath);
19086
19323
  const manifest = resolveManifestForHealth(
@@ -19101,7 +19338,7 @@ name: ${name}
19101
19338
  shorthand: ${shorthand2}
19102
19339
  description: ${name} shard
19103
19340
  `;
19104
- await writeFile72(join102(shardPath, "shard.yaml"), yaml);
19341
+ await writeFile82(join122(shardPath, "shard.yaml"), yaml);
19105
19342
  },
19106
19343
  actionLabel: `Create shard.yaml`
19107
19344
  });
@@ -19139,9 +19376,9 @@ description: ${name} shard
19139
19376
  }
19140
19377
  }
19141
19378
  if (manifest) {
19142
- const yamlPath = join102(shardPath, "shard.yaml");
19379
+ const yamlPath = join122(shardPath, "shard.yaml");
19143
19380
  try {
19144
- const yamlContent = await readFile62(yamlPath, "utf-8");
19381
+ const yamlContent = await readFile82(yamlPath, "utf-8");
19145
19382
  if (/^state\s*:/m.test(yamlContent)) {
19146
19383
  results.push({
19147
19384
  check: "shard.yaml/state",
@@ -19187,14 +19424,14 @@ description: ${name} shard
19187
19424
  });
19188
19425
  }
19189
19426
  for (const dir of SHARD_SPEC_DIRS_SOURCE) {
19190
- const dirPath = join102(shardPath, dir);
19427
+ const dirPath = join122(shardPath, dir);
19191
19428
  if (!await exists2(dirPath)) {
19192
19429
  results.push({
19193
19430
  check: `${dir}/`,
19194
19431
  status: "warning",
19195
19432
  message: "Missing directory",
19196
19433
  action: async () => {
19197
- await mkdir92(dirPath, { recursive: true });
19434
+ await mkdir10(dirPath, { recursive: true });
19198
19435
  },
19199
19436
  actionLabel: `Create ${dir}/`
19200
19437
  });
@@ -19202,14 +19439,14 @@ description: ${name} shard
19202
19439
  }
19203
19440
  if (manifest?.folders) {
19204
19441
  for (const folder of manifest.folders) {
19205
- const meshPath = join102(flintPath, folder);
19442
+ const meshPath = join122(flintPath, folder);
19206
19443
  if (!await exists2(meshPath)) {
19207
19444
  results.push({
19208
19445
  check: `${folder}`,
19209
19446
  status: "warning",
19210
19447
  message: "Declared Mesh folder missing",
19211
19448
  action: async () => {
19212
- await mkdir92(meshPath, { recursive: true });
19449
+ await mkdir10(meshPath, { recursive: true });
19213
19450
  },
19214
19451
  actionLabel: `Create ${folder}`
19215
19452
  });
@@ -19224,7 +19461,7 @@ description: ${name} shard
19224
19461
  { file: "MIGRATIONS.md", content: (_name) => "" }
19225
19462
  ];
19226
19463
  for (const { file, content } of rootMarkdownChecks) {
19227
- const filePath = join102(shardPath, file);
19464
+ const filePath = join122(shardPath, file);
19228
19465
  if (!await exists2(filePath)) {
19229
19466
  const shardDisplayName = manifest?.name || stripShardFolderPrefix(folderName);
19230
19467
  results.push({
@@ -19232,7 +19469,7 @@ description: ${name} shard
19232
19469
  status: "warning",
19233
19470
  message: `Missing ${file}`,
19234
19471
  action: async () => {
19235
- await writeFile72(filePath, content(shardDisplayName));
19472
+ await writeFile82(filePath, content(shardDisplayName));
19236
19473
  },
19237
19474
  actionLabel: `Create ${file}`
19238
19475
  });
@@ -19245,10 +19482,10 @@ description: ${name} shard
19245
19482
  if (manifest && manifest["shard-spec"] === "0.2.0") {
19246
19483
  const descDirs = ["skills", "workflows", "templates", "knowledge"];
19247
19484
  for (const dir of descDirs) {
19248
- const files = await collectMarkdownRelativePaths(join102(shardPath, dir));
19485
+ const files = await collectMarkdownRelativePaths(join122(shardPath, dir));
19249
19486
  for (const relativeFile of files) {
19250
- const filePath = join102(shardPath, dir, relativeFile);
19251
- const content = await readFile62(filePath, "utf-8");
19487
+ const filePath = join122(shardPath, dir, relativeFile);
19488
+ const content = await readFile82(filePath, "utf-8");
19252
19489
  const parsed = parseFrontmatterRecord(content);
19253
19490
  if (!parsed || !parsed.description || typeof parsed.description !== "string" || !parsed.description.trim()) {
19254
19491
  results.push({
@@ -19289,7 +19526,7 @@ async function getShardInfo(flintPath, identifier) {
19289
19526
  const installed = await getAllShardsWithVersions(flintPath);
19290
19527
  const match2 = resolveInstalledShardInfo(installed, identifier);
19291
19528
  if (match2) {
19292
- const shardPath = join102(flintPath, "Shards", match2.folderName);
19529
+ const shardPath = join122(flintPath, "Shards", match2.folderName);
19293
19530
  const manifestResult = await readShardManifest(shardPath);
19294
19531
  const manifest = resolveManifestForHealth(
19295
19532
  manifestResult?.manifest,
@@ -19305,10 +19542,10 @@ async function getShardInfo(flintPath, identifier) {
19305
19542
  dev: decl ? decl.kind === "dev-remote" : false,
19306
19543
  mode: decl ? decl.kind : "installed",
19307
19544
  folderName: match2.folderName,
19308
- skillCount: await countFiles2(join102(shardPath, "skills")),
19309
- templateCount: await countFiles2(join102(shardPath, "templates")),
19310
- workflowCount: await countFiles2(join102(shardPath, "workflows")),
19311
- knowledgeCount: await countFiles2(join102(shardPath, "knowledge"))
19545
+ skillCount: await countFiles2(join122(shardPath, "skills")),
19546
+ templateCount: await countFiles2(join122(shardPath, "templates")),
19547
+ workflowCount: await countFiles2(join122(shardPath, "workflows")),
19548
+ knowledgeCount: await countFiles2(join122(shardPath, "knowledge"))
19312
19549
  };
19313
19550
  }
19314
19551
  return null;
@@ -19326,13 +19563,13 @@ async function getInstalledShardRuntimeInfo(flintPath, identifier) {
19326
19563
  }
19327
19564
  return {
19328
19565
  folderName: shard.folderName,
19329
- shardPath: join112(flintPath, "Shards", shard.folderName)
19566
+ shardPath: join132(flintPath, "Shards", shard.folderName)
19330
19567
  };
19331
19568
  }
19332
19569
  async function discoverScripts(shardPath) {
19333
- const scriptsDir = join112(shardPath, "scripts");
19570
+ const scriptsDir = join132(shardPath, "scripts");
19334
19571
  try {
19335
- const entries = await readdir62(scriptsDir, { withFileTypes: true });
19572
+ const entries = await readdir72(scriptsDir, { withFileTypes: true });
19336
19573
  const scripts = [];
19337
19574
  for (const entry of entries) {
19338
19575
  if (!entry.isFile() || !entry.name.endsWith(".js")) continue;
@@ -19346,7 +19583,7 @@ async function discoverScripts(shardPath) {
19346
19583
  }
19347
19584
  scripts.push({
19348
19585
  name,
19349
- path: join112(scriptsDir, entry.name)
19586
+ path: join132(scriptsDir, entry.name)
19350
19587
  });
19351
19588
  }
19352
19589
  return scripts;
@@ -19370,12 +19607,12 @@ async function runShardScript(flintPath, shardIdentifier, scriptName, args = [])
19370
19607
  const scriptNames = scripts.map((s) => s.name).join(", ");
19371
19608
  throw new Error(`Script "${scriptName}" not found. Available: ${scriptNames}`);
19372
19609
  }
19373
- const resolvedShardPath = resolve42(shard.shardPath);
19374
- const scriptPath = resolve42(script.path);
19610
+ const resolvedShardPath = resolve5(shard.shardPath);
19611
+ const scriptPath = resolve5(script.path);
19375
19612
  if (!isWithinRoot2(resolvedShardPath, scriptPath)) {
19376
19613
  throw new Error(`Invalid script path outside shard: ${script.path}`);
19377
19614
  }
19378
- const resolvedFlintPath = resolve42(flintPath);
19615
+ const resolvedFlintPath = resolve5(flintPath);
19379
19616
  return new Promise((resolve82, reject) => {
19380
19617
  const child = spawn22("node", [scriptPath, ...args], {
19381
19618
  cwd: resolvedFlintPath,
@@ -19426,7 +19663,7 @@ async function syncFlint(flintPath) {
19426
19663
  await stat62(flintConfigDir);
19427
19664
  } catch {
19428
19665
  try {
19429
- await mkdir10(flintConfigDir, { recursive: true });
19666
+ await mkdir11(flintConfigDir, { recursive: true });
19430
19667
  result.bootstrap.created = true;
19431
19668
  } catch (err) {
19432
19669
  result.errors.push({
@@ -19436,11 +19673,11 @@ async function syncFlint(flintPath) {
19436
19673
  }
19437
19674
  }
19438
19675
  for (const dir of STANDARD_DIRECTORIES) {
19439
- const dirPath = join122(flintPath, dir);
19676
+ const dirPath = join142(flintPath, dir);
19440
19677
  try {
19441
19678
  await stat62(dirPath);
19442
19679
  } catch {
19443
- await mkdir10(dirPath, { recursive: true });
19680
+ await mkdir11(dirPath, { recursive: true });
19444
19681
  result.bootstrap.directories.push(dir);
19445
19682
  }
19446
19683
  }
@@ -19449,7 +19686,7 @@ async function syncFlint(flintPath) {
19449
19686
  if (!config) {
19450
19687
  throw new Error("flint.toml not found. Run flint init first.");
19451
19688
  }
19452
- const obsidianDir = join122(flintPath, ".obsidian");
19689
+ const obsidianDir = join142(flintPath, ".obsidian");
19453
19690
  try {
19454
19691
  await stat62(obsidianDir);
19455
19692
  result.obsidian.existed = true;
@@ -19508,10 +19745,10 @@ async function syncFlint(flintPath) {
19508
19745
  const currentFolderName = basename42(flintPath);
19509
19746
  const expectedFolderName = `(Flint) ${tomlName}`;
19510
19747
  if (currentFolderName !== expectedFolderName) {
19511
- const parentDir = dirname32(flintPath);
19512
- const newPath = join122(parentDir, expectedFolderName);
19748
+ const parentDir = dirname42(flintPath);
19749
+ const newPath = join142(parentDir, expectedFolderName);
19513
19750
  try {
19514
- await rename52(flintPath, newPath);
19751
+ await rename62(flintPath, newPath);
19515
19752
  currentFlintPath = newPath;
19516
19753
  result.registry.oldPath = flintPath;
19517
19754
  result.registry.newPath = newPath;
@@ -19555,9 +19792,9 @@ async function syncFlint(flintPath) {
19555
19792
  console.warn(`Registry sync warning: ${err instanceof Error ? err.message : String(err)}`);
19556
19793
  }
19557
19794
  }
19558
- const inboxDir = join122(currentFlintPath, "Inbox");
19795
+ const inboxDir = join142(currentFlintPath, "Inbox");
19559
19796
  try {
19560
- const inboxEntries = await readdir72(inboxDir);
19797
+ const inboxEntries = await readdir82(inboxDir);
19561
19798
  if (inboxEntries.length === 0) {
19562
19799
  await rm52(inboxDir, { recursive: true });
19563
19800
  }
@@ -19585,134 +19822,6 @@ async function syncFlint(flintPath) {
19585
19822
  }
19586
19823
  return result;
19587
19824
  }
19588
- function getObsidianConfigPath() {
19589
- const p = platform22();
19590
- if (p === "darwin") {
19591
- return join132(homedir32(), "Library", "Application Support", "obsidian", "obsidian.json");
19592
- }
19593
- if (p === "win32") {
19594
- const appData = process.env.APPDATA ?? join132(homedir32(), "AppData", "Roaming");
19595
- return join132(appData, "obsidian", "obsidian.json");
19596
- }
19597
- return join132(homedir32(), ".config", "obsidian", "obsidian.json");
19598
- }
19599
- async function readObsidianConfig(configPath = getObsidianConfigPath()) {
19600
- if (!existsSync3(configPath)) {
19601
- return { vaults: {} };
19602
- }
19603
- const raw = await readFile72(configPath, "utf-8");
19604
- const parsed = JSON.parse(raw);
19605
- return {
19606
- ...parsed,
19607
- vaults: parsed.vaults ?? {}
19608
- };
19609
- }
19610
- async function writeObsidianConfig(config, configPath = getObsidianConfigPath()) {
19611
- await mkdir11(dirname42(configPath), { recursive: true });
19612
- if (existsSync3(configPath)) {
19613
- const current = await readFile72(configPath, "utf-8");
19614
- await writeFile82(`${configPath}.backup`, current, "utf-8");
19615
- }
19616
- const tempPath = `${configPath}.tmp.${process.pid}.${Date.now()}`;
19617
- await writeFile82(tempPath, JSON.stringify(config), "utf-8");
19618
- await rename62(tempPath, configPath);
19619
- }
19620
- function findVaultIdByPath(config, absPath) {
19621
- const target = resolve5(absPath);
19622
- for (const [id, vault] of Object.entries(config.vaults)) {
19623
- if (resolve5(vault.path) === target) return id;
19624
- }
19625
- return null;
19626
- }
19627
- function generateVaultId() {
19628
- return randomBytes2(8).toString("hex");
19629
- }
19630
- async function registerVault(absPath, configPath = getObsidianConfigPath()) {
19631
- const target = resolve5(absPath);
19632
- const config = await readObsidianConfig(configPath);
19633
- const existing = findVaultIdByPath(config, target);
19634
- if (existing) {
19635
- return { id: existing, alreadyRegistered: true };
19636
- }
19637
- const id = generateVaultId();
19638
- config.vaults[id] = { path: target, ts: Date.now() };
19639
- await writeObsidianConfig(config, configPath);
19640
- return { id, alreadyRegistered: false };
19641
- }
19642
- async function readDiscovery(path202 = DISCOVERY_FILE_PATH) {
19643
- if (!existsSync22(path202)) return null;
19644
- try {
19645
- const raw = await readFile82(path202, "utf-8");
19646
- const parsed = JSON.parse(raw);
19647
- if (typeof parsed.port !== "number" || typeof parsed.pid !== "number") return null;
19648
- return parsed;
19649
- } catch {
19650
- return null;
19651
- }
19652
- }
19653
- function isPidAlive(pid) {
19654
- try {
19655
- process.kill(pid, 0);
19656
- return true;
19657
- } catch (err) {
19658
- if (err.code === "EPERM") return true;
19659
- return false;
19660
- }
19661
- }
19662
- async function getLivePlugin(path202 = DISCOVERY_FILE_PATH) {
19663
- const record = await readDiscovery(path202);
19664
- if (!record) return null;
19665
- if (!isPidAlive(record.pid)) return null;
19666
- return record;
19667
- }
19668
- async function postOpenVault(port, absPath, timeoutMs = 2e3) {
19669
- return new Promise((resolvePromise) => {
19670
- const body = JSON.stringify({ path: absPath });
19671
- const req = request(
19672
- {
19673
- hostname: "127.0.0.1",
19674
- port,
19675
- path: "/vault/open",
19676
- method: "POST",
19677
- headers: {
19678
- "Content-Type": "application/json",
19679
- "Content-Length": Buffer.byteLength(body)
19680
- },
19681
- timeout: timeoutMs
19682
- },
19683
- (res) => {
19684
- const chunks = [];
19685
- res.on("data", (chunk) => chunks.push(chunk));
19686
- res.on("end", () => {
19687
- const text = Buffer.concat(chunks).toString("utf-8");
19688
- try {
19689
- const parsed = JSON.parse(text);
19690
- if (parsed.ok === true && typeof parsed.id === "string") {
19691
- resolvePromise({ ok: true, id: parsed.id, registered: Boolean(parsed.registered) });
19692
- return;
19693
- }
19694
- const errorMessage = typeof parsed.error === "string" ? parsed.error : `unexpected response (status ${res.statusCode ?? "unknown"})`;
19695
- resolvePromise({ ok: false, error: errorMessage });
19696
- } catch {
19697
- resolvePromise({ ok: false, error: `invalid JSON response (status ${res.statusCode ?? "unknown"})` });
19698
- }
19699
- });
19700
- res.on("error", (err) => {
19701
- resolvePromise({ ok: false, error: err.message });
19702
- });
19703
- }
19704
- );
19705
- req.on("timeout", () => {
19706
- req.destroy();
19707
- resolvePromise({ ok: false, error: `request timed out after ${timeoutMs}ms` });
19708
- });
19709
- req.on("error", (err) => {
19710
- resolvePromise({ ok: false, error: err.message });
19711
- });
19712
- req.write(body);
19713
- req.end();
19714
- });
19715
- }
19716
19825
  function getBuiltinPresetsDir() {
19717
19826
  return join152(__dirname2, "presets");
19718
19827
  }
@@ -19746,7 +19855,7 @@ async function loadPresetFromDir(presetDir) {
19746
19855
  async function discoverPresetsFromDir(presetsDir) {
19747
19856
  const presets = /* @__PURE__ */ new Map();
19748
19857
  try {
19749
- const entries = await readdir82(presetsDir, { withFileTypes: true });
19858
+ const entries = await readdir92(presetsDir, { withFileTypes: true });
19750
19859
  for (const entry of entries) {
19751
19860
  if (!entry.isDirectory()) continue;
19752
19861
  const presetDir = join152(presetsDir, entry.name);
@@ -19980,7 +20089,7 @@ function parseExportDocument(content, name, sourcePath) {
19980
20089
  }
19981
20090
  async function findFilesRecursively(dir, fileName, matches = []) {
19982
20091
  try {
19983
- const entries = await readdir92(dir, { withFileTypes: true });
20092
+ const entries = await readdir102(dir, { withFileTypes: true });
19984
20093
  entries.sort((a, b) => a.name.localeCompare(b.name));
19985
20094
  for (const entry of entries) {
19986
20095
  const fullPath = join17(dir, entry.name);
@@ -20089,7 +20198,7 @@ async function scanExportEligible(flintPath) {
20089
20198
  }
20090
20199
  async function findExportTaggedFiles(dir, flintPath, declared, results) {
20091
20200
  try {
20092
- const entries = await readdir92(dir, { withFileTypes: true });
20201
+ const entries = await readdir102(dir, { withFileTypes: true });
20093
20202
  for (const entry of entries) {
20094
20203
  const fullPath = join17(dir, entry.name);
20095
20204
  if (entry.isDirectory()) {
@@ -21084,7 +21193,7 @@ function registerAllFeatures() {
21084
21193
  for (const feature of allFeatures) registerFeature(feature);
21085
21194
  registered = true;
21086
21195
  }
21087
- var STANDARD_DIRECTORIES, execAsync3, OBSIDIAN_REPO_URL, OBSIDIAN_WINDOWS_REPO_URL, GLOBAL_CONFIG_FILENAME, execAsync22, DEFAULT_PLATES_ORG, PLATE_SKIP_DIRS, FRONTMATTER_RE, SKIP_DIRS, execFileAsync6, execAsync32, REFERENCES_LOCAL_FILE, FulfillmentSchema, ReferencesLocalSchema, FALLBACK2, execFileAsync22, TINDERBOX_CONFIG_FILENAME, REQUIRED_FLINT_DIRS, TINDERBOX_GITIGNORE_HEADER, TINDERBOX_GITIGNORE_PATTERN, SHARD_SYSTEM_FOLDERS, SHARD_SPEC_DIRS_INSTALLED, SHARD_SPEC_DIRS_SOURCE, OPTIONAL_SHARD_ROOT_DIRS, SHARD_DIRS_ALLOWING_NESTING, ROOT_MARKDOWN_FILES, SHARD_NAME_PATTERN, SHARD_NAME_REGEX, SHARD_SEMVER_REGEX, SHARD_SCRIPT_REGEX, DEV_SHARD_SCRIPT_REGEX, MARKDOWN_FILENAME_LINE_REGEX, MARKDOWN_CODE_FENCE_REGEX, MARKDOWN_COMMENT_REGEX, MARKDOWN_LIFECYCLE_REGEX, SKILL_REFERENCE_REGEX, WORKFLOW_REFERENCE_REGEX, TEMPLATE_REFERENCE_REGEX, KNOWLEDGE_REFERENCE_REGEX, HUMAN_CHECKPOINT_REGEX, TYPE_DEFINITION_PROPERTIES, TEMPLATE_LINK_TARGET_REGEX, VALID_COMMAND_NAME, DISCOVERY_FILE_PATH, __dirname2, presetsCache, PROMPTS_BASE_PATH, IntentFrameSchema, EntityFrameSchema, features, KERNEL_FEATURE_ID, EMPTY_INTENT, EMPTY_ENTITY, IDENTITY_FEATURE_ID, IDENTITY_MARKERS_DIR, identity2, BUNDLE_EXPORTS_FEATURE_ID, BUNDLE_EXPORTS_DIR, BUNDLE_EXPORTS_MARKERS_DIR, BundleExportEntrySchema, bundleExports, CODEBASE_REFERENCES_FEATURE_ID, CODEBASE_REFERENCES_MARKERS_DIR, CodebaseReferenceEntrySchema, codebaseReferences, FLINT_BUNDLE_REFERENCES_FEATURE_ID, FLINT_BUNDLE_REFERENCES_MARKERS_DIR, FlintBundleReferenceEntrySchema, flintBundleReferences, FLINT_REFERENCES_FEATURE_ID, FLINT_REFERENCES_MARKERS_DIR, FlintReferenceEntrySchema, flintReferences, LATTICE_REFERENCES_FEATURE_ID, LATTICE_REFERENCES_MARKERS_DIR, LatticeReferenceEntrySchema, latticeReferences, execFileAsync32, WORKSPACE_REPOS_FEATURE_ID, WORKSPACE_REPOS_DIR, WORKSPACE_REPOS_MARKERS_DIR, WorkspaceRepoEntrySchema, workspaceRepos, NAME, OWNER_REPO, LOCAL_SOURCE, InstalledShardEntrySchema, DevRemoteShardEntrySchema, DevLocalShardEntrySchema, DEV_LOCAL_SHARDS_FEATURE_ID, SHARDS_DIR, REQUIRED_ROOT_FILES, devLocalShards, DEV_REMOTE_SHARDS_FEATURE_ID, SHARDS_DIR2, REQUIRED_ROOT_FILES2, devRemoteShards, INSTALLED_SHARDS_FEATURE_ID, SHARDS_DIR3, installedShards, SHARD_REPOS_FEATURE_ID, SHARDS_DIR4, shardRepos, FLINT_BUNDLES_FEATURE_ID, FLINT_BUNDLES_DIR, FLINT_BUNDLES_MARKERS_DIR, FlintBundleEntrySchema, flintBundles, execFileAsync42, SOURCE_REPOS_FEATURE_ID, SOURCE_REPOS_DIR, SOURCE_REPOS_MARKERS_DIR, SourceRepoEntrySchema, sourceRepos, allFeatures, registered;
21196
+ var STANDARD_DIRECTORIES, execAsync3, OBSIDIAN_REPO_URL, OBSIDIAN_WINDOWS_REPO_URL, GLOBAL_CONFIG_FILENAME, execAsync22, DEFAULT_PLATES_ORG, PLATE_SKIP_DIRS, FRONTMATTER_RE, SKIP_DIRS, execFileAsync6, execAsync32, REFERENCES_LOCAL_FILE, FulfillmentSchema, ReferencesLocalSchema, FALLBACK2, DISCOVERY_DIR, execFileAsync22, TINDERBOX_CONFIG_FILENAME, REQUIRED_FLINT_DIRS, TINDERBOX_GITIGNORE_HEADER, TINDERBOX_GITIGNORE_PATTERN, SHARD_SYSTEM_FOLDERS, SHARD_SPEC_DIRS_INSTALLED, SHARD_SPEC_DIRS_SOURCE, OPTIONAL_SHARD_ROOT_DIRS, SHARD_DIRS_ALLOWING_NESTING, ROOT_MARKDOWN_FILES, SHARD_NAME_PATTERN, SHARD_NAME_REGEX, SHARD_SEMVER_REGEX, SHARD_SCRIPT_REGEX, DEV_SHARD_SCRIPT_REGEX, MARKDOWN_FILENAME_LINE_REGEX, MARKDOWN_CODE_FENCE_REGEX, MARKDOWN_COMMENT_REGEX, MARKDOWN_LIFECYCLE_REGEX, SKILL_REFERENCE_REGEX, WORKFLOW_REFERENCE_REGEX, TEMPLATE_REFERENCE_REGEX, KNOWLEDGE_REFERENCE_REGEX, HUMAN_CHECKPOINT_REGEX, TYPE_DEFINITION_PROPERTIES, TEMPLATE_LINK_TARGET_REGEX, VALID_COMMAND_NAME, __dirname2, presetsCache, PROMPTS_BASE_PATH, IntentFrameSchema, EntityFrameSchema, features, KERNEL_FEATURE_ID, EMPTY_INTENT, EMPTY_ENTITY, IDENTITY_FEATURE_ID, IDENTITY_MARKERS_DIR, identity2, BUNDLE_EXPORTS_FEATURE_ID, BUNDLE_EXPORTS_DIR, BUNDLE_EXPORTS_MARKERS_DIR, BundleExportEntrySchema, bundleExports, CODEBASE_REFERENCES_FEATURE_ID, CODEBASE_REFERENCES_MARKERS_DIR, CodebaseReferenceEntrySchema, codebaseReferences, FLINT_BUNDLE_REFERENCES_FEATURE_ID, FLINT_BUNDLE_REFERENCES_MARKERS_DIR, FlintBundleReferenceEntrySchema, flintBundleReferences, FLINT_REFERENCES_FEATURE_ID, FLINT_REFERENCES_MARKERS_DIR, FlintReferenceEntrySchema, flintReferences, LATTICE_REFERENCES_FEATURE_ID, LATTICE_REFERENCES_MARKERS_DIR, LatticeReferenceEntrySchema, latticeReferences, execFileAsync32, WORKSPACE_REPOS_FEATURE_ID, WORKSPACE_REPOS_DIR, WORKSPACE_REPOS_MARKERS_DIR, WorkspaceRepoEntrySchema, workspaceRepos, NAME, OWNER_REPO, LOCAL_SOURCE, InstalledShardEntrySchema, DevRemoteShardEntrySchema, DevLocalShardEntrySchema, DEV_LOCAL_SHARDS_FEATURE_ID, SHARDS_DIR, REQUIRED_ROOT_FILES, devLocalShards, DEV_REMOTE_SHARDS_FEATURE_ID, SHARDS_DIR2, REQUIRED_ROOT_FILES2, devRemoteShards, INSTALLED_SHARDS_FEATURE_ID, SHARDS_DIR3, installedShards, SHARD_REPOS_FEATURE_ID, SHARDS_DIR4, shardRepos, FLINT_BUNDLES_FEATURE_ID, FLINT_BUNDLES_DIR, FLINT_BUNDLES_MARKERS_DIR, FlintBundleEntrySchema, flintBundles, execFileAsync42, SOURCE_REPOS_FEATURE_ID, SOURCE_REPOS_DIR, SOURCE_REPOS_MARKERS_DIR, SourceRepoEntrySchema, sourceRepos, allFeatures, registered;
21088
21197
  var init_dist4 = __esm({
21089
21198
  "../../packages/flint/dist/index.js"() {
21090
21199
  "use strict";
@@ -21153,6 +21262,7 @@ var init_dist4 = __esm({
21153
21262
  bundles: [],
21154
21263
  lattices: []
21155
21264
  };
21265
+ DISCOVERY_DIR = join102(homedir32(), ".nuucognition", "obsidian-plugins");
21156
21266
  execFileAsync22 = promisify52(execFile22);
21157
21267
  TINDERBOX_CONFIG_FILENAME = "tinderbox.toml";
21158
21268
  REQUIRED_FLINT_DIRS = [
@@ -21203,7 +21313,6 @@ var init_dist4 = __esm({
21203
21313
  TYPE_DEFINITION_PROPERTIES = ["Tag", "Naming", "Location", "Archive", "Lifecycle", "Template"];
21204
21314
  TEMPLATE_LINK_TARGET_REGEX = /\[\[(tmp-[A-Za-z0-9_.-]+)\]\]/g;
21205
21315
  VALID_COMMAND_NAME = /^[a-z0-9][a-z0-9_-]*$/;
21206
- DISCOVERY_FILE_PATH = join142(homedir4(), ".nuu", "obsidian-plugin.json");
21207
21316
  __dirname2 = dirname52(fileURLToPath2(import.meta.url));
21208
21317
  presetsCache = null;
21209
21318
  PROMPTS_BASE_PATH = resolvePromptsBasePath();
@@ -25317,14 +25426,14 @@ var require_emoji_regex2 = __commonJS({
25317
25426
  var require_string_width2 = __commonJS({
25318
25427
  "../../node_modules/.pnpm/string-width@4.2.3/node_modules/string-width/index.js"(exports, module) {
25319
25428
  "use strict";
25320
- var stripAnsi5 = require_strip_ansi2();
25429
+ var stripAnsi6 = require_strip_ansi2();
25321
25430
  var isFullwidthCodePoint2 = require_is_fullwidth_code_point2();
25322
25431
  var emojiRegex2 = require_emoji_regex2();
25323
25432
  var stringWidth3 = (string) => {
25324
25433
  if (typeof string !== "string" || string.length === 0) {
25325
25434
  return 0;
25326
25435
  }
25327
- string = stripAnsi5(string);
25436
+ string = stripAnsi6(string);
25328
25437
  if (string.length === 0) {
25329
25438
  return 0;
25330
25439
  }
@@ -25510,7 +25619,7 @@ var require_utils2 = __commonJS({
25510
25619
  }
25511
25620
  return unwindState(state, ret);
25512
25621
  }
25513
- function truncate5(str, desiredLength, truncateChar) {
25622
+ function truncate6(str, desiredLength, truncateChar) {
25514
25623
  truncateChar = truncateChar || "\u2026";
25515
25624
  let lengthOfStr = strlen(str);
25516
25625
  if (lengthOfStr <= desiredLength) {
@@ -25644,7 +25753,7 @@ var require_utils2 = __commonJS({
25644
25753
  strlen,
25645
25754
  repeat,
25646
25755
  pad: pad3,
25647
- truncate: truncate5,
25756
+ truncate: truncate6,
25648
25757
  mergeOptions,
25649
25758
  wordWrap: multiLineWordWrap,
25650
25759
  colorizeLines,
@@ -27294,7 +27403,7 @@ var require_core2 = __commonJS({
27294
27403
  return match2 && match2.index === 0;
27295
27404
  }
27296
27405
  var BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;
27297
- function join49(regexps, separator = "|") {
27406
+ function join51(regexps, separator = "|") {
27298
27407
  let numCaptures = 0;
27299
27408
  return regexps.map((regex3) => {
27300
27409
  numCaptures += 1;
@@ -27598,7 +27707,7 @@ var require_core2 = __commonJS({
27598
27707
  this.exec = () => null;
27599
27708
  }
27600
27709
  const terminators = this.regexes.map((el) => el[1]);
27601
- this.matcherRe = langRe(join49(terminators), true);
27710
+ this.matcherRe = langRe(join51(terminators), true);
27602
27711
  this.lastIndex = 0;
27603
27712
  }
27604
27713
  /** @param {string} s */
@@ -82706,7 +82815,7 @@ var init_lib = __esm({
82706
82815
  });
82707
82816
 
82708
82817
  // ../../node_modules/.pnpm/environment@1.1.0/node_modules/environment/index.js
82709
- var isBrowser2, isNode2, isBun2, isDeno2, isElectron2, isJsDom2, isWebWorker2, isDedicatedWorker2, isSharedWorker2, isServiceWorker2, platform7, isMacOs2, isWindows3, isLinux2, isIos2, isAndroid2;
82818
+ var isBrowser2, isNode2, isBun2, isDeno2, isElectron2, isJsDom2, isWebWorker2, isDedicatedWorker2, isSharedWorker2, isServiceWorker2, platform6, isMacOs2, isWindows3, isLinux2, isIos2, isAndroid2;
82710
82819
  var init_environment = __esm({
82711
82820
  "../../node_modules/.pnpm/environment@1.1.0/node_modules/environment/index.js"() {
82712
82821
  "use strict";
@@ -82720,12 +82829,12 @@ var init_environment = __esm({
82720
82829
  isDedicatedWorker2 = typeof DedicatedWorkerGlobalScope !== "undefined" && globalThis instanceof DedicatedWorkerGlobalScope;
82721
82830
  isSharedWorker2 = typeof SharedWorkerGlobalScope !== "undefined" && globalThis instanceof SharedWorkerGlobalScope;
82722
82831
  isServiceWorker2 = typeof ServiceWorkerGlobalScope !== "undefined" && globalThis instanceof ServiceWorkerGlobalScope;
82723
- platform7 = globalThis.navigator?.userAgentData?.platform;
82724
- isMacOs2 = platform7 === "macOS" || globalThis.navigator?.platform === "MacIntel" || globalThis.navigator?.userAgent?.includes(" Mac ") === true || globalThis.process?.platform === "darwin";
82725
- isWindows3 = platform7 === "Windows" || globalThis.navigator?.platform === "Win32" || globalThis.process?.platform === "win32";
82726
- isLinux2 = platform7 === "Linux" || globalThis.navigator?.platform?.startsWith("Linux") === true || globalThis.navigator?.userAgent?.includes(" Linux ") === true || globalThis.process?.platform === "linux";
82727
- isIos2 = platform7 === "iOS" || globalThis.navigator?.platform === "MacIntel" && globalThis.navigator?.maxTouchPoints > 1 || /iPad|iPhone|iPod/.test(globalThis.navigator?.platform);
82728
- isAndroid2 = platform7 === "Android" || globalThis.navigator?.platform === "Android" || globalThis.navigator?.userAgent?.includes(" Android ") === true || globalThis.process?.platform === "android";
82832
+ platform6 = globalThis.navigator?.userAgentData?.platform;
82833
+ isMacOs2 = platform6 === "macOS" || globalThis.navigator?.platform === "MacIntel" || globalThis.navigator?.userAgent?.includes(" Mac ") === true || globalThis.process?.platform === "darwin";
82834
+ isWindows3 = platform6 === "Windows" || globalThis.navigator?.platform === "Win32" || globalThis.process?.platform === "win32";
82835
+ isLinux2 = platform6 === "Linux" || globalThis.navigator?.platform?.startsWith("Linux") === true || globalThis.navigator?.userAgent?.includes(" Linux ") === true || globalThis.process?.platform === "linux";
82836
+ isIos2 = platform6 === "iOS" || globalThis.navigator?.platform === "MacIntel" && globalThis.navigator?.maxTouchPoints > 1 || /iPad|iPhone|iPod/.test(globalThis.navigator?.platform);
82837
+ isAndroid2 = platform6 === "Android" || globalThis.navigator?.platform === "Android" || globalThis.navigator?.userAgent?.includes(" Android ") === true || globalThis.process?.platform === "android";
82729
82838
  }
82730
82839
  });
82731
82840
 
@@ -83777,7 +83886,7 @@ var require_brace_expansion = __commonJS({
83777
83886
  // src/index.ts
83778
83887
  import { readFileSync as readFileSync17 } from "fs";
83779
83888
  import { fileURLToPath as fileURLToPath8 } from "url";
83780
- import { dirname as dirname13, join as join48 } from "path";
83889
+ import { dirname as dirname13, join as join50 } from "path";
83781
83890
 
83782
83891
  // ../../../main/packages/cli-core/dist/index.js
83783
83892
  import { createRequire as __createRequire } from "module";
@@ -84858,7 +84967,7 @@ var require_suggestSimilar = __commonJS2({
84858
84967
  var require_command = __commonJS2({
84859
84968
  "../../node_modules/.pnpm/commander@12.1.0/node_modules/commander/lib/command.js"(exports) {
84860
84969
  "use strict";
84861
- var EventEmitter3 = __require2("events").EventEmitter;
84970
+ var EventEmitter4 = __require2("events").EventEmitter;
84862
84971
  var childProcess2 = __require2("child_process");
84863
84972
  var path210 = __require2("path");
84864
84973
  var fs62 = __require2("fs");
@@ -84868,7 +84977,7 @@ var require_command = __commonJS2({
84868
84977
  var { Help: Help2 } = require_help();
84869
84978
  var { Option: Option2, DualOptions } = require_option();
84870
84979
  var { suggestSimilar } = require_suggestSimilar();
84871
- var Command2 = class _Command extends EventEmitter3 {
84980
+ var Command2 = class _Command extends EventEmitter4 {
84872
84981
  /**
84873
84982
  * Initialize a new `Command`.
84874
84983
  *
@@ -87409,7 +87518,7 @@ var require_core = __commonJS2({
87409
87518
  return match2 && match2.index === 0;
87410
87519
  }
87411
87520
  var BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;
87412
- function join49(regexps, separator = "|") {
87521
+ function join410(regexps, separator = "|") {
87413
87522
  let numCaptures = 0;
87414
87523
  return regexps.map((regex22) => {
87415
87524
  numCaptures += 1;
@@ -87713,7 +87822,7 @@ var require_core = __commonJS2({
87713
87822
  this.exec = () => null;
87714
87823
  }
87715
87824
  const terminators = this.regexes.map((el) => el[1]);
87716
- this.matcherRe = langRe(join49(terminators), true);
87825
+ this.matcherRe = langRe(join410(terminators), true);
87717
87826
  this.lastIndex = 0;
87718
87827
  }
87719
87828
  /** @param {string} s */
@@ -146687,7 +146796,7 @@ var require_buffer_list = __commonJS2({
146687
146796
  }
146688
146797
  }, {
146689
146798
  key: "join",
146690
- value: function join49(s) {
146799
+ value: function join410(s) {
146691
146800
  if (this.length === 0) return "";
146692
146801
  var p = this.head;
146693
146802
  var ret = "" + p.data;
@@ -156419,6 +156528,7 @@ var FEATURES = createFeatureRegistry([
156419
156528
  { id: "plan", tier: "prod", type: "command", description: "Show drift between intent and actual state (kernel)", requiresAuth: false },
156420
156529
  { id: "list", tier: "prod", type: "command", description: "List flints and mesh content", requiresAuth: false },
156421
156530
  { id: "sync", tier: "prod", type: "command", description: "Synchronize flint with shards", requiresAuth: false },
156531
+ { id: "gigasync", tier: "prod", type: "command", description: "Chain git sync, obsidian update, shard update, and sync", requiresAuth: false },
156422
156532
  { id: "shard", tier: "prod", type: "command", description: "Shard management", requiresAuth: false },
156423
156533
  { id: "git", tier: "prod", type: "command", description: "Git integration", requiresAuth: false },
156424
156534
  { id: "config", tier: "prod", type: "command", description: "Configuration management", requiresAuth: false },
@@ -156515,14 +156625,12 @@ var PROFILE_MIGRATIONS = [
156515
156625
 
156516
156626
  // src/commands/flint/init.ts
156517
156627
  init_dist4();
156518
- import { execSync as execSync2 } from "child_process";
156519
- import { platform as platform4 } from "os";
156520
156628
  import { resolve as resolve9, join as join19 } from "path";
156521
156629
  import { existsSync as existsSync5 } from "fs";
156522
156630
  import { mkdtemp as mkdtemp3, rm as rm9, rename as rename9 } from "fs/promises";
156523
156631
  import { tmpdir as tmpdir3 } from "os";
156524
- import { exec as exec4 } from "child_process";
156525
- import { promisify as promisify9 } from "util";
156632
+ import { exec as exec5 } from "child_process";
156633
+ import { promisify as promisify10 } from "util";
156526
156634
 
156527
156635
  // src/utils.ts
156528
156636
  import { homedir as homedir5 } from "os";
@@ -156651,22 +156759,77 @@ function formatPayload(payload) {
156651
156759
  return export_pc.dim(parts.join(" "));
156652
156760
  }
156653
156761
 
156654
- // src/commands/flint/init.ts
156762
+ // src/open-flint.ts
156763
+ import { exec as exec4 } from "child_process";
156764
+ import { promisify as promisify9 } from "util";
156765
+ import { platform as platform4 } from "os";
156766
+ init_dist4();
156655
156767
  var execAsync4 = promisify9(exec4);
156656
- function openObsidianVaultChooser() {
156768
+ async function launchObsidianAtPath(path30) {
156657
156769
  const os7 = platform4();
156658
- const uri = "obsidian://choose-vault";
156659
- try {
156660
- if (os7 === "darwin") {
156661
- execSync2(`open "${uri}"`, { stdio: "pipe", windowsHide: true });
156662
- } else if (os7 === "win32") {
156663
- execSync2(`start "" "${uri}"`, { stdio: "pipe", windowsHide: true });
156664
- } else {
156665
- execSync2(`xdg-open "${uri}"`, { stdio: "pipe", windowsHide: true });
156770
+ if (os7 === "darwin") {
156771
+ await execAsync4(`open -a "Obsidian" "${path30}"`);
156772
+ } else if (os7 === "win32") {
156773
+ throw new Error("Cold launch on Windows is disabled \u2014 start Obsidian first so the NUU plugin can route the open request.");
156774
+ } else {
156775
+ try {
156776
+ await execAsync4(`obsidian "${path30}"`);
156777
+ } catch {
156778
+ await execAsync4(`xdg-open "${path30}"`);
156666
156779
  }
156667
- } catch {
156668
156780
  }
156669
156781
  }
156782
+ async function openViaPlugin(absPath, port) {
156783
+ const result = await postOpenVault(port, absPath);
156784
+ if (result.ok) {
156785
+ const action = result.registered ? "registered + switched" : "switched";
156786
+ console.log(export_pc.green(`Plugin running \u2014 ${action} via NUU Obsidian (id: ${result.id})`));
156787
+ return true;
156788
+ }
156789
+ console.log(export_pc.yellow(`Plugin call failed: ${result.error} \u2014 falling back to cold launch.`));
156790
+ return false;
156791
+ }
156792
+ async function coldOpen(absPath, alreadyRegistered) {
156793
+ if (!alreadyRegistered) {
156794
+ const result = await registerVault(absPath);
156795
+ console.log(export_pc.dim(`Cold launch \u2014 registered new vault (id: ${result.id}) and starting Obsidian`));
156796
+ } else {
156797
+ console.log(export_pc.dim("Vault already registered \u2014 launching Obsidian"));
156798
+ }
156799
+ await launchObsidianAtPath(absPath);
156800
+ }
156801
+ async function openFlintAtPath(absPath, options3 = {}) {
156802
+ const config = await readObsidianConfig();
156803
+ const registered2 = findVaultIdByPath(config, absPath) !== null;
156804
+ const plugin = options3.usePlugin === false ? null : await getLivePlugin();
156805
+ if (registered2 && !plugin) {
156806
+ console.log(export_pc.dim(`Vault already registered, opening ${absPath}...`));
156807
+ await launchObsidianAtPath(absPath);
156808
+ console.log(export_pc.green("Opened in Obsidian"));
156809
+ return;
156810
+ }
156811
+ if (registered2 && plugin) {
156812
+ console.log(export_pc.dim(`Vault registered and Obsidian is running \u2014 focusing ${absPath}`));
156813
+ if (platform4() === "win32") {
156814
+ const ok = await openViaPlugin(absPath, plugin.port);
156815
+ if (ok) return;
156816
+ throw new Error("Plugin call failed and cold launch is disabled on Windows.");
156817
+ }
156818
+ await launchObsidianAtPath(absPath);
156819
+ console.log(export_pc.green("Opened in Obsidian"));
156820
+ return;
156821
+ }
156822
+ if (!registered2 && plugin) {
156823
+ const ok = await openViaPlugin(absPath, plugin.port);
156824
+ if (ok) return;
156825
+ await coldOpen(absPath, false);
156826
+ return;
156827
+ }
156828
+ await coldOpen(absPath, false);
156829
+ }
156830
+
156831
+ // src/commands/flint/init.ts
156832
+ var execAsync5 = promisify10(exec5);
156670
156833
  function reportSyncResult(result) {
156671
156834
  if (result.obsidian.cloned) {
156672
156835
  console.log();
@@ -156691,7 +156854,7 @@ Cloning ${export_pc.cyan(url)}...
156691
156854
  `);
156692
156855
  tempDir = await mkdtemp3(join19(tmpdir3(), "flint-clone-"));
156693
156856
  try {
156694
- await execAsync4(`git clone "${url}" "${tempDir}"`, { timeout: 12e4, windowsHide: true });
156857
+ await execAsync5(`git clone "${url}" "${tempDir}"`, { timeout: 12e4, windowsHide: true });
156695
156858
  } catch (err) {
156696
156859
  const message = err instanceof Error ? err.message : String(err);
156697
156860
  throw new Error(`Git clone failed: ${message}`);
@@ -156829,8 +156992,7 @@ Creating flint: ${export_pc.bold(name)}
156829
156992
  printResult(kernelResult, true);
156830
156993
  }
156831
156994
  if (result.obsidian.cloned) {
156832
- console.log(export_pc.dim("\nOpening Obsidian vault chooser..."));
156833
- openObsidianVaultChooser();
156995
+ await openFlintAtPath(entry.path);
156834
156996
  }
156835
156997
  console.log();
156836
156998
  } catch (err) {
@@ -157138,72 +157300,6 @@ function printScopeLine(label, pending) {
157138
157300
  // src/commands/flint/open.ts
157139
157301
  init_dist4();
157140
157302
  import { resolve as resolve10 } from "path";
157141
-
157142
- // src/open-flint.ts
157143
- import { exec as exec5 } from "child_process";
157144
- import { promisify as promisify10 } from "util";
157145
- import { platform as platform5 } from "os";
157146
- init_dist4();
157147
- var execAsync5 = promisify10(exec5);
157148
- async function launchObsidianAtPath(path30) {
157149
- const os7 = platform5();
157150
- if (os7 === "darwin") {
157151
- await execAsync5(`open -a "Obsidian" "${path30}"`);
157152
- } else if (os7 === "win32") {
157153
- await execAsync5(`start "" "${path30}"`);
157154
- } else {
157155
- try {
157156
- await execAsync5(`obsidian "${path30}"`);
157157
- } catch {
157158
- await execAsync5(`xdg-open "${path30}"`);
157159
- }
157160
- }
157161
- }
157162
- async function openViaPlugin(absPath, port) {
157163
- const result = await postOpenVault(port, absPath);
157164
- if (result.ok) {
157165
- const action = result.registered ? "registered + switched" : "switched";
157166
- console.log(export_pc.green(`Plugin running \u2014 ${action} via NUU Obsidian (id: ${result.id})`));
157167
- return true;
157168
- }
157169
- console.log(export_pc.yellow(`Plugin call failed: ${result.error} \u2014 falling back to cold launch.`));
157170
- return false;
157171
- }
157172
- async function coldOpen(absPath, alreadyRegistered) {
157173
- if (!alreadyRegistered) {
157174
- const result = await registerVault(absPath);
157175
- console.log(export_pc.dim(`Cold launch \u2014 registered new vault (id: ${result.id}) and starting Obsidian`));
157176
- } else {
157177
- console.log(export_pc.dim("Vault already registered \u2014 launching Obsidian"));
157178
- }
157179
- await launchObsidianAtPath(absPath);
157180
- }
157181
- async function openFlintAtPath(absPath, options3 = {}) {
157182
- const config = await readObsidianConfig();
157183
- const registered2 = findVaultIdByPath(config, absPath) !== null;
157184
- const plugin = options3.usePlugin === false ? null : await getLivePlugin();
157185
- if (registered2 && !plugin) {
157186
- console.log(export_pc.dim(`Vault already registered, opening ${absPath}...`));
157187
- await launchObsidianAtPath(absPath);
157188
- console.log(export_pc.green("Opened in Obsidian"));
157189
- return;
157190
- }
157191
- if (registered2 && plugin) {
157192
- console.log(export_pc.dim(`Vault registered and Obsidian is running \u2014 focusing ${absPath}`));
157193
- await launchObsidianAtPath(absPath);
157194
- console.log(export_pc.green("Opened in Obsidian"));
157195
- return;
157196
- }
157197
- if (!registered2 && plugin) {
157198
- const ok = await openViaPlugin(absPath, plugin.port);
157199
- if (ok) return;
157200
- await coldOpen(absPath, false);
157201
- return;
157202
- }
157203
- await coldOpen(absPath, false);
157204
- }
157205
-
157206
- // src/commands/flint/open.ts
157207
157303
  async function resolveFlintPath(flintName) {
157208
157304
  if (flintName) {
157209
157305
  const flints = await getFlintRegistry();
@@ -157590,6 +157686,221 @@ var syncCommand = new Command("sync").description("Sync shards from flint.toml")
157590
157686
  }
157591
157687
  });
157592
157688
 
157689
+ // src/commands/flint/gigasync.ts
157690
+ import { spawn as spawn4, execSync as execSync2 } from "child_process";
157691
+ import { setTimeout as sleep } from "timers/promises";
157692
+ import { join as join26 } from "path";
157693
+ init_dist4();
157694
+ function obsidianHead(flintPath) {
157695
+ try {
157696
+ return execSync2("git rev-parse HEAD", {
157697
+ cwd: join26(flintPath, ".obsidian"),
157698
+ encoding: "utf-8",
157699
+ stdio: ["ignore", "pipe", "ignore"],
157700
+ windowsHide: true
157701
+ }).trim();
157702
+ } catch {
157703
+ return null;
157704
+ }
157705
+ }
157706
+ var STEPS = [
157707
+ {
157708
+ label: "flint git sync",
157709
+ args: ["git", "sync"],
157710
+ icon: "\u2387",
157711
+ skipIf: async (flintPath) => await isGitInitialized(flintPath) ? null : "git not initialized in this Flint"
157712
+ },
157713
+ {
157714
+ label: "flint obsidian update",
157715
+ args: ["obsidian", "update", "--no-reload"],
157716
+ icon: "\u25C6",
157717
+ before: async (flintPath) => obsidianHead(flintPath),
157718
+ afterNote: async (flintPath, before) => {
157719
+ const after = obsidianHead(flintPath);
157720
+ if (before && after && before !== after) return "reload obsidian to apply";
157721
+ return null;
157722
+ }
157723
+ },
157724
+ { label: "flint shard update", args: ["shard", "update"], icon: "\u2726" },
157725
+ { label: "flint sync", args: ["sync"], icon: "\u21BB" }
157726
+ ];
157727
+ var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
157728
+ var BAR_WIDTH = 32;
157729
+ var ANSI_RE = /\x1b\[[0-9;]*[A-Za-z]/g;
157730
+ function stripAnsi3(s) {
157731
+ return s.replace(ANSI_RE, "");
157732
+ }
157733
+ function truncate3(s, max) {
157734
+ const plain = stripAnsi3(s);
157735
+ if (plain.length <= max) return plain;
157736
+ return plain.slice(0, max - 1) + "\u2026";
157737
+ }
157738
+ function buildBar(completed, total, active) {
157739
+ const ratio = (completed + (active ? 0.5 : 0)) / total;
157740
+ const filled = Math.min(BAR_WIDTH, Math.round(ratio * BAR_WIDTH));
157741
+ const head = active && filled < BAR_WIDTH ? 1 : 0;
157742
+ const full = export_pc.green("\u2588".repeat(Math.max(0, filled - head)));
157743
+ const tip = head ? export_pc.cyan("\u258C") : "";
157744
+ const empty = export_pc.dim("\u2591".repeat(BAR_WIDTH - filled));
157745
+ const pct = `${Math.round(ratio * 100)}%`.padStart(4);
157746
+ return `${full}${tip}${empty} ${export_pc.bold(pct)} ${export_pc.dim(`${completed}/${total}`)}`;
157747
+ }
157748
+ var LiveRender = class {
157749
+ linesPrinted = 0;
157750
+ cursorHidden = false;
157751
+ start() {
157752
+ if (process.stdout.isTTY) {
157753
+ process.stdout.write("\x1B[?25l");
157754
+ this.cursorHidden = true;
157755
+ }
157756
+ }
157757
+ stop() {
157758
+ if (this.cursorHidden) {
157759
+ process.stdout.write("\x1B[?25h");
157760
+ this.cursorHidden = false;
157761
+ }
157762
+ }
157763
+ /** Replace the live block in place. */
157764
+ render(lines) {
157765
+ if (!process.stdout.isTTY) {
157766
+ for (const line of lines) process.stdout.write(line + "\n");
157767
+ return;
157768
+ }
157769
+ if (this.linesPrinted > 0) {
157770
+ process.stdout.write(`\x1B[${this.linesPrinted}A\r\x1B[J`);
157771
+ }
157772
+ process.stdout.write(lines.join("\n") + "\n");
157773
+ this.linesPrinted = lines.length;
157774
+ }
157775
+ /** Commit the live block as permanent output and start fresh. */
157776
+ commit(lines) {
157777
+ if (process.stdout.isTTY && this.linesPrinted > 0) {
157778
+ process.stdout.write(`\x1B[${this.linesPrinted}A\r\x1B[J`);
157779
+ }
157780
+ for (const line of lines) process.stdout.write(line + "\n");
157781
+ this.linesPrinted = 0;
157782
+ }
157783
+ };
157784
+ async function runStep(entry, step2, index, total, live) {
157785
+ const cols = Math.max(40, process.stdout.columns ?? 80);
157786
+ const tailMax = Math.max(20, cols - 6);
157787
+ return new Promise((resolve19) => {
157788
+ const child = spawn4(process.execPath, [entry, ...step2.args], {
157789
+ stdio: ["ignore", "pipe", "pipe"],
157790
+ windowsHide: true
157791
+ });
157792
+ const captured = [];
157793
+ let tail = export_pc.dim("starting\u2026");
157794
+ let frame = 0;
157795
+ let done = false;
157796
+ const handleChunk = (buf) => {
157797
+ const text = buf.toString("utf8");
157798
+ captured.push(text);
157799
+ const lines = text.split(/\r?\n/);
157800
+ for (let i = lines.length - 1; i >= 0; i--) {
157801
+ const cleaned = stripAnsi3(lines[i]).trim();
157802
+ if (cleaned.length > 0) {
157803
+ tail = export_pc.dim(truncate3(cleaned, tailMax));
157804
+ break;
157805
+ }
157806
+ }
157807
+ };
157808
+ child.stdout.on("data", handleChunk);
157809
+ child.stderr.on("data", handleChunk);
157810
+ const draw = () => {
157811
+ const spin = export_pc.cyan(SPINNER_FRAMES[frame % SPINNER_FRAMES.length]);
157812
+ const bar = buildBar(index, total, true);
157813
+ const header = ` ${spin} ${export_pc.cyan(step2.icon)} ${export_pc.bold(step2.label)} ${export_pc.dim(`[${index + 1}/${total}]`)}`;
157814
+ live.render([
157815
+ ` ${bar}`,
157816
+ header,
157817
+ ` ${tail}`
157818
+ ]);
157819
+ frame++;
157820
+ };
157821
+ draw();
157822
+ const ticker = setInterval(() => {
157823
+ if (!done) draw();
157824
+ }, 80);
157825
+ child.on("close", (code) => {
157826
+ done = true;
157827
+ clearInterval(ticker);
157828
+ resolve19({ code: code ?? 1, tail: captured });
157829
+ });
157830
+ });
157831
+ }
157832
+ var gigasyncCommand = new Command("gigasync").description("Chain git sync \u2192 obsidian update \u2192 shard update \u2192 sync (stops on first failure)").addHelpText("after", `
157833
+ Runs in order:
157834
+ 1. flint git sync (skipped if no git repo)
157835
+ 2. flint obsidian update
157836
+ 3. flint shard update
157837
+ 4. flint sync
157838
+
157839
+ If any step exits non-zero, Gigasync stops and exits with that code.
157840
+ `).action(async () => {
157841
+ const entry = process.argv[1];
157842
+ if (!entry) {
157843
+ console.error(export_pc.red("Error: Could not resolve flint entry script (process.argv[1] missing)."));
157844
+ process.exit(1);
157845
+ }
157846
+ const flintPath = await findFlintRoot(process.cwd());
157847
+ if (!flintPath) {
157848
+ console.error(export_pc.red("Error: Not inside a Flint. cd into a Flint and retry."));
157849
+ process.exit(1);
157850
+ }
157851
+ const live = new LiveRender();
157852
+ live.start();
157853
+ const cleanup = () => live.stop();
157854
+ process.on("SIGINT", () => {
157855
+ cleanup();
157856
+ process.exit(130);
157857
+ });
157858
+ process.on("exit", cleanup);
157859
+ const completed = [];
157860
+ for (let i = 0; i < STEPS.length; i++) {
157861
+ const step2 = STEPS[i];
157862
+ if (step2.skipIf) {
157863
+ const reason = await step2.skipIf(flintPath);
157864
+ if (reason) {
157865
+ completed.push(` ${export_pc.yellow("\u2298")} ${export_pc.cyan(step2.icon)} ${step2.label} ${export_pc.dim(`\u2014 skipped (${reason})`)}`);
157866
+ live.render([
157867
+ ` ${buildBar(i + 1, STEPS.length, false)}`,
157868
+ ...completed
157869
+ ]);
157870
+ await sleep(120);
157871
+ continue;
157872
+ }
157873
+ }
157874
+ const beforeState = step2.before ? await step2.before(flintPath) : void 0;
157875
+ const { code, tail } = await runStep(entry, step2, i, STEPS.length, live);
157876
+ if (code !== 0) {
157877
+ live.commit([
157878
+ ` ${buildBar(i, STEPS.length, false)}`,
157879
+ ...completed,
157880
+ ` ${export_pc.red("\u2717")} ${export_pc.cyan(step2.icon)} ${export_pc.bold(step2.label)} ${export_pc.red(`\u2014 exited ${code}`)}`,
157881
+ export_pc.dim(" \u2500\u2500 output \u2500\u2500")
157882
+ ]);
157883
+ process.stdout.write(tail.join(""));
157884
+ if (!tail.join("").endsWith("\n")) process.stdout.write("\n");
157885
+ live.stop();
157886
+ process.exit(code);
157887
+ }
157888
+ const note = step2.afterNote ? await step2.afterNote(flintPath, beforeState) : null;
157889
+ const noteSuffix = note ? ` ${export_pc.yellow(`(${note})`)}` : "";
157890
+ completed.push(` ${export_pc.green("\u2713")} ${export_pc.cyan(step2.icon)} ${step2.label}${noteSuffix}`);
157891
+ live.render([
157892
+ ` ${buildBar(i + 1, STEPS.length, false)}`,
157893
+ ...completed
157894
+ ]);
157895
+ }
157896
+ live.commit([
157897
+ ` ${buildBar(STEPS.length, STEPS.length, false)}`,
157898
+ ...completed,
157899
+ export_pc.bold(export_pc.green(" \u2713 Gigasync complete."))
157900
+ ]);
157901
+ live.stop();
157902
+ });
157903
+
157593
157904
  // src/commands/flint/registry.ts
157594
157905
  init_dist4();
157595
157906
  async function validateEntries(entries) {
@@ -157711,14 +158022,14 @@ var registryCommand = new Command("registry").description("Validate the global f
157711
158022
 
157712
158023
  // src/commands/flint/update.ts
157713
158024
  import { readFileSync as readFileSync4, existsSync as existsSync6 } from "fs";
157714
- import { dirname as dirname10, join as join26 } from "path";
158025
+ import { dirname as dirname10, join as join27 } from "path";
157715
158026
  import { fileURLToPath as fileURLToPath4 } from "url";
157716
158027
  import { execSync as execSync3 } from "child_process";
157717
158028
  import https from "https";
157718
158029
  var __dirname4 = dirname10(fileURLToPath4(import.meta.url));
157719
158030
  function readPkgVersion() {
157720
158031
  for (const rel of ["../..", ".."]) {
157721
- const p = join26(__dirname4, rel, "package.json");
158032
+ const p = join27(__dirname4, rel, "package.json");
157722
158033
  if (existsSync6(p)) {
157723
158034
  return JSON.parse(readFileSync4(p, "utf-8")).version;
157724
158035
  }
@@ -157793,7 +158104,7 @@ var updateCommand = new Command("update").description("Update flint-cli to the l
157793
158104
 
157794
158105
  // src/commands/workspace/workspace.ts
157795
158106
  init_dist4();
157796
- import { join as join27 } from "path";
158107
+ import { join as join28 } from "path";
157797
158108
  import * as readline from "readline";
157798
158109
  async function prompt2(question) {
157799
158110
  const rl = readline.createInterface({
@@ -157824,7 +158135,7 @@ var workspaceCommand = new Command("workspace").description("Manage workspace re
157824
158135
  Creating repository ${name}...`));
157825
158136
  await addWorkspaceRepository(flintPath, name, remote);
157826
158137
  await updateGitignore(flintPath);
157827
- const repoPath = join27(flintPath, "Workspace", "Repos", name);
158138
+ const repoPath = join28(flintPath, "Workspace", "Repos", name);
157828
158139
  console.log(export_pc.green(`
157829
158140
  Created repository: ${export_pc.bold(name)}`));
157830
158141
  console.log(export_pc.dim(` Remote: ${remote}`));
@@ -157889,7 +158200,7 @@ Cloned repository: ${export_pc.bold(name)}`));
157889
158200
  }
157890
158201
  await removeWorkspaceRepository(flintPath, name);
157891
158202
  await updateGitignore(flintPath);
157892
- const localStatePath = join27(flintPath, "Workspace", "Repos", name);
158203
+ const localStatePath = join28(flintPath, "Workspace", "Repos", name);
157893
158204
  console.log(export_pc.green(`
157894
158205
  Removed repository: ${export_pc.bold(name)}`));
157895
158206
  console.log(export_pc.dim(" \u2192 Removed from flint.toml"));
@@ -157976,7 +158287,7 @@ Updated repository: ${export_pc.bold(name)}`));
157976
158287
  // src/commands/sources/source.ts
157977
158288
  init_dist4();
157978
158289
  import { stat as stat13 } from "fs/promises";
157979
- import { join as join28, basename as basename6 } from "path";
158290
+ import { join as join29, basename as basename6 } from "path";
157980
158291
  import { rm as rm11, readdir as readdir14, mkdir as mkdir15, copyFile as copyFile3 } from "fs/promises";
157981
158292
  import * as readline2 from "readline";
157982
158293
  async function prompt3(question) {
@@ -158009,7 +158320,7 @@ repoCommand.addCommand(
158009
158320
  Cloning ${url} (reference copy)...`));
158010
158321
  await addSourceRepository(flintPath, name, url);
158011
158322
  await updateGitignore(flintPath);
158012
- const repoPath = join28(flintPath, "Sources", "Repos", name);
158323
+ const repoPath = join29(flintPath, "Sources", "Repos", name);
158013
158324
  console.log(export_pc.green(`
158014
158325
  Added source repository: ${export_pc.bold(name)}`));
158015
158326
  console.log(export_pc.dim(` URL: ${url}`));
@@ -158045,7 +158356,7 @@ repoCommand.addCommand(
158045
158356
  }
158046
158357
  await removeSourceRepository(flintPath, name);
158047
158358
  await updateGitignore(flintPath);
158048
- const localStatePath = join28(flintPath, "Sources", "Repos", name);
158359
+ const localStatePath = join29(flintPath, "Sources", "Repos", name);
158049
158360
  console.log(export_pc.green(`
158050
158361
  Removed source repository: ${export_pc.bold(name)}`));
158051
158362
  console.log(export_pc.dim(" \u2192 Removed from flint.toml"));
@@ -158244,14 +158555,14 @@ meshexportCommand.addCommand(
158244
158555
  }
158245
158556
  const { flintName, exportName } = parsed;
158246
158557
  console.log();
158247
- const sourceDir = join28(flintPath, "Sources", "Flints", `(Flint) ${flintName}`, `(Mesh Export) ${exportName}`);
158558
+ const sourceDir = join29(flintPath, "Sources", "Flints", `(Flint) ${flintName}`, `(Mesh Export) ${exportName}`);
158248
158559
  const removed = await removeSourceBundleFromConfig(flintPath, { source: "flint", name: ref });
158249
158560
  if (!removed) {
158250
158561
  console.error(export_pc.red(`Error: "${ref}" not found in flint.toml [sources].bundles.`));
158251
158562
  process.exit(1);
158252
158563
  }
158253
158564
  console.log(`${export_pc.green("\u2713")} Removed from flint.toml`);
158254
- const parentDir = join28(flintPath, "Sources", "Flints", `(Flint) ${flintName}`);
158565
+ const parentDir = join29(flintPath, "Sources", "Flints", `(Flint) ${flintName}`);
158255
158566
  try {
158256
158567
  const remaining = await readdir14(parentDir);
158257
158568
  if (remaining.length === 0) {
@@ -158659,7 +158970,7 @@ init_dist4();
158659
158970
  import fs16 from "fs";
158660
158971
  import path20 from "path";
158661
158972
  import crypto2 from "crypto";
158662
- import { spawn as spawn4 } from "child_process";
158973
+ import { spawn as spawn5 } from "child_process";
158663
158974
  function getRegistryPath() {
158664
158975
  return path20.join(getConfigDir("lattice"), "registry.json");
158665
158976
  }
@@ -158891,7 +159202,7 @@ var latticeCommand = new Command("lattice").description("Manage lattice connecti
158891
159202
  const entryPoint = path20.join(entry.path, entryFile);
158892
159203
  const cmd = entry.lang === "python" ? "uv" : "node";
158893
159204
  const cmdArgs = entry.lang === "python" ? ["run", "python", entryPoint, fn, ...args] : [entryPoint, fn, ...args];
158894
- const child = spawn4(cmd, cmdArgs, {
159205
+ const child = spawn5(cmd, cmdArgs, {
158895
159206
  cwd: entry.path,
158896
159207
  env: { ...process.env, ...envLocal },
158897
159208
  stdio: "inherit",
@@ -159020,7 +159331,7 @@ var latticeCommand = new Command("lattice").description("Manage lattice connecti
159020
159331
  // src/commands/outputs/export.ts
159021
159332
  init_dist4();
159022
159333
  import { readFile as readFile13, stat as stat15 } from "fs/promises";
159023
- import { join as join29, basename as basename7 } from "path";
159334
+ import { join as join30, basename as basename7 } from "path";
159024
159335
  import { createInterface as createInterface5 } from "readline";
159025
159336
  async function exists3(path30) {
159026
159337
  try {
@@ -159060,8 +159371,8 @@ async function getExportStatus(flintPath) {
159060
159371
  const declarations = await getExportDeclarations(flintPath);
159061
159372
  const results = [];
159062
159373
  for (const manifest of manifests) {
159063
- const outputDir = join29(flintPath, "Exports", `(Mesh Export) ${manifest.name}`);
159064
- const manifestJsonPath = join29(outputDir, "_manifest.json");
159374
+ const outputDir = join30(flintPath, "Exports", `(Mesh Export) ${manifest.name}`);
159375
+ const manifestJsonPath = join30(outputDir, "_manifest.json");
159065
159376
  const isBuilt = await exists3(manifestJsonPath);
159066
159377
  let fileCount = 0;
159067
159378
  if (isBuilt) {
@@ -159304,7 +159615,7 @@ var exportCommand = new Command("export").description("Manage exports").addComma
159304
159615
  init_dist4();
159305
159616
  import { randomUUID as randomUUID6 } from "crypto";
159306
159617
  import { copyFile as copyFile4, mkdir as mkdir16, writeFile as writeFile12, unlink as unlink3, stat as stat16 } from "fs/promises";
159307
- import { join as join30, basename as basename8, resolve as resolve17 } from "path";
159618
+ import { join as join31, basename as basename8, resolve as resolve17 } from "path";
159308
159619
  async function exists4(path30) {
159309
159620
  try {
159310
159621
  await stat16(path30);
@@ -159373,7 +159684,7 @@ var sendCommand = new Command("send").description("Send files to another Flint's
159373
159684
  process.exit(1);
159374
159685
  }
159375
159686
  const bundleDirName = `(Bundle) ${title}`;
159376
- const bundleDir = join30(targetPath, "Inbox", bundleDirName);
159687
+ const bundleDir = join31(targetPath, "Inbox", bundleDirName);
159377
159688
  if (await exists4(bundleDir)) {
159378
159689
  console.error(export_pc.red(`Error: Bundle "${title}" already exists in target inbox.`));
159379
159690
  process.exit(1);
@@ -159392,7 +159703,7 @@ var sendCommand = new Command("send").description("Send files to another Flint's
159392
159703
  } catch {
159393
159704
  }
159394
159705
  const bundleNoteFileName = `(Inbox) ${bundleDirName}.md`;
159395
- const bundleNotePath = join30(bundleDir, bundleNoteFileName);
159706
+ const bundleNotePath = join31(bundleDir, bundleNoteFileName);
159396
159707
  const moveList = moveFiles.length > 0 ? moveFiles.map((f) => ` - "${f.fileName}"`).join("\n") : "";
159397
159708
  const copyList = copyFiles.length > 0 ? copyFiles.map((f) => ` - "${f.fileName}"`).join("\n") : "";
159398
159709
  let frontmatter = `---
@@ -159421,7 +159732,7 @@ ${instructions}
159421
159732
  console.log(` ${export_pc.green("+")} ${bundleNoteFileName}`);
159422
159733
  for (const file of allFiles) {
159423
159734
  const destFileName = `(Inbox) ${bundleDirName} . ${file.fileName}`;
159424
- const destPath = join30(bundleDir, destFileName);
159735
+ const destPath = join31(bundleDir, destFileName);
159425
159736
  await copyFile4(file.sourcePath, destPath);
159426
159737
  const isCopy = copyFiles.includes(file);
159427
159738
  const label = isCopy ? export_pc.dim(" (copy)") : "";
@@ -159457,8 +159768,8 @@ ${instructions}
159457
159768
 
159458
159769
  // src/commands/config/shard.ts
159459
159770
  init_dist2();
159460
- import { spawn as spawn5 } from "child_process";
159461
- import { join as join31 } from "path";
159771
+ import { spawn as spawn6 } from "child_process";
159772
+ import { join as join35 } from "path";
159462
159773
  import { existsSync as existsSync7 } from "fs";
159463
159774
  import { readFile as readFile14 } from "fs/promises";
159464
159775
  init_dist4();
@@ -159617,7 +159928,7 @@ Shard not found: "${shorthand}"`));
159617
159928
  if (counts.length > 0) {
159618
159929
  console.log(` Contents ${counts.join(", ")}`);
159619
159930
  }
159620
- const shardPath = join31(flintPath, "Shards", detail2.folderName);
159931
+ const shardPath = join35(flintPath, "Shards", detail2.folderName);
159621
159932
  const manifestResult = await readShardManifest(shardPath);
159622
159933
  const manifest = manifestResult?.manifest;
159623
159934
  if (manifest?.dependencies?.length) {
@@ -159659,12 +159970,12 @@ Shard not found: "${shorthand}"`));
159659
159970
  return;
159660
159971
  }
159661
159972
  if (action === "pull") {
159662
- const { execSync: execSync6 } = await import("child_process");
159973
+ const { execSync: execSync5 } = await import("child_process");
159663
159974
  const resolved = await resolveDevShard(flintPath, shorthand);
159664
159975
  if (!resolved) process.exit(1);
159665
159976
  const { info: match2 } = resolved;
159666
- const shardPath = join31(flintPath, "Shards", match2.folderName);
159667
- const gitDir = join31(shardPath, ".git");
159977
+ const shardPath = join35(flintPath, "Shards", match2.folderName);
159978
+ const gitDir = join35(shardPath, ".git");
159668
159979
  if (!existsSync7(gitDir)) {
159669
159980
  console.error(export_pc.red(`
159670
159981
  "${match2.folderName}" has no git repo.`));
@@ -159676,7 +159987,7 @@ Shard not found: "${shorthand}"`));
159676
159987
  Pulling ${match2.folderName}...
159677
159988
  `));
159678
159989
  try {
159679
- execSync6("git pull", { cwd: shardPath, stdio: "inherit" });
159990
+ execSync5("git pull", { cwd: shardPath, stdio: "inherit" });
159680
159991
  console.log(export_pc.green(`
159681
159992
  \u2713 Pulled ${match2.folderName}`));
159682
159993
  } catch {
@@ -159714,7 +160025,7 @@ Pulling ${match2.folderName}...
159714
160025
  Shard not found: "${shorthand}"`));
159715
160026
  process.exit(1);
159716
160027
  }
159717
- const shardDir = join31(flintPath, "Shards", detail2.folderName);
160028
+ const shardDir = join35(flintPath, "Shards", detail2.folderName);
159718
160029
  if (!existsSync7(shardDir)) {
159719
160030
  console.error(export_pc.red(`
159720
160031
  Shard not installed: "${shorthand}"`));
@@ -159725,7 +160036,7 @@ Shard not installed: "${shorthand}"`));
159725
160036
  const execIdx = rawArgs.indexOf("exec");
159726
160037
  const execArgs = execIdx >= 0 ? rawArgs.slice(execIdx + 1) : [];
159727
160038
  const fullCmd = execArgs.join(" ");
159728
- const child = spawn5(fullCmd, [], {
160039
+ const child = spawn6(fullCmd, [], {
159729
160040
  cwd: shardDir,
159730
160041
  stdio: "inherit",
159731
160042
  shell: true,
@@ -160392,7 +160703,7 @@ Created ${export_pc.bold(result.name)}`));
160392
160703
  ).addCommand(
160393
160704
  new Command("dev").description("Promote a Dev Local shard to Dev Remote \u2014 git init, set remote, commit, push").argument("<name>", "Shard name (e.g. reports, living-documents)").argument("<url>", "Git remote URL (e.g., https://github.com/org/repo.git)").option("-p, --path <dir>", "Path to flint").action(async (name, url, options3) => {
160394
160705
  try {
160395
- const { execSync: execSync6 } = await import("child_process");
160706
+ const { execSync: execSync5 } = await import("child_process");
160396
160707
  const { rename: rename11 } = await import("fs/promises");
160397
160708
  const flintPath = await resolveFlint(options3.path);
160398
160709
  const resolved = await resolveDevShard(flintPath, name);
@@ -160417,19 +160728,19 @@ Invalid GitHub remote: "${url}"`));
160417
160728
  console.log();
160418
160729
  return;
160419
160730
  }
160420
- const shardPath = join31(flintPath, "Shards", match2.folderName);
160731
+ const shardPath = join35(flintPath, "Shards", match2.folderName);
160421
160732
  console.log(export_pc.bold(`
160422
160733
  Promoting ${match2.folderName} to Dev Remote...
160423
160734
  `));
160424
- execSync6("git init", { cwd: shardPath, stdio: "pipe" });
160425
- execSync6(`git remote add origin "${url}"`, { cwd: shardPath, stdio: "pipe" });
160426
- execSync6("git branch -M main", { cwd: shardPath, stdio: "pipe" });
160427
- execSync6("git add -A", { cwd: shardPath, stdio: "pipe" });
160428
- execSync6('git commit -m "initial commit"', { cwd: shardPath, stdio: "pipe" });
160429
- execSync6("git push -u origin main", { cwd: shardPath, stdio: "inherit" });
160735
+ execSync5("git init", { cwd: shardPath, stdio: "pipe" });
160736
+ execSync5(`git remote add origin "${url}"`, { cwd: shardPath, stdio: "pipe" });
160737
+ execSync5("git branch -M main", { cwd: shardPath, stdio: "pipe" });
160738
+ execSync5("git add -A", { cwd: shardPath, stdio: "pipe" });
160739
+ execSync5('git commit -m "initial commit"', { cwd: shardPath, stdio: "pipe" });
160740
+ execSync5("git push -u origin main", { cwd: shardPath, stdio: "inherit" });
160430
160741
  const baseName = match2.folderName.replace(/^\(Dev Local\)\s*/, "");
160431
160742
  const devFolderName = `(Dev Remote) ${baseName}`;
160432
- const devPath = join31(flintPath, "Shards", devFolderName);
160743
+ const devPath = join35(flintPath, "Shards", devFolderName);
160433
160744
  if (existsSync7(devPath)) {
160434
160745
  console.error(export_pc.red(`
160435
160746
  Cannot promote: "${devFolderName}" already exists.`));
@@ -160461,7 +160772,7 @@ ${export_pc.bold(devFolderName)} promoted to Dev Remote`));
160461
160772
  new Command("clone").description("Clone a remote shard for development (creates (Dev Remote) folder, does NOT install)").argument("<source>", "Source identifier (e.g. owner/repo)").option("-p, --path <dir>", "Path to flint").action(async (rawSource, options3) => {
160462
160773
  try {
160463
160774
  const flintPath = await resolveFlint(options3.path);
160464
- const { execSync: execSync6 } = await import("child_process");
160775
+ const { execSync: execSync5 } = await import("child_process");
160465
160776
  let source = rawSource;
160466
160777
  if (!rawSource.includes("/") && !rawSource.startsWith("github:")) {
160467
160778
  source = `${NUU_SHARD_PREFIX}${rawSource}`;
@@ -160481,7 +160792,7 @@ Resolving ${source}...`));
160481
160792
  const resolved = await resolveShardSource(parsed, flintPath);
160482
160793
  try {
160483
160794
  const devFolderName = `(Dev Remote) ${resolved.manifest.name}`;
160484
- const devPath = join31(flintPath, "Shards", devFolderName);
160795
+ const devPath = join35(flintPath, "Shards", devFolderName);
160485
160796
  if (existsSync7(devPath)) {
160486
160797
  console.error(export_pc.red(`
160487
160798
  Dev folder already exists: Shards/${devFolderName}`));
@@ -160490,7 +160801,7 @@ Dev folder already exists: Shards/${devFolderName}`));
160490
160801
  }
160491
160802
  const ghSource = parsed;
160492
160803
  console.log(export_pc.dim(`Cloning into Shards/${devFolderName}...`));
160493
- execSync6(
160804
+ execSync5(
160494
160805
  `git clone "https://github.com/${ghSource.owner}/${ghSource.repo}.git" "${devPath}"`,
160495
160806
  { stdio: "pipe", timeout: 6e4 }
160496
160807
  );
@@ -160590,7 +160901,7 @@ Shard not found: "${identifier}"`));
160590
160901
  if (counts.length > 0) {
160591
160902
  console.log(` Contents ${counts.join(", ")}`);
160592
160903
  }
160593
- const shardPath = join31(flintPath, "Shards", detail2.folderName);
160904
+ const shardPath = join35(flintPath, "Shards", detail2.folderName);
160594
160905
  const manifestResult = await readShardManifest(shardPath);
160595
160906
  const manifest = manifestResult?.manifest;
160596
160907
  if (manifest?.dependencies?.length) {
@@ -160642,7 +160953,7 @@ Shard "${identifier}" not found.
160642
160953
  `));
160643
160954
  process.exit(1);
160644
160955
  }
160645
- const shardPath = join31(flintPath, "Shards", info.folderName);
160956
+ const shardPath = join35(flintPath, "Shards", info.folderName);
160646
160957
  const manifestRead = await readShardManifest(shardPath);
160647
160958
  const manifest = manifestRead?.manifest;
160648
160959
  if (!manifest) {
@@ -160893,13 +161204,13 @@ Pending shard migrations for ${result.shard.folderName}:
160893
161204
  ).addCommand(
160894
161205
  new Command("push").description("Commit and push a dev shard to its remote").argument("<name>", "Shard name (e.g. reports, living-documents)").option("-m, --message <msg>", "Commit message").option("-b, --bump <level>", "Bump version in shard.yaml (patch, minor, major)").option("-p, --path <dir>", "Path to flint").action(async (name, options3) => {
160895
161206
  try {
160896
- const { execSync: execSync6 } = await import("child_process");
161207
+ const { execSync: execSync5 } = await import("child_process");
160897
161208
  const flintPath = await resolveFlint(options3.path);
160898
161209
  const resolved = await resolveDevShard(flintPath, name);
160899
161210
  if (!resolved) return;
160900
161211
  const { info: match2 } = resolved;
160901
- const shardPath = join31(flintPath, "Shards", match2.folderName);
160902
- const gitDir = join31(shardPath, ".git");
161212
+ const shardPath = join35(flintPath, "Shards", match2.folderName);
161213
+ const gitDir = join35(shardPath, ".git");
160903
161214
  if (!existsSync7(gitDir)) {
160904
161215
  console.error(export_pc.red(`
160905
161216
  "${match2.folderName}" has no git repo. Initialize one first:`));
@@ -160907,15 +161218,15 @@ Pending shard migrations for ${result.shard.folderName}:
160907
161218
  console.log();
160908
161219
  return;
160909
161220
  }
160910
- const status = execSync6("git status --porcelain", { cwd: shardPath, encoding: "utf-8" }).trim();
161221
+ const status = execSync5("git status --porcelain", { cwd: shardPath, encoding: "utf-8" }).trim();
160911
161222
  if (!status) {
160912
161223
  try {
160913
- const unpushed = execSync6("git log @{u}..HEAD --oneline", { cwd: shardPath, encoding: "utf-8" }).trim();
161224
+ const unpushed = execSync5("git log @{u}..HEAD --oneline", { cwd: shardPath, encoding: "utf-8" }).trim();
160914
161225
  if (unpushed) {
160915
161226
  console.log(export_pc.bold(`
160916
161227
  Pushing ${match2.folderName}...
160917
161228
  `));
160918
- execSync6("git push", { cwd: shardPath, stdio: "inherit" });
161229
+ execSync5("git push", { cwd: shardPath, stdio: "inherit" });
160919
161230
  console.log(export_pc.green(`
160920
161231
  Pushed unpushed commits.`));
160921
161232
  console.log();
@@ -160938,7 +161249,7 @@ Invalid bump level "${level}". Use: patch, minor, or major.`));
160938
161249
  return;
160939
161250
  }
160940
161251
  const { readFile: readFile18, writeFile: writeFile15 } = await import("fs/promises");
160941
- const yamlPath = join31(shardPath, "shard.yaml");
161252
+ const yamlPath = join35(shardPath, "shard.yaml");
160942
161253
  const yamlContent = await readFile18(yamlPath, "utf-8");
160943
161254
  const versionMatch = yamlContent.match(/^version:\s*"?(\d+)\.(\d+)\.(\d+)"?/m);
160944
161255
  if (!versionMatch) {
@@ -160959,13 +161270,13 @@ Could not parse version from shard.yaml.`));
160959
161270
  console.log(export_pc.bold(`
160960
161271
  Pushing ${match2.folderName}...
160961
161272
  `));
160962
- execSync6("git add -A", { cwd: shardPath, stdio: "pipe" });
160963
- execSync6(`git commit -m "${message.replace(/"/g, '\\"')}"`, { cwd: shardPath, stdio: "pipe" });
161273
+ execSync5("git add -A", { cwd: shardPath, stdio: "pipe" });
161274
+ execSync5(`git commit -m "${message.replace(/"/g, '\\"')}"`, { cwd: shardPath, stdio: "pipe" });
160964
161275
  try {
160965
- execSync6("git push", { cwd: shardPath, stdio: "inherit" });
161276
+ execSync5("git push", { cwd: shardPath, stdio: "inherit" });
160966
161277
  } catch {
160967
- const branch = execSync6("git branch --show-current", { cwd: shardPath, encoding: "utf-8" }).trim();
160968
- execSync6(`git push -u origin ${branch}`, { cwd: shardPath, stdio: "inherit" });
161278
+ const branch = execSync5("git branch --show-current", { cwd: shardPath, encoding: "utf-8" }).trim();
161279
+ execSync5(`git push -u origin ${branch}`, { cwd: shardPath, stdio: "inherit" });
160969
161280
  }
160970
161281
  console.log(export_pc.green(`
160971
161282
  ${export_pc.bold(match2.folderName)} pushed.`));
@@ -160989,7 +161300,7 @@ Pushing ${match2.folderName}...
160989
161300
  const resolved = await resolveDevShard(flintPath, name);
160990
161301
  if (!resolved) process.exit(1);
160991
161302
  const { info: match2 } = resolved;
160992
- const shardPath = join31(flintPath, "Shards", match2.folderName);
161303
+ const shardPath = join35(flintPath, "Shards", match2.folderName);
160993
161304
  const detail2 = await getShardInfo(flintPath, match2.folderName);
160994
161305
  if (!detail2) {
160995
161306
  console.error(export_pc.red(`
@@ -161007,10 +161318,10 @@ Cannot read shard info for "${name}".`));
161007
161318
  }
161008
161319
  if (!repo) {
161009
161320
  try {
161010
- const { execSync: execSync6 } = await import("child_process");
161011
- const gitDir = join31(shardPath, ".git");
161321
+ const { execSync: execSync5 } = await import("child_process");
161322
+ const gitDir = join35(shardPath, ".git");
161012
161323
  if (existsSync7(gitDir)) {
161013
- const remoteUrl = execSync6("git remote get-url origin", { cwd: shardPath, encoding: "utf-8" }).trim();
161324
+ const remoteUrl = execSync5("git remote get-url origin", { cwd: shardPath, encoding: "utf-8" }).trim();
161014
161325
  const ghMatch = remoteUrl.match(/github\.com[/:]([\w.-]+\/[\w.-]+?)(?:\.git)?$/);
161015
161326
  if (ghMatch) {
161016
161327
  repo = ghMatch[1];
@@ -161027,7 +161338,7 @@ Cannot determine repo for "${name}".`));
161027
161338
  process.exit(1);
161028
161339
  }
161029
161340
  let readme;
161030
- const readmePath = join31(shardPath, "README.md");
161341
+ const readmePath = join35(shardPath, "README.md");
161031
161342
  if (existsSync7(readmePath)) {
161032
161343
  readme = await readFile14(readmePath, "utf-8");
161033
161344
  }
@@ -161224,7 +161535,7 @@ Failed to fetch published shards: ${msg}`));
161224
161535
  const resolved = await resolveDevShard(flintPath, name);
161225
161536
  if (!resolved) process.exit(1);
161226
161537
  const { info: shard } = resolved;
161227
- const shardPath = join31(flintPath, "Shards", shard.folderName);
161538
+ const shardPath = join35(flintPath, "Shards", shard.folderName);
161228
161539
  const remoteUrl = await getRemoteUrl(shardPath);
161229
161540
  if (!remoteUrl) {
161230
161541
  console.error(export_pc.red(`
@@ -161568,21 +161879,53 @@ function getNestedValue(obj, key) {
161568
161879
  // src/commands/config/obsidian.ts
161569
161880
  init_dist4();
161570
161881
  import { execSync as execSync4, spawnSync } from "child_process";
161571
- import { join as join35 } from "path";
161882
+ import { join as join36 } from "path";
161572
161883
  import { stat as stat17, rm as rm12 } from "fs/promises";
161573
- import { platform as platform6 } from "os";
161884
+ import { platform as platform5 } from "os";
161885
+ import { request as httpRequest } from "http";
161574
161886
  function getExpectedRepoUrl() {
161575
- return platform6() === "win32" ? OBSIDIAN_WINDOWS_REPO_URL : OBSIDIAN_REPO_URL;
161887
+ return platform5() === "win32" ? OBSIDIAN_WINDOWS_REPO_URL : OBSIDIAN_REPO_URL;
161888
+ }
161889
+ function postReload(port) {
161890
+ return new Promise((resolve19, reject) => {
161891
+ const req = httpRequest({
161892
+ hostname: "127.0.0.1",
161893
+ port,
161894
+ method: "POST",
161895
+ path: "/app/reload",
161896
+ timeout: 2e3
161897
+ }, (res) => {
161898
+ res.resume();
161899
+ res.on("end", () => resolve19());
161900
+ });
161901
+ req.on("error", reject);
161902
+ req.on("timeout", () => req.destroy(new Error("timeout")));
161903
+ req.end();
161904
+ });
161905
+ }
161906
+ async function maybeReloadObsidian(flintPath) {
161907
+ const plugin = await findLivePluginForVault(flintPath);
161908
+ if (!plugin) {
161909
+ console.log(export_pc.dim("Obsidian not open for this vault \u2014 skipping reload."));
161910
+ return;
161911
+ }
161912
+ try {
161913
+ await postReload(plugin.port);
161914
+ console.log(export_pc.green("Reloaded Obsidian."));
161915
+ } catch (err) {
161916
+ const message = err instanceof Error ? err.message : String(err);
161917
+ console.log(export_pc.dim(`Could not reach Obsidian plugin (${message}) \u2014 skipping reload.`));
161918
+ }
161576
161919
  }
161577
161920
  var obsidianCommand = new Command("obsidian").description("Manage .obsidian configuration").option("-p, --path <dir>", "Path to flint (default: auto-detect)");
161578
- obsidianCommand.command("update").description("Force pull latest .obsidian from remote (discards local changes)").action(async () => {
161921
+ obsidianCommand.command("update").description("Force pull latest .obsidian from remote (discards local changes)").option("--no-reload", "Skip reloading the running Obsidian app after the pull").action(async (cmdOptions) => {
161579
161922
  const options3 = obsidianCommand.opts();
161580
161923
  const flintPath = options3.path || await findFlintRoot(process.cwd());
161581
161924
  if (!flintPath) {
161582
161925
  console.error(export_pc.red("Error: Not inside a Flint."));
161583
161926
  process.exit(1);
161584
161927
  }
161585
- const obsidianDir = join35(flintPath, ".obsidian");
161928
+ const obsidianDir = join36(flintPath, ".obsidian");
161586
161929
  try {
161587
161930
  await stat17(obsidianDir);
161588
161931
  } catch {
@@ -161609,6 +161952,9 @@ obsidianCommand.command("update").description("Force pull latest .obsidian from
161609
161952
  console.error(export_pc.red(`Error updating .obsidian: ${message}`));
161610
161953
  process.exit(1);
161611
161954
  }
161955
+ if (cmdOptions.reload !== false) {
161956
+ await maybeReloadObsidian(flintPath);
161957
+ }
161612
161958
  });
161613
161959
  if (isFeatureEnabled(FEATURES, "obsidian.push", resolveRuntimeSync({ cliname: "flint" }))) {
161614
161960
  obsidianCommand.command("push").description(`Commit all changes and push to remote ${export_pc.dim("[dev]")}`).option("-m, --message <msg>", "Commit message", "Update obsidian config").action(async (cmdOptions) => {
@@ -161618,7 +161964,7 @@ if (isFeatureEnabled(FEATURES, "obsidian.push", resolveRuntimeSync({ cliname: "f
161618
161964
  console.error(export_pc.red("Error: Not inside a Flint."));
161619
161965
  process.exit(1);
161620
161966
  }
161621
- const obsidianDir = join35(flintPath, ".obsidian");
161967
+ const obsidianDir = join36(flintPath, ".obsidian");
161622
161968
  try {
161623
161969
  await stat17(obsidianDir);
161624
161970
  } catch {
@@ -161655,7 +162001,7 @@ obsidianCommand.command("reset").description("Delete and re-clone .obsidian from
161655
162001
  console.error(export_pc.red("Error: Not inside a Flint."));
161656
162002
  process.exit(1);
161657
162003
  }
161658
- const obsidianDir = join35(flintPath, ".obsidian");
162004
+ const obsidianDir = join36(flintPath, ".obsidian");
161659
162005
  let exists7 = false;
161660
162006
  try {
161661
162007
  await stat17(obsidianDir);
@@ -162132,15 +162478,13 @@ plateCommand.command("info").description("Show Plate details").argument("<name>"
162132
162478
 
162133
162479
  // src/commands/agent/orbh.ts
162134
162480
  init_dist4();
162135
- import { execSync as execSync5, spawnSync as spawnSync7 } from "child_process";
162136
- import { mkdirSync as mkdirSync4, readFileSync as readFileSync15, writeFileSync as writeFileSync2 } from "fs";
162137
- import { join as join39 } from "path";
162138
- import { createInterface as createInterface7 } from "readline";
162481
+ import { spawnSync as spawnSync7 } from "child_process";
162482
+ import { join as join40 } from "path";
162139
162483
 
162140
162484
  // ../orbh-cli/src/index.ts
162141
- import { spawn as spawn8, spawnSync as spawnSync6 } from "child_process";
162142
- import { existsSync as existsSync17, readFileSync as readFileSync14 } from "fs";
162143
- import { dirname as dirname12, join as join38, resolve as resolvePath3 } from "path";
162485
+ import { spawn as spawn9, spawnSync as spawnSync6 } from "child_process";
162486
+ import { existsSync as existsSync18, readFileSync as readFileSync15 } from "fs";
162487
+ import { dirname as dirname12, join as join39, resolve as resolvePath3 } from "path";
162144
162488
  import { fileURLToPath as fileURLToPath6, pathToFileURL } from "url";
162145
162489
 
162146
162490
  // ../../packages/orbh/dist/index.js
@@ -162151,7 +162495,7 @@ import { closeSync, existsSync as existsSync42, openSync, readSync, statSync as
162151
162495
  import { existsSync as existsSync52, readFileSync as readFileSync42, unwatchFile as unwatchFile2, watch as watch2, watchFile as watchFile2 } from "fs";
162152
162496
  import { spawnSync as spawnSync2 } from "child_process";
162153
162497
  import { existsSync as existsSync72, readFileSync as readFileSync6 } from "fs";
162154
- import { dirname as dirname24, join as join36 } from "path";
162498
+ import { dirname as dirname24, join as join37 } from "path";
162155
162499
  import { spawnSync as spawnSync22 } from "child_process";
162156
162500
  import { existsSync as existsSync8 } from "fs";
162157
162501
  import { homedir as homedir8 } from "os";
@@ -162159,7 +162503,7 @@ import { join as join45 } from "path";
162159
162503
  import { existsSync as existsSync9 } from "fs";
162160
162504
  import { join as join53 } from "path";
162161
162505
  import { homedir as homedir23 } from "os";
162162
- import { spawn as spawn6 } from "child_process";
162506
+ import { spawn as spawn7 } from "child_process";
162163
162507
  import { createInterface as createInterface6 } from "readline";
162164
162508
  import { readdirSync as readdirSync3, readFileSync as readFileSync7 } from "fs";
162165
162509
  import { existsSync as existsSync10 } from "fs";
@@ -162172,30 +162516,35 @@ import { existsSync as existsSync12, readdirSync as readdirSync5, readFileSync a
162172
162516
  import { spawnSync as spawnSync3 } from "child_process";
162173
162517
  import { homedir as homedir52 } from "os";
162174
162518
  import { basename as basename23, join as join83 } from "path";
162175
- import { existsSync as existsSync13, readFileSync as readFileSync10, statSync as statSync5, unwatchFile as unwatchFile3, watchFile as watchFile3 } from "fs";
162176
- import { existsSync as existsSync14, mkdirSync as mkdirSync2, readdirSync as readdirSync6, readFileSync as readFileSync11, realpathSync, statSync as statSync6 } from "fs";
162519
+ import { spawn as spawn23 } from "child_process";
162520
+ import { existsSync as existsSync13, readdirSync as readdirSync6, readFileSync as readFileSync10, statSync as statSync5 } from "fs";
162177
162521
  import { homedir as homedir62 } from "os";
162178
162522
  import { basename as basename33, join as join93 } from "path";
162523
+ import { existsSync as existsSync14, readFileSync as readFileSync11, statSync as statSync6, unwatchFile as unwatchFile3, watchFile as watchFile3 } from "fs";
162524
+ import { existsSync as existsSync15, mkdirSync as mkdirSync2, readdirSync as readdirSync7, readFileSync as readFileSync12, realpathSync, statSync as statSync7 } from "fs";
162525
+ import { homedir as homedir72 } from "os";
162526
+ import { basename as basename43, join as join103 } from "path";
162179
162527
  import { randomUUID as randomUUID7 } from "crypto";
162180
162528
  import { EventEmitter } from "events";
162181
162529
  import { randomUUID as randomUUID23 } from "crypto";
162182
162530
  import { mkdirSync as mkdirSync3, readdirSync, readFileSync as readFileSync5, renameSync, writeFileSync } from "fs";
162183
- import { existsSync as existsSync15 } from "fs";
162184
- import { join as join37 } from "path";
162531
+ import { existsSync as existsSync16 } from "fs";
162532
+ import { join as join38 } from "path";
162185
162533
  import { randomUUID as randomUUID33 } from "crypto";
162186
162534
  init_dist3();
162187
162535
  import { watch as watch3 } from "fs";
162188
162536
  import { access as access7 } from "fs/promises";
162189
162537
  import path21 from "path";
162190
162538
  import { fileURLToPath as fileURLToPath5 } from "url";
162191
- import { spawn as spawn32, spawnSync as spawnSync5 } from "child_process";
162192
- import { spawn as spawn23, spawnSync as spawnSync4 } from "child_process";
162193
- import { createWriteStream, existsSync as existsSync152, readdirSync as readdirSync7, readFileSync as readFileSync12, renameSync as renameSync2 } from "fs";
162194
- import { join as join103 } from "path";
162195
- import { homedir as homedir72 } from "os";
162196
- import { existsSync as existsSync16, readFileSync as readFileSync13 } from "fs";
162197
- import { homedir as homedir82 } from "os";
162539
+ import { spawn as spawn42, spawnSync as spawnSync5 } from "child_process";
162540
+ import { spawn as spawn32, spawnSync as spawnSync4 } from "child_process";
162541
+ import { createWriteStream, existsSync as existsSync162, readdirSync as readdirSync8, readFileSync as readFileSync13, renameSync as renameSync2 } from "fs";
162198
162542
  import { join as join113 } from "path";
162543
+ import { homedir as homedir82 } from "os";
162544
+ import { existsSync as existsSync17, readFileSync as readFileSync14 } from "fs";
162545
+ import { homedir as homedir9 } from "os";
162546
+ import { join as join123 } from "path";
162547
+ import { EventEmitter as EventEmitter2 } from "events";
162199
162548
  var __defProp3 = Object.defineProperty;
162200
162549
  var __getOwnPropNames3 = Object.getOwnPropertyNames;
162201
162550
  var __esm2 = (fn, res) => function __init() {
@@ -164199,7 +164548,7 @@ function resolveCommand2(name) {
164199
164548
  const matches = [...content.matchAll(/%(?:~dp0|dp0%)\\([^"%\r\n]+\.m?[jc]?[jt]s)/gi)];
164200
164549
  const last = matches.length > 0 ? matches[matches.length - 1] : void 0;
164201
164550
  if (last && last[1]) {
164202
- const scriptPath = join36(dirname24(resolved), last[1]);
164551
+ const scriptPath = join37(dirname24(resolved), last[1]);
164203
164552
  if (existsSync72(scriptPath)) {
164204
164553
  return { cmd: process.execPath, prependArgs: [scriptPath] };
164205
164554
  }
@@ -164257,6 +164606,10 @@ function parseOpencodeVersion(output) {
164257
164606
  const match2 = output.match(/\bopencode\s+v?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)\b/i);
164258
164607
  return match2?.[1] ?? parseSemver(output);
164259
164608
  }
164609
+ function parseGrokVersion(output) {
164610
+ const match2 = output.match(/\bgrok\s+v?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)\b/i);
164611
+ return match2?.[1] ?? parseSemver(output);
164612
+ }
164260
164613
  function resolveUserHome() {
164261
164614
  return process.env.HOME || homedir8();
164262
164615
  }
@@ -164351,6 +164704,7 @@ var init_executable = __esm2({
164351
164704
  codex: parseCodexVersion,
164352
164705
  droid: parseDroidVersion,
164353
164706
  gemini: parseGeminiVersion,
164707
+ grok: parseGrokVersion,
164354
164708
  opencode: parseOpencodeVersion
164355
164709
  };
164356
164710
  }
@@ -164584,7 +164938,7 @@ async function bootstrapCodexSession(cwd, initPrompt, options3 = {}) {
164584
164938
  const start = async () => {
164585
164939
  const executable = await getExecutable("codex");
164586
164940
  const spawnCmd = executable.resolvedCommand.cmd;
164587
- const proc = spawn6(spawnCmd, [...executable.resolvedCommand.prependArgs, ...buildCodexAppServerArgs(options3)], {
164941
+ const proc = spawn7(spawnCmd, [...executable.resolvedCommand.prependArgs, ...buildCodexAppServerArgs(options3)], {
164588
164942
  stdio: ["pipe", "pipe", "pipe"],
164589
164943
  cwd,
164590
164944
  env: options3.env ? { ...process.env, ...options3.env } : process.env,
@@ -164594,48 +164948,40 @@ async function bootstrapCodexSession(cwd, initPrompt, options3 = {}) {
164594
164948
  const send = (message) => proc.stdin.write(`${JSON.stringify(message)}
164595
164949
  `);
164596
164950
  let threadId = null;
164597
- let sessionPath = null;
164598
164951
  const timeout = setTimeout(() => {
164599
164952
  proc.kill();
164600
164953
  reject(new Error("Timeout waiting for Codex session"));
164601
- }, 3e4);
164954
+ }, 15e3);
164602
164955
  const cleanup = () => {
164603
164956
  clearTimeout(timeout);
164604
164957
  rl.close();
164605
164958
  };
164606
- let pollInterval = null;
164607
- const startPolling = () => {
164608
- pollInterval = setInterval(() => {
164609
- if (sessionPath && existsSync10(sessionPath)) {
164610
- if (pollInterval) {
164611
- clearInterval(pollInterval);
164612
- }
164613
- send({ method: "turn/interrupt", id: 4, params: { threadId } });
164614
- setTimeout(() => {
164615
- cleanup();
164616
- proc.kill();
164617
- resolve19(threadId);
164618
- }, 500);
164619
- }
164620
- }, 200);
164621
- };
164622
164959
  rl.on("line", (line) => {
164623
164960
  try {
164624
164961
  const message = JSON.parse(line);
164625
164962
  if (message.id === 2 && message.result?.thread?.id) {
164626
164963
  threadId = message.result.thread.id;
164627
- sessionPath = message.result.thread.path ?? null;
164628
164964
  send({
164629
- method: "turn/start",
164965
+ method: "thread/inject_items",
164630
164966
  id: 3,
164631
164967
  params: {
164632
164968
  threadId,
164633
- input: [{ type: "text", text: initPrompt }]
164969
+ items: [
164970
+ {
164971
+ type: "message",
164972
+ role: "user",
164973
+ content: [{ type: "input_text", text: initPrompt }]
164974
+ }
164975
+ ]
164634
164976
  }
164635
164977
  });
164978
+ return;
164636
164979
  }
164637
- if (message.id === 3 && message.result?.turn) {
164638
- startPolling();
164980
+ if (message.id === 3 && message.result) {
164981
+ cleanup();
164982
+ proc.kill();
164983
+ resolve19(threadId);
164984
+ return;
164639
164985
  }
164640
164986
  if (message.error && (message.id ?? 0) <= 3) {
164641
164987
  cleanup();
@@ -165219,6 +165565,376 @@ var init_gemini2 = __esm2({
165219
165565
  GEMINI_COMMAND = "gemini";
165220
165566
  }
165221
165567
  });
165568
+ function createGrokMapperContext(options3) {
165569
+ return {
165570
+ toolIdMap: options3?.toolIdMap ?? /* @__PURE__ */ new Map(),
165571
+ transcriptPath: options3?.transcriptPath,
165572
+ turnIndex: 0
165573
+ };
165574
+ }
165575
+ function isRecord7(value) {
165576
+ return typeof value === "object" && value !== null && !Array.isArray(value);
165577
+ }
165578
+ function isContentBlockArray(value) {
165579
+ return Array.isArray(value) && value.every((item) => isRecord7(item));
165580
+ }
165581
+ function stringifyContent3(value) {
165582
+ if (typeof value === "string") return value;
165583
+ if (Array.isArray(value)) return value.map((item) => stringifyContent3(item)).join("\n");
165584
+ if (isRecord7(value)) {
165585
+ if (typeof value.text === "string") return value.text;
165586
+ if (typeof value.content === "string") return value.content;
165587
+ return JSON.stringify(value);
165588
+ }
165589
+ if (value === null || value === void 0) return "";
165590
+ return String(value);
165591
+ }
165592
+ function syntheticTimestamp(context) {
165593
+ const ms = context.turnIndex;
165594
+ context.turnIndex += 1;
165595
+ return new Date(ms).toISOString();
165596
+ }
165597
+ function entryTimestamp(entry, context) {
165598
+ if (typeof entry.timestamp === "string") return entry.timestamp;
165599
+ if (typeof entry.timestamp === "number" && Number.isFinite(entry.timestamp)) {
165600
+ return new Date(entry.timestamp).toISOString();
165601
+ }
165602
+ return syntheticTimestamp(context);
165603
+ }
165604
+ function mapUserEntry2(entry, context) {
165605
+ const content = entry.content;
165606
+ const timestamp = entryTimestamp(entry, context);
165607
+ if (typeof content === "string") {
165608
+ if (content.length === 0) return [];
165609
+ return [{ type: "message", role: "human", text: content, timestamp }];
165610
+ }
165611
+ if (!isContentBlockArray(content)) return [];
165612
+ const mapped = [];
165613
+ for (const block3 of content) {
165614
+ if (block3.type === "text" && typeof block3.text === "string") {
165615
+ if (block3.text.length === 0) continue;
165616
+ mapped.push({ type: "message", role: "human", text: block3.text, timestamp });
165617
+ continue;
165618
+ }
165619
+ if (block3.type === "tool_result" && typeof block3.tool_use_id === "string") {
165620
+ const toolId = block3.tool_use_id;
165621
+ mapped.push({
165622
+ type: "tool-result",
165623
+ id: toolId,
165624
+ tool: context.toolIdMap.get(toolId) ?? "unknown",
165625
+ output: stringifyContent3(block3.content),
165626
+ error: block3.is_error === true,
165627
+ timestamp
165628
+ });
165629
+ }
165630
+ }
165631
+ return mapped;
165632
+ }
165633
+ function mapAssistantEntry2(entry, context) {
165634
+ const content = entry.content;
165635
+ const timestamp = entryTimestamp(entry, context);
165636
+ if (typeof content === "string") {
165637
+ if (content.length === 0) return [];
165638
+ return [{ type: "message", role: "agent", text: content, timestamp }];
165639
+ }
165640
+ if (!isContentBlockArray(content)) return [];
165641
+ const mapped = [];
165642
+ for (const block3 of content) {
165643
+ if (block3.type === "text" && typeof block3.text === "string") {
165644
+ if (block3.text.length === 0) continue;
165645
+ mapped.push({ type: "message", role: "agent", text: block3.text, timestamp });
165646
+ continue;
165647
+ }
165648
+ if (block3.type === "thinking" && typeof block3.text === "string") {
165649
+ if (block3.text.length === 0) continue;
165650
+ mapped.push({ type: "thinking", text: block3.text, timestamp });
165651
+ continue;
165652
+ }
165653
+ if (block3.type === "tool_use" && typeof block3.id === "string" && typeof block3.name === "string") {
165654
+ context.toolIdMap.set(block3.id, block3.name);
165655
+ mapped.push({
165656
+ type: "tool-call",
165657
+ id: block3.id,
165658
+ tool: block3.name,
165659
+ input: isRecord7(block3.input) ? block3.input : {},
165660
+ timestamp
165661
+ });
165662
+ }
165663
+ }
165664
+ return mapped;
165665
+ }
165666
+ function buildGrokToolIdMap(entries) {
165667
+ const toolIdMap = /* @__PURE__ */ new Map();
165668
+ for (const entry of entries) {
165669
+ if (entry.type !== "assistant") continue;
165670
+ if (!isContentBlockArray(entry.content)) continue;
165671
+ for (const block3 of entry.content) {
165672
+ if (block3.type === "tool_use" && typeof block3.id === "string" && typeof block3.name === "string") {
165673
+ toolIdMap.set(block3.id, block3.name);
165674
+ }
165675
+ }
165676
+ }
165677
+ return toolIdMap;
165678
+ }
165679
+ function mapGrokEntry(entry, context) {
165680
+ switch (entry.type) {
165681
+ case "user":
165682
+ return mapUserEntry2(entry, context);
165683
+ case "assistant":
165684
+ return mapAssistantEntry2(entry, context);
165685
+ case "system":
165686
+ default:
165687
+ return [];
165688
+ }
165689
+ }
165690
+ function parseGrokTranscript(content, options3) {
165691
+ const rawEntries = content.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
165692
+ try {
165693
+ return JSON.parse(line);
165694
+ } catch {
165695
+ return null;
165696
+ }
165697
+ }).filter((entry) => entry !== null);
165698
+ const context = createGrokMapperContext({
165699
+ toolIdMap: buildGrokToolIdMap(rawEntries),
165700
+ transcriptPath: options3?.transcriptPath
165701
+ });
165702
+ return rawEntries.flatMap((entry) => mapGrokEntry(entry, context));
165703
+ }
165704
+ var init_grok = __esm2({
165705
+ "src/mappers/grok.ts"() {
165706
+ "use strict";
165707
+ }
165708
+ });
165709
+ function encodeGrokCwd(cwd) {
165710
+ const trimmed = cwd.replace(/[\\/]+$/, "");
165711
+ return encodeURIComponent(trimmed);
165712
+ }
165713
+ function getGrokSessionsRoot() {
165714
+ return join93(homedir62(), ".grok", "sessions");
165715
+ }
165716
+ function buildScopedSessionDir(cwd) {
165717
+ return join93(getGrokSessionsRoot(), encodeGrokCwd(cwd));
165718
+ }
165719
+ function buildTranscriptPath2(cwd, nativeSessionId) {
165720
+ return join93(buildScopedSessionDir(cwd), nativeSessionId, GROK_TRANSCRIPT_FILE);
165721
+ }
165722
+ async function bootstrapGrokSession(cwd, initPrompt, options3 = {}) {
165723
+ const executable = await getExecutable("grok");
165724
+ if (!executable.available) {
165725
+ throw new Error("Grok CLI is not available on PATH.");
165726
+ }
165727
+ const args = [
165728
+ ...executable.resolvedCommand.prependArgs,
165729
+ "-p",
165730
+ initPrompt,
165731
+ "--output-format",
165732
+ "json",
165733
+ "--always-approve",
165734
+ "--cwd",
165735
+ cwd
165736
+ ];
165737
+ if (options3.model) {
165738
+ args.push("--model", options3.model);
165739
+ }
165740
+ if (options3.extraArgs) {
165741
+ args.push(...options3.extraArgs);
165742
+ }
165743
+ return new Promise((resolve19, reject) => {
165744
+ const proc = spawn23(executable.resolvedCommand.cmd, args, {
165745
+ stdio: ["ignore", "pipe", "pipe"],
165746
+ cwd,
165747
+ env: options3.env ? { ...process.env, ...options3.env } : process.env,
165748
+ windowsHide: true
165749
+ });
165750
+ let stdout = "";
165751
+ let stderr = "";
165752
+ proc.stdout?.on("data", (chunk) => {
165753
+ stdout += chunk.toString();
165754
+ });
165755
+ proc.stderr?.on("data", (chunk) => {
165756
+ stderr += chunk.toString();
165757
+ });
165758
+ const timeoutMs = options3.timeoutMs ?? 5 * 6e4;
165759
+ const timer = setTimeout(() => {
165760
+ proc.kill("SIGKILL");
165761
+ reject(new Error(`Timed out bootstrapping Grok session after ${timeoutMs}ms`));
165762
+ }, timeoutMs);
165763
+ proc.on("error", (error3) => {
165764
+ clearTimeout(timer);
165765
+ reject(error3);
165766
+ });
165767
+ proc.on("close", (code) => {
165768
+ clearTimeout(timer);
165769
+ if (code !== 0) {
165770
+ reject(new Error(`Grok bootstrap exited ${code}: ${stderr.trim() || stdout.trim()}`));
165771
+ return;
165772
+ }
165773
+ const sessionId = extractGrokSessionId(stdout);
165774
+ if (!sessionId) {
165775
+ reject(new Error(`Grok bootstrap completed but no sessionId in output: ${stdout.slice(-400)}`));
165776
+ return;
165777
+ }
165778
+ resolve19(sessionId);
165779
+ });
165780
+ });
165781
+ }
165782
+ function extractGrokSessionId(stdout) {
165783
+ const trimmed = stdout.trim();
165784
+ if (trimmed.length === 0) return null;
165785
+ const tryParse = (text) => {
165786
+ try {
165787
+ const parsed = JSON.parse(text);
165788
+ const id = typeof parsed.sessionId === "string" ? parsed.sessionId : typeof parsed.session_id === "string" ? parsed.session_id : null;
165789
+ return id;
165790
+ } catch {
165791
+ return null;
165792
+ }
165793
+ };
165794
+ const whole = tryParse(trimmed);
165795
+ if (whole) return whole;
165796
+ for (const line of trimmed.split(/\r?\n/).reverse()) {
165797
+ const candidate = line.trim();
165798
+ if (!candidate.startsWith("{")) continue;
165799
+ const id = tryParse(candidate);
165800
+ if (id) return id;
165801
+ }
165802
+ return null;
165803
+ }
165804
+ function createGrokHarness() {
165805
+ return {
165806
+ name: "grok",
165807
+ command: GROK_COMMAND,
165808
+ capabilities: {
165809
+ headless: true,
165810
+ interactive: true,
165811
+ preassignSessionId: false,
165812
+ maxTurns: true,
165813
+ budgetLimit: false,
165814
+ toolHooks: false,
165815
+ subagentVisibility: true,
165816
+ structuredOutput: true,
165817
+ permissionBypass: true
165818
+ },
165819
+ applyConfig(config) {
165820
+ const base = applyDefaultConfig(config);
165821
+ const extraArgs = [...base.extraArgs ?? []];
165822
+ if (typeof config.effort === "string" && config.effort.length > 0) {
165823
+ extraArgs.push("--effort", config.effort);
165824
+ }
165825
+ if (typeof config.reasoningEffort === "string" && config.reasoningEffort.length > 0) {
165826
+ extraArgs.push("--reasoning-effort", config.reasoningEffort);
165827
+ }
165828
+ const env3 = { ...base.env ?? {}, ...normalizeProfileEnv(config.env) };
165829
+ const result = {
165830
+ ...extraArgs.length > 0 ? { extraArgs } : {},
165831
+ ...Object.keys(env3).length > 0 ? { env: env3 } : {}
165832
+ };
165833
+ return appendProfileArgs(result, config);
165834
+ },
165835
+ buildSpawnArgs(config) {
165836
+ const args = [
165837
+ "-p",
165838
+ config.prompt,
165839
+ "--output-format",
165840
+ "streaming-json",
165841
+ "--always-approve",
165842
+ "--cwd",
165843
+ config.cwd
165844
+ ];
165845
+ if (typeof config.maxTurns === "number") {
165846
+ args.push("--max-turns", String(config.maxTurns));
165847
+ }
165848
+ if (config.extraArgs) {
165849
+ args.push(...config.extraArgs);
165850
+ }
165851
+ if (config.model) {
165852
+ args.push("--model", config.model);
165853
+ }
165854
+ return args;
165855
+ },
165856
+ buildResumeArgs(nativeSessionId, config) {
165857
+ const args = [
165858
+ "-r",
165859
+ nativeSessionId,
165860
+ "-p",
165861
+ config.prompt ?? "Continue working",
165862
+ "--output-format",
165863
+ "streaming-json",
165864
+ "--always-approve"
165865
+ ];
165866
+ if (config.extraArgs) {
165867
+ args.push(...config.extraArgs);
165868
+ }
165869
+ if (config.model) {
165870
+ args.push("--model", config.model);
165871
+ }
165872
+ return args;
165873
+ },
165874
+ buildInteractiveArgs(config) {
165875
+ const args = ["--always-approve"];
165876
+ if (config.extraArgs) {
165877
+ args.push(...config.extraArgs);
165878
+ }
165879
+ if (config.model) {
165880
+ args.push("--model", config.model);
165881
+ }
165882
+ return args;
165883
+ },
165884
+ buildInteractiveResumeArgs(nativeSessionId, config) {
165885
+ const args = ["-r", nativeSessionId, "--always-approve"];
165886
+ if (config.extraArgs) {
165887
+ args.push(...config.extraArgs);
165888
+ }
165889
+ if (config.model) {
165890
+ args.push("--model", config.model);
165891
+ }
165892
+ return args;
165893
+ },
165894
+ resolveTranscriptPath(nativeSessionId, cwd) {
165895
+ const scopedPath = buildTranscriptPath2(cwd, nativeSessionId);
165896
+ if (existsSync13(scopedPath)) return scopedPath;
165897
+ const root = getGrokSessionsRoot();
165898
+ if (!existsSync13(root)) return scopedPath;
165899
+ try {
165900
+ for (const scope of readdirSync6(root, { withFileTypes: true })) {
165901
+ if (!scope.isDirectory()) continue;
165902
+ const candidate = join93(root, scope.name, nativeSessionId, GROK_TRANSCRIPT_FILE);
165903
+ if (existsSync13(candidate)) return candidate;
165904
+ }
165905
+ } catch {
165906
+ }
165907
+ return scopedPath;
165908
+ },
165909
+ createWatcher(transcriptPath) {
165910
+ return createJsonlTranscriptWatcher(transcriptPath, {
165911
+ createState: () => createGrokMapperContext({ transcriptPath }),
165912
+ map: (entry, state) => mapGrokEntry(entry, state)
165913
+ });
165914
+ },
165915
+ parseTranscript(content, options3) {
165916
+ return parseGrokTranscript(content, { transcriptPath: options3?.transcriptPath });
165917
+ },
165918
+ async isAvailable() {
165919
+ return (await getExecutable("grok")).available;
165920
+ }
165921
+ };
165922
+ }
165923
+ var GROK_COMMAND;
165924
+ var GROK_TRANSCRIPT_FILE;
165925
+ var TRANSCRIPT_DISCOVERY_PADDING_MS3;
165926
+ var init_grok2 = __esm2({
165927
+ "src/harness/grok.ts"() {
165928
+ "use strict";
165929
+ init_grok();
165930
+ init_jsonl_watcher();
165931
+ init_config();
165932
+ init_executable();
165933
+ GROK_COMMAND = "grok";
165934
+ GROK_TRANSCRIPT_FILE = "chat_history.jsonl";
165935
+ TRANSCRIPT_DISCOVERY_PADDING_MS3 = 5 * 6e4;
165936
+ }
165937
+ });
165222
165938
  function diffEntries2(previous, next) {
165223
165939
  const limit = Math.min(previous.length, next.length);
165224
165940
  let index = 0;
@@ -165288,7 +166004,7 @@ var init_opencode_session_watcher = __esm2({
165288
166004
  return [...this.entries];
165289
166005
  }
165290
166006
  startStreamMode() {
165291
- if (existsSync13(this.transcriptPath)) {
166007
+ if (existsSync14(this.transcriptPath)) {
165292
166008
  this.readStreamUpdates();
165293
166009
  }
165294
166010
  watchFile3(this.transcriptPath, { interval: this.options.pollIntervalMs, persistent: false }, () => {
@@ -165296,11 +166012,11 @@ var init_opencode_session_watcher = __esm2({
165296
166012
  });
165297
166013
  }
165298
166014
  refreshSessionSnapshot() {
165299
- if (!this.started || !existsSync13(this.transcriptPath)) {
166015
+ if (!this.started || !existsSync14(this.transcriptPath)) {
165300
166016
  return;
165301
166017
  }
165302
166018
  try {
165303
- const content = readFileSync10(this.transcriptPath, "utf-8");
166019
+ const content = readFileSync11(this.transcriptPath, "utf-8");
165304
166020
  const nextEntries = parseOpencodeTranscript(content, { transcriptPath: this.transcriptPath });
165305
166021
  const newEntries = diffEntries2(this.entries, nextEntries);
165306
166022
  if (newEntries.length === 0 && nextEntries.length === this.entries.length) {
@@ -165315,12 +166031,12 @@ var init_opencode_session_watcher = __esm2({
165315
166031
  }
165316
166032
  }
165317
166033
  readStreamUpdates() {
165318
- if (!this.started || !existsSync13(this.transcriptPath)) {
166034
+ if (!this.started || !existsSync14(this.transcriptPath)) {
165319
166035
  return;
165320
166036
  }
165321
166037
  let fileSize = 0;
165322
166038
  try {
165323
- fileSize = statSync5(this.transcriptPath).size;
166039
+ fileSize = statSync6(this.transcriptPath).size;
165324
166040
  } catch (error3) {
165325
166041
  this.reportError(error3, "Failed to stat OpenCode stream capture");
165326
166042
  return;
@@ -165333,7 +166049,7 @@ var init_opencode_session_watcher = __esm2({
165333
166049
  return;
165334
166050
  }
165335
166051
  try {
165336
- const raw = readFileSync10(this.transcriptPath);
166052
+ const raw = readFileSync11(this.transcriptPath);
165337
166053
  const chunk = raw.subarray(this.byteOffset).toString("utf-8");
165338
166054
  this.byteOffset = raw.length;
165339
166055
  const text = `${this.buffer}${chunk}`;
@@ -165394,35 +166110,35 @@ function isTranscriptRecentEnough3(transcriptPath, startedAt) {
165394
166110
  return true;
165395
166111
  }
165396
166112
  try {
165397
- return statSync6(transcriptPath).mtimeMs >= startedAtMs - OPENCODE_NATIVE_DISCOVERY_PADDING_MS;
166113
+ return statSync7(transcriptPath).mtimeMs >= startedAtMs - OPENCODE_NATIVE_DISCOVERY_PADDING_MS;
165398
166114
  } catch {
165399
166115
  return true;
165400
166116
  }
165401
166117
  }
165402
166118
  function getOpencodeStorageRoot() {
165403
- return join93(homedir62(), ".local", "share", "opencode", "storage");
166119
+ return join103(homedir72(), ".local", "share", "opencode", "storage");
165404
166120
  }
165405
166121
  function getOpencodeSessionRoot() {
165406
- return join93(getOpencodeStorageRoot(), "session");
166122
+ return join103(getOpencodeStorageRoot(), "session");
165407
166123
  }
165408
166124
  function getOpencodeProjectRoot() {
165409
- return join93(getOpencodeStorageRoot(), "project");
166125
+ return join103(getOpencodeStorageRoot(), "project");
165410
166126
  }
165411
166127
  function getOpencodeStreamCaptureDir() {
165412
- return join93(getOpencodeStorageRoot(), "orbh");
166128
+ return join103(getOpencodeStorageRoot(), "orbh");
165413
166129
  }
165414
166130
  function buildPendingOpencodeStreamCapturePath(orbhSessionId) {
165415
- return join93(getOpencodeStreamCaptureDir(), `${orbhSessionId}.jsonl`);
166131
+ return join103(getOpencodeStreamCaptureDir(), `${orbhSessionId}.jsonl`);
165416
166132
  }
165417
166133
  function buildOpencodeStreamCapturePath(nativeSessionId) {
165418
- return join93(getOpencodeStreamCaptureDir(), `${nativeSessionId}.jsonl`);
166134
+ return join103(getOpencodeStreamCaptureDir(), `${nativeSessionId}.jsonl`);
165419
166135
  }
165420
166136
  function readNativeSessionIdFromStreamCapture(streamPath) {
165421
- if (!existsSync14(streamPath)) {
166137
+ if (!existsSync15(streamPath)) {
165422
166138
  return null;
165423
166139
  }
165424
166140
  try {
165425
- const lines = readFileSync11(streamPath, "utf-8").split(/\r?\n/);
166141
+ const lines = readFileSync12(streamPath, "utf-8").split(/\r?\n/);
165426
166142
  for (const line of lines) {
165427
166143
  const trimmed = line.trim();
165428
166144
  if (trimmed.length === 0) {
@@ -165463,17 +166179,17 @@ function mergeOpencodeConfigContent(existing, patch) {
165463
166179
  }
165464
166180
  function listProjectIdsForCwd(cwd) {
165465
166181
  const projectsRoot = getOpencodeProjectRoot();
165466
- if (!existsSync14(projectsRoot)) {
166182
+ if (!existsSync15(projectsRoot)) {
165467
166183
  return [];
165468
166184
  }
165469
166185
  const normalizedCwd = normalizePath(cwd);
165470
166186
  const projectIds = [];
165471
- for (const entry of readdirSync6(projectsRoot)) {
166187
+ for (const entry of readdirSync7(projectsRoot)) {
165472
166188
  if (!entry.endsWith(".json")) {
165473
166189
  continue;
165474
166190
  }
165475
166191
  try {
165476
- const parsed = JSON.parse(readFileSync11(join93(projectsRoot, entry), "utf-8"));
166192
+ const parsed = JSON.parse(readFileSync12(join103(projectsRoot, entry), "utf-8"));
165477
166193
  const worktree = typeof parsed.worktree === "string" ? parsed.worktree : typeof parsed.directory === "string" ? parsed.directory : null;
165478
166194
  if (!worktree || typeof parsed.id !== "string") {
165479
166195
  continue;
@@ -165489,26 +166205,26 @@ function listProjectIdsForCwd(cwd) {
165489
166205
  }
165490
166206
  function readOpencodeSessionId(transcriptPath) {
165491
166207
  try {
165492
- const parsed = JSON.parse(readFileSync11(transcriptPath, "utf-8"));
165493
- return typeof parsed.id === "string" ? parsed.id : basename33(transcriptPath, ".json");
166208
+ const parsed = JSON.parse(readFileSync12(transcriptPath, "utf-8"));
166209
+ return typeof parsed.id === "string" ? parsed.id : basename43(transcriptPath, ".json");
165494
166210
  } catch {
165495
- return basename33(transcriptPath, ".json");
166211
+ return basename43(transcriptPath, ".json");
165496
166212
  }
165497
166213
  }
165498
166214
  function listOpencodeSessionPaths(cwd) {
165499
166215
  const sessionPaths = /* @__PURE__ */ new Map();
165500
166216
  for (const projectId of listProjectIdsForCwd(cwd)) {
165501
- const sessionDir = join93(getOpencodeSessionRoot(), projectId);
165502
- if (!existsSync14(sessionDir)) {
166217
+ const sessionDir = join103(getOpencodeSessionRoot(), projectId);
166218
+ if (!existsSync15(sessionDir)) {
165503
166219
  continue;
165504
166220
  }
165505
- for (const entry of readdirSync6(sessionDir)) {
166221
+ for (const entry of readdirSync7(sessionDir)) {
165506
166222
  if (!entry.startsWith("ses_") || !entry.endsWith(".json")) {
165507
166223
  continue;
165508
166224
  }
165509
- const transcriptPath = join93(sessionDir, entry);
166225
+ const transcriptPath = join103(sessionDir, entry);
165510
166226
  try {
165511
- sessionPaths.set(transcriptPath, statSync6(transcriptPath).mtimeMs);
166227
+ sessionPaths.set(transcriptPath, statSync7(transcriptPath).mtimeMs);
165512
166228
  } catch {
165513
166229
  continue;
165514
166230
  }
@@ -165518,17 +166234,17 @@ function listOpencodeSessionPaths(cwd) {
165518
166234
  }
165519
166235
  function findOpencodeSessionPath(nativeSessionId, cwd) {
165520
166236
  for (const transcriptPath of listOpencodeSessionPaths(cwd)) {
165521
- if (basename33(transcriptPath, ".json") === nativeSessionId) {
166237
+ if (basename43(transcriptPath, ".json") === nativeSessionId) {
165522
166238
  return transcriptPath;
165523
166239
  }
165524
166240
  }
165525
166241
  const sessionRoot = getOpencodeSessionRoot();
165526
- if (!existsSync14(sessionRoot)) {
166242
+ if (!existsSync15(sessionRoot)) {
165527
166243
  return null;
165528
166244
  }
165529
- for (const projectId of readdirSync6(sessionRoot)) {
165530
- const candidate = join93(sessionRoot, projectId, `${nativeSessionId}.json`);
165531
- if (existsSync14(candidate)) {
166245
+ for (const projectId of readdirSync7(sessionRoot)) {
166246
+ const candidate = join103(sessionRoot, projectId, `${nativeSessionId}.json`);
166247
+ if (existsSync15(candidate)) {
165532
166248
  return candidate;
165533
166249
  }
165534
166250
  }
@@ -165539,28 +166255,28 @@ function sessionContainsOrbhSessionId(transcriptPath, orbhSessionId) {
165539
166255
  if (!nativeSessionId) {
165540
166256
  return false;
165541
166257
  }
165542
- const storageRoot = join93(getOpencodeStorageRoot());
165543
- const messageDir = join93(storageRoot, "message", nativeSessionId);
165544
- if (!existsSync14(messageDir)) {
166258
+ const storageRoot = join103(getOpencodeStorageRoot());
166259
+ const messageDir = join103(storageRoot, "message", nativeSessionId);
166260
+ if (!existsSync15(messageDir)) {
165545
166261
  return false;
165546
166262
  }
165547
- for (const entry of readdirSync6(messageDir)) {
165548
- const messagePath = join93(messageDir, entry);
166263
+ for (const entry of readdirSync7(messageDir)) {
166264
+ const messagePath = join103(messageDir, entry);
165549
166265
  try {
165550
- if (readFileSync11(messagePath, "utf-8").includes(orbhSessionId)) {
166266
+ if (readFileSync12(messagePath, "utf-8").includes(orbhSessionId)) {
165551
166267
  return true;
165552
166268
  }
165553
166269
  } catch {
165554
166270
  continue;
165555
166271
  }
165556
- const messageId = basename33(entry, ".json");
165557
- const partDir = join93(storageRoot, "part", messageId);
165558
- if (!existsSync14(partDir)) {
166272
+ const messageId = basename43(entry, ".json");
166273
+ const partDir = join103(storageRoot, "part", messageId);
166274
+ if (!existsSync15(partDir)) {
165559
166275
  continue;
165560
166276
  }
165561
- for (const partEntry of readdirSync6(partDir)) {
166277
+ for (const partEntry of readdirSync7(partDir)) {
165562
166278
  try {
165563
- if (readFileSync11(join93(partDir, partEntry), "utf-8").includes(orbhSessionId)) {
166279
+ if (readFileSync12(join103(partDir, partEntry), "utf-8").includes(orbhSessionId)) {
165564
166280
  return true;
165565
166281
  }
165566
166282
  } catch {
@@ -165706,7 +166422,7 @@ function createOpencodeHarness() {
165706
166422
  },
165707
166423
  resolveTranscriptPath(nativeSessionId, cwd) {
165708
166424
  const streamCapturePath = buildOpencodeStreamCapturePath(nativeSessionId);
165709
- if (existsSync14(streamCapturePath)) {
166425
+ if (existsSync15(streamCapturePath)) {
165710
166426
  return streamCapturePath;
165711
166427
  }
165712
166428
  return findOpencodeSessionPath(nativeSessionId, cwd);
@@ -165769,6 +166485,7 @@ var init_registry = __esm2({
165769
166485
  init_codex2();
165770
166486
  init_droid2();
165771
166487
  init_gemini2();
166488
+ init_grok2();
165772
166489
  init_opencode2();
165773
166490
  registry = /* @__PURE__ */ new Map();
165774
166491
  defaultHarnessRegistry = registry;
@@ -165776,6 +166493,7 @@ var init_registry = __esm2({
165776
166493
  registerHarness(createCodexHarness());
165777
166494
  registerHarness(createDroidHarness());
165778
166495
  registerHarness(createGeminiHarness());
166496
+ registerHarness(createGrokHarness());
165779
166497
  registerHarness(createOpencodeHarness());
165780
166498
  }
165781
166499
  });
@@ -166193,7 +166911,7 @@ function healSessionWithOptions(session, _options) {
166193
166911
  return true;
166194
166912
  }
166195
166913
  var getPendingQuestion = getPendingRequest;
166196
- function isRecord7(value) {
166914
+ function isRecord8(value) {
166197
166915
  return typeof value === "object" && value !== null && !Array.isArray(value);
166198
166916
  }
166199
166917
  function normalizeMessages(value) {
@@ -166201,7 +166919,7 @@ function normalizeMessages(value) {
166201
166919
  return [];
166202
166920
  }
166203
166921
  return value.flatMap((entry) => {
166204
- if (!isRecord7(entry)) {
166922
+ if (!isRecord8(entry)) {
166205
166923
  return [];
166206
166924
  }
166207
166925
  const { id, from, text, timestamp, delivered } = entry;
@@ -166215,18 +166933,18 @@ function normalizeSession(session) {
166215
166933
  return {
166216
166934
  ...session,
166217
166935
  model: typeof session.model === "string" && session.model.length > 0 ? session.model : null,
166218
- metadata: isRecord7(session.metadata) ? session.metadata : {},
166219
- hooks: isRecord7(session.hooks) ? session.hooks : {},
166936
+ metadata: isRecord8(session.metadata) ? session.metadata : {},
166937
+ hooks: isRecord8(session.hooks) ? session.hooks : {},
166220
166938
  messages: normalizeMessages(session.messages)
166221
166939
  };
166222
166940
  }
166223
166941
  function ensureSessionsDir(sessionsDir) {
166224
- if (!existsSync15(sessionsDir)) {
166942
+ if (!existsSync16(sessionsDir)) {
166225
166943
  mkdirSync3(sessionsDir, { recursive: true });
166226
166944
  }
166227
166945
  }
166228
166946
  function getSessionPath(sessionsDir, sessionId) {
166229
- return join37(sessionsDir, `${sessionId}.json`);
166947
+ return join38(sessionsDir, `${sessionId}.json`);
166230
166948
  }
166231
166949
  function createSession(sessionsDir, runtime2, prompt6, options3) {
166232
166950
  ensureSessionsDir(sessionsDir);
@@ -166253,7 +166971,7 @@ function createSession(sessionsDir, runtime2, prompt6, options3) {
166253
166971
  }
166254
166972
  function readSession(sessionsDir, sessionId) {
166255
166973
  const sessionPath = getSessionPath(sessionsDir, sessionId);
166256
- if (!existsSync15(sessionPath)) {
166974
+ if (!existsSync16(sessionPath)) {
166257
166975
  return null;
166258
166976
  }
166259
166977
  try {
@@ -166292,7 +167010,7 @@ function updateSession(sessionsDir, sessionId, update, options3) {
166292
167010
  return nextSession;
166293
167011
  }
166294
167012
  function listSessions(sessionsDir) {
166295
- if (!existsSync15(sessionsDir)) {
167013
+ if (!existsSync16(sessionsDir)) {
166296
167014
  return [];
166297
167015
  }
166298
167016
  return readdirSync(sessionsDir).filter((entry) => entry.endsWith(".json")).map((entry) => readSession(sessionsDir, entry.slice(0, -5))).filter((session) => session !== null).sort((a, b) => b.started.localeCompare(a.started));
@@ -166487,7 +167205,7 @@ var DEFAULTS = {
166487
167205
  includeUsage: true,
166488
167206
  includeSubagents: true
166489
167207
  };
166490
- function truncate3(text, max) {
167208
+ function truncate4(text, max) {
166491
167209
  if (text.length <= max) return text;
166492
167210
  return text.slice(0, max) + "\n... (truncated)";
166493
167211
  }
@@ -166500,7 +167218,7 @@ function formatToolUse(tool, opts, depth) {
166500
167218
  lines.push("");
166501
167219
  if (inputStr) {
166502
167220
  lines.push("````json");
166503
- lines.push(truncate3(inputStr, opts.maxToolInputLength));
167221
+ lines.push(truncate4(inputStr, opts.maxToolInputLength));
166504
167222
  lines.push("````");
166505
167223
  lines.push("");
166506
167224
  }
@@ -166509,7 +167227,7 @@ function formatToolUse(tool, opts, depth) {
166509
167227
  lines.push(resultLabel);
166510
167228
  lines.push("");
166511
167229
  lines.push("````");
166512
- lines.push(truncate3(tool.output, opts.maxToolOutputLength));
167230
+ lines.push(truncate4(tool.output, opts.maxToolOutputLength));
166513
167231
  lines.push("````");
166514
167232
  lines.push("");
166515
167233
  }
@@ -166927,6 +167645,7 @@ init_config();
166927
167645
  init_executable();
166928
167646
  init_droid2();
166929
167647
  init_gemini2();
167648
+ init_grok2();
166930
167649
  init_opencode2();
166931
167650
  init_executable();
166932
167651
  init_gemini2();
@@ -166952,7 +167671,7 @@ function buildHarnessSpawnEnv(cwd, sessionId, sessionsDir, baseEnv = process.env
166952
167671
  delete env3.CODEX_THREAD_ID;
166953
167672
  delete env3.CODEX_CI;
166954
167673
  delete env3.CODEX_SESSION_ID;
166955
- const localBin = join103(homedir72(), ".local", "bin");
167674
+ const localBin = join113(homedir82(), ".local", "bin");
166956
167675
  if (env3.PATH && !env3.PATH.startsWith(localBin)) {
166957
167676
  env3.PATH = `${localBin}:${env3.PATH}`;
166958
167677
  }
@@ -166984,29 +167703,29 @@ function sendNotification(session, exitCode) {
166984
167703
  }
166985
167704
  }
166986
167705
  function listRecentCodexRollouts() {
166987
- const sessionsRoot = join103(homedir72(), ".codex", "sessions");
166988
- if (!existsSync152(sessionsRoot)) {
167706
+ const sessionsRoot = join113(homedir82(), ".codex", "sessions");
167707
+ if (!existsSync162(sessionsRoot)) {
166989
167708
  return [];
166990
167709
  }
166991
167710
  const paths = [];
166992
- for (const year of readdirSync7(sessionsRoot, { withFileTypes: true })) {
167711
+ for (const year of readdirSync8(sessionsRoot, { withFileTypes: true })) {
166993
167712
  if (!year.isDirectory()) {
166994
167713
  continue;
166995
167714
  }
166996
- const yearPath = join103(sessionsRoot, year.name);
166997
- for (const month of readdirSync7(yearPath, { withFileTypes: true })) {
167715
+ const yearPath = join113(sessionsRoot, year.name);
167716
+ for (const month of readdirSync8(yearPath, { withFileTypes: true })) {
166998
167717
  if (!month.isDirectory()) {
166999
167718
  continue;
167000
167719
  }
167001
- const monthPath = join103(yearPath, month.name);
167002
- for (const day of readdirSync7(monthPath, { withFileTypes: true })) {
167720
+ const monthPath = join113(yearPath, month.name);
167721
+ for (const day of readdirSync8(monthPath, { withFileTypes: true })) {
167003
167722
  if (!day.isDirectory()) {
167004
167723
  continue;
167005
167724
  }
167006
- const dayPath = join103(monthPath, day.name);
167007
- for (const fileName of readdirSync7(dayPath)) {
167725
+ const dayPath = join113(monthPath, day.name);
167726
+ for (const fileName of readdirSync8(dayPath)) {
167008
167727
  if (fileName.startsWith("rollout-") && fileName.endsWith(".jsonl")) {
167009
- paths.push(join103(dayPath, fileName));
167728
+ paths.push(join113(dayPath, fileName));
167010
167729
  }
167011
167730
  }
167012
167731
  }
@@ -167018,7 +167737,7 @@ function listCodexNativeSessionCandidates(cwd) {
167018
167737
  const candidates = [];
167019
167738
  for (const rolloutPath of listRecentCodexRollouts()) {
167020
167739
  try {
167021
- const [firstLine] = readFileSync12(rolloutPath, "utf-8").split("\n");
167740
+ const [firstLine] = readFileSync13(rolloutPath, "utf-8").split("\n");
167022
167741
  if (!firstLine) {
167023
167742
  continue;
167024
167743
  }
@@ -167087,7 +167806,7 @@ async function spawnHarnessProcess(options3) {
167087
167806
  return buildPendingOpencodeStreamCapturePath(options3.sessionId);
167088
167807
  })() : null;
167089
167808
  const opencodeStreamCapture = opencodeStreamCapturePath ? createWriteStream(opencodeStreamCapturePath, { flags: "w" }) : null;
167090
- const child = spawn23(spawnCmd, [...executable.resolvedCommand.prependArgs, ...harness.buildSpawnArgs(options3.config)], {
167809
+ const child = spawn32(spawnCmd, [...executable.resolvedCommand.prependArgs, ...harness.buildSpawnArgs(options3.config)], {
167091
167810
  cwd: options3.cwd,
167092
167811
  detached: process.platform !== "win32",
167093
167812
  windowsHide: true,
@@ -167327,13 +168046,13 @@ function parseProfileTarget(target) {
167327
168046
  return { runtime: runtime2, name, explicitProfile: true };
167328
168047
  }
167329
168048
  function getProfilesPath() {
167330
- return join113(homedir82(), ".nuucognition", "orbh", "profiles.json");
168049
+ return join123(homedir9(), ".nuucognition", "orbh", "profiles.json");
167331
168050
  }
167332
168051
  function loadProfiles(filePath = getProfilesPath()) {
167333
- if (!existsSync16(filePath)) {
168052
+ if (!existsSync17(filePath)) {
167334
168053
  return {};
167335
168054
  }
167336
- const raw = readFileSync13(filePath, "utf-8").trim();
168055
+ const raw = readFileSync14(filePath, "utf-8").trim();
167337
168056
  if (!raw) {
167338
168057
  return {};
167339
168058
  }
@@ -167378,11 +168097,200 @@ function resolveTarget(target, profiles) {
167378
168097
  } : null
167379
168098
  };
167380
168099
  }
168100
+ function stripInteractivePrefix(title) {
168101
+ return title.replace(/^\(Interactive\)\s*/i, "").trim();
168102
+ }
168103
+ function extractIcon(inner) {
168104
+ return inner.trimStart().match(/^[^\x00-\x7F]+/)?.[0].trim() ?? "";
168105
+ }
168106
+ function runtimeLabel(runtime2) {
168107
+ if (!runtime2) return "";
168108
+ const overrides = { opencode: "OpenCode" };
168109
+ const key = runtime2.toLowerCase();
168110
+ if (overrides[key]) return overrides[key];
168111
+ return key.charAt(0).toUpperCase() + key.slice(1);
168112
+ }
168113
+ function composeTitle(opts) {
168114
+ const icon = extractIcon(opts.inner);
168115
+ const shortId2 = opts.sessionId.slice(0, 8);
168116
+ const label = runtimeLabel(opts.runtime);
168117
+ const withPrefix2 = (composed) => {
168118
+ const trimmed = composed.trim();
168119
+ if (!label) return trimmed;
168120
+ if (!trimmed) return `${label}:`;
168121
+ return `${label}: ${trimmed}`;
168122
+ };
168123
+ if (opts.titleTransform) {
168124
+ return withPrefix2(
168125
+ opts.titleTransform({
168126
+ inner: opts.inner,
168127
+ icon,
168128
+ title: opts.title,
168129
+ sessionId: opts.sessionId,
168130
+ shortId: shortId2,
168131
+ runtime: opts.runtime,
168132
+ cwd: opts.cwd
168133
+ })
168134
+ );
168135
+ }
168136
+ if (opts.titleFormat) {
168137
+ return withPrefix2(
168138
+ opts.titleFormat.replaceAll("{inner}", opts.inner).replaceAll("{icon}", icon).replaceAll("{title}", opts.title).replaceAll("{sessionId}", opts.sessionId).replaceAll("{shortId}", shortId2).replaceAll("{runtime}", opts.runtime).replaceAll("{cwd}", opts.cwd)
168139
+ );
168140
+ }
168141
+ let body;
168142
+ if (opts.title.length === 0) body = icon.length > 0 ? icon : opts.inner;
168143
+ else if (icon.length === 0) body = opts.title;
168144
+ else body = `${opts.title} ${icon}`;
168145
+ return withPrefix2(body);
168146
+ }
168147
+ async function spawnWithTitleRewrite(opts) {
168148
+ let pty;
168149
+ try {
168150
+ pty = await import("node-pty");
168151
+ } catch (err) {
168152
+ throw new Error(
168153
+ `Title rewriting requires the 'node-pty' optional dependency. Install it or omit --title-format. Original error: ${String(err)}`
168154
+ );
168155
+ }
168156
+ const cols = process.stdout.columns ?? 120;
168157
+ const rows = process.stdout.rows ?? 30;
168158
+ const term = pty.spawn(opts.cmd, opts.args, {
168159
+ name: process.env.TERM ?? "xterm-256color",
168160
+ cols,
168161
+ rows,
168162
+ cwd: opts.cwd,
168163
+ env: opts.env
168164
+ });
168165
+ const emitter = new EventEmitter2();
168166
+ emitter.pid = term.pid;
168167
+ emitter.stderr = null;
168168
+ emitter.kill = (signal) => {
168169
+ try {
168170
+ term.kill(typeof signal === "string" ? signal : void 0);
168171
+ } catch {
168172
+ }
168173
+ return true;
168174
+ };
168175
+ const stdinWasRaw = process.stdin.isTTY ? process.stdin.isRaw : false;
168176
+ if (process.stdin.isTTY && !stdinWasRaw) {
168177
+ process.stdin.setRawMode(true);
168178
+ }
168179
+ process.stdin.resume();
168180
+ const onStdin = (data) => term.write(data.toString("utf8"));
168181
+ process.stdin.on("data", onStdin);
168182
+ const onResize = () => {
168183
+ try {
168184
+ term.resize(process.stdout.columns ?? cols, process.stdout.rows ?? rows);
168185
+ } catch {
168186
+ }
168187
+ };
168188
+ process.stdout.on("resize", onResize);
168189
+ const OSC_TITLE = /\x1b\]([012]);([^\x07\x1b]*)(\x07|\x1b\\)/g;
168190
+ const currentTitle = () => {
168191
+ const raw = opts.getSessionTitle?.() ?? "";
168192
+ return stripInteractivePrefix(raw);
168193
+ };
168194
+ const rewrite = (inner) => composeTitle({
168195
+ inner,
168196
+ title: currentTitle(),
168197
+ sessionId: opts.sessionId,
168198
+ runtime: opts.runtime,
168199
+ cwd: opts.cwd,
168200
+ titleFormat: opts.titleFormat,
168201
+ titleTransform: opts.titleTransform
168202
+ });
168203
+ let lastInner = "";
168204
+ let lastTitle = currentTitle();
168205
+ let lastEmitted = null;
168206
+ const emit = (composed) => {
168207
+ if (composed === lastEmitted) return;
168208
+ lastEmitted = composed;
168209
+ process.stdout.write(`\x1B]0;${composed}\x07`);
168210
+ };
168211
+ const pollTick = () => {
168212
+ const title = currentTitle();
168213
+ if (title === lastTitle) return;
168214
+ lastTitle = title;
168215
+ emit(rewrite(lastInner));
168216
+ };
168217
+ term.onData((chunk) => {
168218
+ const out = chunk.replace(OSC_TITLE, (_match, selector, inner, terminator) => {
168219
+ lastInner = inner;
168220
+ lastTitle = currentTitle();
168221
+ const composed = rewrite(inner);
168222
+ lastEmitted = composed;
168223
+ return `\x1B]${selector};${composed}${terminator}`;
168224
+ });
168225
+ process.stdout.write(out);
168226
+ });
168227
+ emit(rewrite(""));
168228
+ const pollMs = opts.titlePollMs ?? 1e3;
168229
+ const pollTimer = pollMs > 0 && opts.getSessionTitle ? setInterval(pollTick, pollMs) : null;
168230
+ term.onExit(({ exitCode, signal }) => {
168231
+ if (pollTimer) clearInterval(pollTimer);
168232
+ process.stdin.off("data", onStdin);
168233
+ process.stdout.off("resize", onResize);
168234
+ if (process.stdin.isTTY) {
168235
+ try {
168236
+ process.stdin.setRawMode(stdinWasRaw);
168237
+ } catch {
168238
+ }
168239
+ }
168240
+ process.stdin.pause();
168241
+ if (opts.exitTitle && process.stdout.isTTY) {
168242
+ process.stdout.write(`\x1B]0;${opts.exitTitle}\x07`);
168243
+ }
168244
+ emitter.emit("exit", exitCode, signal ? String(signal) : null);
168245
+ });
168246
+ return emitter;
168247
+ }
168248
+ function resolveTitleFormat(explicit) {
168249
+ if (typeof explicit === "string" && explicit.length > 0) return explicit;
168250
+ const env3 = process.env.ORBH_TITLE_FORMAT;
168251
+ if (typeof env3 === "string" && env3.length > 0) return env3;
168252
+ return void 0;
168253
+ }
168254
+ function canRewriteTitle() {
168255
+ return Boolean(process.stdout.isTTY && process.stdin.isTTY);
168256
+ }
168257
+ async function spawnInteractiveChild(opts) {
168258
+ if (canRewriteTitle()) {
168259
+ try {
168260
+ const format = resolveTitleFormat(opts.titleFormat);
168261
+ const getSessionTitle = () => {
168262
+ const session = readSession(opts.sessionsDir, opts.sessionId);
168263
+ return session?.title ?? void 0;
168264
+ };
168265
+ return await spawnWithTitleRewrite({
168266
+ cmd: opts.cmd,
168267
+ args: opts.args,
168268
+ cwd: opts.cwd,
168269
+ env: opts.env,
168270
+ sessionId: opts.sessionId,
168271
+ runtime: opts.runtime,
168272
+ titleFormat: format,
168273
+ titleTransform: opts.titleTransform,
168274
+ exitTitle: opts.titleOnExit ?? opts.runtime,
168275
+ getSessionTitle
168276
+ });
168277
+ } catch (err) {
168278
+ process.stderr.write(`orbh: title rewriting disabled (${err.message})
168279
+ `);
168280
+ }
168281
+ }
168282
+ return spawn42(opts.cmd, opts.args, {
168283
+ cwd: opts.cwd,
168284
+ stdio: "inherit",
168285
+ windowsHide: true,
168286
+ env: opts.env
168287
+ });
168288
+ }
167381
168289
  var DEFAULT_RUNTIME_PREFERENCE = ["codex", "claude", "gemini", "droid"];
167382
168290
  var READY_TIMEOUT_MS = 1e4;
167383
168291
  var COMPLETION_TIMEOUT_MS = 30 * 60 * 1e3;
167384
168292
  var POLL_INTERVAL_MS = 250;
167385
- function sleep(ms) {
168293
+ function sleep2(ms) {
167386
168294
  return new Promise((resolve19) => setTimeout(resolve19, ms));
167387
168295
  }
167388
168296
  async function waitForSession(sessionsDir, sessionId, predicate, timeoutMs) {
@@ -167392,7 +168300,7 @@ async function waitForSession(sessionsDir, sessionId, predicate, timeoutMs) {
167392
168300
  if (session && predicate(session)) {
167393
168301
  return session;
167394
168302
  }
167395
- await sleep(POLL_INTERVAL_MS);
168303
+ await sleep2(POLL_INTERVAL_MS);
167396
168304
  }
167397
168305
  throw new Error(`Timed out while waiting for Orbh session '${sessionId}'.`);
167398
168306
  }
@@ -167645,7 +168553,7 @@ async function spawnDetachedResume(session, harness, options3) {
167645
168553
  throw new Error(`Orbh runtime '${harness.name}' is not installed or not available.`);
167646
168554
  }
167647
168555
  const spawnCmd = executable.resolvedCommand.cmd;
167648
- const child = spawn32(spawnCmd, [...executable.resolvedCommand.prependArgs, ...args], {
168556
+ const child = spawn42(spawnCmd, [...executable.resolvedCommand.prependArgs, ...args], {
167649
168557
  cwd: options3.cwd,
167650
168558
  detached: process.platform !== "win32",
167651
168559
  windowsHide: true,
@@ -167690,7 +168598,8 @@ async function spawnDetachedResume(session, harness, options3) {
167690
168598
  }
167691
168599
  async function waitForInteractiveResult(child, options3, session, runtime2) {
167692
168600
  let stderr = "";
167693
- child.stderr?.on("data", (chunk) => {
168601
+ const stderrStream = child.stderr;
168602
+ stderrStream?.on("data", (chunk) => {
167694
168603
  stderr += chunk.toString();
167695
168604
  });
167696
168605
  return new Promise((resolve19, reject) => {
@@ -167847,11 +168756,19 @@ async function launchInteractive(options3) {
167847
168756
  writeSession(options3.sessionsDir, session2);
167848
168757
  const executable2 = await getExecutable(harness2.name);
167849
168758
  const spawnCmd2 = executable2.resolvedCommand.cmd;
167850
- const child2 = spawn32(spawnCmd2, [...executable2.resolvedCommand.prependArgs, ...args2], {
168759
+ const spawnArgs2 = [...executable2.resolvedCommand.prependArgs, ...args2];
168760
+ const spawnEnv2 = buildHarnessSpawnEnv(options3.cwd, session2.id, options3.sessionsDir);
168761
+ const child2 = await spawnInteractiveChild({
168762
+ cmd: spawnCmd2,
168763
+ args: spawnArgs2,
167851
168764
  cwd: options3.cwd,
167852
- stdio: "inherit",
167853
- windowsHide: true,
167854
- env: buildHarnessSpawnEnv(options3.cwd, session2.id, options3.sessionsDir)
168765
+ env: spawnEnv2,
168766
+ sessionId: session2.id,
168767
+ sessionsDir: options3.sessionsDir,
168768
+ runtime: harness2.name,
168769
+ titleFormat: options3.titleFormat,
168770
+ titleTransform: options3.titleTransform,
168771
+ titleOnExit: options3.titleOnExit
167855
168772
  });
167856
168773
  if (child2.pid) {
167857
168774
  updateCurrentRun(session2, { pid: child2.pid, status: "running" });
@@ -167926,6 +168843,17 @@ async function launchInteractive(options3) {
167926
168843
  model: options3.model,
167927
168844
  extraArgs: appliedConfig.extraArgs
167928
168845
  });
168846
+ } else if (harness.name === "grok") {
168847
+ nativeSessionId = await bootstrapGrokSession(options3.cwd, config.prompt, {
168848
+ env: appliedConfig.env,
168849
+ model: resolvedModel,
168850
+ extraArgs: appliedConfig.extraArgs
168851
+ });
168852
+ args = interactiveResumeArgs(nativeSessionId, {
168853
+ cwd: options3.cwd,
168854
+ model: options3.model,
168855
+ extraArgs: appliedConfig.extraArgs
168856
+ });
167929
168857
  } else {
167930
168858
  if (!interactiveArgs) {
167931
168859
  throw new Error(`Runtime '${harness.name}' does not support interactive launch.`);
@@ -167945,11 +168873,19 @@ async function launchInteractive(options3) {
167945
168873
  writeSession(options3.sessionsDir, session);
167946
168874
  const executable = await getExecutable(harness.name);
167947
168875
  const spawnCmd = executable.resolvedCommand.cmd;
167948
- const child = spawn32(spawnCmd, [...executable.resolvedCommand.prependArgs, ...args], {
168876
+ const spawnArgs = [...executable.resolvedCommand.prependArgs, ...args];
168877
+ const spawnEnv = buildHarnessSpawnEnv(options3.cwd, session.id, options3.sessionsDir, process.env, appliedConfig.env);
168878
+ const child = await spawnInteractiveChild({
168879
+ cmd: spawnCmd,
168880
+ args: spawnArgs,
167949
168881
  cwd: options3.cwd,
167950
- stdio: "inherit",
167951
- windowsHide: true,
167952
- env: buildHarnessSpawnEnv(options3.cwd, session.id, options3.sessionsDir, process.env, appliedConfig.env)
168882
+ env: spawnEnv,
168883
+ sessionId: session.id,
168884
+ sessionsDir: options3.sessionsDir,
168885
+ runtime: harness.name,
168886
+ titleFormat: options3.titleFormat,
168887
+ titleTransform: options3.titleTransform,
168888
+ titleOnExit: options3.titleOnExit
167953
168889
  });
167954
168890
  if (child.pid) {
167955
168891
  updateCurrentRun(session, { pid: child.pid, status: "running" });
@@ -167986,9 +168922,9 @@ init_registry();
167986
168922
  init_dist();
167987
168923
  import { access as access8, readFile as readFile15 } from "fs/promises";
167988
168924
  import path23 from "path";
167989
- import { homedir as homedir9 } from "os";
168925
+ import { homedir as homedir10 } from "os";
167990
168926
  import { randomUUID as randomUUID8 } from "crypto";
167991
- import { spawn as spawn7 } from "child_process";
168927
+ import { spawn as spawn8 } from "child_process";
167992
168928
  import { readFile as readFile26 } from "fs/promises";
167993
168929
  import Fastify from "fastify";
167994
168930
  import { readFile as readFile36, writeFile as writeFile13, mkdir as mkdir17, rm as rm13 } from "fs/promises";
@@ -167997,15 +168933,15 @@ var DEFAULT_HOST = "127.0.0.1";
167997
168933
  var DEFAULT_PORT = 13041;
167998
168934
  var DEFAULT_SESSIONS_DIR = ".orbh/sessions";
167999
168935
  var DEFAULT_CONFIG_FILENAME = "orbh.toml";
168000
- function isRecord8(value) {
168936
+ function isRecord9(value) {
168001
168937
  return typeof value === "object" && value !== null && !Array.isArray(value);
168002
168938
  }
168003
168939
  function expandHome(value) {
168004
168940
  if (value === "~") {
168005
- return homedir9();
168941
+ return homedir10();
168006
168942
  }
168007
168943
  if (value.startsWith("~/")) {
168008
- return path23.join(homedir9(), value.slice(2));
168944
+ return path23.join(homedir10(), value.slice(2));
168009
168945
  }
168010
168946
  return value;
168011
168947
  }
@@ -168026,7 +168962,7 @@ function normalizeSessionsDir(value) {
168026
168962
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
168027
168963
  }
168028
168964
  function normalizeRuntimeOverrides(value) {
168029
- if (!isRecord8(value)) {
168965
+ if (!isRecord9(value)) {
168030
168966
  return {};
168031
168967
  }
168032
168968
  const overrides = {};
@@ -168046,7 +168982,7 @@ async function maybeReadConfig(configPath) {
168046
168982
  }
168047
168983
  const content = await readFile15(configPath, "utf-8");
168048
168984
  const parsed = parse2(content);
168049
- if (!isRecord8(parsed)) {
168985
+ if (!isRecord9(parsed)) {
168050
168986
  throw new Error(`Invalid ${DEFAULT_CONFIG_FILENAME}: expected a TOML object`);
168051
168987
  }
168052
168988
  return parsed;
@@ -169022,7 +169958,7 @@ var OrbhService = class {
169022
169958
  extraArgs: DEFAULT_EXTRA_ARGS_BY_RUNTIME[session.runtime] ?? []
169023
169959
  };
169024
169960
  const spawnCmd = executable.resolvedPath ?? executable.resolvedCommand.cmd;
169025
- const child = spawn7(
169961
+ const child = spawn8(
169026
169962
  spawnCmd,
169027
169963
  [...executable.resolvedCommand.prependArgs, ...args],
169028
169964
  {
@@ -169799,7 +170735,7 @@ async function getOrbhServerStatus(options3 = {}) {
169799
170735
  }
169800
170736
 
169801
170737
  // ../orbh-cli/src/await.ts
169802
- function isRecord9(value) {
170738
+ function isRecord10(value) {
169803
170739
  return typeof value === "object" && value !== null && !Array.isArray(value);
169804
170740
  }
169805
170741
  function normalizeKey(value) {
@@ -169827,7 +170763,7 @@ function collectScalarMatches(value, path30, matches) {
169827
170763
  });
169828
170764
  return;
169829
170765
  }
169830
- if (!isRecord9(value)) {
170766
+ if (!isRecord10(value)) {
169831
170767
  return;
169832
170768
  }
169833
170769
  for (const [key, entry] of Object.entries(value)) {
@@ -169978,7 +170914,7 @@ async function waitForOrbhEvent(options3) {
169978
170914
  // ../../node_modules/.pnpm/strip-ansi@7.2.0/node_modules/strip-ansi/index.js
169979
170915
  init_ansi_regex();
169980
170916
  var regex2 = ansiRegex2();
169981
- function stripAnsi3(string) {
170917
+ function stripAnsi4(string) {
169982
170918
  if (typeof string !== "string") {
169983
170919
  throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
169984
170920
  }
@@ -170125,7 +171061,7 @@ function stringWidth(input, options3 = {}) {
170125
171061
  } = options3;
170126
171062
  let string = input;
170127
171063
  if (!countAnsiEscapeCodes && (string.includes("\x1B") || string.includes("\x9B"))) {
170128
- string = stripAnsi3(string);
171064
+ string = stripAnsi4(string);
170129
171065
  }
170130
171066
  if (string.length === 0) {
170131
171067
  return 0;
@@ -170525,7 +171461,7 @@ var wrapWord = (rows, word, columns) => {
170525
171461
  const characters = getGraphemes(word);
170526
171462
  let isInsideEscape = false;
170527
171463
  let isInsideLinkEscape = false;
170528
- let visible = stringWidth(stripAnsi3(rows.at(-1)));
171464
+ let visible = stringWidth(stripAnsi4(rows.at(-1)));
170529
171465
  for (const [index, character] of characters.entries()) {
170530
171466
  const characterLength = stringWidth(character);
170531
171467
  if (visible + characterLength <= columns) {
@@ -170684,7 +171620,7 @@ function wrapAnsi(string, columns, options3) {
170684
171620
  // ../orbh-cli/src/terminal-format.ts
170685
171621
  var VALID_STATUSES = ["queued", "in-progress", "blocked", "deferred", "finished", "failed", "cancelled"];
170686
171622
  var ANSI_PATTERN = /\u001B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;
170687
- function stripAnsi4(text) {
171623
+ function stripAnsi5(text) {
170688
171624
  return text.replace(ANSI_PATTERN, "");
170689
171625
  }
170690
171626
  function padVisible(text, width) {
@@ -170695,14 +171631,14 @@ function wrapToWidth(text, width) {
170695
171631
  const wrapped = wrapAnsi(text, Math.max(1, width), { hard: true, wordWrap: true, trim: false });
170696
171632
  return wrapped.split("\n");
170697
171633
  }
170698
- function truncate4(text, maxLen) {
171634
+ function truncate5(text, maxLen) {
170699
171635
  if (maxLen === Number.POSITIVE_INFINITY || text.length <= maxLen) {
170700
171636
  return text;
170701
171637
  }
170702
171638
  return `${text.slice(0, maxLen)}...`;
170703
171639
  }
170704
171640
  function summarizeLines(text, maxLen) {
170705
- return truncate4(text.replace(/\s+/g, " ").trim(), maxLen);
171641
+ return truncate5(text.replace(/\s+/g, " ").trim(), maxLen);
170706
171642
  }
170707
171643
  function stringifyValue4(value) {
170708
171644
  if (typeof value === "string") {
@@ -170719,7 +171655,7 @@ function formatToolInputSummary(tool, input, maxLen) {
170719
171655
  return input.file_path;
170720
171656
  }
170721
171657
  if (tool === "Bash" && typeof input.command === "string") {
170722
- return truncate4(input.command, maxLen);
171658
+ return truncate5(input.command, maxLen);
170723
171659
  }
170724
171660
  if ((tool === "Glob" || tool === "Grep") && typeof input.pattern === "string") {
170725
171661
  return input.pattern;
@@ -170729,7 +171665,7 @@ function formatToolInputSummary(tool, input, maxLen) {
170729
171665
  const agentType = typeof input.subagent_type === "string" ? input.subagent_type : "";
170730
171666
  return agentType ? `[${agentType}] ${description}` : description;
170731
171667
  }
170732
- return truncate4(JSON.stringify(input), maxLen);
171668
+ return truncate5(JSON.stringify(input), maxLen);
170733
171669
  }
170734
171670
  function extractAgentResultText(output) {
170735
171671
  const textParts = [];
@@ -170766,7 +171702,7 @@ function boxDivider(title, color, width) {
170766
171702
  let displayTitle = title;
170767
171703
  const vis = stringWidth(title);
170768
171704
  if (vis > maxTitle && maxTitle > 4) {
170769
- const plain = stripAnsi4(title);
171705
+ const plain = stripAnsi5(title);
170770
171706
  displayTitle = export_pc.dim(plain.slice(0, maxTitle - 1) + "\u2026");
170771
171707
  }
170772
171708
  const displayVis = stringWidth(displayTitle);
@@ -171140,7 +172076,7 @@ var TranscriptWatchFormatter = class _TranscriptWatchFormatter {
171140
172076
  if (needsDivider) result.push(this.divider(""));
171141
172077
  result.push(this.wrap(export_pc.magenta(export_pc.bold("Compaction"))));
171142
172078
  if (entry.summary) {
171143
- result.push(...this.wrapContent(export_pc.dim(truncate4(entry.summary, this.maxSummaryLength))));
172079
+ result.push(...this.wrapContent(export_pc.dim(truncate5(entry.summary, this.maxSummaryLength))));
171144
172080
  }
171145
172081
  return result;
171146
172082
  }
@@ -171246,7 +172182,7 @@ function readTranscriptEntries(session, transcriptCwd) {
171246
172182
  return null;
171247
172183
  }
171248
172184
  try {
171249
- const content = readFileSync14(transcriptPath, "utf-8");
172185
+ const content = readFileSync15(transcriptPath, "utf-8");
171250
172186
  return harness.parseTranscript(content, { transcriptPath });
171251
172187
  } catch {
171252
172188
  return null;
@@ -171267,7 +172203,7 @@ async function defaultResumeDeferredSession(resumeContext) {
171267
172203
  }
171268
172204
  var REQUEST_SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
171269
172205
  var REQUEST_LAUNCH_OPTION_KEYS = ["runtime", "stream", "continues", "maxTurns", "budget", "model", "title", "description", "timeout"];
171270
- function sleep2(ms) {
172206
+ function sleep3(ms) {
171271
172207
  return new Promise((resolve19) => setTimeout(resolve19, ms));
171272
172208
  }
171273
172209
  function getStringOption(options3, key) {
@@ -171482,7 +172418,7 @@ async function waitForSessionWithSpinner(sessionsDir, sessionId, timeoutMs) {
171482
172418
  process.stdout.write("\r\x1B[2K");
171483
172419
  return { session, timedOut: true };
171484
172420
  }
171485
- await sleep2(120);
172421
+ await sleep3(120);
171486
172422
  }
171487
172423
  }
171488
172424
  async function waitForSessionQuiet(sessionsDir, sessionId, timeoutMs) {
@@ -171498,7 +172434,7 @@ async function waitForSessionQuiet(sessionsDir, sessionId, timeoutMs) {
171498
172434
  if (deadline !== null && Date.now() > deadline) {
171499
172435
  return { session, timedOut: true };
171500
172436
  }
171501
- await sleep2(500);
172437
+ await sleep3(500);
171502
172438
  }
171503
172439
  }
171504
172440
  async function streamSessionTranscript(session, context, options3) {
@@ -171523,7 +172459,7 @@ async function streamSessionTranscript(session, context, options3) {
171523
172459
  process.stdout.write("\r\x1B[2K");
171524
172460
  return { session: readFreshSession(), timedOut: true };
171525
172461
  }
171526
- await sleep2(500);
172462
+ await sleep3(500);
171527
172463
  current = readFreshSession();
171528
172464
  run2 = getCurrentRun(current);
171529
172465
  nativeId = run2?.nativeSessionId ?? current.id;
@@ -171541,14 +172477,14 @@ async function streamSessionTranscript(session, context, options3) {
171541
172477
  console.log(`${export_pc.bold("Watching")} ${export_pc.cyan(shortId(current.id))} ${export_pc.dim("\xB7")} ${current.runtime}${title} ${export_pc.dim("\xB7")} ${statusIcon(current.status)} ${current.status}`);
171542
172478
  console.log(export_pc.dim(transcriptPath));
171543
172479
  console.log("");
171544
- if (!existsSync17(transcriptPath)) {
172480
+ if (!existsSync18(transcriptPath)) {
171545
172481
  process.stdout.write(export_pc.dim("Waiting for transcript..."));
171546
- while (!existsSync17(transcriptPath)) {
172482
+ while (!existsSync18(transcriptPath)) {
171547
172483
  if (deadline !== null && Date.now() > deadline) {
171548
172484
  process.stdout.write("\r\x1B[2K");
171549
172485
  return { session: readFreshSession(), timedOut: true };
171550
172486
  }
171551
- await sleep2(500);
172487
+ await sleep3(500);
171552
172488
  }
171553
172489
  process.stdout.write("\r\x1B[2K");
171554
172490
  }
@@ -171596,7 +172532,7 @@ async function streamSessionTranscript(session, context, options3) {
171596
172532
  while (true) {
171597
172533
  const fresh = readFreshSession();
171598
172534
  if (isTerminalStatus(fresh.status)) {
171599
- await sleep2(1e3);
172535
+ await sleep3(1e3);
171600
172536
  if (entryCount > 0) {
171601
172537
  process.stdout.write("\r\x1B[2K");
171602
172538
  }
@@ -171626,7 +172562,7 @@ async function streamSessionTranscript(session, context, options3) {
171626
172562
  }, true));
171627
172563
  return { session: fresh, timedOut: true };
171628
172564
  }
171629
- await sleep2(250);
172565
+ await sleep3(250);
171630
172566
  }
171631
172567
  } finally {
171632
172568
  watcher.stop();
@@ -172145,11 +173081,11 @@ ${export_pc.bold("Orbh Session Stats")} ${export_pc.dim("\xB7")} ${export_pc.cya
172145
173081
  console.log(`${export_pc.bold("Watching")} ${export_pc.cyan(shortId(session.id))} ${export_pc.dim("\xB7")} ${session.runtime}${title} ${export_pc.dim("\xB7")} ${statusIcon(session.status)} ${session.status}${metadata}`);
172146
173082
  console.log(export_pc.dim(transcriptPath));
172147
173083
  console.log("");
172148
- if (!existsSync17(transcriptPath)) {
173084
+ if (!existsSync18(transcriptPath)) {
172149
173085
  process.stdout.write(export_pc.dim("Waiting for transcript..."));
172150
173086
  await new Promise((resolvePromise, rejectPromise) => {
172151
173087
  const poll = setInterval(() => {
172152
- if (!existsSync17(transcriptPath)) {
173088
+ if (!existsSync18(transcriptPath)) {
172153
173089
  return;
172154
173090
  }
172155
173091
  clearInterval(poll);
@@ -172836,7 +173772,7 @@ ${export_pc.bold("Orbh Session Stats")} ${export_pc.dim("\xB7")} ${export_pc.cya
172836
173772
  const line = `${REQUEST_SPINNER_FRAMES[frame % REQUEST_SPINNER_FRAMES.length]} waiting for ${pending.length}/${resolvedIds.length} ${export_pc.dim("\xB7")} ${pendingLabel}`;
172837
173773
  process.stdout.write(`\r\x1B[2K${line}`);
172838
173774
  frame++;
172839
- await sleep2(250);
173775
+ await sleep3(250);
172840
173776
  }
172841
173777
  let hasFailure = false;
172842
173778
  for (const fullId of resolvedIds) {
@@ -172929,7 +173865,10 @@ function registerLaunchCommands(command, options3) {
172929
173865
  });
172930
173866
  const interactiveCommand = options3.extendInteractiveCommand ? options3.extendInteractiveCommand(command.command("i")) : command.command("i");
172931
173867
  addOptionalPathOption(
172932
- interactiveCommand.alias("interactive").description("Launch an interactive agent TUI with orbh session tracking").argument("<target>", `Harness runtime or runtime/name (${listHarnesses().join(", ")})`).argument("[prompt]", "Optional initial prompt").option("-c, --continue <sessionId>", "Continue a previous orbh session").option("--continues <sessionId>", "Link as continuation of another session (new session)").option("--model <model>", "Model override"),
173868
+ interactiveCommand.alias("interactive").description("Launch an interactive agent TUI with orbh session tracking").argument("<target>", `Harness runtime or runtime/name (${listHarnesses().join(", ")})`).argument("[prompt]", "Optional initial prompt").option("-c, --continue <sessionId>", "Continue a previous orbh session").option("--continues <sessionId>", "Link as continuation of another session (new session)").option("--model <model>", "Model override").option(
173869
+ "--title-format <fmt>",
173870
+ 'Override the terminal pane title template. Default: "{title} {icon}" \u2014 orbh session title (`(Interactive) ` stripped) plus the harness status icon. Placeholders: {title}, {icon}, {inner}, {shortId}, {sessionId}, {runtime}, {cwd}. Falls back to $ORBH_TITLE_FORMAT.'
173871
+ ),
172933
173872
  options3
172934
173873
  ).action(async (target, prompt6, commandOptions) => {
172935
173874
  const context = await getResolvedContext(commandOptions, options3);
@@ -172954,6 +173893,7 @@ function registerLaunchCommands(command, options3) {
172954
173893
  extraArgs,
172955
173894
  applicationPrompt: commandOptions.continue ? void 0 : options3.buildInteractiveApplicationPrompt,
172956
173895
  commandPath,
173896
+ titleFormat: commandOptions.titleFormat,
172957
173897
  onPrepared: ({ session, run: run2 }) => {
172958
173898
  const resumed = Boolean(commandOptions.continue);
172959
173899
  console.log(`${export_pc.bold(resumed ? "Orbh Interactive Session (resumed)" : "Orbh Interactive Session")}`);
@@ -172995,7 +173935,7 @@ function registerServerCommands(command) {
172995
173935
  if (latest.running) {
172996
173936
  return latest;
172997
173937
  }
172998
- await sleep2(250);
173938
+ await sleep3(250);
172999
173939
  latest = await getOrbhServerStatus(resolveServerConfigOptions(process.cwd(), opts));
173000
173940
  }
173001
173941
  return latest;
@@ -173041,7 +173981,7 @@ function registerServerCommands(command) {
173041
173981
  const daemonChild = process.env.ORBH_DAEMON_CHILD === "1";
173042
173982
  if (opts.daemon && !daemonChild) {
173043
173983
  const childArgs = process.argv.slice(1).filter((arg) => arg !== "--daemon");
173044
- const child = spawn8(process.argv[0] ?? process.execPath, childArgs, {
173984
+ const child = spawn9(process.argv[0] ?? process.execPath, childArgs, {
173045
173985
  cwd: process.cwd(),
173046
173986
  detached: true,
173047
173987
  stdio: "ignore",
@@ -173132,7 +174072,7 @@ function registerServerCommands(command) {
173132
174072
  console.log(export_pc.green(`Orbh server stopped.`));
173133
174073
  return;
173134
174074
  }
173135
- await sleep2(250);
174075
+ await sleep3(250);
173136
174076
  }
173137
174077
  console.error(export_pc.red(`Timed out waiting for orbh server PID ${status.pid} to stop.`));
173138
174078
  process.exit(1);
@@ -173168,7 +174108,7 @@ function registerOrbhCommands(command, options3) {
173168
174108
  }
173169
174109
  async function resolveStandaloneContext() {
173170
174110
  return {
173171
- sessionsDir: process.env.ORBH_SESSIONS_DIR ? resolvePath3(process.env.ORBH_SESSIONS_DIR) : join38(process.cwd(), ".orbh", "sessions"),
174111
+ sessionsDir: process.env.ORBH_SESSIONS_DIR ? resolvePath3(process.env.ORBH_SESSIONS_DIR) : join39(process.cwd(), ".orbh", "sessions"),
173172
174112
  transcriptCwd: process.env.ORBH_CWD ? resolvePath3(process.env.ORBH_CWD) : process.cwd()
173173
174113
  };
173174
174114
  }
@@ -173180,7 +174120,7 @@ function createStandaloneOrbhCommand() {
173180
174120
  return command;
173181
174121
  }
173182
174122
  var __dirname5 = dirname12(fileURLToPath6(import.meta.url));
173183
- var pkg2 = JSON.parse(readFileSync14(join38(__dirname5, "..", "package.json"), "utf-8"));
174123
+ var pkg2 = JSON.parse(readFileSync15(join39(__dirname5, "..", "package.json"), "utf-8"));
173184
174124
  function createStandaloneOrbhProgram() {
173185
174125
  return createStandaloneOrbhCommand().version(formatVersion(pkg2.version ?? "0.0.0", "orbh"));
173186
174126
  }
@@ -173191,7 +174131,7 @@ if (isDirectExecution) {
173191
174131
 
173192
174132
  // src/commands/agent/orbh.ts
173193
174133
  function getSessionsDir(flintPath) {
173194
- return join39(flintPath, ".orbh", "sessions");
174134
+ return join40(flintPath, ".orbh", "sessions");
173195
174135
  }
173196
174136
  async function resolveFlintPath5(optionPath) {
173197
174137
  const flintPath = optionPath || await findFlintRoot(process.cwd());
@@ -173205,23 +174145,6 @@ async function resolveCtx(optionPath) {
173205
174145
  const flintPath = await resolveFlintPath5(optionPath);
173206
174146
  return { flintPath, sessionsDir: getSessionsDir(flintPath) };
173207
174147
  }
173208
- function sessionReferencedInMesh(flintPath, sessionId) {
173209
- try {
173210
- execSync5(`grep -r "${sessionId}" "${join39(flintPath, "Mesh")}" --include="*.md" -l`, { stdio: "pipe", windowsHide: true });
173211
- return true;
173212
- } catch {
173213
- return false;
173214
- }
173215
- }
173216
- function askYesNo(question) {
173217
- const rl = createInterface7({ input: process.stdin, output: process.stdout });
173218
- return new Promise((resolve19) => {
173219
- rl.question(question, (answer) => {
173220
- rl.close();
173221
- resolve19(answer.trim().toLowerCase() === "y" || answer.trim().toLowerCase() === "yes");
173222
- });
173223
- });
173224
- }
173225
174148
  function escapeAppleScriptString(value) {
173226
174149
  return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\r?\n/g, " ");
173227
174150
  }
@@ -173238,54 +174161,6 @@ function sendNotification3(title, message) {
173238
174161
  } catch {
173239
174162
  }
173240
174163
  }
173241
- function buildSessionFrontmatter(sessionId, runtime2) {
173242
- const now = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
173243
- const runtimeTag2 = runtime2 === "claude" ? "claude-code" : runtime2;
173244
- const runtimeTitle = runtime2 === "claude" ? "Claude Code" : runtime2.charAt(0).toUpperCase() + runtime2.slice(1);
173245
- return [
173246
- "---",
173247
- `id: ${sessionId}`,
173248
- "tags:",
173249
- ' - "#agent/session"',
173250
- ` - "#agent/${runtimeTag2}"`,
173251
- `date: ${now}`,
173252
- "---",
173253
- "",
173254
- `# ${runtimeTitle} Session`,
173255
- ""
173256
- ].join("\n");
173257
- }
173258
- function exportSessionTranscript(session, flintPath) {
173259
- const harness = getHarness(session.runtime);
173260
- if (!harness) {
173261
- return;
173262
- }
173263
- const run2 = getCurrentRun(session);
173264
- const nativeId = run2?.nativeSessionId ?? session.id;
173265
- const transcriptPath = harness.resolveTranscriptPath(nativeId, flintPath);
173266
- if (!transcriptPath) {
173267
- console.log(export_pc.dim("No transcript found to export."));
173268
- return;
173269
- }
173270
- let content;
173271
- try {
173272
- content = readFileSync15(transcriptPath, "utf-8");
173273
- } catch {
173274
- console.log(export_pc.dim("Could not read transcript file."));
173275
- return;
173276
- }
173277
- const entries = harness.parseTranscript(content, { transcriptPath });
173278
- if (entries.length === 0) {
173279
- console.log(export_pc.dim("Transcript is empty, skipping export."));
173280
- return;
173281
- }
173282
- const markdown2 = buildSessionFrontmatter(nativeId, session.runtime) + formatTranscriptMarkdown(entries);
173283
- const runtimeDir2 = session.runtime === "claude" ? "Claude Code" : session.runtime.charAt(0).toUpperCase() + session.runtime.slice(1);
173284
- const outputDir = join39(flintPath, "Mesh", "Agents", runtimeDir2);
173285
- mkdirSync4(outputDir, { recursive: true });
173286
- writeFileSync2(join39(outputDir, `${nativeId}.md`), markdown2, "utf-8");
173287
- console.log(export_pc.green(`Session exported \u2192 Mesh/Agents/${runtimeDir2}/${nativeId}.md`));
173288
- }
173289
174164
  var orbhCommand = new Command("orbh").description("Orbh meta-harness agent management").enablePositionalOptions();
173290
174165
  registerOrbhCommands(orbhCommand, {
173291
174166
  commandPath: "flint orbh",
@@ -173336,28 +174211,7 @@ registerOrbhCommands(orbhCommand, {
173336
174211
  title: "(Interactive) New Session",
173337
174212
  description: "TBC"
173338
174213
  }),
173339
- extendInteractiveCommand: (command) => command.option("--dev-channels", "Load development MCP channels (e.g. orbh)").option("--no-export", "Skip transcript export on exit"),
173340
- onInteractiveExit: async ({ session, commandOptions }) => {
173341
- if (typeof commandOptions === "object" && commandOptions !== null && "export" in commandOptions && commandOptions.export === false) {
173342
- return;
173343
- }
173344
- const flintPath = await resolveFlintPath5(
173345
- typeof commandOptions === "object" && commandOptions !== null && "path" in commandOptions ? commandOptions.path : void 0
173346
- );
173347
- const nativeId = getCurrentRun(session)?.nativeSessionId ?? session.id;
173348
- try {
173349
- if (sessionReferencedInMesh(flintPath, session.id) || sessionReferencedInMesh(flintPath, nativeId)) {
173350
- exportSessionTranscript(session, flintPath);
173351
- } else {
173352
- const save = await askYesNo(export_pc.dim("Save session transcript? (y/N) "));
173353
- if (save) {
173354
- exportSessionTranscript(session, flintPath);
173355
- }
173356
- }
173357
- } catch (error3) {
173358
- console.error(export_pc.dim(`Transcript export failed: ${error3 instanceof Error ? error3.message : error3}`));
173359
- }
173360
- }
174214
+ extendInteractiveCommand: (command) => command.option("--dev-channels", "Load development MCP channels (e.g. orbh)")
173361
174215
  });
173362
174216
  orbhCommand.command("artifact").description("Track a created artifact path in the session interface").argument("<id>", "Session ID (full or partial)").argument("<path>", "Path to the artifact").option("-p, --path <dir>", "Path to flint (default: auto-detect)").action(async (id, artifactPath, options3) => {
173363
174217
  const { sessionsDir } = await resolveCtx(options3.path);
@@ -173372,15 +174226,6 @@ orbhCommand.command("artifact").description("Track a created artifact path in th
173372
174226
  writeSession(sessionsDir, session);
173373
174227
  console.log(`Artifact tracked: ${artifactPath}`);
173374
174228
  });
173375
- orbhCommand.command("export").description("Export a session transcript to Mesh/Agents/<Runtime>/").argument("<id>", "Session ID (full or partial)").option("-p, --path <dir>", "Path to flint (default: auto-detect)").action(async (id, options3) => {
173376
- const { flintPath, sessionsDir } = await resolveCtx(options3.path);
173377
- const session = resolveSession(sessionsDir, id);
173378
- if (!session) {
173379
- console.error(export_pc.red(`Error: Session not found: ${id}`));
173380
- process.exit(1);
173381
- }
173382
- exportSessionTranscript(session, flintPath);
173383
- });
173384
174229
  orbhCommand.command("requests").description("View request/response pairs for a session").argument("<id>", "Session ID (full or partial)").option("-p, --path <dir>", "Path to flint (default: auto-detect)").option("--pending", "Show only unanswered requests").action(async (id, options3) => {
173385
174230
  const { sessionsDir } = await resolveCtx(options3.path);
173386
174231
  const session = resolveSession(sessionsDir, id);
@@ -173429,7 +174274,22 @@ ${export_pc.bold("Requests")} ${export_pc.dim(`\u2014 session ${shortId(session.
173429
174274
  });
173430
174275
 
173431
174276
  // src/commands/agent/tinderbox.ts
174277
+ import { stat as stat18 } from "fs/promises";
174278
+ import { join as join41 } from "path";
173432
174279
  init_dist4();
174280
+ async function pathExists6(path30) {
174281
+ try {
174282
+ await stat18(path30);
174283
+ return true;
174284
+ } catch {
174285
+ return false;
174286
+ }
174287
+ }
174288
+ function deriveTinderboxNameFromGitUrl(url) {
174289
+ const match2 = url.match(/[/:]([^/:]+?)(?:\.git)?\/?$/);
174290
+ const raw = match2?.[1] ?? "";
174291
+ return raw.replace(/^\(Tinderbox\)\s+/, "").trim();
174292
+ }
173433
174293
  async function requireTinderboxRoot() {
173434
174294
  const root = await findTinderboxRoot(process.cwd());
173435
174295
  if (!root) {
@@ -173438,6 +174298,21 @@ async function requireTinderboxRoot() {
173438
174298
  }
173439
174299
  return root;
173440
174300
  }
174301
+ function printObsidianRegistration(result) {
174302
+ const newlyRegistered = result.registeredVaults.filter((entry) => !entry.alreadyRegistered);
174303
+ if (newlyRegistered.length > 0) {
174304
+ console.log(export_pc.bold("\nRegistered In Obsidian"));
174305
+ for (const entry of newlyRegistered) {
174306
+ console.log(` ${export_pc.green("\u2713")} ${entry.name} ${export_pc.dim(`(id: ${entry.id})`)}`);
174307
+ }
174308
+ }
174309
+ if (result.focusSwitched) {
174310
+ console.log(export_pc.bold("\nFocus"));
174311
+ console.log(
174312
+ ` ${export_pc.green("\u2713")} ${result.focusSwitched.name} ${export_pc.dim(`(switched via NUU Obsidian plugin, id: ${result.focusSwitched.id})`)}`
174313
+ );
174314
+ }
174315
+ }
173441
174316
  function printSummary(result) {
173442
174317
  console.log(export_pc.bold("\nSummary"));
173443
174318
  console.log(` Cloned: ${result.cloned.length}`);
@@ -173446,6 +174321,9 @@ function printSummary(result) {
173446
174321
  console.log(` Already present: ${result.present.length}`);
173447
174322
  console.log(` Registry updated: ${result.registryUpdated.length}`);
173448
174323
  console.log(` Connections wired: ${result.connectionsWired.length}`);
174324
+ console.log(
174325
+ ` Obsidian vaults registered: ${result.registeredVaults.length}` + (result.focusSwitched ? ` (focused: ${result.focusSwitched.name})` : "")
174326
+ );
173449
174327
  if (result.warnings.length > 0) {
173450
174328
  console.log(export_pc.bold(export_pc.yellow("\nWarnings")));
173451
174329
  for (const warning of result.warnings) {
@@ -173733,10 +174611,156 @@ Flints (${flints.length}):`));
173733
174611
  process.exit(1);
173734
174612
  }
173735
174613
  })
174614
+ ).addCommand(
174615
+ new Command("publish").description("Add a remote to the Tinderbox repo and push the initial commit").argument("<url>", "Git remote URL (e.g. git@github.com:owner/repo.git)").action(async (url) => {
174616
+ const root = await requireTinderboxRoot();
174617
+ try {
174618
+ const { initialized } = await ensureTinderboxGitRepo(root);
174619
+ console.log(
174620
+ initialized ? export_pc.green("\u2713 Initialized git repository") : export_pc.dim("Git already initialized.")
174621
+ );
174622
+ } catch (err) {
174623
+ console.error(export_pc.red(`Failed to initialize git: ${err instanceof Error ? err.message : String(err)}`));
174624
+ process.exit(1);
174625
+ }
174626
+ const addRemote = await runGit(root, ["remote", "add", "origin", url]);
174627
+ if (!addRemote.success) {
174628
+ if (addRemote.error?.includes("already exists")) {
174629
+ const setUrl = await runGit(root, ["remote", "set-url", "origin", url]);
174630
+ if (!setUrl.success) {
174631
+ console.error(export_pc.red(`Failed to update remote: ${setUrl.error}`));
174632
+ process.exit(1);
174633
+ }
174634
+ console.log(export_pc.green(`\u2713 Updated remote origin \u2192 ${url}`));
174635
+ } else {
174636
+ console.error(export_pc.red(`Failed to add remote: ${addRemote.error}`));
174637
+ process.exit(1);
174638
+ }
174639
+ } else {
174640
+ console.log(export_pc.green(`\u2713 Added remote origin \u2192 ${url}`));
174641
+ }
174642
+ const renameBranch = await runGit(root, ["branch", "-M", "main"]);
174643
+ if (!renameBranch.success) {
174644
+ console.error(export_pc.red(`Failed to rename branch: ${renameBranch.error}`));
174645
+ process.exit(1);
174646
+ }
174647
+ const hasCommits = await runGit(root, ["rev-parse", "HEAD"]);
174648
+ if (!hasCommits.success) {
174649
+ const add = await runGit(root, ["add", "-A"]);
174650
+ if (!add.success) {
174651
+ console.error(export_pc.red(`Failed to stage files: ${add.error}`));
174652
+ process.exit(1);
174653
+ }
174654
+ const commit = await runGit(root, ["commit", "-m", "Initial tinderbox commit"]);
174655
+ if (!commit.success) {
174656
+ console.error(export_pc.red(`Failed to create initial commit: ${commit.error}`));
174657
+ process.exit(1);
174658
+ }
174659
+ console.log(export_pc.green("\u2713 Created initial commit"));
174660
+ } else {
174661
+ const status = await getGitStatus(root);
174662
+ if (!status.clean) {
174663
+ const add = await runGit(root, ["add", "-A"]);
174664
+ if (!add.success) {
174665
+ console.error(export_pc.red(`Failed to stage files: ${add.error}`));
174666
+ process.exit(1);
174667
+ }
174668
+ const now = /* @__PURE__ */ new Date();
174669
+ const ts = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")} ${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`;
174670
+ const commit = await runGit(root, ["commit", "-m", `tinderbox sync ${ts}`]);
174671
+ if (!commit.success) {
174672
+ console.error(export_pc.red(`Failed to commit: ${commit.error}`));
174673
+ process.exit(1);
174674
+ }
174675
+ console.log(export_pc.green(`\u2713 Committed pending changes`));
174676
+ }
174677
+ }
174678
+ const push = await runGit(root, ["push", "-u", "origin", "main"]);
174679
+ if (!push.success) {
174680
+ console.error(export_pc.red(`Push failed: ${push.error}`));
174681
+ console.log(export_pc.dim("You can retry with: flint tinderbox git sync"));
174682
+ process.exit(1);
174683
+ }
174684
+ console.log(export_pc.green("\u2713 Pushed to origin/main"));
174685
+ console.log();
174686
+ console.log(export_pc.bold("Tinderbox published. Use `flint tinderbox git sync` to keep in sync."));
174687
+ console.log();
174688
+ })
173736
174689
  );
173737
174690
  var tinderboxCommand = new Command("tinderbox").description("Orchestrate operations across multiple Flints").action(function() {
173738
174691
  this.help();
173739
174692
  }).addCommand(
174693
+ new Command("init").description("Bootstrap an empty Tinderbox, or clone one from a git remote and sync").argument("[name]", "Tinderbox name (defaults to the repo basename when --from is given)").option("--from <url>", "Clone an existing Tinderbox from a git URL, then sync").option("--no-open", "Skip registering Flints in Obsidian and switching focus").action(async (nameArg, opts) => {
174694
+ const cwd = process.cwd();
174695
+ if (opts.from) {
174696
+ const url = opts.from;
174697
+ const name = (nameArg?.trim() || deriveTinderboxNameFromGitUrl(url)).trim();
174698
+ if (!name) {
174699
+ console.error(export_pc.red("Error: Could not derive a name from URL \u2014 pass <name> explicitly."));
174700
+ process.exit(1);
174701
+ }
174702
+ const folderName = getTinderboxFolderNameForRoot(name);
174703
+ const destination = join41(cwd, folderName);
174704
+ if (await pathExists6(destination)) {
174705
+ console.error(export_pc.red(`Error: Destination already exists: ${destination}`));
174706
+ process.exit(1);
174707
+ }
174708
+ console.log(export_pc.dim(`Cloning ${url} \u2192 ${abbreviatePath(destination)}...`));
174709
+ const clone = await runGit(cwd, ["clone", url, folderName]);
174710
+ if (!clone.success) {
174711
+ console.error(export_pc.red(`Clone failed: ${clone.error}`));
174712
+ process.exit(1);
174713
+ }
174714
+ console.log(export_pc.green("\u2713 Cloned"));
174715
+ if (!await pathExists6(join41(destination, "tinderbox.toml"))) {
174716
+ console.error(export_pc.red("Error: Cloned repository is not a Tinderbox (missing tinderbox.toml)."));
174717
+ console.log(export_pc.dim(` ${destination}`));
174718
+ process.exit(1);
174719
+ }
174720
+ console.log(export_pc.dim("\nSyncing declared Flints..."));
174721
+ try {
174722
+ const result = await syncTinderbox(destination, { obsidian: opts.open !== false });
174723
+ printObsidianRegistration(result);
174724
+ printSummary(result);
174725
+ if (result.errors.length > 0) {
174726
+ console.log(export_pc.bold(export_pc.red("\nErrors")));
174727
+ for (const err of result.errors) {
174728
+ console.log(` ${export_pc.red("!")} ${export_pc.bold(err.scope)}: ${err.message}`);
174729
+ }
174730
+ }
174731
+ } catch (err) {
174732
+ const message = err instanceof Error ? err.message : String(err);
174733
+ console.error(export_pc.red(`Sync failed: ${message}`));
174734
+ process.exit(1);
174735
+ }
174736
+ console.log();
174737
+ console.log(export_pc.bold(`Tinderbox initialized from ${url}.`));
174738
+ console.log(export_pc.dim(` ${abbreviatePath(destination)}`));
174739
+ console.log();
174740
+ return;
174741
+ }
174742
+ const trimmedName = nameArg?.trim();
174743
+ if (!trimmedName) {
174744
+ console.error(export_pc.red("Error: <name> is required when --from is not provided."));
174745
+ console.log(export_pc.dim("Usage: flint tinderbox init <name>"));
174746
+ console.log(export_pc.dim(" flint tinderbox init [name] --from <url>"));
174747
+ process.exit(1);
174748
+ }
174749
+ try {
174750
+ const result = await initEmptyTinderbox(cwd, trimmedName);
174751
+ console.log(export_pc.bold("\nTinderbox initialized"));
174752
+ console.log(` ${export_pc.green("\u2713")} ${export_pc.bold(trimmedName)} ${export_pc.dim(abbreviatePath(result.root))}`);
174753
+ console.log();
174754
+ console.log(export_pc.dim(" Empty Tinderbox created. Import Flints with `flint tinderbox import <name>` or edit tinderbox.toml."));
174755
+ console.log(export_pc.dim(" Publish to a remote with `flint tinderbox git publish <url>`."));
174756
+ console.log();
174757
+ } catch (err) {
174758
+ const message = err instanceof Error ? err.message : String(err);
174759
+ console.error(export_pc.red(`Error: ${message}`));
174760
+ process.exit(1);
174761
+ }
174762
+ })
174763
+ ).addCommand(
173740
174764
  new Command("start").description("Promote the current Flint into a new Tinderbox").argument("<name>", "Tinderbox name").argument("[path]", "Parent directory for the new Tinderbox (defaults to the current Flint's parent)").action(async (name, path30) => {
173741
174765
  try {
173742
174766
  const cwd = process.cwd();
@@ -173746,7 +174770,7 @@ var tinderboxCommand = new Command("tinderbox").description("Orchestrate operati
173746
174770
  console.log(` ${export_pc.green("\u2713")} ${export_pc.bold(name)} ${export_pc.dim(abbreviatePath(result.root))}`);
173747
174771
  console.log(` ${export_pc.green("\u2713")} Moved ${export_pc.bold(result.flintMoved.name)} ${export_pc.dim(`${abbreviatePath(result.flintMoved.from)} \u2192 ${abbreviatePath(result.flintMoved.to)}`)}`);
173748
174772
  console.log();
173749
- console.log(export_pc.dim(" Tinderbox is now a git repository. Add a remote with `git remote add origin <url>` from the Tinderbox root."));
174773
+ console.log(export_pc.dim(" Tinderbox is now a git repository. Publish to a remote with `flint tinderbox git publish <url>`."));
173750
174774
  console.log();
173751
174775
  } catch (error3) {
173752
174776
  const message = error3 instanceof Error ? error3.message : String(error3);
@@ -173776,10 +174800,10 @@ var tinderboxCommand = new Command("tinderbox").description("Orchestrate operati
173776
174800
  }
173777
174801
  })
173778
174802
  ).addCommand(
173779
- new Command("sync").description("Materialize Flints, register them, and wire connections").action(async () => {
174803
+ new Command("sync").description("Materialize Flints, register them, and wire connections").option("--no-open", "Skip registering Flints in Obsidian and switching focus").action(async (opts) => {
173780
174804
  try {
173781
174805
  const root = await requireTinderboxRoot();
173782
- const result = await syncTinderbox(root);
174806
+ const result = await syncTinderbox(root, { obsidian: opts.open !== false });
173783
174807
  if (result.cloned.length > 0) {
173784
174808
  console.log(export_pc.bold("\nCloned"));
173785
174809
  for (const name of result.cloned) {
@@ -173804,6 +174828,7 @@ var tinderboxCommand = new Command("tinderbox").description("Orchestrate operati
173804
174828
  console.log(` ${export_pc.green("\u2713")} ${edge.from} -> ${edge.to}`);
173805
174829
  }
173806
174830
  }
174831
+ printObsidianRegistration(result);
173807
174832
  printSummary(result);
173808
174833
  if (result.undeclared.length > 0) {
173809
174834
  console.log(export_pc.bold(export_pc.yellow("Undeclared Flints (on disk but not in config)")));
@@ -173936,11 +174961,11 @@ var tinderboxCommand = new Command("tinderbox").description("Orchestrate operati
173936
174961
  init_dist4();
173937
174962
  import { createRequire as createRequire2 } from "module";
173938
174963
  import path28 from "path";
173939
- import { spawn as spawn10 } from "child_process";
173940
- import { stat as stat19 } from "fs/promises";
174964
+ import { spawn as spawn11 } from "child_process";
174965
+ import { stat as stat20 } from "fs/promises";
173941
174966
 
173942
174967
  // ../../packages/flint-sdk/src/common.ts
173943
- function isRecord10(value) {
174968
+ function isRecord11(value) {
173944
174969
  return typeof value === "object" && value !== null && !Array.isArray(value);
173945
174970
  }
173946
174971
  async function parseErrorBody(response) {
@@ -173948,7 +174973,7 @@ async function parseErrorBody(response) {
173948
174973
  try {
173949
174974
  if (contentType.includes("application/json")) {
173950
174975
  const data = await response.json();
173951
- return isRecord10(data) ? data : null;
174976
+ return isRecord11(data) ? data : null;
173952
174977
  }
173953
174978
  const text = await response.text();
173954
174979
  return text ? { message: text } : null;
@@ -174548,12 +175573,12 @@ var FlintServerClient = class {
174548
175573
 
174549
175574
  // ../../packages/flint-sdk/src/discovery.ts
174550
175575
  async function loadNodeModules() {
174551
- const [{ readFile: readFile18 }, { homedir: homedir11 }, { join: join49, resolve: resolve19 }] = await Promise.all([
175576
+ const [{ readFile: readFile18 }, { homedir: homedir12 }, { join: join51, resolve: resolve19 }] = await Promise.all([
174552
175577
  import("fs/promises"),
174553
175578
  import("os"),
174554
175579
  import("path")
174555
175580
  ]);
174556
- return { readFile: readFile18, homedir: homedir11, join: join49, resolve: resolve19 };
175581
+ return { readFile: readFile18, homedir: homedir12, join: join51, resolve: resolve19 };
174557
175582
  }
174558
175583
  function normalizeRegistryFile(value) {
174559
175584
  if (!value || typeof value !== "object" || !("servers" in value) || !Array.isArray(value.servers)) {
@@ -174569,12 +175594,12 @@ function normalizeRegistryFile(value) {
174569
175594
  return { version: 1, servers };
174570
175595
  }
174571
175596
  async function getServerRegistryPathCandidates(homeDir) {
174572
- const { homedir: homedir11, join: join49 } = await loadNodeModules();
174573
- const root = homeDir ?? homedir11();
175597
+ const { homedir: homedir12, join: join51 } = await loadNodeModules();
175598
+ const root = homeDir ?? homedir12();
174574
175599
  return [
174575
- join49(root, ".nuucognition", "servers.json"),
174576
- join49(root, ".nuucognition", ".flint", "servers.json"),
174577
- join49(root, ".flint", "servers.json")
175600
+ join51(root, ".nuucognition", "servers.json"),
175601
+ join51(root, ".nuucognition", ".flint", "servers.json"),
175602
+ join51(root, ".flint", "servers.json")
174578
175603
  ];
174579
175604
  }
174580
175605
  async function readServerRegistryFile(options3 = {}) {
@@ -174609,9 +175634,9 @@ import { fileURLToPath as fileURLToPath7 } from "url";
174609
175634
  import { join as join54 } from "path";
174610
175635
  import { readdirSync as readdirSync22, existsSync as existsSync43 } from "fs";
174611
175636
  import { randomUUID as randomUUID9, createHash as createHash3 } from "crypto";
174612
- import { EventEmitter as EventEmitter2 } from "events";
174613
- import { readFile as readFile16, stat as stat18 } from "fs/promises";
174614
- import { spawn as spawn9 } from "child_process";
175637
+ import { EventEmitter as EventEmitter3 } from "events";
175638
+ import { readFile as readFile16, stat as stat19 } from "fs/promises";
175639
+ import { spawn as spawn10 } from "child_process";
174615
175640
  import path26 from "path";
174616
175641
  import chokidar from "chokidar";
174617
175642
  import { glob } from "glob";
@@ -176152,12 +177177,12 @@ minimatch.unescape = unescape2;
176152
177177
  // ../../packages/flint-server/dist/index.js
176153
177178
  init_dist();
176154
177179
  import { parse as parseYaml6 } from "yaml";
176155
- import { existsSync as existsSync18, watch as watch4 } from "fs";
177180
+ import { existsSync as existsSync19, watch as watch4 } from "fs";
176156
177181
  import { stat as stat25 } from "fs/promises";
176157
177182
  import path27 from "path";
176158
177183
  import { mkdir as mkdir18, readFile as readFile27, writeFile as writeFile14 } from "fs/promises";
176159
- import { homedir as homedir10 } from "os";
176160
- import { join as join40, resolve as resolve18 } from "path";
177184
+ import { homedir as homedir11 } from "os";
177185
+ import { join as join46, resolve as resolve18 } from "path";
176161
177186
  init_dist4();
176162
177187
  init_dist4();
176163
177188
  init_dist4();
@@ -176166,7 +177191,7 @@ import { existsSync as existsSync24 } from "fs";
176166
177191
  import { stat as stat33, readFile as readFile37 } from "fs/promises";
176167
177192
  import path33 from "path";
176168
177193
  import path43, { join as join211 } from "path";
176169
- import { readdirSync as readdirSync8, readFileSync as readFileSync16, existsSync as existsSync33 } from "fs";
177194
+ import { readdirSync as readdirSync9, readFileSync as readFileSync16, existsSync as existsSync33 } from "fs";
176170
177195
  import { readdir as readdir15 } from "fs/promises";
176171
177196
  import path53 from "path";
176172
177197
  import { readdir as readdir25 } from "fs/promises";
@@ -176174,7 +177199,7 @@ import { join as join310 } from "path";
176174
177199
  import { mkdir as mkdir25, readFile as readFile43, rename as rename10, writeFile as writeFile26, readdir as readdir33 } from "fs/promises";
176175
177200
  import path62 from "path";
176176
177201
  import { writeFile as writeFile35, mkdir as mkdir33, readdir as readdir43, readFile as readFile53, stat as stat43 } from "fs/promises";
176177
- import { join as join46 } from "path";
177202
+ import { join as join47 } from "path";
176178
177203
  var DEFAULT_EVENT_LOG_SIZE = 200;
176179
177204
  function computeRuntimeId(flintPath) {
176180
177205
  const resolved = path26.resolve(flintPath);
@@ -176189,7 +177214,7 @@ var FlintRuntimeImpl = class {
176189
177214
  hooksPath;
176190
177215
  logger;
176191
177216
  eventLogSize;
176192
- emitter = new EventEmitter2();
177217
+ emitter = new EventEmitter3();
176193
177218
  watcher = null;
176194
177219
  hooksConfig = { hooks: {} };
176195
177220
  eventLog = [];
@@ -176471,7 +177496,7 @@ function normalizePath2(filePath) {
176471
177496
  }
176472
177497
  async function safeReadFile(filePath) {
176473
177498
  try {
176474
- const fileStats = await stat18(filePath);
177499
+ const fileStats = await stat19(filePath);
176475
177500
  if (!fileStats.isFile()) {
176476
177501
  return null;
176477
177502
  }
@@ -176571,7 +177596,7 @@ async function executeHook(options3) {
176571
177596
  path26.join(process.cwd(), "node_modules", ".bin"),
176572
177597
  process.env.PATH
176573
177598
  ].filter(Boolean);
176574
- const child = spawn9(command, {
177599
+ const child = spawn10(command, {
176575
177600
  cwd: flintPath,
176576
177601
  env: {
176577
177602
  ...process.env,
@@ -176755,7 +177780,7 @@ function createResilientWatcher({
176755
177780
  if (closed) {
176756
177781
  return;
176757
177782
  }
176758
- if (!existsSync18(targetPath)) {
177783
+ if (!existsSync19(targetPath)) {
176759
177784
  scheduleRestart();
176760
177785
  return;
176761
177786
  }
@@ -176818,9 +177843,9 @@ var RuntimeManager = class {
176818
177843
  }));
176819
177844
  }
176820
177845
  };
176821
- var REGISTRY_PATH = join40(homedir10(), ".nuucognition", "servers.json");
177846
+ var REGISTRY_PATH = join46(homedir11(), ".nuucognition", "servers.json");
176822
177847
  function getRegistryDir() {
176823
- return join40(homedir10(), ".nuucognition");
177848
+ return join46(homedir11(), ".nuucognition");
176824
177849
  }
176825
177850
  async function readServerRegistry() {
176826
177851
  return readServerRegistryEntries({ registryPath: REGISTRY_PATH });
@@ -177421,7 +178446,7 @@ async function buildFlintIdentity(ctx) {
177421
178446
  let totalSessions = 0;
177422
178447
  let activeSessions = 0;
177423
178448
  if (ctx.orbhSessionsDir && existsSync33(ctx.orbhSessionsDir)) {
177424
- const files = readdirSync8(ctx.orbhSessionsDir).filter((f) => f.endsWith(".json"));
178449
+ const files = readdirSync9(ctx.orbhSessionsDir).filter((f) => f.endsWith(".json"));
177425
178450
  totalSessions = files.length;
177426
178451
  for (const file of files) {
177427
178452
  try {
@@ -178084,7 +179109,7 @@ var LiveTranscriptWriter = class {
178084
179109
  writtenPaths = /* @__PURE__ */ new Set();
178085
179110
  constructor(options3) {
178086
179111
  this.flintPath = options3.flintPath;
178087
- this.sessionsDir = join46(options3.flintPath, ".orbh", "sessions");
179112
+ this.sessionsDir = join47(options3.flintPath, ".orbh", "sessions");
178088
179113
  this.channelRegistry = options3.channelRegistry;
178089
179114
  this.suppressPath = options3.suppressPath ?? null;
178090
179115
  this.liveSessionManager = new LiveSessionManager({
@@ -178133,7 +179158,7 @@ var LiveTranscriptWriter = class {
178133
179158
  * but whose session is no longer in-progress.
178134
179159
  */
178135
179160
  async sweepOrphans() {
178136
- const agentsDir = join46(this.flintPath, "Mesh", "Agents");
179161
+ const agentsDir = join47(this.flintPath, "Mesh", "Agents");
178137
179162
  let runtimeDirs;
178138
179163
  try {
178139
179164
  runtimeDirs = await readdir43(agentsDir);
@@ -178141,7 +179166,7 @@ var LiveTranscriptWriter = class {
178141
179166
  return;
178142
179167
  }
178143
179168
  for (const dir of runtimeDirs) {
178144
- const dirPath = join46(agentsDir, dir);
179169
+ const dirPath = join47(agentsDir, dir);
178145
179170
  const dirStat = await stat43(dirPath).catch(() => null);
178146
179171
  if (!dirStat?.isDirectory()) continue;
178147
179172
  let files;
@@ -178152,7 +179177,7 @@ var LiveTranscriptWriter = class {
178152
179177
  }
178153
179178
  for (const file of files) {
178154
179179
  if (!file.endsWith(".md")) continue;
178155
- const filePath = join46(dirPath, file);
179180
+ const filePath = join47(dirPath, file);
178156
179181
  let content;
178157
179182
  try {
178158
179183
  content = await readFile53(filePath, "utf-8");
@@ -178220,8 +179245,8 @@ var LiveTranscriptWriter = class {
178220
179245
  }
178221
179246
  async writeTranscript(sessionId, session, entries, live) {
178222
179247
  const dir = runtimeDir(session.runtime);
178223
- const outputDir = join46(this.flintPath, "Mesh", "Agents", dir);
178224
- const outputPath = join46(outputDir, `${sessionId}.md`);
179248
+ const outputDir = join47(this.flintPath, "Mesh", "Agents", dir);
179249
+ const outputPath = join47(outputDir, `${sessionId}.md`);
178225
179250
  try {
178226
179251
  await mkdir33(outputDir, { recursive: true });
178227
179252
  const frontmatter = buildLiveFrontmatter(session, live);
@@ -178643,7 +179668,7 @@ serverCommand.command("dev").description(
178643
179668
  }
178644
179669
  const devEntry = path28.join(serverPkgDir, "src", "dev.ts");
178645
179670
  try {
178646
- await stat19(devEntry);
179671
+ await stat20(devEntry);
178647
179672
  } catch {
178648
179673
  console.error(export_pc.red("Dev mode requires the server source directory."));
178649
179674
  console.log(
@@ -178665,7 +179690,7 @@ serverCommand.command("dev").description(
178665
179690
  `${export_pc.bold(export_pc.blue("Flint Server"))} ${export_pc.dim("dev mode \u2014 watching for changes")}
178666
179691
  `
178667
179692
  );
178668
- const child = spawn10("tsx", ["watch", devEntry], {
179693
+ const child = spawn11("tsx", ["watch", devEntry], {
178669
179694
  env: env3,
178670
179695
  stdio: "inherit",
178671
179696
  cwd: serverPkgDir,
@@ -178762,11 +179787,11 @@ serverCommand.command("list").description("List all running Flint servers from t
178762
179787
  // src/commands/server/steel.ts
178763
179788
  init_dist4();
178764
179789
  import { readFile as readFile17, readdir as readdir16, rm as rm14 } from "fs/promises";
178765
- import { join as join41 } from "path";
179790
+ import { join as join48 } from "path";
178766
179791
  async function exists6(path30) {
178767
179792
  try {
178768
- const { stat: stat20 } = await import("fs/promises");
178769
- await stat20(path30);
179793
+ const { stat: stat21 } = await import("fs/promises");
179794
+ await stat21(path30);
178770
179795
  return true;
178771
179796
  } catch {
178772
179797
  return false;
@@ -178788,7 +179813,7 @@ var steelCommand = new Command("steel").description("Manage Steel UI state (.ste
178788
179813
  console.error(export_pc.red("Error: Not inside a Flint. Use --path or cd into a Flint."));
178789
179814
  process.exit(1);
178790
179815
  }
178791
- const prefsPath = join41(flintPath, ".steel", "preferences.json");
179816
+ const prefsPath = join48(flintPath, ".steel", "preferences.json");
178792
179817
  if (options3.reset) {
178793
179818
  if (await exists6(prefsPath)) {
178794
179819
  await rm14(prefsPath);
@@ -178818,7 +179843,7 @@ var steelCommand = new Command("steel").description("Manage Steel UI state (.ste
178818
179843
  console.error(export_pc.red("Error: Not inside a Flint. Use --path or cd into a Flint."));
178819
179844
  process.exit(1);
178820
179845
  }
178821
- const plateDir = join41(flintPath, ".steel", "plates", plateName);
179846
+ const plateDir = join48(flintPath, ".steel", "plates", plateName);
178822
179847
  if (options3.reset) {
178823
179848
  if (await exists6(plateDir)) {
178824
179849
  await rm14(plateDir, { recursive: true });
@@ -178842,7 +179867,7 @@ var steelCommand = new Command("steel").description("Manage Steel UI state (.ste
178842
179867
  console.log();
178843
179868
  for (const file of stateFiles) {
178844
179869
  const key = file.name.replace(/\.json$/, "");
178845
- const data = await readJsonFile2(join41(plateDir, file.name));
179870
+ const data = await readJsonFile2(join48(plateDir, file.name));
178846
179871
  console.log(`${export_pc.cyan(key)}:`);
178847
179872
  console.log(JSON.stringify(data, null, 2));
178848
179873
  console.log();
@@ -178861,7 +179886,7 @@ var steelCommand = new Command("steel").description("Manage Steel UI state (.ste
178861
179886
  console.error(export_pc.red("Error: Not inside a Flint. Use --path or cd into a Flint."));
178862
179887
  process.exit(1);
178863
179888
  }
178864
- const boardsDir = join41(flintPath, ".steel", "plates", plateName, "boards");
179889
+ const boardsDir = join48(flintPath, ".steel", "plates", plateName, "boards");
178865
179890
  if (!await exists6(boardsDir)) {
178866
179891
  console.log(export_pc.dim(`No board configs found for plate: ${plateName}`));
178867
179892
  return;
@@ -179257,8 +180282,8 @@ var iamCommand = new Command("iam").argument("<name>", 'Person name to set as id
179257
180282
  init_dist4();
179258
180283
 
179259
180284
  // src/commands/system/helper/_shared.ts
179260
- import { readdirSync as readdirSync9, existsSync as existsSync19, statSync as statSync7 } from "fs";
179261
- import { join as join47, basename as basename10 } from "path";
180285
+ import { readdirSync as readdirSync10, existsSync as existsSync20, statSync as statSync8 } from "fs";
180286
+ import { join as join49, basename as basename10 } from "path";
179262
180287
  function extractNumberFromFile(filename, typeName) {
179263
180288
  const regex3 = new RegExp(`^\\(${typeName}\\)\\s+(\\d+)`, "i");
179264
180289
  const match2 = filename.match(regex3);
@@ -179266,13 +180291,13 @@ function extractNumberFromFile(filename, typeName) {
179266
180291
  }
179267
180292
  function collectFilesRecursively(dirPath) {
179268
180293
  const files = [];
179269
- if (!existsSync19(dirPath)) return files;
179270
- for (const entry of readdirSync9(dirPath)) {
179271
- const fullPath = join47(dirPath, entry);
180294
+ if (!existsSync20(dirPath)) return files;
180295
+ for (const entry of readdirSync10(dirPath)) {
180296
+ const fullPath = join49(dirPath, entry);
179272
180297
  try {
179273
- const stat20 = statSync7(fullPath);
179274
- if (stat20.isDirectory()) files.push(...collectFilesRecursively(fullPath));
179275
- else if (stat20.isFile()) files.push(basename10(fullPath));
180298
+ const stat21 = statSync8(fullPath);
180299
+ if (stat21.isDirectory()) files.push(...collectFilesRecursively(fullPath));
180300
+ else if (stat21.isFile()) files.push(basename10(fullPath));
179276
180301
  } catch {
179277
180302
  continue;
179278
180303
  }
@@ -179280,8 +180305,8 @@ function collectFilesRecursively(dirPath) {
179280
180305
  return files;
179281
180306
  }
179282
180307
  function getNextNumber(flintPath, typeName) {
179283
- const meshDir = join47(flintPath, "Mesh");
179284
- if (!existsSync19(meshDir)) return 1;
180308
+ const meshDir = join49(flintPath, "Mesh");
180309
+ if (!existsSync20(meshDir)) return 1;
179285
180310
  const numbers = collectFilesRecursively(meshDir).map((f) => extractNumberFromFile(f, typeName)).filter((n) => n !== null);
179286
180311
  return numbers.length === 0 ? 1 : Math.max(...numbers) + 1;
179287
180312
  }
@@ -179470,7 +180495,7 @@ var whoamiCommand = new Command("whoami").description("Show the current person i
179470
180495
  // src/index.ts
179471
180496
  registerAllFeatures();
179472
180497
  var __dirname6 = dirname13(fileURLToPath8(import.meta.url));
179473
- var pkg3 = JSON.parse(readFileSync17(join48(__dirname6, "..", "package.json"), "utf-8"));
180498
+ var pkg3 = JSON.parse(readFileSync17(join50(__dirname6, "..", "package.json"), "utf-8"));
179474
180499
  var profile = getBuildMode("flint");
179475
180500
  await runCliMigrations({
179476
180501
  cliname: "flint",
@@ -179511,7 +180536,7 @@ program2.name("flint").description("Flint cognitive workspace CLI").version(form
179511
180536
  setCommandGroups(program2, [
179512
180537
  {
179513
180538
  label: "Flint",
179514
- commands: ["init", "list", "status", "open", "register", "unregister", "delete", "move", "sync", "plan", "registry", "update"]
180539
+ commands: ["init", "list", "status", "open", "register", "unregister", "delete", "move", "sync", "gigasync", "plan", "registry", "update"]
179515
180540
  },
179516
180541
  {
179517
180542
  label: "Related Entities",
@@ -179555,6 +180580,7 @@ var COMMAND_MAP = [
179555
180580
  { featureId: "list", command: listCommand },
179556
180581
  { featureId: "shard", command: shardCommand },
179557
180582
  { featureId: "sync", command: syncCommand },
180583
+ { featureId: "gigasync", command: gigasyncCommand },
179558
180584
  { featureId: "git", command: gitCommand },
179559
180585
  { featureId: "open", command: openCommand },
179560
180586
  { featureId: "register", command: registerCommand },