@stagewhisper/stagewhisper 0.9.0 → 0.14.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/index.ts +52 -75
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -3
- package/plugin-main.ts +77 -0
- package/setup-entry.ts +0 -4
package/index.ts
CHANGED
|
@@ -1,77 +1,54 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
console.log(` openclaw config set plugins.entries.stagewhisper.config.relayToken ${JSON.stringify(result.relay_token)}`);
|
|
40
|
-
console.log(` openclaw config set plugins.entries.stagewhisper.config.label ${JSON.stringify(result.label)}`);
|
|
41
|
-
console.log("\n Then restart OpenClaw to activate the relay:\n");
|
|
42
|
-
console.log(" openclaw gateway restart\n");
|
|
43
|
-
} catch (err) {
|
|
44
|
-
console.error(`\n✗ Pairing failed: ${err}\n`);
|
|
45
|
-
process.exit(1);
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
sw.command("status")
|
|
51
|
-
.description("Show StageWhisper relay connection status")
|
|
52
|
-
.action(() => {
|
|
53
|
-
const relayState = service.getState();
|
|
54
|
-
const cfg = api.pluginConfig as Record<string, string> | undefined;
|
|
55
|
-
const configured = !!(cfg?.["integrationId"] && cfg?.["relayToken"]);
|
|
56
|
-
|
|
57
|
-
if (!configured) {
|
|
58
|
-
console.log("\nStageWhisper: not paired\n");
|
|
59
|
-
console.log(" Run: openclaw stagewhisper pair --code <CODE> --api-url <URL>\n");
|
|
60
|
-
console.log(" Get the pairing code from StageWhisper desktop: Settings → Assistant → Generate Pairing Code\n");
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
// OpenClaw loads external plugins via jiti from ~/.openclaw/extensions/.
|
|
5
|
+
// jiti's alias map is built by walking up from the plugin file's directory
|
|
6
|
+
// to find a package.json with name "openclaw" — but external plugins live
|
|
7
|
+
// outside the openclaw package tree, so the walk never finds it and
|
|
8
|
+
// 'openclaw/plugin-sdk/*' imports fail with "Cannot find module".
|
|
9
|
+
//
|
|
10
|
+
// This bootstrap creates a node_modules/openclaw symlink pointing to the
|
|
11
|
+
// actual openclaw package (located via process.argv[1]), then loads the
|
|
12
|
+
// real plugin entry where the openclaw imports live.
|
|
13
|
+
|
|
14
|
+
function ensureOpenClawResolvable(): void {
|
|
15
|
+
const pluginDir =
|
|
16
|
+
typeof __dirname === "string"
|
|
17
|
+
? __dirname
|
|
18
|
+
: path.dirname(new URL(import.meta.url).pathname);
|
|
19
|
+
|
|
20
|
+
const link = path.join(pluginDir, "node_modules", "openclaw");
|
|
21
|
+
if (fs.existsSync(link)) return;
|
|
22
|
+
|
|
23
|
+
const binPath = process.argv[1];
|
|
24
|
+
if (!binPath) return;
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
const resolved = fs.realpathSync(binPath);
|
|
28
|
+
let dir = path.dirname(resolved);
|
|
29
|
+
for (let i = 0; i < 20; i++) {
|
|
30
|
+
const pkgPath = path.join(dir, "package.json");
|
|
31
|
+
if (fs.existsSync(pkgPath)) {
|
|
32
|
+
try {
|
|
33
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
34
|
+
if (pkg.name === "openclaw") {
|
|
35
|
+
fs.mkdirSync(path.join(pluginDir, "node_modules"), {
|
|
36
|
+
recursive: true,
|
|
37
|
+
});
|
|
38
|
+
fs.symlinkSync(dir, link, "dir");
|
|
61
39
|
return;
|
|
62
40
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
});
|
|
41
|
+
} catch {}
|
|
42
|
+
}
|
|
43
|
+
const parent = path.dirname(dir);
|
|
44
|
+
if (parent === dir) break;
|
|
45
|
+
dir = parent;
|
|
46
|
+
}
|
|
47
|
+
} catch {}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
ensureOpenClawResolvable();
|
|
51
|
+
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
53
|
+
const pluginMain = require("./plugin-main");
|
|
54
|
+
export default pluginMain.default ?? pluginMain;
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stagewhisper/stagewhisper",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenClaw channel plugin that connects StageWhisper live calls to your AI assistant",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"files": [
|
|
8
8
|
"index.ts",
|
|
9
|
-
"
|
|
9
|
+
"plugin-main.ts",
|
|
10
10
|
"api.ts",
|
|
11
11
|
"src",
|
|
12
12
|
"openclaw.plugin.json",
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
"extensions": [
|
|
22
22
|
"./index.ts"
|
|
23
23
|
],
|
|
24
|
-
"setupEntry": "./setup-entry.ts",
|
|
25
24
|
"channel": {
|
|
26
25
|
"id": "stagewhisper",
|
|
27
26
|
"label": "StageWhisper",
|
package/plugin-main.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
2
|
+
import { stagewhisperPlugin } from "./src/channel.js";
|
|
3
|
+
import { setRuntime } from "./src/runtime.js";
|
|
4
|
+
import { createRelayService } from "./src/service.js";
|
|
5
|
+
|
|
6
|
+
export default definePluginEntry({
|
|
7
|
+
id: "stagewhisper",
|
|
8
|
+
name: "StageWhisper",
|
|
9
|
+
description: "Turn live call moments into assistant tasks via StageWhisper",
|
|
10
|
+
register(api) {
|
|
11
|
+
api.registerChannel({ plugin: stagewhisperPlugin });
|
|
12
|
+
|
|
13
|
+
const service = createRelayService(api);
|
|
14
|
+
|
|
15
|
+
api.registerCli(({ program }) => {
|
|
16
|
+
const sw = program
|
|
17
|
+
.command("stagewhisper")
|
|
18
|
+
.description("StageWhisper integration");
|
|
19
|
+
|
|
20
|
+
sw.command("pair")
|
|
21
|
+
.description("Pair with StageWhisper using a pairing code from the desktop app")
|
|
22
|
+
.requiredOption("--code <code>", "Pairing code from Settings → Assistant")
|
|
23
|
+
.requiredOption("--api-url <url>", "StageWhisper backend URL (e.g. https://api.stagewhisper.io)")
|
|
24
|
+
.option("--label <label>", "Label for this OpenClaw host", "OpenClaw")
|
|
25
|
+
.action(
|
|
26
|
+
async (opts: { code: string; apiUrl: string; label?: string }) => {
|
|
27
|
+
const { StageWhisperClient } = await import("./src/client.js");
|
|
28
|
+
const client = new StageWhisperClient(opts.apiUrl, "", "");
|
|
29
|
+
try {
|
|
30
|
+
const result = await client.completePairing(
|
|
31
|
+
opts.code,
|
|
32
|
+
opts.label ?? "OpenClaw",
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
console.log(`\n✓ Paired with StageWhisper (${result.label})\n`);
|
|
36
|
+
console.log(" Apply the config:\n");
|
|
37
|
+
console.log(` openclaw config set plugins.entries.stagewhisper.config.apiBaseUrl ${JSON.stringify(opts.apiUrl)}`);
|
|
38
|
+
console.log(` openclaw config set plugins.entries.stagewhisper.config.integrationId ${JSON.stringify(result.integration_id)}`);
|
|
39
|
+
console.log(` openclaw config set plugins.entries.stagewhisper.config.relayToken ${JSON.stringify(result.relay_token)}`);
|
|
40
|
+
console.log(` openclaw config set plugins.entries.stagewhisper.config.label ${JSON.stringify(result.label)}`);
|
|
41
|
+
console.log("\n Then restart OpenClaw to activate the relay:\n");
|
|
42
|
+
console.log(" openclaw gateway restart\n");
|
|
43
|
+
} catch (err) {
|
|
44
|
+
console.error(`\n✗ Pairing failed: ${err}\n`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
sw.command("status")
|
|
51
|
+
.description("Show StageWhisper relay connection status")
|
|
52
|
+
.action(() => {
|
|
53
|
+
const relayState = service.getState();
|
|
54
|
+
const cfg = api.pluginConfig as Record<string, string> | undefined;
|
|
55
|
+
const configured = !!(cfg?.["integrationId"] && cfg?.["relayToken"]);
|
|
56
|
+
|
|
57
|
+
if (!configured) {
|
|
58
|
+
console.log("\nStageWhisper: not paired\n");
|
|
59
|
+
console.log(" Run: openclaw stagewhisper pair --code <CODE> --api-url <URL>\n");
|
|
60
|
+
console.log(" Get the pairing code from StageWhisper desktop: Settings → Assistant → Generate Pairing Code\n");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
console.log(`\nStageWhisper relay:`);
|
|
65
|
+
console.log(` Connected: ${relayState.connected}`);
|
|
66
|
+
console.log(` Last heartbeat: ${relayState.lastHeartbeat?.toISOString() ?? "never"}`);
|
|
67
|
+
console.log(` Reconnect attempts: ${relayState.reconnectAttempts}`);
|
|
68
|
+
console.log(` Backend: ${cfg?.["apiBaseUrl"] ?? "(unset)"}\n`);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (api.registrationMode !== "full") return;
|
|
73
|
+
|
|
74
|
+
setRuntime(api.runtime);
|
|
75
|
+
api.registerService(service);
|
|
76
|
+
},
|
|
77
|
+
});
|
package/setup-entry.ts
DELETED