@fdcn/sourcefed 0.3.5 → 0.3.7
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/README.md +2 -7
- package/dist/{chunk-X3BZSHKZ.js → chunk-E6J3BAXP.js} +198 -160
- package/dist/cli.js +215 -222
- package/dist/daemon.js +200 -162
- package/dist/mcp.js +1 -1
- package/dist/opencode.js +258 -121
- package/dist/pi.js +1 -1
- package/dist/tui-compiled.mjs +57 -67
- package/dist.dts/adapters/opencode/bridge.d.ts +66 -22
- package/dist.dts/adapters/opencode/subscriptions.d.ts +46 -0
- package/dist.dts/adapters/opencode/tool-result.d.ts +2 -1
- package/dist.dts/adapters/opencode/tools/monitor_create.d.ts +3 -2
- package/dist.dts/adapters/opencode/tools/monitor_list.d.ts +3 -2
- package/dist.dts/adapters/opencode/tools/monitor_start.d.ts +3 -2
- package/dist.dts/adapters/opencode/tools/monitor_status.d.ts +3 -2
- package/dist.dts/adapters/opencode/tools/monitor_stop.d.ts +3 -2
- package/dist.dts/packages/cli/src/utils/setup.d.ts +0 -1
- package/dist.dts/packages/daemon/src/event-stream.d.ts +26 -0
- package/dist.dts/packages/daemon/src/types/client.d.ts +3 -1
- package/dist.dts/packages/daemon/src/utils/index.d.ts +0 -1
- package/package.json +1 -1
- package/dist.dts/packages/daemon/src/utils/forward.d.ts +0 -32
- package/dist.dts/packages/daemon/src/utils/gate.d.ts +0 -33
- package/dist.dts/packages/daemon/src/utils/request-router.d.ts +0 -11
- /package/dist.dts/{packages/daemon/src/forward.test.d.ts → adapters/opencode/lifecycle.test.d.ts} +0 -0
- /package/dist.dts/packages/daemon/src/{gate.test.d.ts → stream-lifecycle.test.d.ts} +0 -0
|
@@ -1,34 +1,80 @@
|
|
|
1
|
+
import { type QueuedMonitorEvent } from "@fdcn/sourcefed/core";
|
|
1
2
|
import { type Plugin } from "@opencode/plugin";
|
|
3
|
+
import { OpenCodeSubscriptions, type SessionLocation } from "./subscriptions.js";
|
|
2
4
|
type SessionDomain = Plugin.Context["session"];
|
|
3
|
-
type RpcDomain =
|
|
5
|
+
type RpcDomain = (definition: typeof ChauffeurGate) => {
|
|
6
|
+
gate(input: unknown, options: {
|
|
7
|
+
signal: AbortSignal;
|
|
8
|
+
}): Promise<unknown>;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Chauffeur's gate, declared here so sourcefed does not depend on Chauffeur.
|
|
12
|
+
* When the Chauffeur plugin runs in this OpenCode process, it decides which
|
|
13
|
+
* events reach the session; otherwise every event is delivered.
|
|
14
|
+
*/
|
|
15
|
+
declare const ChauffeurGate: {
|
|
16
|
+
readonly id: "chauffeur";
|
|
17
|
+
readonly methods: {
|
|
18
|
+
readonly gate: {
|
|
19
|
+
readonly input: {
|
|
20
|
+
readonly type: "object";
|
|
21
|
+
readonly properties: {
|
|
22
|
+
readonly sessionID: {
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
};
|
|
25
|
+
readonly monitorID: {
|
|
26
|
+
readonly type: "string";
|
|
27
|
+
};
|
|
28
|
+
readonly source: {
|
|
29
|
+
readonly type: "string";
|
|
30
|
+
};
|
|
31
|
+
readonly kind: {
|
|
32
|
+
readonly type: "string";
|
|
33
|
+
};
|
|
34
|
+
readonly summary: {
|
|
35
|
+
readonly type: "string";
|
|
36
|
+
};
|
|
37
|
+
readonly body: {
|
|
38
|
+
readonly type: "string";
|
|
39
|
+
};
|
|
40
|
+
readonly actionable: {
|
|
41
|
+
readonly type: "boolean";
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
readonly required: readonly ["sessionID", "source", "kind", "summary", "actionable"];
|
|
45
|
+
};
|
|
46
|
+
readonly output: {
|
|
47
|
+
readonly type: "object";
|
|
48
|
+
readonly properties: {
|
|
49
|
+
readonly deliver: {
|
|
50
|
+
readonly type: "boolean";
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
readonly required: readonly ["deliver"];
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
readonly events: {};
|
|
58
|
+
};
|
|
4
59
|
export declare class OpenCodeBridge {
|
|
5
60
|
private readonly session;
|
|
6
|
-
private readonly rpc
|
|
7
|
-
|
|
8
|
-
private readonly
|
|
9
|
-
private
|
|
10
|
-
private
|
|
11
|
-
private
|
|
12
|
-
constructor(session: SessionDomain, rpc
|
|
61
|
+
private readonly rpc;
|
|
62
|
+
readonly location: SessionLocation;
|
|
63
|
+
private readonly hub;
|
|
64
|
+
private started;
|
|
65
|
+
private closed;
|
|
66
|
+
private closing;
|
|
67
|
+
constructor(session: Pick<SessionDomain, "get" | "synthetic">, rpc: RpcDomain | undefined, location: SessionLocation, hub?: OpenCodeSubscriptions);
|
|
13
68
|
/**
|
|
14
69
|
* Chauffeur or the CLI can create a monitor for a session here at any time,
|
|
15
70
|
* without this bridge's tools, so check for new targets periodically too.
|
|
16
71
|
*/
|
|
17
72
|
start(): Promise<void>;
|
|
18
|
-
ensureTarget(sessionID: string): Promise<void>;
|
|
19
73
|
callTool(name: string, arguments_: Record<string, unknown>, sessionID: string): Promise<unknown>;
|
|
20
74
|
close(): Promise<void>;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
* Monitors outlive this process, so after a restart nothing listens for their
|
|
25
|
-
* sessions until something subscribes. Subscribe every session that has an
|
|
26
|
-
* enabled monitor and still exists here; a deleted session is skipped, since
|
|
27
|
-
* delivering to it would fail and retry forever.
|
|
28
|
-
*/
|
|
29
|
-
private resubscribe;
|
|
30
|
-
private resubscribeTarget;
|
|
31
|
-
private routeEvents;
|
|
75
|
+
refresh(): Promise<void>;
|
|
76
|
+
getSession(sessionID: string, signal: AbortSignal): Promise<import("@opencode/client").SessionInfo>;
|
|
77
|
+
routeEvents(events: QueuedMonitorEvent[]): Promise<void>;
|
|
32
78
|
/**
|
|
33
79
|
* Ask Chauffeur's gate, when it runs in this process. Only an explicit
|
|
34
80
|
* `deliver: false` withholds the event; no gate, an error, or a slow answer
|
|
@@ -37,6 +83,4 @@ export declare class OpenCodeBridge {
|
|
|
37
83
|
private admitted;
|
|
38
84
|
private target;
|
|
39
85
|
}
|
|
40
|
-
export declare function setOpenCodeBridge(bridge: OpenCodeBridge): void;
|
|
41
|
-
export declare function getOpenCodeBridge(): OpenCodeBridge;
|
|
42
86
|
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { QueuedMonitorEvent } from "@fdcn/sourcefed/core";
|
|
2
|
+
import type { DaemonClient } from "@fdcn/sourcefed/daemon";
|
|
3
|
+
export type SessionLocation = {
|
|
4
|
+
directory: string;
|
|
5
|
+
project: {
|
|
6
|
+
id: string;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
type SessionInfo = {
|
|
10
|
+
projectID: string;
|
|
11
|
+
location: {
|
|
12
|
+
directory: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export interface SubscriptionOwner {
|
|
16
|
+
readonly location: SessionLocation;
|
|
17
|
+
getSession(sessionID: string, signal: AbortSignal): Promise<SessionInfo>;
|
|
18
|
+
routeEvents(events: QueuedMonitorEvent[]): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
/** One client, timer and stream per enabled session, shared by all plugin locations. */
|
|
21
|
+
export declare class OpenCodeSubscriptions {
|
|
22
|
+
private readonly connect;
|
|
23
|
+
private readonly owners;
|
|
24
|
+
private readonly subscriptions;
|
|
25
|
+
private readonly lifetime;
|
|
26
|
+
private daemon;
|
|
27
|
+
private connecting;
|
|
28
|
+
private refreshing;
|
|
29
|
+
private dirty;
|
|
30
|
+
private lastAttemptAt;
|
|
31
|
+
private timer;
|
|
32
|
+
constructor(connect: () => Promise<DaemonClient>);
|
|
33
|
+
get closed(): boolean;
|
|
34
|
+
add(owner: SubscriptionOwner): Promise<void>;
|
|
35
|
+
remove(owner: SubscriptionOwner): Promise<void>;
|
|
36
|
+
request(method: string, params: Record<string, unknown>): Promise<unknown>;
|
|
37
|
+
refresh(): Promise<void>;
|
|
38
|
+
private refreshLoop;
|
|
39
|
+
private ensureDaemon;
|
|
40
|
+
private reconcile;
|
|
41
|
+
private ownerFor;
|
|
42
|
+
private subscribe;
|
|
43
|
+
private route;
|
|
44
|
+
private closeSubscription;
|
|
45
|
+
}
|
|
46
|
+
export {};
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import type { OpenCodeBridge } from "./bridge.js";
|
|
2
|
+
export declare function callMonitorTool(bridge: OpenCodeBridge, name: string, arguments_: Record<string, unknown>, sessionID: string): Promise<string>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ToolContext } from "@opencode/plugin/promise/tool";
|
|
2
|
-
|
|
2
|
+
import type { OpenCodeBridge } from "../bridge.js";
|
|
3
|
+
declare const _default: (bridge: OpenCodeBridge) => {
|
|
3
4
|
name: string;
|
|
4
5
|
description: string;
|
|
5
6
|
input: {
|
|
@@ -50,4 +51,4 @@ declare const definition: {
|
|
|
50
51
|
content: string;
|
|
51
52
|
}>;
|
|
52
53
|
};
|
|
53
|
-
export default
|
|
54
|
+
export default _default;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ToolContext } from "@opencode/plugin/promise/tool";
|
|
2
|
-
|
|
2
|
+
import type { OpenCodeBridge } from "../bridge.js";
|
|
3
|
+
declare const _default: (bridge: OpenCodeBridge) => {
|
|
3
4
|
name: string;
|
|
4
5
|
description: string;
|
|
5
6
|
input: {
|
|
@@ -11,4 +12,4 @@ declare const definition: {
|
|
|
11
12
|
content: string;
|
|
12
13
|
}>;
|
|
13
14
|
};
|
|
14
|
-
export default
|
|
15
|
+
export default _default;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ToolContext } from "@opencode/plugin/promise/tool";
|
|
2
|
-
|
|
2
|
+
import type { OpenCodeBridge } from "../bridge.js";
|
|
3
|
+
declare const _default: (bridge: OpenCodeBridge) => {
|
|
3
4
|
name: string;
|
|
4
5
|
description: string;
|
|
5
6
|
input: {
|
|
@@ -17,4 +18,4 @@ declare const definition: {
|
|
|
17
18
|
content: string;
|
|
18
19
|
}>;
|
|
19
20
|
};
|
|
20
|
-
export default
|
|
21
|
+
export default _default;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ToolContext } from "@opencode/plugin/promise/tool";
|
|
2
|
-
|
|
2
|
+
import type { OpenCodeBridge } from "../bridge.js";
|
|
3
|
+
declare const _default: (bridge: OpenCodeBridge) => {
|
|
3
4
|
name: string;
|
|
4
5
|
description: string;
|
|
5
6
|
input: {
|
|
@@ -17,4 +18,4 @@ declare const definition: {
|
|
|
17
18
|
content: string;
|
|
18
19
|
}>;
|
|
19
20
|
};
|
|
20
|
-
export default
|
|
21
|
+
export default _default;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ToolContext } from "@opencode/plugin/promise/tool";
|
|
2
|
-
|
|
2
|
+
import type { OpenCodeBridge } from "../bridge.js";
|
|
3
|
+
declare const _default: (bridge: OpenCodeBridge) => {
|
|
3
4
|
name: string;
|
|
4
5
|
description: string;
|
|
5
6
|
input: {
|
|
@@ -17,4 +18,4 @@ declare const definition: {
|
|
|
17
18
|
content: string;
|
|
18
19
|
}>;
|
|
19
20
|
};
|
|
20
|
-
export default
|
|
21
|
+
export default _default;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { QueuedMonitorEvent } from "@fdcn/sourcefed/core";
|
|
2
|
+
/** Owns one SSE connection, its setup, serialized delivery and reconnect loop. */
|
|
3
|
+
export declare class DaemonEventStream {
|
|
4
|
+
private readonly url;
|
|
5
|
+
private readonly headers;
|
|
6
|
+
private readonly onEvents;
|
|
7
|
+
private readonly acknowledge;
|
|
8
|
+
private readonly onClose;
|
|
9
|
+
private readonly controller;
|
|
10
|
+
private readonly subscribed;
|
|
11
|
+
private stream;
|
|
12
|
+
private delivering;
|
|
13
|
+
private closing;
|
|
14
|
+
private ready;
|
|
15
|
+
private failedDelivery;
|
|
16
|
+
constructor(url: string, headers: Record<string, string>, onEvents: (events: QueuedMonitorEvent[]) => Promise<void>, acknowledge: (events: QueuedMonitorEvent[], signal: AbortSignal) => Promise<void>, onClose: () => void);
|
|
17
|
+
start(signal?: AbortSignal): Promise<void>;
|
|
18
|
+
close(): Promise<void>;
|
|
19
|
+
private drain;
|
|
20
|
+
private run;
|
|
21
|
+
private read;
|
|
22
|
+
private frame;
|
|
23
|
+
private deliver;
|
|
24
|
+
private waitForDelivery;
|
|
25
|
+
}
|
|
26
|
+
export declare function pause(ms: number, signal: AbortSignal): Promise<void>;
|
|
@@ -10,7 +10,9 @@ export type DaemonClientOptions = {
|
|
|
10
10
|
};
|
|
11
11
|
export interface DaemonClient {
|
|
12
12
|
request(method: string, params?: Record<string, unknown>): Promise<unknown>;
|
|
13
|
-
subscribe(target: MonitorTarget, onEvents: (events: QueuedMonitorEvent[]) => Promise<void
|
|
13
|
+
subscribe(target: MonitorTarget, onEvents: (events: QueuedMonitorEvent[]) => Promise<void>, options?: {
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
}): Promise<{
|
|
14
16
|
close(): Promise<void>;
|
|
15
17
|
}>;
|
|
16
18
|
close(): Promise<void>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export { daemonEnvironment } from "./env.js";
|
|
2
2
|
export { serveHttp, type HttpServer, type HttpServerOptions } from "./http-server.js";
|
|
3
|
-
export { RequestRouter } from "./request-router.js";
|
|
4
3
|
export { DEFAULT_DAEMON_URL, daemonCommand, defaultDaemonUrl, sleep, spawnLocalDaemon, withTimeout } from "./spawn.js";
|
|
5
4
|
export { NotifyingEventSink } from "./sink.js";
|
|
6
5
|
export { decodeTarget, encodeTarget, targetKey } from "./target.js";
|
package/package.json
CHANGED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { MonitorEvent, MonitorEventSink, MonitorRecord } from "@fdcn/sourcefed/core";
|
|
2
|
-
export type ForwardOptions = {
|
|
3
|
-
url: string;
|
|
4
|
-
token?: string;
|
|
5
|
-
fetch?: typeof fetch;
|
|
6
|
-
};
|
|
7
|
-
/** The JSON body POSTed for each delivered event. */
|
|
8
|
-
export type ForwardedEvent = {
|
|
9
|
-
target: MonitorRecord["target"];
|
|
10
|
-
monitorID: string;
|
|
11
|
-
source: MonitorRecord["source"];
|
|
12
|
-
event: MonitorEvent;
|
|
13
|
-
};
|
|
14
|
-
/** `SOURCEFED_FORWARD_URL` (and optional `SOURCEFED_FORWARD_TOKEN`), when set. */
|
|
15
|
-
export declare function forwardFromEnv(): ForwardOptions | undefined;
|
|
16
|
-
/**
|
|
17
|
-
* Delivers to `inner`, then POSTs a copy of each delivered event to another
|
|
18
|
-
* local consumer. Forwarding never blocks or fails delivery.
|
|
19
|
-
*/
|
|
20
|
-
export declare class ForwardingEventSink implements MonitorEventSink {
|
|
21
|
-
private readonly inner;
|
|
22
|
-
private readonly options;
|
|
23
|
-
constructor(inner: MonitorEventSink, options: ForwardOptions);
|
|
24
|
-
deliver(input: {
|
|
25
|
-
monitor: MonitorRecord;
|
|
26
|
-
event: MonitorEvent;
|
|
27
|
-
}): Promise<{
|
|
28
|
-
ok: boolean;
|
|
29
|
-
error?: string;
|
|
30
|
-
}>;
|
|
31
|
-
private forward;
|
|
32
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { MonitorEvent, MonitorEventSink, MonitorRecord } from "@fdcn/sourcefed/core";
|
|
2
|
-
export type GateOptions = {
|
|
3
|
-
url: string;
|
|
4
|
-
token?: string;
|
|
5
|
-
fetch?: typeof fetch;
|
|
6
|
-
};
|
|
7
|
-
/** The JSON body POSTed for each event; the gate replies `{ "deliver": boolean }`. */
|
|
8
|
-
export type GatedEvent = {
|
|
9
|
-
target: MonitorRecord["target"];
|
|
10
|
-
monitorID: string;
|
|
11
|
-
source: MonitorRecord["source"];
|
|
12
|
-
event: MonitorEvent;
|
|
13
|
-
};
|
|
14
|
-
/** `SOURCEFED_GATE_URL` (and optional `SOURCEFED_GATE_TOKEN`), when set. */
|
|
15
|
-
export declare function gateFromEnv(): GateOptions | undefined;
|
|
16
|
-
/**
|
|
17
|
-
* Asks another local consumer whether each event should reach the session.
|
|
18
|
-
* Only an explicit `{ "deliver": false }` withholds it; a failed, slow, or
|
|
19
|
-
* unclear answer delivers, so the gate can never lose an event.
|
|
20
|
-
*/
|
|
21
|
-
export declare class GatedEventSink implements MonitorEventSink {
|
|
22
|
-
private readonly inner;
|
|
23
|
-
private readonly options;
|
|
24
|
-
constructor(inner: MonitorEventSink, options: GateOptions);
|
|
25
|
-
deliver(input: {
|
|
26
|
-
monitor: MonitorRecord;
|
|
27
|
-
event: MonitorEvent;
|
|
28
|
-
}): Promise<{
|
|
29
|
-
ok: boolean;
|
|
30
|
-
error?: string;
|
|
31
|
-
}>;
|
|
32
|
-
private withheld;
|
|
33
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export declare class RequestRouter {
|
|
2
|
-
private readonly pending;
|
|
3
|
-
private cursor;
|
|
4
|
-
nextID(): number;
|
|
5
|
-
register(id: number): Promise<unknown>;
|
|
6
|
-
settle(id: number, frame: {
|
|
7
|
-
result?: unknown;
|
|
8
|
-
error?: string;
|
|
9
|
-
}): void;
|
|
10
|
-
rejectAll(error: Error): void;
|
|
11
|
-
}
|
/package/dist.dts/{packages/daemon/src/forward.test.d.ts → adapters/opencode/lifecycle.test.d.ts}
RENAMED
|
File without changes
|
|
File without changes
|