@fml-inc/fml 0.1.3 → 0.3.0
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/.claude-plugin/plugin.json +1 -1
- package/dist/{chunk-I5BHNW37.js → chunk-BOREGHA6.js} +37 -1
- package/dist/chunk-BOREGHA6.js.map +1 -0
- package/dist/{chunk-YIWT7BWN.js → chunk-CFPXJT5Q.js} +2 -2
- package/dist/chunk-MUKYS4IB.js +93 -0
- package/dist/chunk-MUKYS4IB.js.map +1 -0
- package/dist/cli.js +185 -42
- package/dist/cli.js.map +1 -1
- package/dist/{daemon-2YGD43RJ.js → daemon-GM3WNS4Z.js} +3 -3
- package/dist/{daemon-utils-LIG6K2MK.js → daemon-utils-CJO4XVJQ.js} +2 -2
- package/dist/mcp/server.js +4 -4
- package/dist/postinstall.js +1 -1
- package/dist/postinstall.js.map +1 -1
- package/package.json +4 -3
- package/scripts/postinstall.cjs +25 -0
- package/dist/chunk-I5BHNW37.js.map +0 -1
- package/dist/chunk-ZA4RG25C.js +0 -61
- package/dist/chunk-ZA4RG25C.js.map +0 -1
- /package/dist/{chunk-YIWT7BWN.js.map → chunk-CFPXJT5Q.js.map} +0 -0
- /package/dist/{daemon-2YGD43RJ.js.map → daemon-GM3WNS4Z.js.map} +0 -0
- /package/dist/{daemon-utils-LIG6K2MK.js.map → daemon-utils-CJO4XVJQ.js.map} +0 -0
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
handleStop,
|
|
4
4
|
isSyncRunning,
|
|
5
5
|
parsePanopticonRunning
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-CFPXJT5Q.js";
|
|
7
|
+
import "./chunk-MUKYS4IB.js";
|
|
8
8
|
import "./chunk-4YEAQJPF.js";
|
|
9
9
|
import "./chunk-PZ5AY32C.js";
|
|
10
10
|
export {
|
|
@@ -13,4 +13,4 @@ export {
|
|
|
13
13
|
isSyncRunning,
|
|
14
14
|
parsePanopticonRunning
|
|
15
15
|
};
|
|
16
|
-
//# sourceMappingURL=daemon-
|
|
16
|
+
//# sourceMappingURL=daemon-GM3WNS4Z.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
isDaemonRunning,
|
|
5
5
|
panopticonExec,
|
|
6
6
|
resolvePanopticonBin
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-MUKYS4IB.js";
|
|
8
8
|
import "./chunk-4YEAQJPF.js";
|
|
9
9
|
import "./chunk-PZ5AY32C.js";
|
|
10
10
|
export {
|
|
@@ -14,4 +14,4 @@ export {
|
|
|
14
14
|
panopticonExec,
|
|
15
15
|
resolvePanopticonBin
|
|
16
16
|
};
|
|
17
|
-
//# sourceMappingURL=daemon-utils-
|
|
17
|
+
//# sourceMappingURL=daemon-utils-CJO4XVJQ.js.map
|
package/dist/mcp/server.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
createApiClient,
|
|
4
4
|
ensureNativeModules,
|
|
5
5
|
getAuthenticatedClient
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-BOREGHA6.js";
|
|
7
7
|
import {
|
|
8
8
|
Sentry,
|
|
9
9
|
authStorePath,
|
|
@@ -14,8 +14,8 @@ import {
|
|
|
14
14
|
} from "../chunk-CUBBYHH7.js";
|
|
15
15
|
import {
|
|
16
16
|
parsePanopticonRunning
|
|
17
|
-
} from "../chunk-
|
|
18
|
-
import "../chunk-
|
|
17
|
+
} from "../chunk-CFPXJT5Q.js";
|
|
18
|
+
import "../chunk-MUKYS4IB.js";
|
|
19
19
|
import {
|
|
20
20
|
FML_DATA_DIR,
|
|
21
21
|
FML_LOG_DIR
|
|
@@ -499,7 +499,7 @@ async function main() {
|
|
|
499
499
|
await server.connect(transport);
|
|
500
500
|
if (!parsePanopticonRunning()) {
|
|
501
501
|
try {
|
|
502
|
-
const { handleStart } = await import("../daemon-
|
|
502
|
+
const { handleStart } = await import("../daemon-GM3WNS4Z.js");
|
|
503
503
|
await handleStart();
|
|
504
504
|
} catch {
|
|
505
505
|
console.error(
|
package/dist/postinstall.js
CHANGED
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from "url";
|
|
|
7
7
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
var fmlBin = join(__dirname, "..", "bin", "fml");
|
|
9
9
|
try {
|
|
10
|
-
execFileSync(
|
|
10
|
+
execFileSync(process.execPath, [fmlBin, "install"], {
|
|
11
11
|
stdio: "inherit",
|
|
12
12
|
timeout: 12e4
|
|
13
13
|
});
|
package/dist/postinstall.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/postinstall.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Lightweight postinstall — runs `fml install` to set up fml-specific\n * config (directories, marketplace, plugin cache, sync target).\n *\n * Panopticon setup is handled by @fml-inc/panopticon's own postinstall\n * which npm runs automatically as a dependency.\n */\nimport { execFileSync } from \"node:child_process\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst fmlBin = join(__dirname, \"..\", \"bin\", \"fml\");\n\ntry {\n execFileSync(
|
|
1
|
+
{"version":3,"sources":["../src/postinstall.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Lightweight postinstall — runs `fml install` to set up fml-specific\n * config (directories, marketplace, plugin cache, sync target).\n *\n * Panopticon setup is handled by @fml-inc/panopticon's own postinstall\n * which npm runs automatically as a dependency.\n */\nimport { execFileSync } from \"node:child_process\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst fmlBin = join(__dirname, \"..\", \"bin\", \"fml\");\n\ntry {\n execFileSync(process.execPath, [fmlBin, \"install\"], {\n stdio: \"inherit\",\n timeout: 120_000,\n });\n} catch {\n // fml install failed — not fatal for postinstall\n}\n"],"mappings":";;;AAQA,SAAS,oBAAoB;AAC7B,SAAS,SAAS,YAAY;AAC9B,SAAS,qBAAqB;AAE9B,IAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,IAAM,SAAS,KAAK,WAAW,MAAM,OAAO,KAAK;AAEjD,IAAI;AACF,eAAa,QAAQ,UAAU,CAAC,QAAQ,SAAS,GAAG;AAAA,IAClD,OAAO;AAAA,IACP,SAAS;AAAA,EACX,CAAC;AACH,QAAQ;AAER;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fml-inc/fml",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "FML agent tools for Claude Code",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"files": [
|
|
23
23
|
"bin/",
|
|
24
24
|
"dist/",
|
|
25
|
+
"scripts/postinstall.cjs",
|
|
25
26
|
".claude-plugin/"
|
|
26
27
|
],
|
|
27
28
|
"scripts": {
|
|
@@ -29,13 +30,13 @@
|
|
|
29
30
|
"dev": "tsup --watch",
|
|
30
31
|
"prepack": "node scripts/generate-plugin-manifest.js",
|
|
31
32
|
"pack:local": "pnpm build && pnpm pack",
|
|
32
|
-
"postinstall": "
|
|
33
|
+
"postinstall": "node scripts/postinstall.cjs",
|
|
33
34
|
"type-check": "tsc --noEmit",
|
|
34
35
|
"test": "vitest run",
|
|
35
36
|
"test:watch": "vitest"
|
|
36
37
|
},
|
|
37
38
|
"dependencies": {
|
|
38
|
-
"@fml-inc/panopticon": "^0.2.
|
|
39
|
+
"@fml-inc/panopticon": "^0.2.14",
|
|
39
40
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
40
41
|
"better-sqlite3": "^11.0.0",
|
|
41
42
|
"commander": "^13.1.0",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Cross-platform npm/pnpm postinstall entry. The bash form
|
|
3
|
+
// `[ ! -d dist ] || (node ./dist/postinstall.js && ...)` doesn't work on
|
|
4
|
+
// Windows cmd.exe, so we do the existence check in Node.
|
|
5
|
+
//
|
|
6
|
+
// dist/postinstall.js → calls `fml install`, which handles claude plugin
|
|
7
|
+
// registration. No need to invoke `claude` again from here.
|
|
8
|
+
const fs = require("node:fs");
|
|
9
|
+
const path = require("node:path");
|
|
10
|
+
const { execFileSync } = require("node:child_process");
|
|
11
|
+
|
|
12
|
+
const distEntry = path.resolve(__dirname, "..", "dist", "postinstall.js");
|
|
13
|
+
if (!fs.existsSync(distEntry)) {
|
|
14
|
+
// Source repo before first build — nothing to do.
|
|
15
|
+
process.exit(0);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
execFileSync(process.execPath, [distEntry], {
|
|
20
|
+
stdio: "inherit",
|
|
21
|
+
timeout: 120_000,
|
|
22
|
+
});
|
|
23
|
+
} catch {
|
|
24
|
+
// Best-effort: never fail install over a postinstall hook.
|
|
25
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/native-check.ts","../src/convex-client.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { execSync } from \"node:child_process\";\nimport { rmSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/**\n * Verify that better-sqlite3's native addon matches the running Node version.\n * If mismatched (e.g. user upgraded Node), attempt an automatic rebuild.\n * Call this before any code that imports better-sqlite3.\n */\nexport function ensureNativeModules(): void {\n const require = createRequire(import.meta.url);\n try {\n require(\"better-sqlite3\");\n } catch (err) {\n const msg = err instanceof Error ? err.message : \"\";\n if (!msg.includes(\"NODE_MODULE_VERSION\")) {\n throw err;\n }\n\n console.error(\n \"[fml] better-sqlite3 was compiled for a different Node.js version, rebuilding...\",\n );\n\n const pkgRoot = join(dirname(fileURLToPath(import.meta.url)), \"..\");\n\n // Remove stale build directory to avoid EEXIST errors from node-gyp\n const sqlitePath = dirname(require.resolve(\"better-sqlite3/package.json\"));\n rmSync(join(sqlitePath, \"build\"), { recursive: true, force: true });\n\n try {\n execSync(\"npm rebuild better-sqlite3\", {\n cwd: pkgRoot,\n stdio: \"inherit\",\n timeout: 60_000,\n });\n console.error(\"[fml] Rebuild complete.\");\n } catch {\n console.error(\n \"[fml] Automatic rebuild failed. Please run manually:\\n\" +\n ` cd ${pkgRoot} && rm -rf node_modules/better-sqlite3/build && npm rebuild better-sqlite3`,\n );\n process.exit(1);\n }\n }\n}\n","import type { FunctionReference } from \"convex/server\";\nimport { resolveRepoFromCwd } from \"@fml-inc/panopticon/repo\";\nimport { getSelectedOrg, getValidToken } from \"./auth/token-store.js\";\nimport { CONVEX_URL } from \"./config.js\";\nimport type {\n RepoConfigSnapshotDetail,\n RepoConfigSnapshotSummary,\n ResolvedRepo,\n UserConfigSnapshotDetail,\n UserConfigSnapshotSummary,\n} from \"./types.js\";\n\n// ── Shared plumbing ─────────────────────────────────────────────────────────\n\nexport interface ToolResult {\n ok: boolean;\n result?: unknown;\n error?: string;\n}\n\nexport interface OrgInfo {\n _id: string;\n name: string;\n slug?: string;\n repos?: Array<{\n _id: string;\n fullName: string;\n owner: string;\n name: string;\n private: boolean;\n }>;\n}\n\nfunction ref<T extends \"query\" | \"mutation\" | \"action\">(\n path: string,\n): FunctionReference<T> {\n return path as unknown as FunctionReference<T>;\n}\n\n// ── API client factory ──────────────────────────────────────────────────────\n\nexport function createApiClient(token: string) {\n const isServiceToken = token.startsWith(\"fml_st_\");\n\n let clientPromise: Promise<{\n query: <T>(\n ref: FunctionReference<\"query\">,\n args: Record<string, unknown>,\n ) => Promise<T>;\n mutation: <T>(\n ref: FunctionReference<\"mutation\">,\n args: Record<string, unknown>,\n ) => Promise<T>;\n action: <T>(\n ref: FunctionReference<\"action\">,\n args: Record<string, unknown>,\n ) => Promise<T>;\n }> | null = null;\n\n function getClient() {\n if (!clientPromise) {\n clientPromise = import(\"convex/browser\").then(({ ConvexHttpClient }) => {\n const client = new ConvexHttpClient(CONVEX_URL);\n client.setAuth(token);\n return client;\n });\n }\n return clientPromise;\n }\n\n /**\n * Derive the Convex site URL (HTTP actions) from the cloud URL.\n * Convex uses paired domains: *.convex.cloud for client APIs,\n * *.convex.site for HTTP actions. This is a stable Convex convention.\n */\n function getSiteUrl(): string {\n return CONVEX_URL.replace(\".convex.cloud\", \".convex.site\").replace(\n /\\/$/,\n \"\",\n );\n }\n\n return {\n // ── Orgs ──────────────────────────────────────────────────────────────\n\n async queryOrgs(): Promise<OrgInfo[]> {\n if (isServiceToken) {\n // Service tokens can't call Convex actions directly — org is embedded in the token\n return [];\n }\n const client = await getClient();\n return await client.query(ref(\"user/plugin:getMyOrgsAndRepos\"), {});\n },\n\n // ── Tool gateway ─────────────────────────────────────────────────────\n\n async callBackend(\n toolName: string,\n args: Record<string, unknown>,\n opts?: { org?: string },\n ): Promise<ToolResult> {\n try {\n if (isServiceToken) {\n // Service token path: POST to HTTP endpoint (Convex can't validate non-JWT tokens)\n // Thread user identity: sandbox agents set FML_USER_EXTERNAL_ID;\n // device-flow logins fall back to the id stashed on the stored token\n // so tools can execute with the real user context even though the\n // token's actAsExternalId is the namespaced system:cli:* string.\n const { readTokens } = await import(\"./auth/token-store.js\");\n const userExternalId =\n process.env.FML_USER_EXTERNAL_ID ?? readTokens()?.user.id;\n const res = await fetch(`${getSiteUrl()}/api/tools/execute`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify({\n toolName,\n args,\n ...(userExternalId && { userExternalId }),\n }),\n });\n const text = await res.text();\n let data: ToolResult;\n try {\n data = JSON.parse(text) as ToolResult;\n } catch {\n return {\n ok: false,\n error: `HTTP ${res.status}: ${text.slice(0, 200)}`,\n };\n }\n if (!res.ok && !data.error) {\n return { ok: false, error: `HTTP ${res.status}` };\n }\n return data;\n }\n\n // JWT path: standard Convex action\n const client = await getClient();\n const actionArgs: Record<string, unknown> = { toolName, args };\n // Explicit org > stored org selection > repo-based inference\n const org = opts?.org ?? getSelectedOrg();\n if (org) actionArgs.org = org;\n const repo = resolveRepoFromCwd(process.cwd());\n if (repo) actionArgs.repo = repo.repo;\n\n const result = await client.action(\n ref<\"action\">(\"user/tool_gateway:executeTool\"),\n actionArgs,\n );\n return { ok: true, result };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (msg.includes(\"Unauthorized\") || msg.includes(\"not authenticated\")) {\n return {\n ok: false,\n error:\n \"Authentication expired. Run `fml login` to sign in again, then restart Claude Code.\",\n };\n }\n return { ok: false, error: msg };\n }\n },\n\n // ── Repo resolution ──────────────────────────────────────────────────\n\n async resolveRepo(\n orgSlug: string,\n repoFullName: string,\n ): Promise<ResolvedRepo | null> {\n const client = await getClient();\n return await client.query(ref(\"user/cli:resolveRepo\"), {\n orgSlug,\n repoFullName,\n });\n },\n\n // ── Config snapshots ─────────────────────────────────────────────────\n\n async listUserConfigSnapshots(\n orgSlug: string,\n ): Promise<UserConfigSnapshotSummary[]> {\n const client = await getClient();\n const result = await client.query<UserConfigSnapshotSummary[] | null>(\n ref(\"user/config_snapshots:listUserSnapshots\"),\n { orgSlug },\n );\n return result ?? [];\n },\n\n async getUserConfigDetail(\n orgSlug: string,\n githubUsername: string,\n ): Promise<UserConfigSnapshotDetail | null> {\n const client = await getClient();\n return await client.query(ref(\"user/config_snapshots:getUserDetail\"), {\n orgSlug,\n githubUsername,\n });\n },\n\n async listRepoConfigSnapshots(\n orgSlug: string,\n repository?: string,\n ): Promise<RepoConfigSnapshotSummary[]> {\n const client = await getClient();\n const result = await client.query<RepoConfigSnapshotSummary[] | null>(\n ref(\"user/config_snapshots:listRepoSnapshots\"),\n { orgSlug, repository },\n );\n return result ?? [];\n },\n\n async getRepoConfigDetail(\n orgSlug: string,\n repository: string,\n ): Promise<RepoConfigSnapshotDetail | null> {\n const client = await getClient();\n return await client.query(ref(\"user/config_snapshots:getRepoDetail\"), {\n orgSlug,\n repository,\n });\n },\n };\n}\n\n// ── Convenience: auto-authenticated client ──────────────────────────────────\n\n/**\n * Create an API client using the stored auth token.\n * Returns null if not authenticated.\n */\nexport async function getAuthenticatedClient() {\n const token = await getValidToken();\n if (!token) return null;\n return createApiClient(token);\n}\n"],"mappings":"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","names":["require"]}
|
package/dist/chunk-ZA4RG25C.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
FML_DATA_DIR,
|
|
3
|
-
FML_LOG_DIR
|
|
4
|
-
} from "./chunk-4YEAQJPF.js";
|
|
5
|
-
|
|
6
|
-
// src/daemon-utils.ts
|
|
7
|
-
import fs from "fs";
|
|
8
|
-
import path from "path";
|
|
9
|
-
import { execFileSync } from "child_process";
|
|
10
|
-
var SYNC_PID_FILE = path.join(FML_DATA_DIR, "sync.pid");
|
|
11
|
-
var SYNC_LOG_FILE = path.join(FML_LOG_DIR, "sync.log");
|
|
12
|
-
function isDaemonRunning(pidFile) {
|
|
13
|
-
if (!fs.existsSync(pidFile)) return { running: false, pid: null };
|
|
14
|
-
const pid = parseInt(fs.readFileSync(pidFile, "utf-8").trim(), 10);
|
|
15
|
-
try {
|
|
16
|
-
process.kill(pid, 0);
|
|
17
|
-
return { running: true, pid };
|
|
18
|
-
} catch {
|
|
19
|
-
return { running: false, pid };
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
function resolvePanopticonBin() {
|
|
23
|
-
try {
|
|
24
|
-
const result = execFileSync("which", ["panopticon"], {
|
|
25
|
-
encoding: "utf-8",
|
|
26
|
-
timeout: 5e3
|
|
27
|
-
}).trim();
|
|
28
|
-
if (result) return result;
|
|
29
|
-
} catch {
|
|
30
|
-
}
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
function panopticonExec(...argsAndOpts) {
|
|
34
|
-
let timeout = 1e4;
|
|
35
|
-
const args = [];
|
|
36
|
-
for (const a of argsAndOpts) {
|
|
37
|
-
if (typeof a === "string") args.push(a);
|
|
38
|
-
else timeout = a.timeout ?? timeout;
|
|
39
|
-
}
|
|
40
|
-
const bin = resolvePanopticonBin();
|
|
41
|
-
if (!bin) return { ok: false, stdout: "panopticon binary not found" };
|
|
42
|
-
try {
|
|
43
|
-
const stdout = execFileSync("node", [bin, ...args], {
|
|
44
|
-
encoding: "utf-8",
|
|
45
|
-
timeout
|
|
46
|
-
});
|
|
47
|
-
return { ok: true, stdout };
|
|
48
|
-
} catch (err) {
|
|
49
|
-
const e = err;
|
|
50
|
-
return { ok: false, stdout: (e.stdout ?? "") + (e.stderr ?? "") };
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export {
|
|
55
|
-
SYNC_PID_FILE,
|
|
56
|
-
SYNC_LOG_FILE,
|
|
57
|
-
isDaemonRunning,
|
|
58
|
-
resolvePanopticonBin,
|
|
59
|
-
panopticonExec
|
|
60
|
-
};
|
|
61
|
-
//# sourceMappingURL=chunk-ZA4RG25C.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/daemon-utils.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { execFileSync } from \"node:child_process\";\nimport { FML_DATA_DIR, FML_LOG_DIR } from \"./dirs.js\";\n\nexport const SYNC_PID_FILE = path.join(FML_DATA_DIR, \"sync.pid\");\nexport const SYNC_LOG_FILE = path.join(FML_LOG_DIR, \"sync.log\");\n\nexport function isDaemonRunning(pidFile: string): {\n running: boolean;\n pid: number | null;\n} {\n if (!fs.existsSync(pidFile)) return { running: false, pid: null };\n const pid = parseInt(fs.readFileSync(pidFile, \"utf-8\").trim(), 10);\n try {\n process.kill(pid, 0);\n return { running: true, pid };\n } catch {\n return { running: false, pid };\n }\n}\n\n/** Resolve the panopticon CLI binary from PATH (globally installed). */\nexport function resolvePanopticonBin(): string | null {\n try {\n const result = execFileSync(\"which\", [\"panopticon\"], {\n encoding: \"utf-8\",\n timeout: 5_000,\n }).trim();\n if (result) return result;\n } catch {}\n\n return null;\n}\n\n/** Run a panopticon CLI command and return stdout. */\nexport function panopticonExec(...args: string[]): {\n ok: boolean;\n stdout: string;\n};\nexport function panopticonExec(\n ...argsAndOpts: [...string[], { timeout?: number }]\n): { ok: boolean; stdout: string };\nexport function panopticonExec(\n ...argsAndOpts: Array<string | { timeout?: number }>\n): {\n ok: boolean;\n stdout: string;\n} {\n let timeout = 10_000;\n const args: string[] = [];\n for (const a of argsAndOpts) {\n if (typeof a === \"string\") args.push(a);\n else timeout = a.timeout ?? timeout;\n }\n const bin = resolvePanopticonBin();\n if (!bin) return { ok: false, stdout: \"panopticon binary not found\" };\n try {\n const stdout = execFileSync(\"node\", [bin, ...args], {\n encoding: \"utf-8\",\n timeout,\n });\n return { ok: true, stdout };\n } catch (err: unknown) {\n const e = err as { stdout?: string; stderr?: string; status?: number };\n return { ok: false, stdout: (e.stdout ?? \"\") + (e.stderr ?? \"\") };\n }\n}\n"],"mappings":";;;;;;AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,oBAAoB;AAGtB,IAAM,gBAAgB,KAAK,KAAK,cAAc,UAAU;AACxD,IAAM,gBAAgB,KAAK,KAAK,aAAa,UAAU;AAEvD,SAAS,gBAAgB,SAG9B;AACA,MAAI,CAAC,GAAG,WAAW,OAAO,EAAG,QAAO,EAAE,SAAS,OAAO,KAAK,KAAK;AAChE,QAAM,MAAM,SAAS,GAAG,aAAa,SAAS,OAAO,EAAE,KAAK,GAAG,EAAE;AACjE,MAAI;AACF,YAAQ,KAAK,KAAK,CAAC;AACnB,WAAO,EAAE,SAAS,MAAM,IAAI;AAAA,EAC9B,QAAQ;AACN,WAAO,EAAE,SAAS,OAAO,IAAI;AAAA,EAC/B;AACF;AAGO,SAAS,uBAAsC;AACpD,MAAI;AACF,UAAM,SAAS,aAAa,SAAS,CAAC,YAAY,GAAG;AAAA,MACnD,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC,EAAE,KAAK;AACR,QAAI,OAAQ,QAAO;AAAA,EACrB,QAAQ;AAAA,EAAC;AAET,SAAO;AACT;AAUO,SAAS,kBACX,aAIH;AACA,MAAI,UAAU;AACd,QAAM,OAAiB,CAAC;AACxB,aAAW,KAAK,aAAa;AAC3B,QAAI,OAAO,MAAM,SAAU,MAAK,KAAK,CAAC;AAAA,QACjC,WAAU,EAAE,WAAW;AAAA,EAC9B;AACA,QAAM,MAAM,qBAAqB;AACjC,MAAI,CAAC,IAAK,QAAO,EAAE,IAAI,OAAO,QAAQ,8BAA8B;AACpE,MAAI;AACF,UAAM,SAAS,aAAa,QAAQ,CAAC,KAAK,GAAG,IAAI,GAAG;AAAA,MAClD,UAAU;AAAA,MACV;AAAA,IACF,CAAC;AACD,WAAO,EAAE,IAAI,MAAM,OAAO;AAAA,EAC5B,SAAS,KAAc;AACrB,UAAM,IAAI;AACV,WAAO,EAAE,IAAI,OAAO,SAAS,EAAE,UAAU,OAAO,EAAE,UAAU,IAAI;AAAA,EAClE;AACF;","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|