@tekmidian/pai 0.13.3 → 0.13.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import "../db-CmYbAVCD.mjs";
|
|
|
6
6
|
import "../helpers-IjZkXBhj.mjs";
|
|
7
7
|
import "../embeddings-BJPOcbik.mjs";
|
|
8
8
|
import "../search-HcdKtMla.mjs";
|
|
9
|
-
import "../pick-
|
|
9
|
+
import "../pick-CsHZ8Abv.mjs";
|
|
10
10
|
import "../kg-extraction-C8DEUHTS.mjs";
|
|
11
11
|
import "../factory-Q88X1bAN.mjs";
|
|
12
12
|
import "../config-C8m-tPhP.mjs";
|
package/dist/cli/program.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import "../db-CmYbAVCD.mjs";
|
|
|
5
5
|
import "../helpers-IjZkXBhj.mjs";
|
|
6
6
|
import "../embeddings-BJPOcbik.mjs";
|
|
7
7
|
import "../search-HcdKtMla.mjs";
|
|
8
|
-
import { C as registerDaemonCommands, D as registerProjectsCommands, E as registerRegistryCommands, O as findMovedPath, S as registerBackupCommands, T as registerMemoryCommands, _ as registerObservationCommands, a as cmdPauseAll, b as registerSetupCommand, c as cmdPause, d as registerKgCommands, f as registerTopicCommands, g as registerSkillCommands, h as registerUpdateCommand, i as cmdClearNames, k as resolveIdentifier, l as registerHelpCommand, m as registerNotifyCommands, n as cmdFind, o as cmdGoto, p as registerTaskCommands, r as cmdList, s as cmdEnd, t as cmdPick, u as registerDbCommands, v as registerZettelCommands, w as registerMcpCommands, x as registerRestoreCommands, y as registerObsidianCommands } from "../pick-
|
|
8
|
+
import { C as registerDaemonCommands, D as registerProjectsCommands, E as registerRegistryCommands, O as findMovedPath, S as registerBackupCommands, T as registerMemoryCommands, _ as registerObservationCommands, a as cmdPauseAll, b as registerSetupCommand, c as cmdPause, d as registerKgCommands, f as registerTopicCommands, g as registerSkillCommands, h as registerUpdateCommand, i as cmdClearNames, k as resolveIdentifier, l as registerHelpCommand, m as registerNotifyCommands, n as cmdFind, o as cmdGoto, p as registerTaskCommands, r as cmdList, s as cmdEnd, t as cmdPick, u as registerDbCommands, v as registerZettelCommands, w as registerMcpCommands, x as registerRestoreCommands, y as registerObsidianCommands } from "../pick-CsHZ8Abv.mjs";
|
|
9
9
|
import "../kg-extraction-C8DEUHTS.mjs";
|
|
10
10
|
import "../factory-Q88X1bAN.mjs";
|
|
11
11
|
import "../config-C8m-tPhP.mjs";
|
|
@@ -1898,9 +1898,80 @@ function registerMemoryCommands(memoryCmd, getDb) {
|
|
|
1898
1898
|
registerStatsCommands(memoryCmd, getDb);
|
|
1899
1899
|
}
|
|
1900
1900
|
|
|
1901
|
+
//#endregion
|
|
1902
|
+
//#region src/config/claude-json.ts
|
|
1903
|
+
/**
|
|
1904
|
+
* claude-json.ts — safe read/write for ~/.claude.json
|
|
1905
|
+
*
|
|
1906
|
+
* This file is not ours. It holds every MCP server registration plus Claude
|
|
1907
|
+
* Code's own per-project state — on a working machine, hundreds of kilobytes
|
|
1908
|
+
* that no one can reconstruct by hand. PAI only ever adds one key to it.
|
|
1909
|
+
*
|
|
1910
|
+
* The previous implementation (duplicated in mcp.ts and daemon.ts) did:
|
|
1911
|
+
*
|
|
1912
|
+
* try { return JSON.parse(read(path)); } catch { return {}; }
|
|
1913
|
+
*
|
|
1914
|
+
* followed by a full-file write. A malformed or transiently unreadable file
|
|
1915
|
+
* therefore became an empty object, and the next write replaced the user's
|
|
1916
|
+
* entire config with just PAI's entry. No error, no backup, exit code 0.
|
|
1917
|
+
*
|
|
1918
|
+
* The precondition is unlikely, which is exactly the problem: `pai setup` is
|
|
1919
|
+
* advertised as idempotent and safe to re-run, so it is what people run when
|
|
1920
|
+
* something is already broken — the state in which the file is most likely to
|
|
1921
|
+
* be malformed.
|
|
1922
|
+
*/
|
|
1923
|
+
const CLAUDE_JSON_PATH = join(homedir(), ".claude.json");
|
|
1924
|
+
const BACKUP_PATH = `${CLAUDE_JSON_PATH}.bak-pai`;
|
|
1925
|
+
/**
|
|
1926
|
+
* Read ~/.claude.json.
|
|
1927
|
+
*
|
|
1928
|
+
* A missing file is a legitimate first-run state and yields {}. Anything else
|
|
1929
|
+
* — malformed JSON, permissions, a half-written file — throws. Returning {}
|
|
1930
|
+
* for an unreadable file is what turns a read problem into data loss on the
|
|
1931
|
+
* next write.
|
|
1932
|
+
*/
|
|
1933
|
+
function readClaudeJson() {
|
|
1934
|
+
if (!existsSync(CLAUDE_JSON_PATH)) return {};
|
|
1935
|
+
let raw;
|
|
1936
|
+
try {
|
|
1937
|
+
raw = readFileSync(CLAUDE_JSON_PATH, "utf8");
|
|
1938
|
+
} catch (e) {
|
|
1939
|
+
throw new Error(`Could not read ${CLAUDE_JSON_PATH}: ${e instanceof Error ? e.message : String(e)}\nRefusing to continue — writing now would replace your MCP registrations with PAI's alone.`);
|
|
1940
|
+
}
|
|
1941
|
+
try {
|
|
1942
|
+
return JSON.parse(raw);
|
|
1943
|
+
} catch (e) {
|
|
1944
|
+
throw new Error(`${CLAUDE_JSON_PATH} is not valid JSON: ${e instanceof Error ? e.message : String(e)}\nRefusing to continue — overwriting it would destroy every MCP server registration it holds.\nFix the file, or move it aside and let Claude Code recreate it, then re-run this command.`);
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
/**
|
|
1948
|
+
* Write ~/.claude.json, keeping a backup and never leaving it half-written.
|
|
1949
|
+
*
|
|
1950
|
+
* Writes to a temp file and renames: rename is atomic within a filesystem, so
|
|
1951
|
+
* a crash mid-write leaves the original intact rather than truncated. The
|
|
1952
|
+
* previous direct writeFileSync could truncate the file and then fail.
|
|
1953
|
+
*/
|
|
1954
|
+
function writeClaudeJson(data) {
|
|
1955
|
+
const serialized = JSON.stringify(data, null, 2) + "\n";
|
|
1956
|
+
if (existsSync(CLAUDE_JSON_PATH)) try {
|
|
1957
|
+
copyFileSync(CLAUDE_JSON_PATH, BACKUP_PATH);
|
|
1958
|
+
} catch (e) {
|
|
1959
|
+
throw new Error(`Could not back up ${CLAUDE_JSON_PATH} to ${BACKUP_PATH}: ${e instanceof Error ? e.message : String(e)}\nRefusing to write without a backup.`);
|
|
1960
|
+
}
|
|
1961
|
+
const tmp = `${CLAUDE_JSON_PATH}.tmp-pai-${process.pid}`;
|
|
1962
|
+
try {
|
|
1963
|
+
writeFileSync(tmp, serialized, "utf8");
|
|
1964
|
+
renameSync(tmp, CLAUDE_JSON_PATH);
|
|
1965
|
+
} catch (e) {
|
|
1966
|
+
try {
|
|
1967
|
+
if (existsSync(tmp)) unlinkSync(tmp);
|
|
1968
|
+
} catch {}
|
|
1969
|
+
throw new Error(`Failed to write ${CLAUDE_JSON_PATH}: ${e instanceof Error ? e.message : String(e)}\nThe original is unchanged${existsSync(BACKUP_PATH) ? `; a backup is at ${BACKUP_PATH}` : ""}.`);
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1901
1973
|
//#endregion
|
|
1902
1974
|
//#region src/cli/commands/mcp.ts
|
|
1903
|
-
const CLAUDE_JSON_PATH$1 = join(homedir(), ".claude.json");
|
|
1904
1975
|
/**
|
|
1905
1976
|
* Resolve the absolute path to the built MCP entry point.
|
|
1906
1977
|
*
|
|
@@ -1911,21 +1982,9 @@ const CLAUDE_JSON_PATH$1 = join(homedir(), ".claude.json");
|
|
|
1911
1982
|
function getMcpBinPath() {
|
|
1912
1983
|
return join(dirname(fileURLToPath(import.meta.url)), "../mcp/index.mjs");
|
|
1913
1984
|
}
|
|
1914
|
-
function readClaudeJson$1() {
|
|
1915
|
-
if (!existsSync(CLAUDE_JSON_PATH$1)) return {};
|
|
1916
|
-
try {
|
|
1917
|
-
const raw = readFileSync(CLAUDE_JSON_PATH$1, "utf8");
|
|
1918
|
-
return JSON.parse(raw);
|
|
1919
|
-
} catch {
|
|
1920
|
-
return {};
|
|
1921
|
-
}
|
|
1922
|
-
}
|
|
1923
|
-
function writeClaudeJson$1(data) {
|
|
1924
|
-
writeFileSync(CLAUDE_JSON_PATH$1, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
1925
|
-
}
|
|
1926
1985
|
function cmdInstall$1() {
|
|
1927
1986
|
const mcpBin = getMcpBinPath();
|
|
1928
|
-
const config = readClaudeJson
|
|
1987
|
+
const config = readClaudeJson();
|
|
1929
1988
|
if (typeof config.mcpServers !== "object" || config.mcpServers === null) config.mcpServers = {};
|
|
1930
1989
|
const servers = config.mcpServers;
|
|
1931
1990
|
if ("pai" in servers) {
|
|
@@ -1939,7 +1998,7 @@ function cmdInstall$1() {
|
|
|
1939
1998
|
args: [mcpBin]
|
|
1940
1999
|
};
|
|
1941
2000
|
try {
|
|
1942
|
-
writeClaudeJson
|
|
2001
|
+
writeClaudeJson(config);
|
|
1943
2002
|
} catch (e) {
|
|
1944
2003
|
console.error(err(`Failed to write ~/.claude.json: ${e}`));
|
|
1945
2004
|
process.exit(1);
|
|
@@ -1958,7 +2017,7 @@ function cmdInstall$1() {
|
|
|
1958
2017
|
}
|
|
1959
2018
|
function cmdStatus$3() {
|
|
1960
2019
|
const mcpBin = getMcpBinPath();
|
|
1961
|
-
const config = readClaudeJson
|
|
2020
|
+
const config = readClaudeJson();
|
|
1962
2021
|
const servers = typeof config.mcpServers === "object" && config.mcpServers !== null ? config.mcpServers : {};
|
|
1963
2022
|
const registered = "pai" in servers;
|
|
1964
2023
|
const binExists = existsSync(mcpBin);
|
|
@@ -1997,7 +2056,6 @@ function registerMcpCommands(mcpCmd) {
|
|
|
1997
2056
|
//#endregion
|
|
1998
2057
|
//#region src/cli/commands/daemon.ts
|
|
1999
2058
|
const HOME$2 = homedir();
|
|
2000
|
-
const CLAUDE_JSON_PATH = join(HOME$2, ".claude.json");
|
|
2001
2059
|
const PLIST_LABEL = "com.pai.pai-daemon";
|
|
2002
2060
|
const LAUNCH_AGENTS_DIR = join(HOME$2, "Library", "LaunchAgents");
|
|
2003
2061
|
const PLIST_PATH = join(LAUNCH_AGENTS_DIR, `${PLIST_LABEL}.plist`);
|
|
@@ -2017,18 +2075,6 @@ function getDaemonBinPath() {
|
|
|
2017
2075
|
function getShimBinPath() {
|
|
2018
2076
|
return join(dirname(fileURLToPath(import.meta.url)), "../daemon-mcp/index.mjs");
|
|
2019
2077
|
}
|
|
2020
|
-
function readClaudeJson() {
|
|
2021
|
-
if (!existsSync(CLAUDE_JSON_PATH)) return {};
|
|
2022
|
-
try {
|
|
2023
|
-
const raw = readFileSync(CLAUDE_JSON_PATH, "utf8");
|
|
2024
|
-
return JSON.parse(raw);
|
|
2025
|
-
} catch {
|
|
2026
|
-
return {};
|
|
2027
|
-
}
|
|
2028
|
-
}
|
|
2029
|
-
function writeClaudeJson(data) {
|
|
2030
|
-
writeFileSync(CLAUDE_JSON_PATH, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
2031
|
-
}
|
|
2032
2078
|
function generatePlist(daemonBin) {
|
|
2033
2079
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
2034
2080
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -2624,6 +2670,86 @@ function registerRestoreCommands(program) {
|
|
|
2624
2670
|
});
|
|
2625
2671
|
}
|
|
2626
2672
|
|
|
2673
|
+
//#endregion
|
|
2674
|
+
//#region src/config/json-store.ts
|
|
2675
|
+
/**
|
|
2676
|
+
* json-store.ts — read/write JSON config files without destroying them
|
|
2677
|
+
*
|
|
2678
|
+
* The failure this exists to prevent:
|
|
2679
|
+
*
|
|
2680
|
+
* try { return JSON.parse(read(path)); } catch { return {}; }
|
|
2681
|
+
* ... later ...
|
|
2682
|
+
* write(path, JSON.stringify(ourData));
|
|
2683
|
+
*
|
|
2684
|
+
* An unreadable file becomes an empty object, and the next write makes that
|
|
2685
|
+
* permanent. Silently, exit code 0. This shape appeared three times in this
|
|
2686
|
+
* repo against three different files, and twice in AIBroker.
|
|
2687
|
+
*
|
|
2688
|
+
* The distinction that matters is between *missing* and *unreadable*:
|
|
2689
|
+
*
|
|
2690
|
+
* missing — legitimate first run. Start fresh; writing is safe.
|
|
2691
|
+
* unreadable — the file exists and we could not parse it. Those bytes are
|
|
2692
|
+
* the only copy of something. Never overwrite them.
|
|
2693
|
+
*
|
|
2694
|
+
* Collapsing the second into the first is the bug.
|
|
2695
|
+
*
|
|
2696
|
+
* NOT everything deserves this guard. For a transient buffer — an undelivered
|
|
2697
|
+
* message queue, a cache — starting fresh IS the correct recovery, and
|
|
2698
|
+
* refusing to write would disable the feature permanently. Use `writeJsonAtomic`
|
|
2699
|
+
* alone there: it still prevents a crash from truncating a good file, without
|
|
2700
|
+
* blocking recovery. Reserve `readJsonStrict` for data a user cannot rebuild.
|
|
2701
|
+
*/
|
|
2702
|
+
/**
|
|
2703
|
+
* Read a JSON file, distinguishing "absent" from "damaged".
|
|
2704
|
+
*
|
|
2705
|
+
* @param path file to read
|
|
2706
|
+
* @param label how to name it to the user, e.g. "~/.claude.json"
|
|
2707
|
+
* @throws if the file exists but cannot be read or parsed
|
|
2708
|
+
*/
|
|
2709
|
+
function readJsonStrict(path, label = path) {
|
|
2710
|
+
if (!existsSync(path)) return {};
|
|
2711
|
+
let raw;
|
|
2712
|
+
try {
|
|
2713
|
+
raw = readFileSync(path, "utf8");
|
|
2714
|
+
} catch (e) {
|
|
2715
|
+
throw new Error(`Could not read ${label}: ${e instanceof Error ? e.message : String(e)}\nRefusing to continue — writing now would replace its contents with ours alone.`);
|
|
2716
|
+
}
|
|
2717
|
+
try {
|
|
2718
|
+
return JSON.parse(raw);
|
|
2719
|
+
} catch (e) {
|
|
2720
|
+
throw new Error(`${label} exists but is not valid JSON: ${e instanceof Error ? e.message : String(e)}\nRefusing to continue — overwriting it would destroy whatever it holds.\nRepair the file, or move it aside and re-run this command.`);
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
/**
|
|
2724
|
+
* Write JSON without risking the existing file.
|
|
2725
|
+
*
|
|
2726
|
+
* Keeps a `.bak-pai` copy of the previous contents, then writes to a temp file
|
|
2727
|
+
* and renames. Rename is atomic within a filesystem, so a crash mid-write
|
|
2728
|
+
* leaves the original intact rather than truncated — which is how these files
|
|
2729
|
+
* become corrupt in the first place.
|
|
2730
|
+
*/
|
|
2731
|
+
function writeJsonAtomic(path, data, opts = {}) {
|
|
2732
|
+
const { backup = true, label = path } = opts;
|
|
2733
|
+
const serialized = JSON.stringify(data, null, 2) + "\n";
|
|
2734
|
+
const dir = dirname(path);
|
|
2735
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
2736
|
+
if (backup && existsSync(path)) try {
|
|
2737
|
+
copyFileSync(path, `${path}.bak-pai`);
|
|
2738
|
+
} catch (e) {
|
|
2739
|
+
throw new Error(`Could not back up ${label}: ${e instanceof Error ? e.message : String(e)}\nRefusing to write without a backup.`);
|
|
2740
|
+
}
|
|
2741
|
+
const tmp = `${path}.tmp-pai-${process.pid}`;
|
|
2742
|
+
try {
|
|
2743
|
+
writeFileSync(tmp, serialized, "utf8");
|
|
2744
|
+
renameSync(tmp, path);
|
|
2745
|
+
} catch (e) {
|
|
2746
|
+
try {
|
|
2747
|
+
if (existsSync(tmp)) unlinkSync(tmp);
|
|
2748
|
+
} catch {}
|
|
2749
|
+
throw new Error(`Failed to write ${label}: ${e instanceof Error ? e.message : String(e)}\nThe original is unchanged.`);
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
|
|
2627
2753
|
//#endregion
|
|
2628
2754
|
//#region src/cli/commands/setup/utils.ts
|
|
2629
2755
|
/**
|
|
@@ -2695,17 +2821,18 @@ async function promptYesNo(rl, question, defaultYes = true) {
|
|
|
2695
2821
|
if (answer === "") return defaultYes;
|
|
2696
2822
|
return answer.toLowerCase().startsWith("y");
|
|
2697
2823
|
}
|
|
2824
|
+
/**
|
|
2825
|
+
* This file holds the Postgres connection string, the storage backend choice,
|
|
2826
|
+
* notification routing and any tracker API token — none of which the user can
|
|
2827
|
+
* reconstruct from memory. It previously returned {} on a parse failure and
|
|
2828
|
+
* then overwrote the file, so a damaged config was replaced by whatever the
|
|
2829
|
+
* current command happened to be setting.
|
|
2830
|
+
*/
|
|
2698
2831
|
function readConfigRaw() {
|
|
2699
|
-
|
|
2700
|
-
try {
|
|
2701
|
-
return JSON.parse(readFileSync(CONFIG_FILE$2, "utf-8"));
|
|
2702
|
-
} catch {
|
|
2703
|
-
return {};
|
|
2704
|
-
}
|
|
2832
|
+
return readJsonStrict(CONFIG_FILE$2, "~/.config/pai/config.json");
|
|
2705
2833
|
}
|
|
2706
2834
|
function writeConfigRaw(data) {
|
|
2707
|
-
|
|
2708
|
-
writeFileSync(CONFIG_FILE$2, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
2835
|
+
writeJsonAtomic(CONFIG_FILE$2, data, { label: "~/.config/pai/config.json" });
|
|
2709
2836
|
}
|
|
2710
2837
|
function mergeConfig(updates) {
|
|
2711
2838
|
const current = readConfigRaw();
|
|
@@ -3388,27 +3515,18 @@ async function stepTsHooks(rl) {
|
|
|
3388
3515
|
|
|
3389
3516
|
//#endregion
|
|
3390
3517
|
//#region src/cli/commands/settings-manager.ts
|
|
3518
|
+
const SETTINGS_FILE = join(join(homedir(), ".claude"), "settings.json");
|
|
3391
3519
|
/**
|
|
3392
|
-
* settings
|
|
3393
|
-
*
|
|
3394
|
-
*
|
|
3395
|
-
*
|
|
3396
|
-
* - hooks: appended per hookType, deduplicated by command string
|
|
3397
|
-
* - statusLine: written only if the key is not already present
|
|
3520
|
+
* ~/.claude/settings.json is Claude Code's own file, not ours: hooks, env,
|
|
3521
|
+
* permissions, statusline, enabled plugins. PAI only ever adds to it. Returning
|
|
3522
|
+
* {} for a damaged file and then writing meant a stray parse error could strip
|
|
3523
|
+
* every hook registration the user had.
|
|
3398
3524
|
*/
|
|
3399
|
-
const CLAUDE_DIR = join(homedir(), ".claude");
|
|
3400
|
-
const SETTINGS_FILE = join(CLAUDE_DIR, "settings.json");
|
|
3401
3525
|
function readSettingsJson() {
|
|
3402
|
-
|
|
3403
|
-
try {
|
|
3404
|
-
return JSON.parse(readFileSync(SETTINGS_FILE, "utf-8"));
|
|
3405
|
-
} catch {
|
|
3406
|
-
return {};
|
|
3407
|
-
}
|
|
3526
|
+
return readJsonStrict(SETTINGS_FILE, "~/.claude/settings.json");
|
|
3408
3527
|
}
|
|
3409
3528
|
function writeSettingsJson(data) {
|
|
3410
|
-
|
|
3411
|
-
writeFileSync(SETTINGS_FILE, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
3529
|
+
writeJsonAtomic(SETTINGS_FILE, data, { label: "~/.claude/settings.json" });
|
|
3412
3530
|
}
|
|
3413
3531
|
/**
|
|
3414
3532
|
* Merge env vars — add keys that are absent, never overwrite existing ones.
|
|
@@ -6048,7 +6166,7 @@ function stepVerifyRepo() {
|
|
|
6048
6166
|
const gitDir = capture("git rev-parse --show-toplevel", getPaiSrcDir());
|
|
6049
6167
|
if (!gitDir) {
|
|
6050
6168
|
error("Not a git repository. Cannot update automatically.");
|
|
6051
|
-
info("Install PAI via npm to get automatic updates: npm install -g @
|
|
6169
|
+
info("Install PAI via npm to get automatic updates: npm install -g @tekmidian/pai");
|
|
6052
6170
|
return null;
|
|
6053
6171
|
}
|
|
6054
6172
|
const remote = capture("git remote get-url origin", gitDir);
|
|
@@ -9015,4 +9133,4 @@ async function cmdPick(db, opts = {}) {
|
|
|
9015
9133
|
|
|
9016
9134
|
//#endregion
|
|
9017
9135
|
export { registerDaemonCommands as C, registerProjectsCommands as D, registerRegistryCommands as E, findMovedPath as O, registerBackupCommands as S, registerMemoryCommands as T, registerObservationCommands as _, cmdPauseAll as a, registerSetupCommand as b, cmdPause as c, registerKgCommands as d, registerTopicCommands as f, registerSkillCommands as g, registerUpdateCommand as h, cmdClearNames as i, resolveIdentifier as k, registerHelpCommand as l, registerNotifyCommands as m, cmdFind as n, cmdGoto as o, registerTaskCommands as p, cmdList as r, cmdEnd as s, cmdPick as t, registerDbCommands as u, registerZettelCommands as v, registerMcpCommands as w, registerRestoreCommands as x, registerObsidianCommands as y };
|
|
9018
|
-
//# sourceMappingURL=pick-
|
|
9136
|
+
//# sourceMappingURL=pick-CsHZ8Abv.mjs.map
|