@fml-inc/fml 0.3.0 → 0.5.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/bin/fml +17 -0
- package/bin/mcp-server +17 -0
- package/dist/{chunk-CUBBYHH7.js → chunk-5BHBYQ2F.js} +84 -30
- package/dist/chunk-5BHBYQ2F.js.map +1 -0
- package/dist/chunk-OI562MUP.js +217 -0
- package/dist/chunk-OI562MUP.js.map +1 -0
- package/dist/{chunk-MUKYS4IB.js → chunk-YH5ROR7G.js} +1 -25
- package/dist/chunk-YH5ROR7G.js.map +1 -0
- package/dist/{chunk-CFPXJT5Q.js → chunk-ZFUJ5ZQP.js} +17 -9
- package/dist/chunk-ZFUJ5ZQP.js.map +1 -0
- package/dist/cli.js +60 -42
- package/dist/cli.js.map +1 -1
- package/dist/daemon-J27JBWLV.js +17 -0
- package/dist/daemon-utils-OODBIYB7.js +10 -0
- package/dist/mcp/server.js +112 -13
- package/dist/mcp/server.js.map +1 -1
- package/dist/{token-store-HOFFHNNN.js → token-store-T2RNLXRM.js} +2 -3
- package/package.json +2 -9
- package/bin/sync-daemon +0 -3
- package/dist/chunk-4YEAQJPF.js +0 -47
- package/dist/chunk-4YEAQJPF.js.map +0 -1
- package/dist/chunk-BOREGHA6.js +0 -221
- package/dist/chunk-BOREGHA6.js.map +0 -1
- package/dist/chunk-CFPXJT5Q.js.map +0 -1
- package/dist/chunk-CUBBYHH7.js.map +0 -1
- package/dist/chunk-MUKYS4IB.js.map +0 -1
- package/dist/daemon-GM3WNS4Z.js +0 -16
- package/dist/daemon-utils-CJO4XVJQ.js +0 -17
- /package/dist/{daemon-GM3WNS4Z.js.map → daemon-J27JBWLV.js.map} +0 -0
- /package/dist/{daemon-utils-CJO4XVJQ.js.map → daemon-utils-OODBIYB7.js.map} +0 -0
- /package/dist/{token-store-HOFFHNNN.js.map → token-store-T2RNLXRM.js.map} +0 -0
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
SYNC_PID_FILE,
|
|
3
|
-
isDaemonRunning,
|
|
4
2
|
panopticonExec
|
|
5
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-YH5ROR7G.js";
|
|
6
4
|
|
|
7
5
|
// src/commands/daemon.ts
|
|
8
6
|
function parsePanopticonRunning() {
|
|
@@ -10,9 +8,6 @@ function parsePanopticonRunning() {
|
|
|
10
8
|
const serverLine = result.stdout.split("\n").find((l) => l.startsWith("Server:"));
|
|
11
9
|
return result.ok && /running/i.test(serverLine ?? "");
|
|
12
10
|
}
|
|
13
|
-
function isSyncRunning() {
|
|
14
|
-
return isDaemonRunning(SYNC_PID_FILE);
|
|
15
|
-
}
|
|
16
11
|
async function handleStart() {
|
|
17
12
|
const startResult = panopticonExec("start");
|
|
18
13
|
console.log(
|
|
@@ -23,11 +18,24 @@ function handleStop() {
|
|
|
23
18
|
const stopResult = panopticonExec("stop");
|
|
24
19
|
console.log(stopResult.stdout.trim() || "Panopticon stopped");
|
|
25
20
|
}
|
|
21
|
+
function handleSyncStart() {
|
|
22
|
+
const result = panopticonExec("sync", "enable");
|
|
23
|
+
console.log(
|
|
24
|
+
result.stdout.trim() || (result.ok ? "Sync enabled" : "Failed to enable sync")
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
function handleSyncStop() {
|
|
28
|
+
const result = panopticonExec("sync", "disable");
|
|
29
|
+
console.log(
|
|
30
|
+
result.stdout.trim() || (result.ok ? "Sync disabled" : "Failed to disable sync")
|
|
31
|
+
);
|
|
32
|
+
}
|
|
26
33
|
|
|
27
34
|
export {
|
|
28
35
|
parsePanopticonRunning,
|
|
29
|
-
isSyncRunning,
|
|
30
36
|
handleStart,
|
|
31
|
-
handleStop
|
|
37
|
+
handleStop,
|
|
38
|
+
handleSyncStart,
|
|
39
|
+
handleSyncStop
|
|
32
40
|
};
|
|
33
|
-
//# sourceMappingURL=chunk-
|
|
41
|
+
//# sourceMappingURL=chunk-ZFUJ5ZQP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/daemon.ts"],"sourcesContent":["import { panopticonExec } from \"../daemon-utils.js\";\n\n// ── Status helpers (used by doctor, status) ─────────────────────────────────\n\nexport function parsePanopticonRunning(): boolean {\n const result = panopticonExec(\"status\");\n const serverLine = result.stdout\n .split(\"\\n\")\n .find((l) => l.startsWith(\"Server:\"));\n return result.ok && /running/i.test(serverLine ?? \"\");\n}\n\n// ── Panopticon server start / stop (used by CLI, env restart, install, MCP) ──\n\nexport async function handleStart(): Promise<void> {\n const startResult = panopticonExec(\"start\");\n console.log(\n startResult.stdout.trim() ||\n (startResult.ok ? \"Panopticon started\" : \"Failed to start panopticon\"),\n );\n}\n\nexport function handleStop(): void {\n const stopResult = panopticonExec(\"stop\");\n console.log(stopResult.stdout.trim() || \"Panopticon stopped\");\n}\n\n// ── Sync start / stop (used by `fml sync start|stop`) ───────────────────────\n// Sync runs inside the panopticon server; these toggle the persisted\n// sync-enabled flag via panopticon, independent of the server lifecycle.\n\nexport function handleSyncStart(): void {\n const result = panopticonExec(\"sync\", \"enable\");\n console.log(\n result.stdout.trim() ||\n (result.ok ? \"Sync enabled\" : \"Failed to enable sync\"),\n );\n}\n\nexport function handleSyncStop(): void {\n const result = panopticonExec(\"sync\", \"disable\");\n console.log(\n result.stdout.trim() ||\n (result.ok ? \"Sync disabled\" : \"Failed to disable sync\"),\n );\n}\n"],"mappings":";;;;;AAIO,SAAS,yBAAkC;AAChD,QAAM,SAAS,eAAe,QAAQ;AACtC,QAAM,aAAa,OAAO,OACvB,MAAM,IAAI,EACV,KAAK,CAAC,MAAM,EAAE,WAAW,SAAS,CAAC;AACtC,SAAO,OAAO,MAAM,WAAW,KAAK,cAAc,EAAE;AACtD;AAIA,eAAsB,cAA6B;AACjD,QAAM,cAAc,eAAe,OAAO;AAC1C,UAAQ;AAAA,IACN,YAAY,OAAO,KAAK,MACrB,YAAY,KAAK,uBAAuB;AAAA,EAC7C;AACF;AAEO,SAAS,aAAmB;AACjC,QAAM,aAAa,eAAe,MAAM;AACxC,UAAQ,IAAI,WAAW,OAAO,KAAK,KAAK,oBAAoB;AAC9D;AAMO,SAAS,kBAAwB;AACtC,QAAM,SAAS,eAAe,QAAQ,QAAQ;AAC9C,UAAQ;AAAA,IACN,OAAO,OAAO,KAAK,MAChB,OAAO,KAAK,iBAAiB;AAAA,EAClC;AACF;AAEO,SAAS,iBAAuB;AACrC,QAAM,SAAS,eAAe,QAAQ,SAAS;AAC/C,UAAQ;AAAA,IACN,OAAO,OAAO,KAAK,MAChB,OAAO,KAAK,kBAAkB;AAAA,EACnC;AACF;","names":[]}
|
package/dist/cli.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
ensureNativeModules,
|
|
3
|
+
createFmlClient,
|
|
5
4
|
getAuthenticatedClient
|
|
6
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-OI562MUP.js";
|
|
7
6
|
import {
|
|
8
7
|
CONVEX_URL,
|
|
9
8
|
DEFAULT_SYNC_URL,
|
|
10
9
|
DEFAULT_TARGET_NAME,
|
|
10
|
+
FML_DATA_DIR,
|
|
11
|
+
FML_LOG_DIR,
|
|
11
12
|
Sentry,
|
|
12
13
|
WORKOS_API_URL,
|
|
13
14
|
WORKOS_AUTH_URL,
|
|
14
15
|
authStorePath,
|
|
16
|
+
envConfigExists,
|
|
15
17
|
getActiveEnv,
|
|
16
18
|
getSelectedOrg,
|
|
17
19
|
getSiteUrl,
|
|
@@ -22,21 +24,19 @@ import {
|
|
|
22
24
|
setSelectedOrg,
|
|
23
25
|
writeEnvConfig,
|
|
24
26
|
writeTokens
|
|
25
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-5BHBYQ2F.js";
|
|
26
28
|
import {
|
|
27
29
|
handleStart,
|
|
28
30
|
handleStop,
|
|
31
|
+
handleSyncStart,
|
|
32
|
+
handleSyncStop,
|
|
29
33
|
parsePanopticonRunning
|
|
30
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-ZFUJ5ZQP.js";
|
|
31
35
|
import {
|
|
32
36
|
execBinSync,
|
|
33
37
|
panopticonExec,
|
|
34
38
|
resolveBin
|
|
35
|
-
} from "./chunk-
|
|
36
|
-
import {
|
|
37
|
-
FML_DATA_DIR,
|
|
38
|
-
FML_LOG_DIR
|
|
39
|
-
} from "./chunk-4YEAQJPF.js";
|
|
39
|
+
} from "./chunk-YH5ROR7G.js";
|
|
40
40
|
import "./chunk-PZ5AY32C.js";
|
|
41
41
|
|
|
42
42
|
// src/cli.ts
|
|
@@ -220,7 +220,7 @@ async function handleDoctor(opts) {
|
|
|
220
220
|
const spinner = startSpinner("API");
|
|
221
221
|
if (token) {
|
|
222
222
|
try {
|
|
223
|
-
const result = await
|
|
223
|
+
const result = await createFmlClient(token).callBackend("ping", {});
|
|
224
224
|
if (result.ok) {
|
|
225
225
|
pushAndReport(
|
|
226
226
|
{
|
|
@@ -366,15 +366,17 @@ function writeJsonFile(filePath, data) {
|
|
|
366
366
|
fs.writeFileSync(filePath, `${JSON.stringify(data, null, 2)}
|
|
367
367
|
`);
|
|
368
368
|
}
|
|
369
|
-
async function handleInstall() {
|
|
369
|
+
async function handleInstall(opts = {}) {
|
|
370
|
+
const force = opts.force ?? false;
|
|
370
371
|
const pluginRoot = getPluginRoot();
|
|
371
|
-
console.log(
|
|
372
|
+
console.log(`Installing fml${force ? " (--force)" : ""}...
|
|
373
|
+
`);
|
|
372
374
|
console.log("[1/5] Setting up panopticon...");
|
|
373
|
-
const { resolvePanopticonBin } = await import("./daemon-utils-
|
|
375
|
+
const { resolvePanopticonBin } = await import("./daemon-utils-OODBIYB7.js");
|
|
374
376
|
let freshInstall = false;
|
|
375
377
|
const bin = resolvePanopticonBin();
|
|
376
|
-
let needsInstall = !bin;
|
|
377
|
-
if (bin) {
|
|
378
|
+
let needsInstall = !bin || force;
|
|
379
|
+
if (bin && !force) {
|
|
378
380
|
const MIN_PANOPTICON = "0.2.2";
|
|
379
381
|
const vResult = panopticonExec("--version", { timeout: 5e3 });
|
|
380
382
|
const installed = vResult.ok ? vResult.stdout.trim().split("+")[0] : "0.0.0";
|
|
@@ -529,7 +531,9 @@ async function handleInstall() {
|
|
|
529
531
|
);
|
|
530
532
|
}
|
|
531
533
|
}
|
|
532
|
-
|
|
534
|
+
if (!envConfigExists()) {
|
|
535
|
+
writeEnvConfig({ active: DEFAULT_TARGET_NAME });
|
|
536
|
+
}
|
|
533
537
|
console.log("");
|
|
534
538
|
printBanner();
|
|
535
539
|
console.log("Done! Start a new coding session to activate.\n");
|
|
@@ -701,7 +705,7 @@ function handleUninstall(opts) {
|
|
|
701
705
|
// src/commands/update.ts
|
|
702
706
|
import { execSync as execSync2 } from "child_process";
|
|
703
707
|
async function handleUpdate() {
|
|
704
|
-
const currentVersion = true ? "0.
|
|
708
|
+
const currentVersion = true ? "0.5.0+738a81c" : "unknown";
|
|
705
709
|
console.log(`Current: ${currentVersion}`);
|
|
706
710
|
console.log("Updating via npm...\n");
|
|
707
711
|
try {
|
|
@@ -712,7 +716,7 @@ async function handleUpdate() {
|
|
|
712
716
|
timeout: 12e4,
|
|
713
717
|
env
|
|
714
718
|
});
|
|
715
|
-
console.log("\nUpdated. Run `fml install --
|
|
719
|
+
console.log("\nUpdated. Run `fml install --force` to reconfigure.");
|
|
716
720
|
} catch (err) {
|
|
717
721
|
Sentry.captureException(err);
|
|
718
722
|
const msg = err instanceof Error ? err.stderr?.toString() ?? err.message : String(err);
|
|
@@ -732,11 +736,12 @@ import {
|
|
|
732
736
|
import crypto from "crypto";
|
|
733
737
|
import http from "http";
|
|
734
738
|
async function fetchWorkosClientId() {
|
|
735
|
-
const
|
|
736
|
-
const
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
739
|
+
const response = await fetch(`${getSiteUrl()}/api/auth/config`);
|
|
740
|
+
const data = await response.json();
|
|
741
|
+
if (!response.ok || data.ok === false || !data.workosClientId) {
|
|
742
|
+
throw new Error(data.error ?? `HTTP ${response.status}`);
|
|
743
|
+
}
|
|
744
|
+
return data.workosClientId;
|
|
740
745
|
}
|
|
741
746
|
async function canOpenBrowser() {
|
|
742
747
|
if (process.env.FML_DEVICE_FLOW === "1") return false;
|
|
@@ -993,15 +998,22 @@ async function linkGitHubIdentity() {
|
|
|
993
998
|
if (fmlToken.startsWith("fml_st_")) {
|
|
994
999
|
return;
|
|
995
1000
|
}
|
|
996
|
-
const
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1001
|
+
const linkResponse = await fetch(`${getSiteUrl()}/api/auth/link-github-identity`, {
|
|
1002
|
+
method: "POST",
|
|
1003
|
+
headers: {
|
|
1004
|
+
"Content-Type": "application/json",
|
|
1005
|
+
Authorization: `Bearer ${fmlToken}`
|
|
1006
|
+
},
|
|
1007
|
+
body: JSON.stringify({
|
|
1008
|
+
githubUsername: user.login,
|
|
1009
|
+
githubId: user.id,
|
|
1010
|
+
githubEmail: user.email ?? void 0
|
|
1011
|
+
})
|
|
1004
1012
|
});
|
|
1013
|
+
const linkResult = await linkResponse.json();
|
|
1014
|
+
if (!linkResponse.ok || linkResult.ok === false) {
|
|
1015
|
+
throw new Error(linkResult.error ?? `HTTP ${linkResponse.status}`);
|
|
1016
|
+
}
|
|
1005
1017
|
console.log(`Linked GitHub account: ${user.login}`);
|
|
1006
1018
|
} catch (err) {
|
|
1007
1019
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -1048,10 +1060,11 @@ async function selectOrg() {
|
|
|
1048
1060
|
try {
|
|
1049
1061
|
const token = await getValidToken();
|
|
1050
1062
|
if (!token) return;
|
|
1051
|
-
const api =
|
|
1063
|
+
const api = createFmlClient(token);
|
|
1052
1064
|
const orgs = await api.queryOrgs();
|
|
1053
1065
|
if (orgs.length === 0) return;
|
|
1054
|
-
const
|
|
1066
|
+
const current = getSelectedOrg();
|
|
1067
|
+
const org = current && orgs.find((o) => (o.slug ?? o.name) === current) || orgs[0];
|
|
1055
1068
|
const slug = org.slug ?? org.name;
|
|
1056
1069
|
setSelectedOrg(slug);
|
|
1057
1070
|
console.log(`Selected org: ${org.name} (${slug})`);
|
|
@@ -1062,7 +1075,7 @@ async function handleLogin(opts) {
|
|
|
1062
1075
|
const { name: envName } = getActiveEnv();
|
|
1063
1076
|
const existingToken = await getValidToken();
|
|
1064
1077
|
if (existingToken) {
|
|
1065
|
-
const { readTokens: readTokens2 } = await import("./token-store-
|
|
1078
|
+
const { readTokens: readTokens2 } = await import("./token-store-T2RNLXRM.js");
|
|
1066
1079
|
const stored = readTokens2();
|
|
1067
1080
|
console.log(
|
|
1068
1081
|
`Already logged in as ${stored?.user.name} (${stored?.user.email}) on ${envName}.`
|
|
@@ -1114,7 +1127,7 @@ async function handleOrg(slug) {
|
|
|
1114
1127
|
console.error("Not logged in. Run `fml login` first.");
|
|
1115
1128
|
process.exit(1);
|
|
1116
1129
|
}
|
|
1117
|
-
const api =
|
|
1130
|
+
const api = createFmlClient(token);
|
|
1118
1131
|
const orgs = await api.queryOrgs();
|
|
1119
1132
|
if (orgs.length === 0) {
|
|
1120
1133
|
console.error("No organizations found.");
|
|
@@ -1946,7 +1959,7 @@ async function handleConfigDetail(opts) {
|
|
|
1946
1959
|
// src/commands/tools.ts
|
|
1947
1960
|
import { readFileSync } from "fs";
|
|
1948
1961
|
import path3 from "path";
|
|
1949
|
-
var pluginVersion = true ? "0.
|
|
1962
|
+
var pluginVersion = true ? "0.5.0+738a81c" : void 0;
|
|
1950
1963
|
async function getApi() {
|
|
1951
1964
|
const api = await getAuthenticatedClient();
|
|
1952
1965
|
if (!api) {
|
|
@@ -2072,13 +2085,12 @@ async function handleToolsCall(name, opts) {
|
|
|
2072
2085
|
}
|
|
2073
2086
|
|
|
2074
2087
|
// src/cli.ts
|
|
2075
|
-
ensureNativeModules();
|
|
2076
2088
|
await initSentry();
|
|
2077
2089
|
if (process.argv.length <= 2 || process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
2078
2090
|
printBanner();
|
|
2079
2091
|
}
|
|
2080
2092
|
var program = new Command().name("fml").description("FML agent tools for Claude Code").version(
|
|
2081
|
-
true ? "0.
|
|
2093
|
+
true ? "0.5.0+738a81c" : "dev"
|
|
2082
2094
|
);
|
|
2083
2095
|
var tools = program.command("tools", { hidden: true }).description("List all available CLI commands (including hidden agent tools)").action(() => {
|
|
2084
2096
|
function formatCmd(cmd, prefix = "") {
|
|
@@ -2102,7 +2114,10 @@ var tools = program.command("tools", { hidden: true }).description("List all ava
|
|
|
2102
2114
|
tools.command("list").description("List backend tools available via the dynamic catalog").option("--category <category>", "Filter by category").option("--json", "Output as JSON").action((opts) => handleToolsList(opts));
|
|
2103
2115
|
tools.command("describe").description("Show description and input schema for a backend tool").argument("<name>", "Tool name (e.g. integration-github)").option("--json", "Output as JSON").action((name, opts) => handleToolsDescribe(name, opts));
|
|
2104
2116
|
tools.command("call").description("Invoke a backend tool by name with JSON args").argument("<name>", "Tool name").option("--args <json>", "Args as a JSON string (defaults to {})").option("--file <path>", "Path to a JSON file containing args").action((name, opts) => handleToolsCall(name, opts));
|
|
2105
|
-
program.command("install").description("Register plugin, hooks, and daemons").
|
|
2117
|
+
program.command("install").description("Register plugin, hooks, and daemons").option(
|
|
2118
|
+
"--force",
|
|
2119
|
+
"Reinstall even if already set up (upgrades panopticon, re-registers plugin)"
|
|
2120
|
+
).action((opts) => handleInstall(opts));
|
|
2106
2121
|
program.command("uninstall").description("Remove fml plugin, hooks, and optionally all data").option(
|
|
2107
2122
|
"--target <target>",
|
|
2108
2123
|
"Target CLI: claude, gemini, codex, claude-desktop, all"
|
|
@@ -2118,9 +2133,12 @@ program.command("env").description("Show or switch environment (dev/prod)").argu
|
|
|
2118
2133
|
if (target) handleEnvSwitch(target);
|
|
2119
2134
|
else handleEnvShow();
|
|
2120
2135
|
});
|
|
2121
|
-
program.command("
|
|
2122
|
-
|
|
2136
|
+
var panopticon = program.command("panopticon").description("Start or stop the panopticon server");
|
|
2137
|
+
panopticon.command("start").description("Start the panopticon server").action(() => handleStart());
|
|
2138
|
+
panopticon.command("stop").description("Stop the panopticon server").action(() => handleStop());
|
|
2123
2139
|
var sync = program.command("sync").description("Manage sync configuration");
|
|
2140
|
+
sync.command("start").description("Start syncing to configured targets (enable sync)").action(() => handleSyncStart());
|
|
2141
|
+
sync.command("stop").description("Stop syncing (disable sync; leaves targets configured)").action(() => handleSyncStop());
|
|
2124
2142
|
sync.command("setup").description("Configure sync targets (convenience shortcut)").action(() => handleSyncSetup());
|
|
2125
2143
|
sync.command("list").description("List all sync targets").action(() => handleSyncList());
|
|
2126
2144
|
sync.command("add").description("Add a sync target").argument("<name>", "Unique target name").argument("<url>", "OTLP HTTP endpoint URL").option("--token-cmd <cmd>", "Shell command that returns a bearer token").option("--token <token>", "Static bearer token").action(
|