@dv.nghiem/flowdeck 0.4.0 → 0.4.2
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/hooks/notifications.d.ts +73 -8
- package/dist/hooks/notifications.d.ts.map +1 -1
- package/dist/hooks/notifications.test.d.ts +14 -0
- package/dist/hooks/notifications.test.d.ts.map +1 -0
- package/dist/hooks/session-idle-hook.d.ts +5 -3
- package/dist/hooks/session-idle-hook.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +101 -16
- package/dist/mcp/index.d.ts +2 -3
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/tools/codegraph-tool.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,21 +1,86 @@
|
|
|
1
|
-
type NotifyLevel = "info" | "critical";
|
|
1
|
+
export type NotifyLevel = "info" | "critical";
|
|
2
|
+
/**
|
|
3
|
+
* Structured reasons that can trigger a notification.
|
|
4
|
+
* Helps consumers understand why a notification fired.
|
|
5
|
+
*/
|
|
6
|
+
export type NotificationReason = "completed" | "input_required" | "confirmation_required" | "error";
|
|
7
|
+
/**
|
|
8
|
+
* Normalise a raw command string to a bare command name.
|
|
9
|
+
* "/fd-discuss" → "discuss", "fd-plan" → "plan", "new-feature" → "new-feature"
|
|
10
|
+
*/
|
|
11
|
+
export declare function normalizeCommandName(raw: string): string;
|
|
2
12
|
/**
|
|
3
13
|
* Fire a desktop notification without blocking the caller.
|
|
4
14
|
* Silently ignores failures — notification is best-effort only.
|
|
5
15
|
*/
|
|
6
16
|
export declare function notify(title: string, body: string, level?: NotifyLevel): void;
|
|
17
|
+
export type NotifyFn = (title: string, body: string, level?: NotifyLevel) => void;
|
|
18
|
+
/**
|
|
19
|
+
* Event-driven notification controller.
|
|
20
|
+
*
|
|
21
|
+
* Lifecycle:
|
|
22
|
+
* 1. onCommandExecuted() — records that a command was dispatched (NOT yet processed)
|
|
23
|
+
* 2. onSessionIdle() — fires notification when the agent finishes processing
|
|
24
|
+
* 3. onSessionError() — fires notification on critical failure
|
|
25
|
+
*
|
|
26
|
+
* Deduplication: the same (command + lifecycle-state) pair is never notified twice,
|
|
27
|
+
* even if session.idle fires multiple times in a row.
|
|
28
|
+
*
|
|
29
|
+
* @param notifyFn — injectable notify function (defaults to the real OS notifier; pass
|
|
30
|
+
* a test stub to avoid spawning OS processes in tests).
|
|
31
|
+
* @param log — optional diagnostic logger.
|
|
32
|
+
*/
|
|
33
|
+
export declare class NotificationController {
|
|
34
|
+
/** The command currently awaiting a session.idle notification, or null. */
|
|
35
|
+
private pendingCommand;
|
|
36
|
+
/** Key of the last notification that was fired; used for deduplication. */
|
|
37
|
+
private lastNotifiedKey;
|
|
38
|
+
private readonly notifyFn;
|
|
39
|
+
private readonly log;
|
|
40
|
+
constructor(notifyFn?: NotifyFn, log?: (msg: string) => void);
|
|
41
|
+
/**
|
|
42
|
+
* Called when the `command.executed` event fires.
|
|
43
|
+
* Records the command so the next session.idle can produce the right notification.
|
|
44
|
+
* Must NOT fire a notification — the command has only been dispatched, not completed.
|
|
45
|
+
*/
|
|
46
|
+
onCommandExecuted(rawCommand: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Called when the `session.idle` event fires.
|
|
49
|
+
* Fires at most one notification per pending command.
|
|
50
|
+
* If no command is pending, fires a generic completion notification only when
|
|
51
|
+
* the agent actually edited files (hasEdits = true).
|
|
52
|
+
*
|
|
53
|
+
* @param hasEdits — true when the session file tracker has recorded edits this turn.
|
|
54
|
+
*/
|
|
55
|
+
onSessionIdle(hasEdits: boolean): void;
|
|
56
|
+
/**
|
|
57
|
+
* Called when the `session.error` event fires.
|
|
58
|
+
* Always fires unless the identical error was already reported.
|
|
59
|
+
*/
|
|
60
|
+
onSessionError(errorMsg: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* Reset all state. Useful in tests or when starting a new session.
|
|
63
|
+
*/
|
|
64
|
+
reset(): void;
|
|
65
|
+
getPendingCommand(): string | null;
|
|
66
|
+
getLastNotifiedKey(): string | null;
|
|
67
|
+
}
|
|
7
68
|
/**
|
|
8
|
-
* Fires a notification when a
|
|
9
|
-
*
|
|
69
|
+
* Fires a notification when a permission is requested.
|
|
70
|
+
* This is event-driven (permission.ask hook fires after the agent's request)
|
|
71
|
+
* so it does not need to go through the NotificationController.
|
|
10
72
|
*/
|
|
11
|
-
export declare function
|
|
73
|
+
export declare function notifyPermissionNeeded(tool: string): void;
|
|
12
74
|
/**
|
|
13
|
-
*
|
|
75
|
+
* @deprecated Use NotificationController.onSessionIdle() instead.
|
|
76
|
+
* Kept for backward compatibility — does nothing now that the controller
|
|
77
|
+
* handles all session-idle notifications.
|
|
14
78
|
*/
|
|
15
79
|
export declare function notifySessionIdle(): void;
|
|
16
80
|
/**
|
|
17
|
-
*
|
|
81
|
+
* @deprecated Use NotificationController.onCommandExecuted() + onSessionIdle() instead.
|
|
82
|
+
* This function fired notifications on command ENTRY (too early).
|
|
83
|
+
* It is preserved as a no-op so that any lingering callers compile without error.
|
|
18
84
|
*/
|
|
19
|
-
export declare function
|
|
20
|
-
export {};
|
|
85
|
+
export declare function notifyCommandInteraction(_command: string): void;
|
|
21
86
|
//# sourceMappingURL=notifications.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/hooks/notifications.ts"],"names":[],"mappings":"AAsBA,
|
|
1
|
+
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/hooks/notifications.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,UAAU,CAAA;AAE7C;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAC1B,WAAW,GACX,gBAAgB,GAChB,uBAAuB,GACvB,OAAO,CAAA;AAEX;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,WAAoB,GAAG,IAAI,CAoCrF;AAUD,MAAM,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;AAEjF;;;;;;;;;;;;;;GAcG;AACH,qBAAa,sBAAsB;IACjC,2EAA2E;IAC3E,OAAO,CAAC,cAAc,CAAsB;IAC5C,2EAA2E;IAC3E,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAuB;gBAE/B,QAAQ,GAAE,QAAiB,EAAE,GAAG,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAe;IAK9E;;;;OAIG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAc3C;;;;;;;OAOG;IACH,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IA4CtC;;;OAGG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAgBtC;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb,iBAAiB,IAAI,MAAM,GAAG,IAAI;IAClC,kBAAkB,IAAI,MAAM,GAAG,IAAI;CACpC;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMzD;AAID;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE/D"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NotificationController Tests
|
|
3
|
+
*
|
|
4
|
+
* Covers the core timing contract:
|
|
5
|
+
* - No notification when a command is merely entered (command.execute.before)
|
|
6
|
+
* - Notification fires on session.idle after a completion command
|
|
7
|
+
* - Notification fires on session.idle after an interactive command
|
|
8
|
+
* - Notification fires on session.error
|
|
9
|
+
* - Duplicate notifications are suppressed
|
|
10
|
+
* - Long-running command only notifies at the correct lifecycle point
|
|
11
|
+
* - Generic (non-command) idle notification fires only when edits exist
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=notifications.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifications.test.d.ts","sourceRoot":"","sources":["../../src/hooks/notifications.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Session Idle Hook
|
|
3
3
|
* Fires when OpenCode's session becomes idle (task completed).
|
|
4
|
-
*
|
|
5
|
-
* 2. Logs a summary of edited files via client.app.log
|
|
4
|
+
* Logs a summary of edited files via client.app.log.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
6
|
+
* NOTE: Desktop notifications are no longer sent from this hook.
|
|
7
|
+
* They are handled by NotificationController in notifications.ts, which
|
|
8
|
+
* fires at the correct lifecycle points (session.idle after a command,
|
|
9
|
+
* session.error on failure) and deduplicates properly.
|
|
8
10
|
*/
|
|
9
11
|
import type { SessionFileTracker } from "./file-tracker";
|
|
10
12
|
export declare function createSessionIdleHook(client: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-idle-hook.d.ts","sourceRoot":"","sources":["../../src/hooks/session-idle-hook.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"session-idle-hook.d.ts","sourceRoot":"","sources":["../../src/hooks/session-idle-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAExD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE;IAAE,GAAG,EAAE;QAAE,GAAG,EAAE,CAAC,IAAI,EAAE;YAAE,IAAI,EAAE;gBAAE,OAAO,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;gBAAC,OAAO,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;KAAE,CAAA;CAAE,EAC5I,OAAO,EAAE,kBAAkB,uBA0B5B"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAgGjD,QAAA,MAAM,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAgGjD,QAAA,MAAM,MAAM,EAAE,MAkVb,CAAA;AAED,eAAe,MAAM,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -2046,7 +2046,7 @@ function markCodegraphStale(dir) {
|
|
|
2046
2046
|
|
|
2047
2047
|
// src/tools/codegraph-tool.ts
|
|
2048
2048
|
var codegraphTool = tool16({
|
|
2049
|
-
description: "Manage codegraph
|
|
2049
|
+
description: "Manage codegraph lifecycle only: check installation, install, init/rebuild the index, refresh (incremental sync), " + "query status, or mark-stale. Valid actions: check | install | init | refresh | status | mark-stale. " + "Do NOT use this tool for code intelligence queries (files, search, callers, callees, etc.) — " + "those are available as codegraph MCP tools (codegraph_files, codegraph_search, codegraph_context, " + "codegraph_explore, codegraph_callers, codegraph_callees, codegraph_impact, codegraph_trace) " + "when the index is ready.",
|
|
2050
2050
|
args: {
|
|
2051
2051
|
action: tool16.schema.enum(["check", "install", "init", "refresh", "status", "mark-stale"]),
|
|
2052
2052
|
agent: tool16.schema.string().optional()
|
|
@@ -2125,6 +2125,14 @@ var codegraphTool = tool16({
|
|
|
2125
2125
|
markCodegraphStale(dir);
|
|
2126
2126
|
return JSON.stringify({ success: true, message: "codegraph index marked stale — next init will do a full rebuild" });
|
|
2127
2127
|
}
|
|
2128
|
+
default: {
|
|
2129
|
+
const unknownAction = args.action;
|
|
2130
|
+
return JSON.stringify({
|
|
2131
|
+
success: false,
|
|
2132
|
+
error: `Unknown action "${unknownAction}". Valid actions: check, install, init, refresh, status, mark-stale.`,
|
|
2133
|
+
hint: `For code intelligence queries (files, search, callers, etc.) use the codegraph MCP tools directly: ` + `codegraph_files, codegraph_search, codegraph_context, codegraph_explore, codegraph_callers, ` + `codegraph_callees, codegraph_impact, codegraph_trace.`
|
|
2134
|
+
});
|
|
2135
|
+
}
|
|
2128
2136
|
}
|
|
2129
2137
|
}
|
|
2130
2138
|
});
|
|
@@ -2553,6 +2561,9 @@ var COMPLETION_COMMANDS = new Set([
|
|
|
2553
2561
|
"execute",
|
|
2554
2562
|
"verify"
|
|
2555
2563
|
]);
|
|
2564
|
+
function normalizeCommandName(raw) {
|
|
2565
|
+
return raw.replace(/^\//, "").replace(/^fd-/, "");
|
|
2566
|
+
}
|
|
2556
2567
|
function notify(title, body, level = "info") {
|
|
2557
2568
|
const platform = process.platform;
|
|
2558
2569
|
try {
|
|
@@ -2584,16 +2595,80 @@ function tryTerminalBell() {
|
|
|
2584
2595
|
process.stdout.write("\x07");
|
|
2585
2596
|
} catch {}
|
|
2586
2597
|
}
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2598
|
+
|
|
2599
|
+
class NotificationController {
|
|
2600
|
+
pendingCommand = null;
|
|
2601
|
+
lastNotifiedKey = null;
|
|
2602
|
+
notifyFn;
|
|
2603
|
+
log;
|
|
2604
|
+
constructor(notifyFn = notify, log = () => {}) {
|
|
2605
|
+
this.notifyFn = notifyFn;
|
|
2606
|
+
this.log = log;
|
|
2607
|
+
}
|
|
2608
|
+
onCommandExecuted(rawCommand) {
|
|
2609
|
+
const name = normalizeCommandName(rawCommand);
|
|
2610
|
+
if (!INTERACTIVE_COMMANDS.has(name) && !COMPLETION_COMMANDS.has(name)) {
|
|
2611
|
+
this.log(`[notify] command.executed: "${name}" — not a tracked command, skipping`);
|
|
2612
|
+
return;
|
|
2613
|
+
}
|
|
2614
|
+
this.log(`[notify] command.executed: "${name}" recorded as pending`);
|
|
2615
|
+
this.pendingCommand = name;
|
|
2616
|
+
this.lastNotifiedKey = null;
|
|
2617
|
+
}
|
|
2618
|
+
onSessionIdle(hasEdits) {
|
|
2619
|
+
if (this.pendingCommand) {
|
|
2620
|
+
const name = this.pendingCommand;
|
|
2621
|
+
const dedupeKey = `idle:${name}`;
|
|
2622
|
+
if (this.lastNotifiedKey === dedupeKey) {
|
|
2623
|
+
this.log(`[notify] suppressed duplicate: state=session.idle command=${name}`);
|
|
2624
|
+
return;
|
|
2625
|
+
}
|
|
2626
|
+
const reason = INTERACTIVE_COMMANDS.has(name) ? "input_required" : "completed";
|
|
2627
|
+
this.log(`[notify] firing notification: reason=${reason} command=${name} source=session.idle`);
|
|
2628
|
+
if (reason === "input_required") {
|
|
2629
|
+
this.notifyFn(`FlowDeck: /${name}`, "Your input is needed — please check OpenCode", "critical");
|
|
2630
|
+
} else {
|
|
2631
|
+
this.notifyFn(`FlowDeck: /${name} complete`, "Review the output and choose your next step", "info");
|
|
2632
|
+
}
|
|
2633
|
+
this.lastNotifiedKey = dedupeKey;
|
|
2634
|
+
this.pendingCommand = null;
|
|
2635
|
+
return;
|
|
2636
|
+
}
|
|
2637
|
+
if (hasEdits) {
|
|
2638
|
+
const dedupeKey = "idle:generic";
|
|
2639
|
+
if (this.lastNotifiedKey === dedupeKey) {
|
|
2640
|
+
this.log(`[notify] suppressed duplicate: state=session.idle source=generic`);
|
|
2641
|
+
return;
|
|
2642
|
+
}
|
|
2643
|
+
this.log(`[notify] firing notification: reason=completed source=session.idle (generic, has edits)`);
|
|
2644
|
+
this.notifyFn("FlowDeck Task Completed", "Agent is idle and waiting for your next instruction", "info");
|
|
2645
|
+
this.lastNotifiedKey = dedupeKey;
|
|
2646
|
+
} else {
|
|
2647
|
+
this.log(`[notify] session.idle — no pending command, no edits — suppressed`);
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2650
|
+
onSessionError(errorMsg) {
|
|
2651
|
+
const snippet = errorMsg.slice(0, 60);
|
|
2652
|
+
const dedupeKey = `error:${snippet}`;
|
|
2653
|
+
if (this.lastNotifiedKey === dedupeKey) {
|
|
2654
|
+
this.log(`[notify] suppressed duplicate: state=session.error`);
|
|
2655
|
+
return;
|
|
2656
|
+
}
|
|
2657
|
+
this.log(`[notify] firing notification: reason=error source=session.error`);
|
|
2658
|
+
this.notifyFn("FlowDeck Error", snippet || "An error occurred", "critical");
|
|
2659
|
+
this.lastNotifiedKey = dedupeKey;
|
|
2660
|
+
this.pendingCommand = null;
|
|
2661
|
+
}
|
|
2662
|
+
reset() {
|
|
2663
|
+
this.pendingCommand = null;
|
|
2664
|
+
this.lastNotifiedKey = null;
|
|
2665
|
+
}
|
|
2666
|
+
getPendingCommand() {
|
|
2667
|
+
return this.pendingCommand;
|
|
2668
|
+
}
|
|
2669
|
+
getLastNotifiedKey() {
|
|
2670
|
+
return this.lastNotifiedKey;
|
|
2593
2671
|
}
|
|
2594
|
-
}
|
|
2595
|
-
function notifySessionIdle() {
|
|
2596
|
-
notify("FlowDeck Task Completed", "Agent is idle and waiting for your next instruction", "info");
|
|
2597
2672
|
}
|
|
2598
2673
|
function notifyPermissionNeeded(tool17) {
|
|
2599
2674
|
notify("FlowDeck Permission Required", `Agent needs approval to use tool: ${tool17}`, "critical");
|
|
@@ -3097,7 +3172,6 @@ function createSessionIdleHook(client, tracker) {
|
|
|
3097
3172
|
const edited = tracker.getEditedPaths();
|
|
3098
3173
|
if (edited.length === 0)
|
|
3099
3174
|
return;
|
|
3100
|
-
notifySessionIdle();
|
|
3101
3175
|
const summary = `[FlowDeck] Session idle — ${edited.length} file(s) modified this session`;
|
|
3102
3176
|
await client.app.log({ body: { service: "flowdeck", level: "info", message: summary } }).catch(() => {});
|
|
3103
3177
|
const preview = edited.slice(0, 10);
|
|
@@ -3409,8 +3483,7 @@ function createFlowDeckMcps() {
|
|
|
3409
3483
|
if (!disabled.has("codegraph") && isCodegraphInstalled()) {
|
|
3410
3484
|
mcps.codegraph = {
|
|
3411
3485
|
type: "local",
|
|
3412
|
-
command: "codegraph",
|
|
3413
|
-
args: ["serve", "--mcp"],
|
|
3486
|
+
command: ["codegraph", "serve", "--mcp"],
|
|
3414
3487
|
enabled: true
|
|
3415
3488
|
};
|
|
3416
3489
|
}
|
|
@@ -7223,6 +7296,7 @@ var plugin = async (input, _options) => {
|
|
|
7223
7296
|
const orchestratorGuard = new OrchestratorGuard;
|
|
7224
7297
|
const appLog = (msg) => client.app.log({ body: { service: "flowdeck", level: "info", message: msg } }).catch(() => {});
|
|
7225
7298
|
const autoLearnHook = createAutoLearnHook(client, fileTracker, directory, appLog);
|
|
7299
|
+
const notifCtrl = new NotificationController(undefined, appLog);
|
|
7226
7300
|
const agentConfigs = getAgentConfigs({});
|
|
7227
7301
|
const mcps = createFlowDeckMcps();
|
|
7228
7302
|
return {
|
|
@@ -7323,9 +7397,7 @@ var plugin = async (input, _options) => {
|
|
|
7323
7397
|
"file.edited": fileEdited,
|
|
7324
7398
|
"file.watcher.updated": fileWatcherUpdated,
|
|
7325
7399
|
"experimental.session.compacting": compactionHook,
|
|
7326
|
-
"command.execute.before": async (
|
|
7327
|
-
notifyCommandInteraction(input2.command);
|
|
7328
|
-
},
|
|
7400
|
+
"command.execute.before": async (_input, _output) => {},
|
|
7329
7401
|
"permission.ask": async (input2, _output) => {
|
|
7330
7402
|
notifyPermissionNeeded(input2.title);
|
|
7331
7403
|
},
|
|
@@ -7334,9 +7406,17 @@ var plugin = async (input, _options) => {
|
|
|
7334
7406
|
if (type === "session.created" || type === "session.started") {
|
|
7335
7407
|
await sessionStartHook({ directory });
|
|
7336
7408
|
}
|
|
7409
|
+
if (type === "command.executed") {
|
|
7410
|
+
const commandName = event?.properties?.name ?? "";
|
|
7411
|
+
if (commandName) {
|
|
7412
|
+
notifCtrl.onCommandExecuted(commandName);
|
|
7413
|
+
}
|
|
7414
|
+
}
|
|
7337
7415
|
await contextMonitor.event({ event });
|
|
7338
7416
|
orchestratorGuard.onEvent(event);
|
|
7339
7417
|
if (type === "session.idle") {
|
|
7418
|
+
const hasEdits = fileTracker.getEditedPaths().length > 0;
|
|
7419
|
+
notifCtrl.onSessionIdle(hasEdits);
|
|
7340
7420
|
try {
|
|
7341
7421
|
await sessionIdleHook();
|
|
7342
7422
|
await autoLearnHook();
|
|
@@ -7344,6 +7424,11 @@ var plugin = async (input, _options) => {
|
|
|
7344
7424
|
fileTracker.clear();
|
|
7345
7425
|
}
|
|
7346
7426
|
}
|
|
7427
|
+
if (type === "session.error") {
|
|
7428
|
+
const err = event?.properties?.error;
|
|
7429
|
+
const errorMsg = (err && typeof err === "object" && "message" in err ? String(err.message) : undefined) ?? (typeof err === "string" ? err : undefined) ?? "An unexpected error occurred";
|
|
7430
|
+
notifCtrl.onSessionError(errorMsg);
|
|
7431
|
+
}
|
|
7347
7432
|
},
|
|
7348
7433
|
"tool.execute.before": async (toolInput, toolOutput) => {
|
|
7349
7434
|
if ((toolInput.tool === "read" || toolInput.tool === "view") && toolOutput?.args) {
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -21,9 +21,8 @@ type RemoteMcp = {
|
|
|
21
21
|
};
|
|
22
22
|
type LocalMcp = {
|
|
23
23
|
type: "local";
|
|
24
|
-
command: string;
|
|
25
|
-
|
|
26
|
-
env?: Record<string, string>;
|
|
24
|
+
command: string[];
|
|
25
|
+
environment?: Record<string, string>;
|
|
27
26
|
enabled: boolean;
|
|
28
27
|
};
|
|
29
28
|
export declare function createFlowDeckMcps(): Record<string, RemoteMcp | LocalMcp>;
|
package/dist/mcp/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,QAAQ,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,KAAK,CAAC,EAAE,KAAK,CAAA;CACd,CAAA;AAED,KAAK,QAAQ,GAAG;IACd,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,QAAQ,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,KAAK,CAAC,EAAE,KAAK,CAAA;CACd,CAAA;AAED,KAAK,QAAQ,GAAG;IACd,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAOD,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC,CA+DzE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegraph-tool.d.ts","sourceRoot":"","sources":["../../src/tools/codegraph-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAa/D,eAAO,MAAM,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"codegraph-tool.d.ts","sourceRoot":"","sources":["../../src/tools/codegraph-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAa/D,eAAO,MAAM,aAAa,EAAE,cA2H1B,CAAA"}
|