@tekmidian/pai 0.13.3 → 0.13.4
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-CmG7SCtp.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-CmG7SCtp.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">
|
|
@@ -6048,7 +6094,7 @@ function stepVerifyRepo() {
|
|
|
6048
6094
|
const gitDir = capture("git rev-parse --show-toplevel", getPaiSrcDir());
|
|
6049
6095
|
if (!gitDir) {
|
|
6050
6096
|
error("Not a git repository. Cannot update automatically.");
|
|
6051
|
-
info("Install PAI via npm to get automatic updates: npm install -g @
|
|
6097
|
+
info("Install PAI via npm to get automatic updates: npm install -g @tekmidian/pai");
|
|
6052
6098
|
return null;
|
|
6053
6099
|
}
|
|
6054
6100
|
const remote = capture("git remote get-url origin", gitDir);
|
|
@@ -9015,4 +9061,4 @@ async function cmdPick(db, opts = {}) {
|
|
|
9015
9061
|
|
|
9016
9062
|
//#endregion
|
|
9017
9063
|
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-
|
|
9064
|
+
//# sourceMappingURL=pick-CmG7SCtp.mjs.map
|