@fml-inc/fml 0.8.10-dev.1 → 0.8.10
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/README.md +114 -3
- package/agent-assets/mini-swe-agent/FML_WORKFLOW.md +62 -0
- package/agent-assets/mini-swe-agent/fml_mini_agent.py +483 -0
- package/agent-assets/mini-swe-agent/fml_mini_bootstrap.py +141 -0
- package/bin/fml +18 -4
- package/dist/{chunk-2DGHAVVR.js → chunk-OUXFHL3I.js} +1 -1
- package/dist/{chunk-JPHN4VKM.js → chunk-PTDADW47.js} +197 -94
- package/dist/{chunk-5SI6S4HW.js → chunk-U4BM27VN.js} +1 -1
- package/dist/{chunk-5PEFBQNX.js → chunk-XB7EIDWY.js} +17 -4
- package/dist/cli.js +4600 -3882
- package/dist/hook-handler.js +39 -11
- package/dist/mcp/server.js +5 -5
- package/dist/observer-server.js +5 -5
- package/dist/pi/extension.js +17 -4
- package/dist/sync-cycle.js +2 -2
- package/package.json +1 -1
package/dist/hook-handler.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
readObserverAuthToken,
|
|
20
20
|
readObserverState,
|
|
21
21
|
recordHookInboxLoss
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-XB7EIDWY.js";
|
|
23
23
|
import {
|
|
24
24
|
resolveRepositoryRootFromCwd,
|
|
25
25
|
resolveRepositorySlugFromCwd
|
|
@@ -231,17 +231,17 @@ function isSubsequentUserPrompt(sessionId, eventSyncId, stateDir = FML_HOOK_CONT
|
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
|
-
function
|
|
234
|
+
function contextWasEmitted(sessionId, contextKey, stateDir) {
|
|
235
235
|
try {
|
|
236
236
|
return fs2.existsSync(
|
|
237
|
-
markerPath(stateDir, "path", `${sessionId}:${
|
|
237
|
+
markerPath(stateDir, "path", `${sessionId}:${contextKey}`)
|
|
238
238
|
);
|
|
239
239
|
} catch {
|
|
240
240
|
return true;
|
|
241
241
|
}
|
|
242
242
|
}
|
|
243
|
-
function
|
|
244
|
-
const claim = markerPath(stateDir, "path", `${sessionId}:${
|
|
243
|
+
function claimContextEmission(sessionId, contextKey, stateDir) {
|
|
244
|
+
const claim = markerPath(stateDir, "path", `${sessionId}:${contextKey}`);
|
|
245
245
|
if (!ensureMarkerDirectory(claim)) return false;
|
|
246
246
|
try {
|
|
247
247
|
fs2.writeFileSync(claim, "", { flag: "wx", mode: 384 });
|
|
@@ -300,7 +300,7 @@ function canonicalHookContextFilePath(filePath, cwd, repositoryRoot) {
|
|
|
300
300
|
return resolved.replace(/\\/g, "/");
|
|
301
301
|
}
|
|
302
302
|
function buildServerHookContextRequest(target2, event, stateDir = FML_HOOK_CONTEXT_STATE_DIR, repositoryRoot = null) {
|
|
303
|
-
if (target2 !== "claude" && target2 !== "codex" && target2 !== "pi") {
|
|
303
|
+
if (target2 !== "claude" && target2 !== "codex" && target2 !== "pi" && target2 !== "mini-swe-agent") {
|
|
304
304
|
return null;
|
|
305
305
|
}
|
|
306
306
|
if (!event.repository) return null;
|
|
@@ -312,6 +312,21 @@ function buildServerHookContextRequest(target2, event, stateDir = FML_HOOK_CONTE
|
|
|
312
312
|
injectionId: hookContextInjectionId(target2, event.syncId),
|
|
313
313
|
nowMs: event.timestampMs
|
|
314
314
|
};
|
|
315
|
+
if (target2 === "mini-swe-agent") {
|
|
316
|
+
const payload = event.payload;
|
|
317
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload) || !("prompt" in payload)) {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
const prompt = payload.prompt;
|
|
321
|
+
if (event.eventType !== "BeforeModel" || typeof prompt !== "string" || !prompt.trim() || contextWasEmitted(markerSessionId, `model:${event.syncId}`, stateDir)) {
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
return isSubsequentUserPrompt(markerSessionId, event.syncId, stateDir) ? {
|
|
325
|
+
...base,
|
|
326
|
+
eventType: "UserPromptSubmit",
|
|
327
|
+
prompt: prompt.slice(0, MAX_PROMPT_CHARS)
|
|
328
|
+
} : { ...base, eventType: "SessionStart" };
|
|
329
|
+
}
|
|
315
330
|
if (event.eventType === "SessionStart") {
|
|
316
331
|
return { ...base, eventType: "SessionStart" };
|
|
317
332
|
}
|
|
@@ -336,7 +351,7 @@ function buildServerHookContextRequest(target2, event, stateDir = FML_HOOK_CONTE
|
|
|
336
351
|
event.cwd,
|
|
337
352
|
repositoryRoot
|
|
338
353
|
);
|
|
339
|
-
if (
|
|
354
|
+
if (contextWasEmitted(
|
|
340
355
|
markerSessionId,
|
|
341
356
|
`${event.repository}:${filePath}`,
|
|
342
357
|
stateDir
|
|
@@ -627,6 +642,9 @@ async function requestServerHookContextInjection(request, destination, opts = {}
|
|
|
627
642
|
}
|
|
628
643
|
}
|
|
629
644
|
function hookOutput(request, injection) {
|
|
645
|
+
if (request.target === "mini-swe-agent") {
|
|
646
|
+
return { context: injection.additionalContext };
|
|
647
|
+
}
|
|
630
648
|
return {
|
|
631
649
|
...injection.receipt ? { systemMessage: injection.receipt } : {},
|
|
632
650
|
hookSpecificOutput: {
|
|
@@ -652,9 +670,16 @@ async function requestServerHookContext(target2, event, destination, opts = {})
|
|
|
652
670
|
opts
|
|
653
671
|
);
|
|
654
672
|
if (injection === null) return {};
|
|
673
|
+
if (target2 === "mini-swe-agent" && !claimContextEmission(
|
|
674
|
+
`${target2}:${request.sessionId}`,
|
|
675
|
+
`model:${event.syncId}`,
|
|
676
|
+
stateDir
|
|
677
|
+
)) {
|
|
678
|
+
return {};
|
|
679
|
+
}
|
|
655
680
|
if (injection.additionalContext === null) {
|
|
656
681
|
if (request.eventType === "PreToolUse" && request.filePath) {
|
|
657
|
-
|
|
682
|
+
claimContextEmission(
|
|
658
683
|
`${target2}:${request.sessionId}`,
|
|
659
684
|
`${request.repository}:${request.filePath}`,
|
|
660
685
|
stateDir
|
|
@@ -662,7 +687,7 @@ async function requestServerHookContext(target2, event, destination, opts = {})
|
|
|
662
687
|
}
|
|
663
688
|
return {};
|
|
664
689
|
}
|
|
665
|
-
if (request.eventType === "PreToolUse" && request.filePath && !
|
|
690
|
+
if (request.eventType === "PreToolUse" && request.filePath && !claimContextEmission(
|
|
666
691
|
`${target2}:${request.sessionId}`,
|
|
667
692
|
`${request.repository}:${request.filePath}`,
|
|
668
693
|
stateDir
|
|
@@ -681,7 +706,8 @@ var INSTALLED_HOOK_TARGETS = Object.freeze([
|
|
|
681
706
|
"claude",
|
|
682
707
|
"codex",
|
|
683
708
|
"gemini",
|
|
684
|
-
"grok"
|
|
709
|
+
"grok",
|
|
710
|
+
"mini-swe-agent"
|
|
685
711
|
]);
|
|
686
712
|
function parseHookTarget(value) {
|
|
687
713
|
return INSTALLED_HOOK_TARGETS.includes(
|
|
@@ -917,6 +943,8 @@ async function runHookHandlerForOutput(target2, opts = {}) {
|
|
|
917
943
|
}
|
|
918
944
|
|
|
919
945
|
// src/hook-handler.ts
|
|
920
|
-
var target = parseHookTarget(
|
|
946
|
+
var target = parseHookTarget(
|
|
947
|
+
process.argv[2] === "hook" ? process.argv[3] === "--target" && process.argv.length === 5 ? process.argv[4] : void 0 : process.argv[2]
|
|
948
|
+
);
|
|
921
949
|
var output = target ? await runHookHandlerForOutput(target).catch(() => ({})) : {};
|
|
922
950
|
process.stdout.write(JSON.stringify(output));
|
package/dist/mcp/server.js
CHANGED
|
@@ -309,7 +309,7 @@ function registerTools(server2, environment = getActiveEnv()) {
|
|
|
309
309
|
timeRange: z.enum(["1h", "6h", "24h", "7d", "30d"]).optional().describe("Preset time range. Default '7d'."),
|
|
310
310
|
since: z.string().optional().describe("ISO 8601 start timestamp. Overrides timeRange."),
|
|
311
311
|
until: z.string().optional().describe("ISO 8601 end timestamp."),
|
|
312
|
-
target: z.enum(["claude", "codex", "gemini", "mastra"]).optional().describe("Filter by agent type. Omit for all."),
|
|
312
|
+
target: z.enum(["claude", "codex", "gemini", "mastra", "mini-swe-agent"]).optional().describe("Filter by agent type. Omit for all."),
|
|
313
313
|
scope: z.enum(["org", "project", "user"]).optional().describe("Query scope. 'org' (default), 'project', or 'user'."),
|
|
314
314
|
githubUsername: z.string().optional().describe("Required when scope is 'user'. GitHub username.")
|
|
315
315
|
},
|
|
@@ -317,10 +317,10 @@ function registerTools(server2, environment = getActiveEnv()) {
|
|
|
317
317
|
);
|
|
318
318
|
server2.tool(
|
|
319
319
|
"list_engineering_sessions",
|
|
320
|
-
"List agent sessions (Claude Code, Codex, Gemini CLI, Mastra). Each session includes first prompt preview and event counts.",
|
|
320
|
+
"List agent sessions (Claude Code, Codex, Gemini CLI, Mastra, mini-swe-agent). Each session includes first prompt preview and event counts.",
|
|
321
321
|
{
|
|
322
322
|
scope: z.enum(["org", "project"]).optional().describe("Query scope. Default 'org'."),
|
|
323
|
-
target: z.enum(["claude", "codex", "gemini", "mastra"]).optional().describe("Filter by agent type. Omit for all."),
|
|
323
|
+
target: z.enum(["claude", "codex", "gemini", "mastra", "mini-swe-agent"]).optional().describe("Filter by agent type. Omit for all."),
|
|
324
324
|
githubUsername: z.string().optional().describe("Filter to sessions by this GitHub username."),
|
|
325
325
|
timeRange: z.enum(["1h", "6h", "24h", "7d", "30d"]).optional(),
|
|
326
326
|
since: z.string().optional().describe("ISO 8601 start timestamp."),
|
|
@@ -348,7 +348,7 @@ function registerTools(server2, environment = getActiveEnv()) {
|
|
|
348
348
|
since: z.string().optional().describe("ISO 8601 start timestamp."),
|
|
349
349
|
until: z.string().optional().describe("ISO 8601 end timestamp."),
|
|
350
350
|
groupBy: z.enum(["session", "model", "day", "user"]).optional().describe("How to group results."),
|
|
351
|
-
target: z.enum(["claude", "codex", "gemini", "mastra"]).optional().describe("Filter by agent type. Omit for all."),
|
|
351
|
+
target: z.enum(["claude", "codex", "gemini", "mastra", "mini-swe-agent"]).optional().describe("Filter by agent type. Omit for all."),
|
|
352
352
|
timezone: z.string().optional().describe(
|
|
353
353
|
"IANA timezone fallback for day grouping when a session's author has no recorded timezone (author-recorded timezones win). Defaults to UTC."
|
|
354
354
|
),
|
|
@@ -365,7 +365,7 @@ function registerTools(server2, environment = getActiveEnv()) {
|
|
|
365
365
|
timeRange: z.enum(["1h", "6h", "24h", "7d", "30d"]).optional(),
|
|
366
366
|
since: z.string().optional(),
|
|
367
367
|
until: z.string().optional(),
|
|
368
|
-
target: z.enum(["claude", "codex", "gemini", "mastra"]).optional().describe("Filter by agent type. Omit for all."),
|
|
368
|
+
target: z.enum(["claude", "codex", "gemini", "mastra", "mini-swe-agent"]).optional().describe("Filter by agent type. Omit for all."),
|
|
369
369
|
limit: z.number().optional().describe("Max results (default 20).")
|
|
370
370
|
},
|
|
371
371
|
async (args) => handleTool("search-engineering-sessions", args)
|
package/dist/observer-server.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
isWinShim,
|
|
6
6
|
quoteWinArg,
|
|
7
7
|
resolveBin
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-U4BM27VN.js";
|
|
9
9
|
import {
|
|
10
10
|
createHookSyncLoop,
|
|
11
11
|
getActiveHookDestinationBinding
|
|
@@ -30,16 +30,16 @@ import {
|
|
|
30
30
|
removeObserverStateIfOwned,
|
|
31
31
|
retireHookInboxEntry,
|
|
32
32
|
updateObserverState
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-XB7EIDWY.js";
|
|
34
34
|
import "./chunk-7V7G7NVF.js";
|
|
35
35
|
import {
|
|
36
36
|
ObserverSyncCycleAbortedError,
|
|
37
37
|
runObserverSyncCycleSubprocess
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-OUXFHL3I.js";
|
|
39
39
|
import {
|
|
40
40
|
createCliRawSync,
|
|
41
41
|
invalidateCliRawSyncDiscoveryCache
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-PTDADW47.js";
|
|
43
43
|
import "./chunk-F57IFY3K.js";
|
|
44
44
|
import {
|
|
45
45
|
FML_OBSERVER_AUTH_TOKEN_FILE,
|
|
@@ -1563,7 +1563,7 @@ var hookRejectionStatus = () => ({
|
|
|
1563
1563
|
...lastRejectedReason !== void 0 ? { lastRejectedReason } : {},
|
|
1564
1564
|
...lastRejectedTarget !== void 0 ? { lastRejectedTarget } : {}
|
|
1565
1565
|
});
|
|
1566
|
-
var packageVersion = true ? "0.8.10
|
|
1566
|
+
var packageVersion = true ? "0.8.10+45913c27" : "dev";
|
|
1567
1567
|
var health = () => ({
|
|
1568
1568
|
status: "ok",
|
|
1569
1569
|
service: OBSERVER_SERVICE_NAME,
|
package/dist/pi/extension.js
CHANGED
|
@@ -1776,7 +1776,8 @@ var HOOK_TARGETS = Object.freeze([
|
|
|
1776
1776
|
"codex",
|
|
1777
1777
|
"gemini",
|
|
1778
1778
|
"grok",
|
|
1779
|
-
"pi"
|
|
1779
|
+
"pi",
|
|
1780
|
+
"mini-swe-agent"
|
|
1780
1781
|
]);
|
|
1781
1782
|
|
|
1782
1783
|
// ../../packages/agent-targets/src/catalog/hook-events.json
|
|
@@ -1853,6 +1854,14 @@ var hook_events_default = {
|
|
|
1853
1854
|
"PreCompact",
|
|
1854
1855
|
"PostCompact",
|
|
1855
1856
|
"SessionEnd"
|
|
1857
|
+
],
|
|
1858
|
+
"mini-swe-agent": [
|
|
1859
|
+
"SessionStart",
|
|
1860
|
+
"UserPromptSubmit",
|
|
1861
|
+
"BeforeModel",
|
|
1862
|
+
"PostToolUse",
|
|
1863
|
+
"Stop",
|
|
1864
|
+
"SessionEnd"
|
|
1856
1865
|
]
|
|
1857
1866
|
};
|
|
1858
1867
|
|
|
@@ -1870,6 +1879,9 @@ var GROK_HOOK_EVENTS = Object.freeze([
|
|
|
1870
1879
|
...hook_events_default.grok
|
|
1871
1880
|
]);
|
|
1872
1881
|
var PI_HOOK_EVENTS = Object.freeze([...hook_events_default.pi]);
|
|
1882
|
+
var MINI_SWE_AGENT_HOOK_EVENTS = Object.freeze([
|
|
1883
|
+
...hook_events_default["mini-swe-agent"]
|
|
1884
|
+
]);
|
|
1873
1885
|
|
|
1874
1886
|
// ../../packages/agent-targets/src/hooks/read-command.ts
|
|
1875
1887
|
import path2 from "node:path";
|
|
@@ -2245,9 +2257,9 @@ function normalizedEvent(target, payload, context) {
|
|
|
2245
2257
|
"command"
|
|
2246
2258
|
);
|
|
2247
2259
|
const toolName = firstString(payload, ["tool_name", "toolName", "name"]);
|
|
2248
|
-
const filePath = firstString(payload, ["file_path", "filePath", "path"]) ?? (toolInput ? firstString(toolInput, ["file_path", "filePath", "path"]) : void 0) ?? (command && toolName && SHELL_TOOL_NAMES.has(toolName.toLowerCase()) ? extractReadFilePathFromCommand(command) ?? void 0 : void 0);
|
|
2260
|
+
const filePath = firstString(payload, ["file_path", "filePath", "path"]) ?? (toolInput ? firstString(toolInput, ["file_path", "filePath", "path"]) : void 0) ?? (target !== "mini-swe-agent" && command && toolName && SHELL_TOOL_NAMES.has(toolName.toLowerCase()) ? extractReadFilePathFromCommand(command) ?? void 0 : void 0);
|
|
2249
2261
|
const userPrompt = boundedExtractedText(
|
|
2250
|
-
firstText(payload, ["prompt", "user_prompt", "userPrompt"]) ?? (target === "gemini" ? geminiUserPrompt(payload) : void 0),
|
|
2262
|
+
target === "mini-swe-agent" && eventType !== "UserPromptSubmit" ? void 0 : firstText(payload, ["prompt", "user_prompt", "userPrompt"]) ?? (target === "gemini" ? geminiUserPrompt(payload) : void 0),
|
|
2251
2263
|
"user_prompt"
|
|
2252
2264
|
);
|
|
2253
2265
|
const plan = boundedExtractedText(firstText(payload, ["plan"]), "plan");
|
|
@@ -2303,7 +2315,8 @@ var HOOK_NORMALIZATION_CAPABILITIES = Object.freeze([
|
|
|
2303
2315
|
capability("codex", CODEX_HOOK_EVENTS),
|
|
2304
2316
|
capability("gemini", GEMINI_HOOK_EVENTS),
|
|
2305
2317
|
capability("grok", GROK_HOOK_EVENTS),
|
|
2306
|
-
capability("pi", PI_HOOK_EVENTS)
|
|
2318
|
+
capability("pi", PI_HOOK_EVENTS),
|
|
2319
|
+
capability("mini-swe-agent", MINI_SWE_AGENT_HOOK_EVENTS)
|
|
2307
2320
|
]);
|
|
2308
2321
|
|
|
2309
2322
|
// src/hooks/context.ts
|
package/dist/sync-cycle.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runObserverSyncCycle
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-OUXFHL3I.js";
|
|
5
|
+
import "./chunk-PTDADW47.js";
|
|
6
6
|
import "./chunk-F57IFY3K.js";
|
|
7
7
|
import "./chunk-HDAFEHUY.js";
|
|
8
8
|
import "./chunk-MLKGABMK.js";
|