super-dsh 0.3.0-e → 0.3.0-g
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 +13 -55
- package/client/index.js +141 -10
- package/cordis.patch.yml +6 -3
- package/package.json +12 -5
- package/remote/file-worker.js +341 -0
- package/remote/plugin.d.ts +523 -0
- package/remote/plugin.js +4979 -0
- package/remote/provenance.json +64 -0
- package/superd-hub/dist/a2a-row.d.ts +18 -2
- package/superd-hub/dist/a2a-row.js +11 -69
- package/superd-hub/dist/bundle-setup.d.ts +16 -6
- package/superd-hub/dist/bundle-setup.js +84 -148
- package/superd-hub/dist/client/companion-api.d.ts +5 -0
- package/superd-hub/dist/client/companion-api.js +30 -0
- package/superd-hub/dist/companion-contract.d.ts +9 -0
- package/superd-hub/dist/companion-contract.js +1 -0
- package/superd-hub/dist/companions.d.ts +30 -0
- package/superd-hub/dist/companions.js +209 -0
- package/superd-hub/dist/exec-pty-framing.d.ts +3 -1
- package/superd-hub/dist/exec-pty-framing.js +12 -4
- package/superd-hub/dist/exec-pty-session.d.ts +2 -0
- package/superd-hub/dist/exec-pty-session.js +7 -13
- package/superd-hub/dist/exec.d.ts +5 -2
- package/superd-hub/dist/exec.js +34 -54
- package/superd-hub/dist/fusion-transport.js +1 -0
- package/superd-hub/dist/gateway.js +24 -11
- package/superd-hub/dist/hub-tool.d.ts +3 -0
- package/superd-hub/dist/hub-tool.js +13 -5
- package/superd-hub/dist/remote-file-rpc.d.ts +20 -0
- package/superd-hub/dist/remote-file-rpc.js +574 -0
- package/superd-hub/dist/remote-job-client.d.ts +3 -0
- package/superd-hub/dist/remote-job-client.js +197 -0
- package/superd-hub/dist/remote-job-rpc.d.ts +21 -0
- package/superd-hub/dist/remote-job-rpc.js +155 -0
- package/superd-hub/dist/remote-provider.d.ts +13 -0
- package/superd-hub/dist/remote-provider.js +151 -0
- package/superd-hub/dist/remote-row.d.ts +6 -0
- package/superd-hub/dist/remote-row.js +13 -0
- package/superd-hub/lib/client/index.js +141 -10
- package/superd-hub/package.json +1 -2
- package/superd-hub/scripts/register-companion.mjs +0 -100
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": 1,
|
|
3
|
+
"entry": "better-dsh/src/remote/plugin.ts",
|
|
4
|
+
"workerEntry": "better-dsh/src/remote/file-worker.ts",
|
|
5
|
+
"sources": {
|
|
6
|
+
"better-dsh/src/remote/agent-registration.ts": "459301354ea1ab713984bb01bc491a080256d4e983e55ff074e2665c3213d355",
|
|
7
|
+
"better-dsh/src/remote/archive-python.ts": "9494689d508fa0f145cb7fc562233ce07fb1a88c2127b68c51b0b48bdd790611",
|
|
8
|
+
"better-dsh/src/remote/archive.ts": "fd32f96dc63421be7d56eb545badf355c6ee2498599605ffa48958b9efca9a63",
|
|
9
|
+
"better-dsh/src/remote/copy.ts": "345b348c658b75d9f678aaa1b3d4fce6115cb61a7f0ff6966727f15b570cdc35",
|
|
10
|
+
"better-dsh/src/remote/driver.ts": "e2bd098b4ac8eb1ed766b8a0826027c4dff84d98913c120dbb37cec433227fd7",
|
|
11
|
+
"better-dsh/src/remote/endpoints.ts": "280bf0cc3dbc939ef2ccee940e61e05f40f35c9d8782e3d1824da47260958ed4",
|
|
12
|
+
"better-dsh/src/remote/file-worker.ts": "31ac019a944cf7fdcd0ff044f8b330d923bf4d384c77056f9b7e3032bc8c9598",
|
|
13
|
+
"better-dsh/src/remote/hub-contract.ts": "4bd333f3ef3e94305a64f04c03948a9dae4bbf5268b0d26d9de99770be2d8ac9",
|
|
14
|
+
"better-dsh/src/remote/input.ts": "7e543adb0973c25cbd24103c2d838db0fdacdd32525278d789004fc237dcd924",
|
|
15
|
+
"better-dsh/src/remote/jobs.ts": "9587f2694426fcf00ff33d9db164d5b15ea659aed7dbcb1df2640fa3f08b2149",
|
|
16
|
+
"better-dsh/src/remote/nonce-framing.ts": "5592fec76cec0c1e1ac75f4806d0904cd111bf2061b1fada4f0dfa12014d1233",
|
|
17
|
+
"better-dsh/src/remote/oneshot.ts": "99f2c809ba1159c7865ec3cff2e6d7b1f165a7f03185a6fc9505c1a534ba57bc",
|
|
18
|
+
"better-dsh/src/remote/output-ring.ts": "a79104bd3dcddab06a3fe7e52d239a70becd4f2dcddd0c9b6513f5fe3c4ed0bc",
|
|
19
|
+
"better-dsh/src/remote/plugin.ts": "96a7cd4878d7a4ef76ed26cf48d58824ecf40e6892078ad55c9b3bacbdebe41e",
|
|
20
|
+
"better-dsh/src/remote/process.ts": "478eef8a252aa2747e8890950c5d6785e2d877343377c7f4f0da3ba1c32f77db",
|
|
21
|
+
"better-dsh/src/remote/pty-session.ts": "8ea63b3357c681c5dcacacbfb99da532cae8ed293482e7a54c0362b0f9f27a3d",
|
|
22
|
+
"better-dsh/src/remote/roster.ts": "753803521accb7a5eacc19a9bada648af8ee5fc67a152247915b92e9ddeb6887",
|
|
23
|
+
"better-dsh/src/remote/rsync.ts": "9cb0f4d2d0de599220024e33cc8c3eb3979e68b694f2486cf1b31bc2a4a0273c",
|
|
24
|
+
"better-dsh/src/remote/ssh-config.ts": "71ce833be5c934430e8a9ca982af055fccb71d6c3e64513ae83e7937b070e446",
|
|
25
|
+
"better-dsh/src/remote/ssh-lease.ts": "834c769b74996b3b8fb5d68b6bddae7ab8e72fb1d5d23229fa1c0f2ca780c504",
|
|
26
|
+
"better-dsh/src/remote/ssh-process.ts": "583502d157b0ae2dacd8a635200713727c7354e6793e40f924cac41d62b1bd2c",
|
|
27
|
+
"better-dsh/src/remote/ssh-relay.ts": "88eef0344f04e34f243780a44f7a94f0822dfc79c824e95a8f552034491df34c",
|
|
28
|
+
"better-dsh/src/remote/ssh-source-proxy.ts": "5ebb132ec9ae3263bd2bd76545abb63bec58521bc0703ffd793c90ef05c1923c",
|
|
29
|
+
"better-dsh/src/remote/ssh-targets.ts": "b8d83bfeda038ab604b4b6e312a719926508ea82fb54d2c02b939b51fbf7bbc3",
|
|
30
|
+
"better-dsh/src/remote/status.ts": "54264917bd50401c5a2f2ff9df325af7a5e790597e6307fcdc46a8455d18b530",
|
|
31
|
+
"better-dsh/src/remote/target.ts": "965a04b3561aa56ee089876a869fd2116b1773ef34b053b3006905fcde063a43",
|
|
32
|
+
"better-dsh/src/remote/tool.ts": "3222ac9e9460353e38170346b58b1be8e8beb066fa95fc90344c60aa673339e2",
|
|
33
|
+
"better-dsh/src/remote/transports.ts": "545706b7ef14c5fb626964b5b63f4b946e026ea90a5efc5202c5a38503f9bc16",
|
|
34
|
+
"better-dsh/third_party/schemastery/lib/index.cjs": "aca1c1a47c7b6034feee01501aefca3e6dd97a0bac4fe334fd30647ae5a9e480",
|
|
35
|
+
"better-dsh/third_party/schemastery/lib/index.d.mts": "66847f605af58c42575333c825eefdec4ad38278ad6cb260e37aa0cc63803bbd",
|
|
36
|
+
"better-dsh/third_party/schemastery/lib/index.mjs": "cfcbe46c7416bdb35ce891c252152bbf519e08199bede5930dd7cb880c65f1ef",
|
|
37
|
+
"better-dsh/third_party/schemastery/lib/types/index.d.ts": "fca846c1420a192b7ae749da96afa0c9b5c57b2e7dff418153674f90200f4e27",
|
|
38
|
+
"better-dsh/third_party/schemastery/lib/types/index.d.ts.map": "ee91a9f4c24c9bc82b5a37e8c84f690f5ec6e2385795902683557b0a08812e47",
|
|
39
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/index.js": "ba44c0871656e4c7cac2c3c8a2ff644e0d2eb9d6bda7f6355866d686d513268e",
|
|
40
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/types/array.d.ts": "f63b6a79179ea0f70902e1c9d8c98b3fd457b124c7c5dcb3adccc4fae5a8c5b6",
|
|
41
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/types/array.d.ts.map": "76e7996107ba6d4ea97eebe33c825e85f53392fd9b21e87248d0030903f5cdf1",
|
|
42
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/types/index.d.ts": "850b1bde1c4b0dd26069a365e3837180890205f243f962838c4b769302aa583b",
|
|
43
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/types/index.d.ts.map": "cc8b19e444b8d7a04697460273e5ace19f1ea4ca51bbc987b3397c0e261d5e5c",
|
|
44
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/types/misc.d.ts": "b3ffb1d306130b143d309b7621dc0f94446bf0d0721a5aeaae92f1112c3a852c",
|
|
45
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/types/misc.d.ts.map": "7fd470887c2b1a2c86c5b149fdfddc90d7a00bea047547391ad6d169d1bc468f",
|
|
46
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/types/string.d.ts": "018925218746fd81518276960ee5eaaf7664f7ac0a1bc01d6604903254186ced",
|
|
47
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/types/string.d.ts.map": "6f10c183f6f0c7aac796f6fd0ae3b16b30d455a86d7d2018ecf3641093adeeac",
|
|
48
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/types/time.d.ts": "2fb4faf4cb90b96c83a3282f6cad6eafd3395a251ae2d193a0a27c63cf4dfc78",
|
|
49
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/types/time.d.ts.map": "afad91a505bd82c857a69ad72718e59d4a08f05c35493854ac000ace760a3a51",
|
|
50
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/types/types.d.ts": "ecec322706391b1eed65497f97bb2ba53dfee289d276c35b91ad83550b61a2fa",
|
|
51
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/types/types.d.ts.map": "6da6f71fd5de4144c9f2862aad0951c5586e7b03e95a9624c4ec5730c39cd368",
|
|
52
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/types/volatile.d.ts": "9733d9ecf59e8b86a6e5605c830e2efacbd93e527c3fd8388aaf0d09649fef0c",
|
|
53
|
+
"better-dsh/third_party/schemastery/node_modules/@deepseek-ai/cosmokit/lib/types/volatile.d.ts.map": "7f41de53d13986b169df89edba078f017f0acdaff8338d00ddc45596a19fefa4",
|
|
54
|
+
"better-dsh/third_party/schemastery/node_modules/@standard-schema/spec/dist/index.cjs": "68eba92bc1637688388d7adc1fe5aa748b27c7101ad40123e64135bb5e9ed8e7",
|
|
55
|
+
"better-dsh/third_party/schemastery/node_modules/@standard-schema/spec/dist/index.d.cts": "bdd14f07b4eca0b4b5203b85b8dbc4d084c749fa590bee5ea613e1641dcd3b29",
|
|
56
|
+
"better-dsh/third_party/schemastery/node_modules/@standard-schema/spec/dist/index.d.ts": "bdd14f07b4eca0b4b5203b85b8dbc4d084c749fa590bee5ea613e1641dcd3b29",
|
|
57
|
+
"better-dsh/third_party/schemastery/node_modules/@standard-schema/spec/dist/index.js": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
|
58
|
+
},
|
|
59
|
+
"outputs": {
|
|
60
|
+
"file-worker.js": "f84f5b48de915949d85c3d0340a343cc5901218c3bc2dafdf5cecaa244f7b6e3",
|
|
61
|
+
"plugin.d.ts": "d3d4c66e98bfda9ef29fec639991dc9f7eeab960e915edf042050b5b82c91870",
|
|
62
|
+
"plugin.js": "91d8903c9ececd4ad6f11d4a7580efb5e68e68221b180646a187baad7a2df99e"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -38,14 +38,21 @@
|
|
|
38
38
|
* (a2a-host.ts), and FEDERATED wire adapters pass through unwrapped.
|
|
39
39
|
*/
|
|
40
40
|
import type { Context } from '@deepseek-ai/cordis';
|
|
41
|
+
import z from '@deepseek-ai/schemastery';
|
|
41
42
|
/** Stable Cordis plugin (row) name. */
|
|
42
43
|
export declare const name = "superd-a2a";
|
|
44
|
+
export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
45
|
+
localExec: z<boolean, boolean, "defined">;
|
|
46
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
47
|
+
localExec: z<boolean, boolean, "defined">;
|
|
48
|
+
}>>, "plain">;
|
|
43
49
|
/** Zero static injects — the tools/typertGateway legs are dynamic (dormancy). */
|
|
44
50
|
export declare const inject: string[];
|
|
45
51
|
/** Injection seam for tests: a tmpdir home instead of the ambient/prod DSH_HOME (rpc.ts discipline). */
|
|
46
52
|
export interface HubToolRowOptions {
|
|
47
53
|
/** Hub home backing the registries; defaults to `resolveDshHome()` at wiring time. */
|
|
48
54
|
home?: string;
|
|
55
|
+
localExec?: boolean;
|
|
49
56
|
}
|
|
50
57
|
/**
|
|
51
58
|
* Wire the tool row: build T2+T3's service with ctx0's own gateway injected
|
|
@@ -56,10 +63,19 @@ export interface HubToolRowOptions {
|
|
|
56
63
|
*/
|
|
57
64
|
export declare function wireHubToolRow(ctx: Context, opts?: HubToolRowOptions): void;
|
|
58
65
|
/** MUST stay an arrow (RM0/better-dash note: function declarations get `new`-called, disposers lost). */
|
|
59
|
-
export declare const apply: (ctx: Context
|
|
66
|
+
export declare const apply: (ctx: Context, config?: {
|
|
67
|
+
localExec?: boolean;
|
|
68
|
+
}) => void;
|
|
60
69
|
declare const _default: {
|
|
61
70
|
name: string;
|
|
62
71
|
inject: string[];
|
|
63
|
-
|
|
72
|
+
Config: z<Schemastery.ObjectS<NoInfer<{
|
|
73
|
+
localExec: z<boolean, boolean, "defined">;
|
|
74
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
75
|
+
localExec: z<boolean, boolean, "defined">;
|
|
76
|
+
}>>, "plain">;
|
|
77
|
+
apply: (ctx: Context, config?: {
|
|
78
|
+
localExec?: boolean;
|
|
79
|
+
}) => void;
|
|
64
80
|
};
|
|
65
81
|
export default _default;
|
|
@@ -8,13 +8,10 @@ import { setSweepCollectors } from './mesh-link.js';
|
|
|
8
8
|
import { consoleA2aLog } from './a2a-log.js';
|
|
9
9
|
import { createA2aService } from './a2a-service.js';
|
|
10
10
|
import { resolveA2aGatewayFor, localA2aInitiator } from './a2a-host.js';
|
|
11
|
-
import { registerA2aRpc
|
|
12
|
-
import { runOneShotExec, postOneShotExec } from './exec.js';
|
|
11
|
+
import { registerA2aRpc } from './mesh-rpc.js';
|
|
13
12
|
import { ensureSelf, listRemotes } from './machines.js';
|
|
14
|
-
import {
|
|
15
|
-
import
|
|
16
|
-
import { LocalScriptChannel, WsPtyChannel } from './exec-pty-channel.js';
|
|
17
|
-
import { PTY_EXEC_PATH } from './exec-pty-rpc.js';
|
|
13
|
+
import { createHubExec } from './remote-provider.js';
|
|
14
|
+
import z from '@deepseek-ai/schemastery';
|
|
18
15
|
import { agentLinks } from './agent-roster.js';
|
|
19
16
|
import { foreignAgentHandle, registerForeignHubHost, foreignHubEndpoint } from './foreign-hub.js';
|
|
20
17
|
import { refreshHermesNativeEndpoint } from './foreign-native.js';
|
|
@@ -22,6 +19,7 @@ import { refreshClaudeNativeEndpoint } from './foreign-claude.js';
|
|
|
22
19
|
import { refreshAgyNativeEndpoint } from './foreign-agy.js';
|
|
23
20
|
/** Stable Cordis plugin (row) name. */
|
|
24
21
|
export const name = 'superd-a2a';
|
|
22
|
+
export const Config = z.object({ localExec: z.boolean().default(false) });
|
|
25
23
|
/** Zero static injects — the tools/typertGateway legs are dynamic (dormancy). */
|
|
26
24
|
export const inject = [];
|
|
27
25
|
/**
|
|
@@ -87,70 +85,14 @@ export function wireHubToolRow(ctx, opts = {}) {
|
|
|
87
85
|
// /api fence like the machines route; registered on the same inject scope
|
|
88
86
|
// (they live and die with the typertGateway seam).
|
|
89
87
|
registerA2aRpc(t, ingestRef);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
// P4 exec face: the local executing side + the wire leg over the pairing
|
|
93
|
-
// cookie. The initiator-side per-machine knob (execEnabled) is honored
|
|
94
|
-
// here, before any bytes leave (spec §5).
|
|
95
|
-
const execFace = {
|
|
96
|
-
selfM4: () => ensureSelf(home, 'local').id,
|
|
97
|
-
run: (input) => runOneShotExec(input, alog),
|
|
98
|
-
post: async (machineId, input) => {
|
|
99
|
-
const row = listRemotes(home).find((r) => r.id === machineId);
|
|
100
|
-
if (row === undefined)
|
|
101
|
-
throw new Error(`unknown machine "${machineId}" — call agents for the roster`);
|
|
102
|
-
if (row.execEnabled === false)
|
|
103
|
-
throw new Error(`exec is disabled for machine "${machineId}" on this registry row (execEnabled=false)`);
|
|
104
|
-
alog?.('info', 'exec.remote', { machine: machineId, cmd: input.cmd, timeoutSec: input.timeoutSec ?? 120 });
|
|
105
|
-
const result = await postOneShotExec(row.origin, input, { cookie: cookieOf(row.id, home) });
|
|
106
|
-
// F6 (first-person 0.1.7-d finding): the initiator side needs its own
|
|
107
|
-
// completion line — without it a remote result lives only in the tool
|
|
108
|
-
// response and the initiator's journal stays blind to the outcome.
|
|
109
|
-
alog?.('info', 'exec.remote.done', {
|
|
110
|
-
machine: machineId,
|
|
111
|
-
exit: result.exit ?? 'none',
|
|
112
|
-
durationMs: result.durationMs,
|
|
113
|
-
...(result.outcome === 'exited' ? {} : { outcome: result.outcome }),
|
|
114
|
-
...(result.truncated ? { truncated: true } : {}),
|
|
115
|
-
});
|
|
116
|
-
return result;
|
|
117
|
-
},
|
|
118
|
-
};
|
|
119
|
-
// P4 §8.2 initiator half: the PTY pool. Session key = (calling DSH
|
|
120
|
-
// session, machine) — per-agent direct, no central allocation (D12).
|
|
121
|
-
const ptyPool = new PtyPool({ idleTtlSec: 600 });
|
|
122
|
-
ctx.effect(() => () => { void ptyPool.disposeAll(); }, 'superd-a2a: pty pool teardown');
|
|
123
|
-
const execPty = async (sessionKey, machine, cmd, opts = {}) => {
|
|
124
|
-
const channelOf = () => {
|
|
125
|
-
if (machine === ensureSelf(home, 'local').id)
|
|
126
|
-
return new LocalScriptChannel();
|
|
127
|
-
const row = listRemotes(home).find((r) => r.id === machine);
|
|
128
|
-
if (row === undefined)
|
|
129
|
-
throw new Error(`unknown machine "${machine}" — call agents for the roster`);
|
|
130
|
-
if (row.execEnabled === false)
|
|
131
|
-
throw new Error(`exec is disabled for machine "${machine}" on this registry row (execEnabled=false)`);
|
|
132
|
-
alog?.('info', 'exec.pty.dial', { machine, session: sessionKey });
|
|
133
|
-
return new WsPtyChannel(`${row.origin.replace(/^http/, 'ws')}${PTY_EXEC_PATH}`, { cookie: cookieOf(row.id, home) });
|
|
134
|
-
};
|
|
135
|
-
const session = ptyPool.getOrCreate(`${sessionKey}|m:${machine}`, channelOf);
|
|
136
|
-
const result = await session.dispatch(cmd, { ...(opts.timeoutSec === undefined ? {} : { timeoutSec: opts.timeoutSec }) });
|
|
137
|
-
alog?.('info', 'exec.pty.run', {
|
|
138
|
-
machine,
|
|
139
|
-
cmd: cmd.length > 120 ? `${cmd.slice(0, 117)}...` : cmd,
|
|
140
|
-
exit: result.exit ?? 'none',
|
|
141
|
-
...(result.cwd !== null ? { cwd: result.cwd } : {}),
|
|
142
|
-
durationMs: result.durationMs,
|
|
143
|
-
...(result.reconnected ? { reconnected: true } : {}),
|
|
144
|
-
...(result.timedOut ? { timedOut: true } : {}),
|
|
145
|
-
});
|
|
146
|
-
return result;
|
|
147
|
-
};
|
|
148
|
-
const execFaceFull = { ...execFace, pty: execPty };
|
|
88
|
+
const exec = createHubExec(home, alog);
|
|
89
|
+
t.effect(() => () => exec.dispose(), 'superd-a2a: exec initiator cleanup');
|
|
149
90
|
// the a2a endpoints (POST /api/superd/a2a + GET /api/superd/a2a/outbox) ride the shared
|
|
150
91
|
const toolDeps = {
|
|
151
92
|
service,
|
|
152
93
|
delivery,
|
|
153
|
-
exec:
|
|
94
|
+
exec: exec.face,
|
|
95
|
+
localExec: opts.localExec ?? false,
|
|
154
96
|
// R6: the agent_status leg reads the R5 cache (the sweep's legs fill it)
|
|
155
97
|
status: () => loadAgentStatus(home),
|
|
156
98
|
roster: () => rosterViewOf(home),
|
|
@@ -173,7 +115,7 @@ export function wireHubToolRow(ctx, opts = {}) {
|
|
|
173
115
|
});
|
|
174
116
|
}
|
|
175
117
|
/** MUST stay an arrow (RM0/better-dash note: function declarations get `new`-called, disposers lost). */
|
|
176
|
-
export const apply = (ctx) => {
|
|
177
|
-
wireHubToolRow(ctx);
|
|
118
|
+
export const apply = (ctx, config = {}) => {
|
|
119
|
+
wireHubToolRow(ctx, config);
|
|
178
120
|
};
|
|
179
|
-
export default { name, inject, apply };
|
|
121
|
+
export default { name, inject, Config, apply };
|
|
@@ -1,13 +1,23 @@
|
|
|
1
|
+
/** Better Dash is installed by the current profile's native Plugin Manager. */
|
|
1
2
|
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
-
import
|
|
3
|
+
import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
4
|
+
import { BetterDashCompanion } from './companions.js';
|
|
5
|
+
import type { BetterDashStatus } from './companion-contract.js';
|
|
6
|
+
export { BetterDashCompanion } from './companions.js';
|
|
7
|
+
export type { BetterDashStatus } from './companion-contract.js';
|
|
3
8
|
export declare const name = "superd-bundle-setup";
|
|
4
9
|
export declare const inject: string[];
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
10
|
+
declare module '@deepseek-ai/cordis' {
|
|
11
|
+
interface Context {
|
|
12
|
+
superdCompanions: SuperdCompanions;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export declare class SuperdCompanions extends TypertRemoteService {
|
|
16
|
+
private readonly companion;
|
|
17
|
+
constructor(ctx: Context, companion: BetterDashCompanion);
|
|
18
|
+
getBetterDash(): Promise<BetterDashStatus>;
|
|
19
|
+
installBetterDash(): Promise<BetterDashStatus>;
|
|
8
20
|
}
|
|
9
|
-
/** First registration enables a companion; native reconciliation preserves retained disablement. */
|
|
10
|
-
export declare function reconcileRegistryCompanions(profile: ProfileContext, signal?: AbortSignal): Promise<DeliveryResult>;
|
|
11
21
|
export declare function apply(ctx: Context): void;
|
|
12
22
|
declare const _default: {
|
|
13
23
|
name: string;
|
|
@@ -1,158 +1,94 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import { join } from 'node:path';
|
|
6
|
-
import { fileURLToPath } from 'node:url';
|
|
7
|
-
import { withFileLock, writeFileAtomic } from '@deepseek-ai/dsh-atomic-write';
|
|
8
|
-
import * as AppBoot from '@deepseek-ai/dsh-app-boot';
|
|
9
|
-
export const name = 'superd-bundle-setup';
|
|
10
|
-
export const inject = ['profileContext', 'appReady'];
|
|
11
|
-
const hash = (bytes) => createHash('sha256').update(bytes).digest('hex');
|
|
12
|
-
// Refresh-capable hosts retain loaded package provenance: promoting the
|
|
13
|
-
// companion from its containing pack to a direct dependency needs a restart.
|
|
14
|
-
// Older hosts without this API keep their first-registration behavior.
|
|
15
|
-
const nativePackages = AppBoot.PluginPackages?.prototype;
|
|
16
|
-
const restartForPromotion = nativePackages !== undefined && typeof Reflect.get(nativePackages, 'refresh') === 'function';
|
|
17
|
-
const json = async (path) => JSON.parse(await readFile(path, 'utf8'));
|
|
18
|
-
async function optionalJson(path) {
|
|
19
|
-
try {
|
|
20
|
-
return await json(path);
|
|
1
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
2
|
+
var useValue = arguments.length > 2;
|
|
3
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
4
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
21
5
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
clearTimeout(timeout);
|
|
43
|
-
signal?.removeEventListener('abort', abort);
|
|
44
|
-
if (signal?.aborted) {
|
|
45
|
-
fail(signal.reason);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
if (code !== 0) {
|
|
49
|
-
fail(new Error(`Native companion registration failed (${code}): ${diagnostic.trim() || output.trim()}`));
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
try {
|
|
53
|
-
const result = JSON.parse(output);
|
|
54
|
-
if (result.exitCode !== 0)
|
|
55
|
-
fail(new Error(`Native companion registration failed (${result.exitCode}); diagnostics: ${result.logPath ?? 'unavailable'}`));
|
|
56
|
-
else if (!['installed', 'owner-changed', 'companion-changed', 'companion-removed'].includes(result.disposition))
|
|
57
|
-
fail(new Error('Native companion registration returned an invalid disposition'));
|
|
58
|
-
else
|
|
59
|
-
done(result.disposition);
|
|
60
|
-
}
|
|
61
|
-
catch (error) {
|
|
62
|
-
fail(error);
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
child.stdin.on('error', () => { });
|
|
66
|
-
child.stdin.end(JSON.stringify({ profile, expected }));
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
/** First registration enables a companion; native reconciliation preserves retained disablement. */
|
|
70
|
-
export async function reconcileRegistryCompanions(profile, signal) {
|
|
71
|
-
const directory = join(profile.home, 'companion-registration');
|
|
72
|
-
await mkdir(directory, { recursive: true, mode: 0o700 });
|
|
73
|
-
const key = hash(profile.dir);
|
|
74
|
-
return withFileLock(join(directory, key + '.delivery'), async () => {
|
|
75
|
-
signal?.throwIfAborted();
|
|
76
|
-
const receiptPath = join(directory, key + '.json');
|
|
77
|
-
const receipts = await optionalJson(receiptPath) ?? {};
|
|
78
|
-
const manifest = await json(join(profile.dir, 'package.json'));
|
|
79
|
-
const result = { installed: [], restartRequired: false };
|
|
80
|
-
for (const owner of Object.keys(manifest.dependencies ?? {})) {
|
|
81
|
-
const ownerDir = join(profile.dir, 'node_modules', owner);
|
|
82
|
-
const ownerManifest = await optionalJson(join(ownerDir, 'package.json'));
|
|
83
|
-
if (owner !== 'super-dsh' || ownerManifest?.name !== owner)
|
|
84
|
-
continue;
|
|
85
|
-
const version = ownerManifest.dependencies?.['better-dsh'];
|
|
86
|
-
if (version === undefined || version !== ownerManifest.version)
|
|
87
|
-
throw new Error('Super Dash requires its synchronized exact Better registry dependency');
|
|
88
|
-
const item = { name: 'better-dsh', version };
|
|
89
|
-
const current = await json(join(profile.dir, 'package.json'));
|
|
90
|
-
const ownerSpec = current.dependencies?.[owner];
|
|
91
|
-
if (ownerSpec === undefined)
|
|
92
|
-
continue;
|
|
93
|
-
const priorSpec = current.dependencies?.[item.name];
|
|
94
|
-
const receiptKey = `${owner}:${item.name}`;
|
|
95
|
-
if (priorSpec === undefined && receipts[receiptKey] === version)
|
|
96
|
-
continue; // same-version explicit removal
|
|
97
|
-
const installed = await optionalJson(join(profile.dir, 'node_modules', item.name, 'package.json'));
|
|
98
|
-
if (priorSpec === version && installed?.name === item.name && installed.version === version) {
|
|
99
|
-
receipts[receiptKey] = version;
|
|
100
|
-
await writeFileAtomic(receiptPath, JSON.stringify(receipts) + '\n', { mode: 0o600 });
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
signal?.throwIfAborted();
|
|
104
|
-
const disposition = await installNative(profile, { owner, ownerSpec, companion: item, ...priorSpec === undefined ? {} : { priorSpec } }, signal);
|
|
105
|
-
if (disposition === 'owner-changed' || disposition === 'companion-changed')
|
|
106
|
-
continue;
|
|
107
|
-
receipts[receiptKey] = version;
|
|
108
|
-
await writeFileAtomic(receiptPath, JSON.stringify(receipts) + '\n', { mode: 0o600 });
|
|
109
|
-
if (disposition === 'companion-removed')
|
|
110
|
-
continue;
|
|
111
|
-
result.installed.push(`${item.name}@${item.version}`);
|
|
112
|
-
result.restartRequired ||= priorSpec !== undefined || restartForPromotion;
|
|
6
|
+
return useValue ? value : void 0;
|
|
7
|
+
};
|
|
8
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
9
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
10
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
11
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
12
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
13
|
+
var _, done = false;
|
|
14
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
15
|
+
var context = {};
|
|
16
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
17
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
18
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
19
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
20
|
+
if (kind === "accessor") {
|
|
21
|
+
if (result === void 0) continue;
|
|
22
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
23
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
24
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
25
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
113
26
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
export function apply(ctx) {
|
|
118
|
-
const signal = new AbortController();
|
|
119
|
-
let started = false, running = false, again = false;
|
|
120
|
-
const reconcile = async () => {
|
|
121
|
-
if (!started || signal.signal.aborted)
|
|
122
|
-
return;
|
|
123
|
-
if (running) {
|
|
124
|
-
again = true;
|
|
125
|
-
return;
|
|
27
|
+
else if (_ = accept(result)) {
|
|
28
|
+
if (kind === "field") initializers.unshift(_);
|
|
29
|
+
else descriptor[key] = _;
|
|
126
30
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
31
|
+
}
|
|
32
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
33
|
+
done = true;
|
|
34
|
+
};
|
|
35
|
+
import { Remote, TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
36
|
+
import { BetterDashCompanion } from './companions.js';
|
|
37
|
+
import { PACK_VERSION } from './pack-version.js';
|
|
38
|
+
export { BetterDashCompanion } from './companions.js';
|
|
39
|
+
export const name = 'superd-bundle-setup';
|
|
40
|
+
export const inject = ['profileContext', 'appReady'];
|
|
41
|
+
let SuperdCompanions = (() => {
|
|
42
|
+
let _classSuper = TypertRemoteService;
|
|
43
|
+
let _instanceExtraInitializers = [];
|
|
44
|
+
let _getBetterDash_decorators;
|
|
45
|
+
let _installBetterDash_decorators;
|
|
46
|
+
return class SuperdCompanions extends _classSuper {
|
|
47
|
+
static {
|
|
48
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
49
|
+
_getBetterDash_decorators = [Remote];
|
|
50
|
+
_installBetterDash_decorators = [Remote];
|
|
51
|
+
__esDecorate(this, null, _getBetterDash_decorators, { kind: "method", name: "getBetterDash", static: false, private: false, access: { has: obj => "getBetterDash" in obj, get: obj => obj.getBetterDash }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
52
|
+
__esDecorate(this, null, _installBetterDash_decorators, { kind: "method", name: "installBetterDash", static: false, private: false, access: { has: obj => "installBetterDash" in obj, get: obj => obj.installBetterDash }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
53
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
138
54
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
void reconcile();
|
|
144
|
-
}
|
|
55
|
+
companion = __runInitializers(this, _instanceExtraInitializers);
|
|
56
|
+
constructor(ctx, companion) {
|
|
57
|
+
super(ctx, 'superdCompanions');
|
|
58
|
+
this.companion = companion;
|
|
145
59
|
}
|
|
60
|
+
getBetterDash() { return this.companion.getBetterDash(); }
|
|
61
|
+
installBetterDash() { return this.companion.installBetterDash(); }
|
|
146
62
|
};
|
|
63
|
+
})();
|
|
64
|
+
export { SuperdCompanions };
|
|
65
|
+
export function apply(ctx) {
|
|
66
|
+
const companion = new BetterDashCompanion(ctx.profileContext, PACK_VERSION, () => ctx.get('pluginManager'));
|
|
67
|
+
new SuperdCompanions(ctx, companion);
|
|
147
68
|
ctx.effect(() => {
|
|
148
|
-
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
// Never await a child here: manager HMR may be holding the profile lock it needs.
|
|
69
|
+
let ready = false, registering = true;
|
|
70
|
+
const start = () => {
|
|
71
|
+
void companion.ensureAutomatic().then(status => {
|
|
72
|
+
if (status.error !== undefined)
|
|
73
|
+
ctx.logger.warn(status.error);
|
|
74
|
+
}).catch(error => ctx.logger.warn('Better Dash companion status failed', error));
|
|
155
75
|
};
|
|
156
|
-
|
|
76
|
+
const offReady = ctx.appReady.onReady(() => {
|
|
77
|
+
ready = true;
|
|
78
|
+
// Cold readiness occurs after boot, outside HMR. A live mount gets an
|
|
79
|
+
// immediate callback while its parent HMR transaction is still active:
|
|
80
|
+
// wait for the native changed notification below instead.
|
|
81
|
+
if (!registering)
|
|
82
|
+
start();
|
|
83
|
+
});
|
|
84
|
+
registering = false;
|
|
85
|
+
const offChange = ctx.on('plugin-manager/changed', () => {
|
|
86
|
+
// Native configure/HMR has finished here, but the parent's profile lock
|
|
87
|
+
// is still held. Return immediately; child install queues that lock.
|
|
88
|
+
if (ready)
|
|
89
|
+
start();
|
|
90
|
+
});
|
|
91
|
+
return () => { offReady(); offChange(); companion.dispose(); };
|
|
92
|
+
}, 'bundle-delivery: native companions');
|
|
157
93
|
}
|
|
158
94
|
export default { name, inject, apply };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Local ctx0 companion management, independent of the selected agent world. */
|
|
2
|
+
import { type FetchLike } from './runtime-settings-api.js';
|
|
3
|
+
import type { BetterDashStatus } from '../companion-contract.js';
|
|
4
|
+
export type CompanionOperation = 'getBetterDash' | 'installBetterDash';
|
|
5
|
+
export declare function callCompanion(operation: CompanionOperation, doFetch?: FetchLike): Promise<BetterDashStatus>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** Local ctx0 companion management, independent of the selected agent world. */
|
|
2
|
+
import { mintRpcId } from './runtime-settings-api.js';
|
|
3
|
+
export async function callCompanion(operation, doFetch) {
|
|
4
|
+
const method = `superdCompanions/${operation}`;
|
|
5
|
+
const send = doFetch ?? ((path, init) => fetch(path, init));
|
|
6
|
+
const response = await send(`/api/${method}`, {
|
|
7
|
+
method: 'POST', credentials: 'same-origin', headers: { 'content-type': 'application/json' },
|
|
8
|
+
body: JSON.stringify({ type: 'client-request', rpcId: mintRpcId(), method, payload: { args: {} } }),
|
|
9
|
+
});
|
|
10
|
+
if (!response.ok)
|
|
11
|
+
throw new Error(`Better Dash: HTTP ${response.status}`);
|
|
12
|
+
let body;
|
|
13
|
+
try {
|
|
14
|
+
body = JSON.parse(await response.text());
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
throw new Error('Better Dash: unreadable response');
|
|
18
|
+
}
|
|
19
|
+
const result = body?.result;
|
|
20
|
+
if (result?.ok !== true)
|
|
21
|
+
throw new Error(result?.error?.message ?? 'Better Dash: request failed');
|
|
22
|
+
const value = result.value;
|
|
23
|
+
if (value === null || typeof value !== 'object' || typeof value.installed !== 'boolean'
|
|
24
|
+
|| typeof value.installing !== 'boolean' || typeof value.requestedVersion !== 'string'
|
|
25
|
+
|| (value.version !== undefined && typeof value.version !== 'string')
|
|
26
|
+
|| (value.enabled !== undefined && typeof value.enabled !== 'boolean')
|
|
27
|
+
|| (value.error !== undefined && typeof value.error !== 'string'))
|
|
28
|
+
throw new Error('Better Dash: invalid status');
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ProfileContext } from '@deepseek-ai/dsh-app-boot';
|
|
2
|
+
import type { PluginManager } from '@deepseek-ai/dsh-plugin-manager';
|
|
3
|
+
import type { BetterDashStatus } from './companion-contract.js';
|
|
4
|
+
type Manager = Pick<PluginManager, 'listBundles' | 'installBundle'>;
|
|
5
|
+
/** One controller per native profile; no package, registry, HMR or selection writer of its own. */
|
|
6
|
+
export declare class BetterDashCompanion {
|
|
7
|
+
private readonly version;
|
|
8
|
+
private readonly manager;
|
|
9
|
+
private readonly directory;
|
|
10
|
+
private readonly receipt;
|
|
11
|
+
private readonly legacy;
|
|
12
|
+
private initialized?;
|
|
13
|
+
private intent;
|
|
14
|
+
private active?;
|
|
15
|
+
private stopped;
|
|
16
|
+
private restartNotice?;
|
|
17
|
+
constructor(profile: Pick<ProfileContext, 'home' | 'dir'>, version: string, manager: () => Manager | undefined);
|
|
18
|
+
private initialize;
|
|
19
|
+
private cleanLegacy;
|
|
20
|
+
private save;
|
|
21
|
+
getBetterDash(): Promise<BetterDashStatus>;
|
|
22
|
+
ensureAutomatic(): Promise<BetterDashStatus>;
|
|
23
|
+
installBetterDash(): Promise<BetterDashStatus>;
|
|
24
|
+
private run;
|
|
25
|
+
private install;
|
|
26
|
+
/** Read-only observation: an intermediate native event must never trigger reinstatement. */
|
|
27
|
+
observeNativeChange(): Promise<BetterDashStatus>;
|
|
28
|
+
dispose(): void;
|
|
29
|
+
}
|
|
30
|
+
export {};
|