@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/_orbh/prompts/base.md +1 -1
- package/dist/index.js +1826 -800
- package/package.json +9 -6
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
|
-
|
|
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
|
|
14104
|
-
import { homedir as
|
|
14105
|
-
import { basename as basename32, dirname as
|
|
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 {
|
|
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
|
|
14123
|
-
import { homedir as
|
|
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
|
|
14119
|
+
import { readFile as readFile62, readdir as readdir42, realpath } from "fs/promises";
|
|
14126
14120
|
import { existsSync as existsSync22 } from "fs";
|
|
14127
|
-
import { join as
|
|
14128
|
-
import { homedir as
|
|
14121
|
+
import { join as join102 } from "path";
|
|
14122
|
+
import { homedir as homedir32 } from "os";
|
|
14129
14123
|
import { request } from "http";
|
|
14130
|
-
import {
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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 =
|
|
16834
|
-
const home =
|
|
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 =
|
|
16996
|
+
current = dirname32(current);
|
|
16839
16997
|
}
|
|
16840
16998
|
} catch {
|
|
16841
|
-
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 =
|
|
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
|
|
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 =
|
|
16867
|
-
if (!await pathExists32(
|
|
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 =
|
|
16898
|
-
if (await pathExists32(
|
|
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(
|
|
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(
|
|
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:
|
|
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 &&
|
|
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 (
|
|
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
|
|
17123
|
+
await mkdir92(join112(flintPath, dir), { recursive: true });
|
|
16966
17124
|
}
|
|
16967
17125
|
}
|
|
16968
17126
|
async function materializeGitFlint(root, declaration) {
|
|
16969
|
-
const tempPath =
|
|
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 =
|
|
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
|
|
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 &&
|
|
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 &&
|
|
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 =
|
|
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 &&
|
|
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 ||
|
|
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 &&
|
|
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
|
|
17553
|
+
const entries = await readdir52(path202, { withFileTypes: true });
|
|
17345
17554
|
let count = 1;
|
|
17346
17555
|
for (const entry of entries) {
|
|
17347
|
-
count += await countFiles(
|
|
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 =
|
|
17353
|
-
if (await pathExists32(
|
|
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:
|
|
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 =
|
|
17370
|
-
const targetParent =
|
|
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 (
|
|
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
|
|
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 =
|
|
17656
|
+
const gitignorePath = join112(root, ".gitignore");
|
|
17448
17657
|
let existing = "";
|
|
17449
17658
|
try {
|
|
17450
|
-
existing = await
|
|
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
|
|
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 =
|
|
17464
|
-
if (!await pathExists32(
|
|
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 =
|
|
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(
|
|
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 =
|
|
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(
|
|
17730
|
+
if (await pathExists32(join112(tinderboxRoot, TINDERBOX_CONFIG_FILENAME))) {
|
|
17494
17731
|
throw new Error(`tinderbox.toml already exists at ${tinderboxRoot}`);
|
|
17495
17732
|
}
|
|
17496
|
-
await
|
|
17497
|
-
const destinationFlint =
|
|
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 (
|
|
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 =
|
|
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
|
|
17892
|
+
await mkdir10(join122(folderPath, sub), { recursive: true });
|
|
17656
17893
|
}
|
|
17657
|
-
const yamlPath =
|
|
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
|
|
17902
|
+
await writeFile82(yamlPath, stub, "utf-8");
|
|
17666
17903
|
}
|
|
17667
|
-
const readmePath =
|
|
17904
|
+
const readmePath = join122(folderPath, "README.md");
|
|
17668
17905
|
if (!await exists2(readmePath)) {
|
|
17669
|
-
await
|
|
17906
|
+
await writeFile82(readmePath, `# ${name}
|
|
17670
17907
|
`, "utf-8");
|
|
17671
17908
|
}
|
|
17672
|
-
const releasePath =
|
|
17909
|
+
const releasePath = join122(folderPath, "RELEASE.md");
|
|
17673
17910
|
if (!await exists2(releasePath)) {
|
|
17674
|
-
await
|
|
17911
|
+
await writeFile82(releasePath, "# 0.1.0\n\n- Initial shard scaffold\n", "utf-8");
|
|
17675
17912
|
}
|
|
17676
|
-
const migrationsPath =
|
|
17913
|
+
const migrationsPath = join122(folderPath, "MIGRATIONS.md");
|
|
17677
17914
|
if (!await exists2(migrationsPath)) {
|
|
17678
|
-
await
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
17793
|
-
const nextPath =
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
18266
|
+
const filePath = join122(shardPath, relativePath);
|
|
18030
18267
|
if (!await exists2(filePath)) return [];
|
|
18031
|
-
const content = await
|
|
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(
|
|
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 =
|
|
18314
|
+
const filePath = join122(shardPath, relativePath);
|
|
18078
18315
|
if (!await exists2(filePath)) return [];
|
|
18079
|
-
const content = await
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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
|
|
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 =
|
|
18549
|
+
const filePath = join122(shardPath, relativePath);
|
|
18313
18550
|
if (!await exists2(filePath)) return [];
|
|
18314
|
-
const content = await
|
|
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 =
|
|
18348
|
-
const workspaceReqsDir =
|
|
18349
|
-
const yamlPath =
|
|
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
|
|
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
|
|
18595
|
+
const content = await readFile82(yamlPath, "utf-8");
|
|
18359
18596
|
const cleaned = content.replace(/^scripts\s*:.*(?:\n(?:[ \t]+.*))*\n?/m, "");
|
|
18360
|
-
await
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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 =
|
|
18849
|
+
const dirPath = join122(shardPath, dir);
|
|
18613
18850
|
if (!await exists2(dirPath)) return;
|
|
18614
18851
|
const visit = async (currentPath, relativePrefix = "") => {
|
|
18615
|
-
const entries = await
|
|
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(
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
19246
|
+
const installedPath = join122(flintPath, entry.dest);
|
|
19010
19247
|
if (!await exists2(installedPath)) continue;
|
|
19011
|
-
const content = await
|
|
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 =
|
|
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
|
|
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 =
|
|
19379
|
+
const yamlPath = join122(shardPath, "shard.yaml");
|
|
19143
19380
|
try {
|
|
19144
|
-
const yamlContent = await
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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(
|
|
19485
|
+
const files = await collectMarkdownRelativePaths(join122(shardPath, dir));
|
|
19249
19486
|
for (const relativeFile of files) {
|
|
19250
|
-
const filePath =
|
|
19251
|
-
const content = await
|
|
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 =
|
|
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(
|
|
19309
|
-
templateCount: await countFiles2(
|
|
19310
|
-
workflowCount: await countFiles2(
|
|
19311
|
-
knowledgeCount: await countFiles2(
|
|
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:
|
|
19566
|
+
shardPath: join132(flintPath, "Shards", shard.folderName)
|
|
19330
19567
|
};
|
|
19331
19568
|
}
|
|
19332
19569
|
async function discoverScripts(shardPath) {
|
|
19333
|
-
const scriptsDir =
|
|
19570
|
+
const scriptsDir = join132(shardPath, "scripts");
|
|
19334
19571
|
try {
|
|
19335
|
-
const entries = await
|
|
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:
|
|
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 =
|
|
19374
|
-
const scriptPath =
|
|
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 =
|
|
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
|
|
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 =
|
|
19676
|
+
const dirPath = join142(flintPath, dir);
|
|
19440
19677
|
try {
|
|
19441
19678
|
await stat62(dirPath);
|
|
19442
19679
|
} catch {
|
|
19443
|
-
await
|
|
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 =
|
|
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 =
|
|
19512
|
-
const newPath =
|
|
19748
|
+
const parentDir = dirname42(flintPath);
|
|
19749
|
+
const newPath = join142(parentDir, expectedFolderName);
|
|
19513
19750
|
try {
|
|
19514
|
-
await
|
|
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 =
|
|
19795
|
+
const inboxDir = join142(currentFlintPath, "Inbox");
|
|
19559
19796
|
try {
|
|
19560
|
-
const inboxEntries = await
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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 =
|
|
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
|
|
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:
|
|
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
|
|
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(
|
|
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,
|
|
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
|
-
|
|
82724
|
-
isMacOs2 =
|
|
82725
|
-
isWindows3 =
|
|
82726
|
-
isLinux2 =
|
|
82727
|
-
isIos2 =
|
|
82728
|
-
isAndroid2 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
156525
|
-
import { promisify as
|
|
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/
|
|
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
|
|
156768
|
+
async function launchObsidianAtPath(path30) {
|
|
156657
156769
|
const os7 = platform4();
|
|
156658
|
-
|
|
156659
|
-
|
|
156660
|
-
|
|
156661
|
-
|
|
156662
|
-
|
|
156663
|
-
|
|
156664
|
-
|
|
156665
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
159064
|
-
const manifestJsonPath =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
159461
|
-
import { join as
|
|
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 =
|
|
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:
|
|
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 =
|
|
159667
|
-
const gitDir =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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:
|
|
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 =
|
|
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
|
-
|
|
160425
|
-
|
|
160426
|
-
|
|
160427
|
-
|
|
160428
|
-
|
|
160429
|
-
|
|
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 =
|
|
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:
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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:
|
|
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 =
|
|
160902
|
-
const gitDir =
|
|
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 =
|
|
161221
|
+
const status = execSync5("git status --porcelain", { cwd: shardPath, encoding: "utf-8" }).trim();
|
|
160911
161222
|
if (!status) {
|
|
160912
161223
|
try {
|
|
160913
|
-
const unpushed =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
160963
|
-
|
|
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
|
-
|
|
161276
|
+
execSync5("git push", { cwd: shardPath, stdio: "inherit" });
|
|
160966
161277
|
} catch {
|
|
160967
|
-
const branch =
|
|
160968
|
-
|
|
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 =
|
|
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:
|
|
161011
|
-
const gitDir =
|
|
161321
|
+
const { execSync: execSync5 } = await import("child_process");
|
|
161322
|
+
const gitDir = join35(shardPath, ".git");
|
|
161012
161323
|
if (existsSync7(gitDir)) {
|
|
161013
|
-
const remoteUrl =
|
|
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 =
|
|
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 =
|
|
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
|
|
161882
|
+
import { join as join36 } from "path";
|
|
161572
161883
|
import { stat as stat17, rm as rm12 } from "fs/promises";
|
|
161573
|
-
import { platform as
|
|
161884
|
+
import { platform as platform5 } from "os";
|
|
161885
|
+
import { request as httpRequest } from "http";
|
|
161574
161886
|
function getExpectedRepoUrl() {
|
|
161575
|
-
return
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 {
|
|
162136
|
-
import {
|
|
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
|
|
162142
|
-
import { existsSync as
|
|
162143
|
-
import { dirname as dirname12, join as
|
|
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
|
|
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
|
|
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 {
|
|
162176
|
-
import { existsSync as
|
|
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
|
|
162184
|
-
import { join as
|
|
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
|
|
162192
|
-
import { spawn as
|
|
162193
|
-
import { createWriteStream, existsSync as
|
|
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 =
|
|
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 =
|
|
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
|
-
},
|
|
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: "
|
|
164965
|
+
method: "thread/inject_items",
|
|
164630
164966
|
id: 3,
|
|
164631
164967
|
params: {
|
|
164632
164968
|
threadId,
|
|
164633
|
-
|
|
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
|
|
164638
|
-
|
|
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 (
|
|
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 || !
|
|
166015
|
+
if (!this.started || !existsSync14(this.transcriptPath)) {
|
|
165300
166016
|
return;
|
|
165301
166017
|
}
|
|
165302
166018
|
try {
|
|
165303
|
-
const content =
|
|
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 || !
|
|
166034
|
+
if (!this.started || !existsSync14(this.transcriptPath)) {
|
|
165319
166035
|
return;
|
|
165320
166036
|
}
|
|
165321
166037
|
let fileSize = 0;
|
|
165322
166038
|
try {
|
|
165323
|
-
fileSize =
|
|
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 =
|
|
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
|
|
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
|
|
166119
|
+
return join103(homedir72(), ".local", "share", "opencode", "storage");
|
|
165404
166120
|
}
|
|
165405
166121
|
function getOpencodeSessionRoot() {
|
|
165406
|
-
return
|
|
166122
|
+
return join103(getOpencodeStorageRoot(), "session");
|
|
165407
166123
|
}
|
|
165408
166124
|
function getOpencodeProjectRoot() {
|
|
165409
|
-
return
|
|
166125
|
+
return join103(getOpencodeStorageRoot(), "project");
|
|
165410
166126
|
}
|
|
165411
166127
|
function getOpencodeStreamCaptureDir() {
|
|
165412
|
-
return
|
|
166128
|
+
return join103(getOpencodeStorageRoot(), "orbh");
|
|
165413
166129
|
}
|
|
165414
166130
|
function buildPendingOpencodeStreamCapturePath(orbhSessionId) {
|
|
165415
|
-
return
|
|
166131
|
+
return join103(getOpencodeStreamCaptureDir(), `${orbhSessionId}.jsonl`);
|
|
165416
166132
|
}
|
|
165417
166133
|
function buildOpencodeStreamCapturePath(nativeSessionId) {
|
|
165418
|
-
return
|
|
166134
|
+
return join103(getOpencodeStreamCaptureDir(), `${nativeSessionId}.jsonl`);
|
|
165419
166135
|
}
|
|
165420
166136
|
function readNativeSessionIdFromStreamCapture(streamPath) {
|
|
165421
|
-
if (!
|
|
166137
|
+
if (!existsSync15(streamPath)) {
|
|
165422
166138
|
return null;
|
|
165423
166139
|
}
|
|
165424
166140
|
try {
|
|
165425
|
-
const lines =
|
|
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 (!
|
|
166182
|
+
if (!existsSync15(projectsRoot)) {
|
|
165467
166183
|
return [];
|
|
165468
166184
|
}
|
|
165469
166185
|
const normalizedCwd = normalizePath(cwd);
|
|
165470
166186
|
const projectIds = [];
|
|
165471
|
-
for (const entry of
|
|
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(
|
|
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(
|
|
165493
|
-
return typeof parsed.id === "string" ? parsed.id :
|
|
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
|
|
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 =
|
|
165502
|
-
if (!
|
|
166217
|
+
const sessionDir = join103(getOpencodeSessionRoot(), projectId);
|
|
166218
|
+
if (!existsSync15(sessionDir)) {
|
|
165503
166219
|
continue;
|
|
165504
166220
|
}
|
|
165505
|
-
for (const entry of
|
|
166221
|
+
for (const entry of readdirSync7(sessionDir)) {
|
|
165506
166222
|
if (!entry.startsWith("ses_") || !entry.endsWith(".json")) {
|
|
165507
166223
|
continue;
|
|
165508
166224
|
}
|
|
165509
|
-
const transcriptPath =
|
|
166225
|
+
const transcriptPath = join103(sessionDir, entry);
|
|
165510
166226
|
try {
|
|
165511
|
-
sessionPaths.set(transcriptPath,
|
|
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 (
|
|
166237
|
+
if (basename43(transcriptPath, ".json") === nativeSessionId) {
|
|
165522
166238
|
return transcriptPath;
|
|
165523
166239
|
}
|
|
165524
166240
|
}
|
|
165525
166241
|
const sessionRoot = getOpencodeSessionRoot();
|
|
165526
|
-
if (!
|
|
166242
|
+
if (!existsSync15(sessionRoot)) {
|
|
165527
166243
|
return null;
|
|
165528
166244
|
}
|
|
165529
|
-
for (const projectId of
|
|
165530
|
-
const candidate =
|
|
165531
|
-
if (
|
|
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 =
|
|
165543
|
-
const messageDir =
|
|
165544
|
-
if (!
|
|
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
|
|
165548
|
-
const messagePath =
|
|
166263
|
+
for (const entry of readdirSync7(messageDir)) {
|
|
166264
|
+
const messagePath = join103(messageDir, entry);
|
|
165549
166265
|
try {
|
|
165550
|
-
if (
|
|
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 =
|
|
165557
|
-
const partDir =
|
|
165558
|
-
if (!
|
|
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
|
|
166277
|
+
for (const partEntry of readdirSync7(partDir)) {
|
|
165562
166278
|
try {
|
|
165563
|
-
if (
|
|
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 (
|
|
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
|
|
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 (!
|
|
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:
|
|
166219
|
-
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 (!
|
|
166942
|
+
if (!existsSync16(sessionsDir)) {
|
|
166225
166943
|
mkdirSync3(sessionsDir, { recursive: true });
|
|
166226
166944
|
}
|
|
166227
166945
|
}
|
|
166228
166946
|
function getSessionPath(sessionsDir, sessionId) {
|
|
166229
|
-
return
|
|
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 (!
|
|
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 (!
|
|
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
|
|
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(
|
|
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(
|
|
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 =
|
|
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 =
|
|
166988
|
-
if (!
|
|
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
|
|
167711
|
+
for (const year of readdirSync8(sessionsRoot, { withFileTypes: true })) {
|
|
166993
167712
|
if (!year.isDirectory()) {
|
|
166994
167713
|
continue;
|
|
166995
167714
|
}
|
|
166996
|
-
const yearPath =
|
|
166997
|
-
for (const month of
|
|
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 =
|
|
167002
|
-
for (const day of
|
|
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 =
|
|
167007
|
-
for (const fileName of
|
|
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(
|
|
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] =
|
|
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 =
|
|
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
|
|
168049
|
+
return join123(homedir9(), ".nuucognition", "orbh", "profiles.json");
|
|
167331
168050
|
}
|
|
167332
168051
|
function loadProfiles(filePath = getProfilesPath()) {
|
|
167333
|
-
if (!
|
|
168052
|
+
if (!existsSync17(filePath)) {
|
|
167334
168053
|
return {};
|
|
167335
168054
|
}
|
|
167336
|
-
const raw =
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
-
|
|
167853
|
-
|
|
167854
|
-
|
|
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
|
|
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
|
-
|
|
167951
|
-
|
|
167952
|
-
|
|
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
|
|
168925
|
+
import { homedir as homedir10 } from "os";
|
|
167990
168926
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
167991
|
-
import { spawn as
|
|
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
|
|
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
|
|
168941
|
+
return homedir10();
|
|
168006
168942
|
}
|
|
168007
168943
|
if (value.startsWith("~/")) {
|
|
168008
|
-
return path23.join(
|
|
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 (!
|
|
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 (!
|
|
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 =
|
|
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
|
|
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 (!
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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(
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 (!
|
|
172480
|
+
if (!existsSync18(transcriptPath)) {
|
|
171545
172481
|
process.stdout.write(export_pc.dim("Waiting for transcript..."));
|
|
171546
|
-
while (!
|
|
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
|
|
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
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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) :
|
|
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(
|
|
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
|
|
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)")
|
|
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.
|
|
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
|
|
173940
|
-
import { stat as
|
|
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
|
|
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
|
|
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:
|
|
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:
|
|
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:
|
|
174573
|
-
const root = homeDir ??
|
|
175597
|
+
const { homedir: homedir12, join: join51 } = await loadNodeModules();
|
|
175598
|
+
const root = homeDir ?? homedir12();
|
|
174574
175599
|
return [
|
|
174575
|
-
|
|
174576
|
-
|
|
174577
|
-
|
|
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
|
|
174613
|
-
import { readFile as readFile16, stat as
|
|
174614
|
-
import { spawn as
|
|
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
|
|
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
|
|
176160
|
-
import { join as
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 (!
|
|
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 =
|
|
177846
|
+
var REGISTRY_PATH = join46(homedir11(), ".nuucognition", "servers.json");
|
|
176822
177847
|
function getRegistryDir() {
|
|
176823
|
-
return
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
178224
|
-
const outputPath =
|
|
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
|
|
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 =
|
|
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
|
|
179790
|
+
import { join as join48 } from "path";
|
|
178766
179791
|
async function exists6(path30) {
|
|
178767
179792
|
try {
|
|
178768
|
-
const { stat:
|
|
178769
|
-
await
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 =
|
|
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
|
|
179261
|
-
import { join as
|
|
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 (!
|
|
179270
|
-
for (const entry of
|
|
179271
|
-
const fullPath =
|
|
180294
|
+
if (!existsSync20(dirPath)) return files;
|
|
180295
|
+
for (const entry of readdirSync10(dirPath)) {
|
|
180296
|
+
const fullPath = join49(dirPath, entry);
|
|
179272
180297
|
try {
|
|
179273
|
-
const
|
|
179274
|
-
if (
|
|
179275
|
-
else if (
|
|
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 =
|
|
179284
|
-
if (!
|
|
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(
|
|
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 },
|