@parall/agent-core 1.42.1 → 1.43.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/dist/bin/channel-exec.d.ts +4 -0
- package/dist/bin/channel-exec.d.ts.map +1 -0
- package/dist/bin/channel-exec.js +246 -0
- package/dist/channel-capability.d.ts +16 -0
- package/dist/channel-capability.d.ts.map +1 -0
- package/dist/channel-capability.js +155 -0
- package/dist/channel-token.d.ts +19 -0
- package/dist/channel-token.d.ts.map +1 -0
- package/dist/channel-token.js +73 -0
- package/dist/event-format.d.ts.map +1 -1
- package/dist/event-format.js +21 -16
- package/dist/gateway-base.d.ts +12 -0
- package/dist/gateway-base.d.ts.map +1 -1
- package/dist/gateway-base.js +30 -3
- package/dist/gateway-lane-flow.d.ts +20 -1
- package/dist/gateway-lane-flow.d.ts.map +1 -1
- package/dist/gateway-lane-flow.js +75 -6
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/platform-config.d.ts +15 -0
- package/dist/platform-config.d.ts.map +1 -1
- package/dist/platform-config.js +28 -0
- package/dist/prompt-fragments.d.ts +1 -1
- package/dist/prompt-fragments.d.ts.map +1 -1
- package/dist/prompt-fragments.js +29 -7
- package/dist/skills/index.js +1 -1
- package/dist/skills/parall-platform.d.ts +1 -1
- package/dist/skills/parall-platform.d.ts.map +1 -1
- package/dist/skills/parall-platform.js +23 -4
- package/dist/types.d.ts +5 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/bin/channel-exec.ts +262 -0
- package/src/channel-capability.ts +187 -0
- package/src/channel-token.ts +92 -0
- package/src/event-format.ts +21 -16
- package/src/gateway-base.ts +44 -6
- package/src/gateway-lane-flow.ts +89 -4
- package/src/index.ts +3 -0
- package/src/platform-config.ts +44 -0
- package/src/prompt-fragments.ts +29 -7
- package/src/skills/index.ts +1 -1
- package/src/skills/parall-platform.ts +23 -4
- package/src/types.ts +5 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel-exec.d.ts","sourceRoot":"","sources":["../../src/bin/channel-exec.ts"],"names":[],"mappings":"AA0LA,iBAAS,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQ9C;AAED,iBAAS,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjD;AA4BD,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// channel-exec — the short-lived exec form of the channel-capability
|
|
2
|
+
// credential engine. Invoked by the pointer shims the materializer drops on
|
|
3
|
+
// the capability PATH (e.g. `lark-cli` → `node <this file> --channel feishu
|
|
4
|
+
// --bin lark-cli --skip-dir <shimDir> -- <args…>`): mints a fresh short-lived
|
|
5
|
+
// token from the platform on EVERY call, injects it as the vendor CLI's own
|
|
6
|
+
// documented env credentials, resolves the real binary past the shim
|
|
7
|
+
// directory, and execs it with stdio passthrough.
|
|
8
|
+
//
|
|
9
|
+
// This is a process entry point, not a library — importing it runs main().
|
|
10
|
+
// It lives inside @parall/agent-core so it ships atomically with the bridge
|
|
11
|
+
// (image / daemon bundle), never depending on agent-writable install state.
|
|
12
|
+
// Design: docs/engineering-design/agent-capability-fragments-design.md §5.1.
|
|
13
|
+
import { spawnSync } from 'node:child_process';
|
|
14
|
+
import * as fs from 'node:fs';
|
|
15
|
+
import * as path from 'node:path';
|
|
16
|
+
import { pathToFileURL } from 'node:url';
|
|
17
|
+
import { CHANNEL_POINTER_MAGIC } from '../channel-capability.js';
|
|
18
|
+
import { ChannelTokenError, mintChannelToken } from '../channel-token.js';
|
|
19
|
+
// The vendor binary each channel targets is fixed HERE, not taken from the
|
|
20
|
+
// caller — channel-exec must never mint a token and hand it to a
|
|
21
|
+
// caller-named program. `--bin` is deliberately not an argument, so a request
|
|
22
|
+
// like `--channel feishu --bin evil` (with a tampered PATH) cannot redirect
|
|
23
|
+
// the minted token to an attacker-chosen executable.
|
|
24
|
+
const CHANNEL_BIN = { feishu: 'lark-cli' };
|
|
25
|
+
function fail(prefix, msg, code) {
|
|
26
|
+
// Write to fd 2 SYNCHRONOUSLY: process.exit() right after an async
|
|
27
|
+
// process.stderr.write() can truncate the message when stderr is a pipe
|
|
28
|
+
// (notably on Windows) — and this path carries the install hint / revocation
|
|
29
|
+
// message the agent must relay to the user. writeSync flushes before exit;
|
|
30
|
+
// exit still runs so fail() keeps its `never` contract.
|
|
31
|
+
try {
|
|
32
|
+
fs.writeSync(2, `${prefix}: ${msg}\n`);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// best-effort — still exit with the intended status
|
|
36
|
+
}
|
|
37
|
+
process.exit(code);
|
|
38
|
+
}
|
|
39
|
+
function parseArgs(argv) {
|
|
40
|
+
const out = { channel: '', skipDir: '', rest: [] };
|
|
41
|
+
for (let i = 0; i < argv.length; i++) {
|
|
42
|
+
const a = argv[i];
|
|
43
|
+
if (a === '--') {
|
|
44
|
+
out.rest = argv.slice(i + 1);
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
if (a === '--channel')
|
|
48
|
+
out.channel = argv[++i] ?? '';
|
|
49
|
+
else if (a === '--skip-dir')
|
|
50
|
+
out.skipDir = argv[++i] ?? '';
|
|
51
|
+
else
|
|
52
|
+
fail('channel-exec', `unknown argument ${a}`, 2);
|
|
53
|
+
}
|
|
54
|
+
if (!out.channel) {
|
|
55
|
+
fail('channel-exec', 'usage: channel-exec --channel <type> [--skip-dir <dir>] -- <args…>', 2);
|
|
56
|
+
}
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
// A candidate that carries the pointer magic in its head is one of OUR
|
|
60
|
+
// pointers (or a stray copy of one) — never the real vendor binary. This
|
|
61
|
+
// makes self-recursion structurally impossible even when the skip-dir hint
|
|
62
|
+
// is wrong or the pointer got copied elsewhere on PATH.
|
|
63
|
+
function isCapabilityPointer(candidate) {
|
|
64
|
+
try {
|
|
65
|
+
const fd = fs.openSync(candidate, 'r');
|
|
66
|
+
try {
|
|
67
|
+
const buf = Buffer.alloc(256);
|
|
68
|
+
const n = fs.readSync(fd, buf, 0, buf.length, 0);
|
|
69
|
+
return buf.toString('utf8', 0, n).includes(CHANNEL_POINTER_MAGIC);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
fs.closeSync(fd);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Resolve the REAL vendor binary along PATH, skipping the shim's own
|
|
80
|
+
// directory (realpath comparison, so symlinked layouts don't fool it).
|
|
81
|
+
function resolveRealBin(bin, skipDir) {
|
|
82
|
+
const isWin = process.platform === 'win32';
|
|
83
|
+
// npm on Windows installs `<bin>` (sh) + `<bin>.cmd` + `<bin>.ps1`; the sh
|
|
84
|
+
// file is not spawnable by CreateProcess, so prefer the .cmd/.exe forms.
|
|
85
|
+
const exts = isWin ? ['.cmd', '.exe', '.bat'] : [''];
|
|
86
|
+
let skipReal = null;
|
|
87
|
+
if (skipDir) {
|
|
88
|
+
try {
|
|
89
|
+
skipReal = fs.realpathSync(skipDir);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
skipReal = null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
for (const dir of (process.env.PATH || '').split(path.delimiter)) {
|
|
96
|
+
if (!dir)
|
|
97
|
+
continue;
|
|
98
|
+
let real;
|
|
99
|
+
try {
|
|
100
|
+
real = fs.realpathSync(dir);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (skipReal && real === skipReal)
|
|
106
|
+
continue;
|
|
107
|
+
for (const ext of exts) {
|
|
108
|
+
const candidate = path.join(dir, bin + ext);
|
|
109
|
+
try {
|
|
110
|
+
if (fs.statSync(candidate).isFile() && !isCapabilityPointer(candidate))
|
|
111
|
+
return candidate;
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// keep scanning
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
// The exact lark-cli env credentials the broker OWNS: the values it injects
|
|
121
|
+
// plus the ambient auth inputs it must strip so nothing widens the identity
|
|
122
|
+
// beyond the minted grant. Scrubbing is confined to THESE names — never a
|
|
123
|
+
// blanket LARKSUITE_CLI_* wipe — so legitimate operator controls
|
|
124
|
+
// (LARKSUITE_CLI_CONFIG_DIR / LOG_DIR / CONTENT_SAFETY_MODE / …) survive.
|
|
125
|
+
const FEISHU_OWNED_ENV = [
|
|
126
|
+
// injected (canonical values set below)
|
|
127
|
+
'LARKSUITE_CLI_APP_ID',
|
|
128
|
+
'LARKSUITE_CLI_BRAND',
|
|
129
|
+
'LARKSUITE_CLI_TENANT_ACCESS_TOKEN',
|
|
130
|
+
'LARKSUITE_CLI_DEFAULT_AS',
|
|
131
|
+
'LARKSUITE_CLI_STRICT_MODE',
|
|
132
|
+
// ambient auth bypass inputs that must not reach the child
|
|
133
|
+
'LARKSUITE_CLI_APP_SECRET',
|
|
134
|
+
'LARKSUITE_CLI_USER_ACCESS_TOKEN',
|
|
135
|
+
'LARKSUITE_CLI_AUTH_PROXY',
|
|
136
|
+
'LARKSUITE_CLI_PROXY_KEY',
|
|
137
|
+
];
|
|
138
|
+
// Per-channel env injection: the ONLY channel-specific knowledge in this
|
|
139
|
+
// entry.
|
|
140
|
+
function buildChildEnv(channel, minted) {
|
|
141
|
+
const env = { ...process.env };
|
|
142
|
+
if (channel === 'feishu') {
|
|
143
|
+
// Delete the broker-owned names case-insensitively: Windows env keys are
|
|
144
|
+
// case-insensitive and a plain-object spread keeps the host's casing, so
|
|
145
|
+
// an uppercase-only delete would miss e.g. `Larksuite_Cli_Auth_Proxy` (a
|
|
146
|
+
// bypass leak) or leave a stale-cased duplicate shadowing the injected
|
|
147
|
+
// token. Non-owned LARKSUITE_CLI_* operator settings are left untouched.
|
|
148
|
+
const owned = new Set(FEISHU_OWNED_ENV);
|
|
149
|
+
for (const key of Object.keys(env)) {
|
|
150
|
+
if (owned.has(key.toUpperCase()))
|
|
151
|
+
delete env[key];
|
|
152
|
+
}
|
|
153
|
+
env.LARKSUITE_CLI_APP_ID = minted.app_id;
|
|
154
|
+
env.LARKSUITE_CLI_BRAND = minted.brand || 'feishu';
|
|
155
|
+
env.LARKSUITE_CLI_TENANT_ACCESS_TOKEN = minted.token;
|
|
156
|
+
// Bot lock: the credential is the app's, not a human's.
|
|
157
|
+
env.LARKSUITE_CLI_DEFAULT_AS = 'bot';
|
|
158
|
+
env.LARKSUITE_CLI_STRICT_MODE = 'bot';
|
|
159
|
+
return env;
|
|
160
|
+
}
|
|
161
|
+
fail('channel-exec', `unsupported channel type "${channel}"`, 2);
|
|
162
|
+
}
|
|
163
|
+
// Windows argv-preserving quoting, ported from cross-spawn (the npm-ecosystem
|
|
164
|
+
// standard for correctly launching .cmd shims). Node's `shell: true` does NOT
|
|
165
|
+
// escape arguments — it concatenates them, so JSON/message args split or
|
|
166
|
+
// inject on cmd.exe — and CreateProcess cannot run a .cmd directly. The proven
|
|
167
|
+
// path is cmd.exe /d /s /c with each token escaped for BOTH the CreateProcess
|
|
168
|
+
// argv layer and the cmd.exe metachar layer (double-escaped because a .cmd
|
|
169
|
+
// re-parses). Still Windows-only and NO Windows CI: validate on a real Windows
|
|
170
|
+
// host before the first Windows selfhost user (the round-trip tests lock the
|
|
171
|
+
// escaping rules, not the live cmd.exe behavior).
|
|
172
|
+
// cmd.exe metacharacters, matching cross-spawn's metaCharsRegExp (v7.0.6). ONE
|
|
173
|
+
// set shared by BOTH the command and the arguments — cross-spawn uses a single
|
|
174
|
+
// regex for both, and a split set is a real correctness hole: a metachar
|
|
175
|
+
// caret-escaped in the command path but left bare in an argument (or the
|
|
176
|
+
// reverse) survives only one of cmd.exe's two parse passes. Includes the
|
|
177
|
+
// separators (space, `;`, `,`) and glob chars (`*`, `?`) so a quoted argument's
|
|
178
|
+
// separators are still neutralized for the `.cmd` re-parse, exactly as
|
|
179
|
+
// cross-spawn does.
|
|
180
|
+
const CMD_META_CHARS = /([()\][%!^"`<>&|;, *?])/g;
|
|
181
|
+
function escapeCmdArgument(arg) {
|
|
182
|
+
let out = `${arg}`;
|
|
183
|
+
// Double backslashes before a quote, and trailing backslashes, then wrap.
|
|
184
|
+
out = out.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\*)$/, '$1$1');
|
|
185
|
+
out = `"${out}"`;
|
|
186
|
+
// cmd metachars, escaped twice (the .cmd forwarder re-parses).
|
|
187
|
+
out = out.replace(CMD_META_CHARS, '^$1').replace(CMD_META_CHARS, '^$1');
|
|
188
|
+
return out;
|
|
189
|
+
}
|
|
190
|
+
function escapeCmdCommand(command) {
|
|
191
|
+
return command.replace(CMD_META_CHARS, '^$1');
|
|
192
|
+
}
|
|
193
|
+
function runReal(realBin, args, env, prefix) {
|
|
194
|
+
const isWinScript = process.platform === 'win32' && /\.(cmd|bat)$/i.test(realBin);
|
|
195
|
+
const result = isWinScript
|
|
196
|
+
? spawnSync(process.env.comspec || 'cmd.exe', [
|
|
197
|
+
'/d',
|
|
198
|
+
'/s',
|
|
199
|
+
'/c',
|
|
200
|
+
`"${[escapeCmdCommand(realBin), ...args.map(escapeCmdArgument)].join(' ')}"`,
|
|
201
|
+
], { stdio: 'inherit', env, windowsVerbatimArguments: true })
|
|
202
|
+
: spawnSync(realBin, args, { stdio: 'inherit', env });
|
|
203
|
+
if (result.error) {
|
|
204
|
+
fail(prefix, `failed to run ${realBin}: ${String(result.error)}`, 1);
|
|
205
|
+
}
|
|
206
|
+
if (result.signal) {
|
|
207
|
+
process.kill(process.pid, result.signal);
|
|
208
|
+
// Unreachable in practice; satisfy the `never` contract if the signal is trapped.
|
|
209
|
+
process.exit(1);
|
|
210
|
+
}
|
|
211
|
+
process.exit(result.status === null ? 1 : result.status);
|
|
212
|
+
}
|
|
213
|
+
// Exported for round-trip unit tests (Windows spawn can't run in CI).
|
|
214
|
+
export { escapeCmdArgument, escapeCmdCommand };
|
|
215
|
+
async function main() {
|
|
216
|
+
const { channel, skipDir, rest } = parseArgs(process.argv.slice(2));
|
|
217
|
+
const bin = CHANNEL_BIN[channel];
|
|
218
|
+
if (!bin)
|
|
219
|
+
fail('channel-exec', `unsupported channel type "${channel}"`, 2);
|
|
220
|
+
const prefix = bin;
|
|
221
|
+
let minted;
|
|
222
|
+
try {
|
|
223
|
+
minted = await mintChannelToken(channel, process.env);
|
|
224
|
+
}
|
|
225
|
+
catch (err) {
|
|
226
|
+
if (err instanceof ChannelTokenError)
|
|
227
|
+
fail(prefix, err.message, 1);
|
|
228
|
+
fail(prefix, String(err), 1);
|
|
229
|
+
}
|
|
230
|
+
const real = resolveRealBin(bin, skipDir);
|
|
231
|
+
if (!real) {
|
|
232
|
+
const hint = channel === 'feishu'
|
|
233
|
+
? 'Install it once with:\n npm i -g @larksuite/cli && npx skills add larksuite/cli -y -g'
|
|
234
|
+
: 'Install it and retry.';
|
|
235
|
+
fail(prefix, `the ${bin} binary is not installed. ${hint}`, 127);
|
|
236
|
+
}
|
|
237
|
+
runReal(real, rest, buildChildEnv(channel, minted), prefix);
|
|
238
|
+
}
|
|
239
|
+
// Run main() only when invoked AS A PROGRAM (the pointer shim runs
|
|
240
|
+
// `node <this>`), not when a test imports this module for the escape helpers.
|
|
241
|
+
// Holds in both layouts: npm (argv[1] = channel-exec.js) and bundle
|
|
242
|
+
// (argv[1] = parall-channel-exec.js, which is also this module's own url).
|
|
243
|
+
const invokedPath = process.argv[1];
|
|
244
|
+
if (invokedPath && import.meta.url === pathToFileURL(invokedPath).href) {
|
|
245
|
+
void main();
|
|
246
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GatewayLogger } from './dispatch-adapter.js';
|
|
2
|
+
import type { AgentCapability } from './platform-config.js';
|
|
3
|
+
export declare const CAPABILITY_FEISHU_CLI = "feishu-cli";
|
|
4
|
+
export declare const CHANNEL_POINTER_MAGIC = "parall channel capability pointer";
|
|
5
|
+
export declare function capabilityBinDir(stateDir: string): string;
|
|
6
|
+
export declare function channelExecEntryPath(): string;
|
|
7
|
+
/**
|
|
8
|
+
* Idempotently reconcile local capability pointers with the delivered
|
|
9
|
+
* capability list. Call at boot (after the first config fetch) and on every
|
|
10
|
+
* config refresh. Never throws — a pointer write failure must not take down
|
|
11
|
+
* a config refresh (the capability simply stays unusable until the next pass).
|
|
12
|
+
*/
|
|
13
|
+
export declare function materializeChannelCapabilities(stateDir: string, capabilities: AgentCapability[], log?: GatewayLogger): void;
|
|
14
|
+
export declare function renderPosixPointer(nodeExecPath: string, entryJsPath: string, binDir: string, channel: string): string;
|
|
15
|
+
export declare function renderCmdPointer(nodeExecPath: string, entryJsPath: string, binDir: string, channel: string): string;
|
|
16
|
+
//# sourceMappingURL=channel-capability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel-capability.d.ts","sourceRoot":"","sources":["../src/channel-capability.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAoB5D,eAAO,MAAM,qBAAqB,eAAe,CAAC;AAMlD,eAAO,MAAM,qBAAqB,sCAAsC,CAAC;AAMzE,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzD;AAcD,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,eAAe,EAAE,EAC/B,GAAG,CAAC,EAAE,aAAa,GAClB,IAAI,CAMN;AAuED,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,MAAM,CAkBR;AAED,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,MAAM,CAUR"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
// Runtime-side materializer for channel capabilities — a pure PLACEMENT
|
|
5
|
+
// layer. The server declares WHAT the agent has (agents.capabilities[]);
|
|
6
|
+
// the credential logic lives in this package's channel-exec entry
|
|
7
|
+
// (bin/channel-exec.ts, reusing channel-token.ts); this module only drops
|
|
8
|
+
// constant POINTER shims onto the capability PATH so the vendor command name
|
|
9
|
+
// (e.g. `lark-cli`, which the official skills invoke directly) routes into
|
|
10
|
+
// that entry. Pointers reference channel-exec by IN-PACKAGE ABSOLUTE PATH —
|
|
11
|
+
// no PATH lookup, no dependence on agent-writable install state; the engine
|
|
12
|
+
// ships atomically with the bridge.
|
|
13
|
+
//
|
|
14
|
+
// Revocation keeps the pointer in place (nothing to remove): the pointer's
|
|
15
|
+
// content is independent of grant state, and revocation semantics are
|
|
16
|
+
// enforced by the platform mint endpoint (403 with an agent-readable
|
|
17
|
+
// message). Deleting would let PATH fall through to a directly-installed
|
|
18
|
+
// real CLI past the mint gate — the failure mode the old deny-stub existed
|
|
19
|
+
// to prevent; a constant pointer prevents it structurally.
|
|
20
|
+
// Design: docs/engineering-design/agent-capability-fragments-design.md §5.1.
|
|
21
|
+
export const CAPABILITY_FEISHU_CLI = 'feishu-cli';
|
|
22
|
+
// Marker embedded in every generated pointer. channel-exec skips any PATH
|
|
23
|
+
// candidate whose head carries it, so a pointer (or a stray copy of one) can
|
|
24
|
+
// never be mistaken for the real vendor binary — self-recursion is
|
|
25
|
+
// structurally impossible even if the skip-dir hint is wrong.
|
|
26
|
+
export const CHANNEL_POINTER_MAGIC = 'parall channel capability pointer';
|
|
27
|
+
// SSOT for the shim directory: bridges prepend this to the child PATH once,
|
|
28
|
+
// unconditionally — the directory is constant, its content tracks grants, so
|
|
29
|
+
// a grant reaches even long-lived subprocesses (the shell re-resolves PATH
|
|
30
|
+
// per command) without any respawn.
|
|
31
|
+
export function capabilityBinDir(stateDir) {
|
|
32
|
+
return path.join(stateDir, 'bin');
|
|
33
|
+
}
|
|
34
|
+
// Absolute path of the channel-exec entry, resolved across BOTH distribution
|
|
35
|
+
// layouts — mirroring the daemon's resolveBbBrowserDaemonPath:
|
|
36
|
+
// - npm / hosted image: agent-core's dist tree exists on disk →
|
|
37
|
+
// ./bin/channel-exec.js sits under this module's dir.
|
|
38
|
+
// - standalone bundle (@parall/daemon / CDN self-update / desktop): esbuild
|
|
39
|
+
// flattens this module INTO bundle/parall-claude-agent.js, so ./bin/…
|
|
40
|
+
// doesn't exist; the bundle ships parall-channel-exec.js as a sibling flat
|
|
41
|
+
// artifact (scripts/bundle-daemon.mjs), resolved next to this file.
|
|
42
|
+
// Prefer the sibling (bundle) and fall through to the in-package path (dev /
|
|
43
|
+
// npm), like the bb-browser resolver — the two candidates are mutually
|
|
44
|
+
// exclusive so order only affects which stat wins in the impossible case that
|
|
45
|
+
// both exist.
|
|
46
|
+
export function channelExecEntryPath() {
|
|
47
|
+
const selfDir = path.dirname(fileURLToPath(import.meta.url));
|
|
48
|
+
const sibling = path.join(selfDir, 'parall-channel-exec.js');
|
|
49
|
+
if (fs.existsSync(sibling))
|
|
50
|
+
return sibling;
|
|
51
|
+
return fileURLToPath(new URL('./bin/channel-exec.js', import.meta.url));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Idempotently reconcile local capability pointers with the delivered
|
|
55
|
+
* capability list. Call at boot (after the first config fetch) and on every
|
|
56
|
+
* config refresh. Never throws — a pointer write failure must not take down
|
|
57
|
+
* a config refresh (the capability simply stays unusable until the next pass).
|
|
58
|
+
*/
|
|
59
|
+
export function materializeChannelCapabilities(stateDir, capabilities, log) {
|
|
60
|
+
try {
|
|
61
|
+
reconcileFeishuCli(stateDir, capabilities, log);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
log?.warn(`channel capability materialization failed: ${String(err)}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function reconcileFeishuCli(stateDir, capabilities, log) {
|
|
68
|
+
const binDir = capabilityBinDir(stateDir);
|
|
69
|
+
const posixPath = path.join(binDir, 'lark-cli');
|
|
70
|
+
const granted = capabilities.some((c) => c.key === CAPABILITY_FEISHU_CLI);
|
|
71
|
+
const hadPointer = fs.existsSync(posixPath);
|
|
72
|
+
// Write/refresh pointers when GRANTED, or when a pointer already exists (a
|
|
73
|
+
// previously-granted, now-revoked agent). The refresh-on-revoke case is
|
|
74
|
+
// load-bearing for bundle self-update: the pointer embeds channel-exec's
|
|
75
|
+
// ABSOLUTE path, which resolves through the daemon's `current` symlink into
|
|
76
|
+
// a versioned dir; after an upgrade prunes the old version, a stale retained
|
|
77
|
+
// pointer would fail MODULE_NOT_FOUND instead of reaching the mint 403.
|
|
78
|
+
// Re-rendering every pass keeps the pointer aimed at the LIVE channel-exec,
|
|
79
|
+
// so a revoked agent still gets the self-explanatory 403. A NEVER-granted
|
|
80
|
+
// agent (no pointer) is left untouched — the operator's own lark-cli install
|
|
81
|
+
// stays clean.
|
|
82
|
+
if (!granted && !hadPointer)
|
|
83
|
+
return;
|
|
84
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
85
|
+
const entry = channelExecEntryPath();
|
|
86
|
+
// The node binary is referenced by ABSOLUTE path (process.execPath), not the
|
|
87
|
+
// bare name `node`: packaged installs (desktop / daemon bundle) embed the
|
|
88
|
+
// runtime as `parall-node` with no plain `node` on PATH, so a bare `node`
|
|
89
|
+
// would die before channel-exec ever runs and break bundle parity at the
|
|
90
|
+
// last hop. process.execPath is the very node currently running the bridge —
|
|
91
|
+
// the parall-node in a bundle, the system node under npm.
|
|
92
|
+
const nodeExec = process.execPath;
|
|
93
|
+
writePointerIfChanged(posixPath, renderPosixPointer(nodeExec, entry, binDir, 'feishu'), log);
|
|
94
|
+
// Windows companion: cmd/PowerShell resolve executables via PATHEXT and
|
|
95
|
+
// ignore extensionless shebang files. (The agent's own Bash tool on Windows
|
|
96
|
+
// is git-bash, which uses the sh pointer above — the .cmd is the cmd/
|
|
97
|
+
// PowerShell fallback; its %* follows standard batch semantics, same as any
|
|
98
|
+
// npm-installed .cmd bin.)
|
|
99
|
+
writePointerIfChanged(path.join(binDir, 'lark-cli.cmd'), renderCmdPointer(nodeExec, entry, binDir, 'feishu'), log);
|
|
100
|
+
}
|
|
101
|
+
function writePointerIfChanged(filePath, content, log) {
|
|
102
|
+
let existing = null;
|
|
103
|
+
try {
|
|
104
|
+
existing = fs.readFileSync(filePath, 'utf8');
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
existing = null;
|
|
108
|
+
}
|
|
109
|
+
if (existing !== content) {
|
|
110
|
+
fs.writeFileSync(filePath, content, { mode: 0o755 });
|
|
111
|
+
log?.info(`channel capability: pointer materialized (${path.basename(filePath)})`);
|
|
112
|
+
}
|
|
113
|
+
// Mode is enforced even when content is unchanged (a prior partial write
|
|
114
|
+
// or umask drift must not leave the pointer non-executable).
|
|
115
|
+
fs.chmodSync(filePath, 0o755);
|
|
116
|
+
}
|
|
117
|
+
// Pointer content is versioned HERE (never delivered by the server — config
|
|
118
|
+
// carries declarations, not code). It embeds the entry's AND the bin dir's
|
|
119
|
+
// absolute paths at write time — no $(dirname)/external commands (a minimal
|
|
120
|
+
// PATH must not break the pointer), and the skip hint cannot drift. A
|
|
121
|
+
// package upgrade that moves paths changes the rendered content, and the
|
|
122
|
+
// boot-time materialize pass rewrites it (self-healing).
|
|
123
|
+
// The target binary is NOT passed on the command line — channel-exec derives
|
|
124
|
+
// it from the channel (feishu → lark-cli), so a caller cannot redirect the
|
|
125
|
+
// minted token to a different program. binDir is still passed as the skip hint.
|
|
126
|
+
export function renderPosixPointer(nodeExecPath, entryJsPath, binDir, channel) {
|
|
127
|
+
return [
|
|
128
|
+
'#!/bin/sh',
|
|
129
|
+
`# Generated by @parall/agent-core — ${CHANNEL_POINTER_MAGIC} (do not edit).`,
|
|
130
|
+
'# Credential + exec logic lives in the agent-core package; revocation is',
|
|
131
|
+
'# enforced by the platform mint endpoint, so this pointer stays constant.',
|
|
132
|
+
// Strip Node preload-hijack vars BEFORE launching node: NODE_OPTIONS
|
|
133
|
+
// (e.g. --require=/evil.js) and NODE_PATH would execute caller-supplied code
|
|
134
|
+
// at interpreter startup — BEFORE channel-exec's own env scrub, i.e. before
|
|
135
|
+
// the mint. The pointer is a platform-authored trust-boundary artifact whose
|
|
136
|
+
// whole job is a CONTROLLED launch of the broker (absolute node, magic
|
|
137
|
+
// guard, skip-dir); this closes the same env-hijack class for node startup
|
|
138
|
+
// that the absolute node path closes for PATH, keeping the launch deterministic.
|
|
139
|
+
'unset NODE_OPTIONS NODE_PATH',
|
|
140
|
+
// "$@" preserves argv exactly (this is the agent's main path via git-bash).
|
|
141
|
+
`exec "${nodeExecPath}" "${entryJsPath}" --channel ${channel} --skip-dir "${binDir}" -- "$@"`,
|
|
142
|
+
'',
|
|
143
|
+
].join('\n');
|
|
144
|
+
}
|
|
145
|
+
export function renderCmdPointer(nodeExecPath, entryJsPath, binDir, channel) {
|
|
146
|
+
return [
|
|
147
|
+
'@echo off',
|
|
148
|
+
`rem Generated by @parall/agent-core - ${CHANNEL_POINTER_MAGIC} (do not edit).`,
|
|
149
|
+
// Clear Node preload-hijack vars before launching node (see the sh pointer).
|
|
150
|
+
'set "NODE_OPTIONS="',
|
|
151
|
+
'set "NODE_PATH="',
|
|
152
|
+
`"${nodeExecPath}" "${entryJsPath}" --channel ${channel} --skip-dir "${binDir}" -- %*`,
|
|
153
|
+
'',
|
|
154
|
+
].join('\r\n');
|
|
155
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface MintedChannelToken {
|
|
2
|
+
channel_type: string;
|
|
3
|
+
token_type: string;
|
|
4
|
+
app_id: string;
|
|
5
|
+
brand: string;
|
|
6
|
+
token: string;
|
|
7
|
+
expires_at: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class ChannelTokenError extends Error {
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Exchange the agent's channel grant for a short-lived provider token.
|
|
13
|
+
* Deliberately NO local caching at any layer here: the parall round trip is
|
|
14
|
+
* tens of ms (the expensive vendor exchange is absorbed by the server-side
|
|
15
|
+
* Redis cache), and every call re-passing the server gate is what makes
|
|
16
|
+
* revocation and re-credentialing bite on the very next invocation.
|
|
17
|
+
*/
|
|
18
|
+
export declare function mintChannelToken(channelType: string, env: NodeJS.ProcessEnv): Promise<MintedChannelToken>;
|
|
19
|
+
//# sourceMappingURL=channel-token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel-token.d.ts","sourceRoot":"","sources":["../src/channel-token.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAID,qBAAa,iBAAkB,SAAQ,KAAK;CAAG;AAI/C;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,OAAO,CAAC,kBAAkB,CAAC,CA2D7B"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Channel-capability credential client — the ONE place that talks to the
|
|
2
|
+
// platform mint endpoint. Consumed today by the short-lived exec form
|
|
3
|
+
// (bin/channel-exec.ts); the future resident forms (proxy / mcp, hosted by
|
|
4
|
+
// the bridge process) reuse this module so swimlane routing, error
|
|
5
|
+
// presentation, and any future retry/telemetry policy stay single-sourced.
|
|
6
|
+
// Design: docs/engineering-design/agent-capability-fragments-design.md §5.
|
|
7
|
+
// Thrown for every mint failure; `message` is written for the AGENT to read
|
|
8
|
+
// (and relay to the user when the platform says the capability is revoked).
|
|
9
|
+
export class ChannelTokenError extends Error {
|
|
10
|
+
}
|
|
11
|
+
const MINT_TIMEOUT_MS = 10_000;
|
|
12
|
+
/**
|
|
13
|
+
* Exchange the agent's channel grant for a short-lived provider token.
|
|
14
|
+
* Deliberately NO local caching at any layer here: the parall round trip is
|
|
15
|
+
* tens of ms (the expensive vendor exchange is absorbed by the server-side
|
|
16
|
+
* Redis cache), and every call re-passing the server gate is what makes
|
|
17
|
+
* revocation and re-credentialing bite on the very next invocation.
|
|
18
|
+
*/
|
|
19
|
+
export async function mintChannelToken(channelType, env) {
|
|
20
|
+
const apiUrl = (env.PRLL_API_URL || '').replace(/\/+$/, '');
|
|
21
|
+
const apiKey = env.PRLL_API_KEY || '';
|
|
22
|
+
const orgId = env.PRLL_ORG_ID || '';
|
|
23
|
+
if (!apiUrl || !apiKey || !orgId) {
|
|
24
|
+
throw new ChannelTokenError('PRLL_API_URL/PRLL_API_KEY/PRLL_ORG_ID missing from the environment');
|
|
25
|
+
}
|
|
26
|
+
const headers = {
|
|
27
|
+
'Content-Type': 'application/json',
|
|
28
|
+
Authorization: `Bearer ${apiKey}`,
|
|
29
|
+
};
|
|
30
|
+
// Swimlane routing must ride the mint request exactly like every SDK call —
|
|
31
|
+
// a bridge deployed in a PR swimlane mints against its own API/DB.
|
|
32
|
+
const swimlane = (env.PRLL_SWIMLANE_NAME || '').trim();
|
|
33
|
+
if (swimlane)
|
|
34
|
+
headers['X-Prll-Swimlane'] = swimlane;
|
|
35
|
+
const controller = new AbortController();
|
|
36
|
+
const timer = setTimeout(() => controller.abort(), MINT_TIMEOUT_MS);
|
|
37
|
+
let resp;
|
|
38
|
+
try {
|
|
39
|
+
resp = await fetch(`${apiUrl}/api/v1/orgs/${encodeURIComponent(orgId)}/agents/me/channel-token`, {
|
|
40
|
+
method: 'POST',
|
|
41
|
+
headers,
|
|
42
|
+
body: JSON.stringify({ channel_type: channelType }),
|
|
43
|
+
signal: controller.signal,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
throw new ChannelTokenError(`could not reach the Parall platform to authenticate (${String(err)}); channel actions are unavailable right now`);
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
clearTimeout(timer);
|
|
51
|
+
}
|
|
52
|
+
if (!resp.ok) {
|
|
53
|
+
let msg = `platform returned HTTP ${resp.status}`;
|
|
54
|
+
try {
|
|
55
|
+
const body = (await resp.json());
|
|
56
|
+
if (body?.error?.message)
|
|
57
|
+
msg = body.error.message;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// non-JSON error body: keep the status-line message
|
|
61
|
+
}
|
|
62
|
+
throw new ChannelTokenError(msg);
|
|
63
|
+
}
|
|
64
|
+
// Validate every field the caller actually injects into the vendor CLI, not
|
|
65
|
+
// just `token`: a 2xx missing app_id/brand would otherwise launch the real
|
|
66
|
+
// CLI with an incomplete credential env and fail opaquely downstream.
|
|
67
|
+
const minted = (await resp.json());
|
|
68
|
+
const nonEmpty = (v) => typeof v === 'string' && v.length > 0;
|
|
69
|
+
if (!minted || !nonEmpty(minted.token) || !nonEmpty(minted.app_id) || !nonEmpty(minted.brand)) {
|
|
70
|
+
throw new ChannelTokenError('platform returned an unusable token payload');
|
|
71
|
+
}
|
|
72
|
+
return minted;
|
|
73
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-format.d.ts","sourceRoot":"","sources":["../src/event-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAS1D,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAkIzD;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEtE;
|
|
1
|
+
{"version":3,"file":"event-format.d.ts","sourceRoot":"","sources":["../src/event-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAS1D,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAkIzD;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEtE;AAgED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAK/D;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,CAkBnE"}
|
package/dist/event-format.js
CHANGED
|
@@ -174,22 +174,27 @@ function buildSendMessageHint(event) {
|
|
|
174
174
|
return `\n<system-reminder>To communicate, use the CLI: \`parall messages send\` / \`parall dm\`. Your plain text output is not delivered.</system-reminder>`;
|
|
175
175
|
}
|
|
176
176
|
if (event.type === 'channel_message') {
|
|
177
|
-
//
|
|
178
|
-
//
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
177
|
+
// Single-path routing (multi-channel-architecture-design §6): with the
|
|
178
|
+
// `<provider>-cli` capability granted, the vendor CLI on PATH is THE
|
|
179
|
+
// reply path; without it there is no outbound path at all — say so
|
|
180
|
+
// instead of pointing at the retired provider clip.
|
|
181
|
+
// channelCliCapable alone decides: only feishu mints exist today, so a
|
|
182
|
+
// live grant implies Feishu even when the cosmetic provider-label lookup
|
|
183
|
+
// failed (event.channelProvider undefined).
|
|
184
|
+
if (event.channelCliCapable) {
|
|
185
|
+
const convRef = event.channelExternalConversationId
|
|
186
|
+
? `chat_id "${event.channelExternalConversationId}"`
|
|
187
|
+
: 'the conversation id named in this event';
|
|
188
|
+
// Offer the in-thread alternative whenever the inbound message id is
|
|
189
|
+
// known — otherwise the hint nudges every threaded conversation toward
|
|
190
|
+
// a new top-level message.
|
|
191
|
+
const threadAlt = event.channelExternalMessageId
|
|
192
|
+
? ` To reply threaded to this specific message, reference message_id "${event.channelExternalMessageId}".`
|
|
193
|
+
: '';
|
|
194
|
+
return `\n<system-reminder>To reply, use the official Feishu CLI on your PATH: send a message to ${convRef} with \`lark-cli im\` (see \`lark-cli im --help\` for send syntax; auth is provisioned automatically).${threadAlt} lark-cli is the ONLY outbound path — your plain text output is NOT delivered to the external conversation.</system-reminder>`;
|
|
195
|
+
}
|
|
196
|
+
const platform = event.channelProvider ?? 'the external platform';
|
|
197
|
+
return `\n<system-reminder>This message arrived from ${platform}, but outbound replies are currently disabled for this org (no channel capability granted). Do NOT attempt to reply on the external platform. If action is needed, surface it inside Parall (\`parall messages send\` / \`parall dm\`). Your plain text output is not delivered anywhere.</system-reminder>`;
|
|
193
198
|
}
|
|
194
199
|
if (event.type === 'external_trigger' || event.targetId.startsWith('xtr_')) {
|
|
195
200
|
return `\n<system-reminder>This external trigger is incoming-only. Your plain text output is not sent back to the external provider. To communicate in Parall, use \`parall messages send\` / \`parall dm\`; provider-specific outbound actions require a separate capability.</system-reminder>`;
|
package/dist/gateway-base.d.ts
CHANGED
|
@@ -61,6 +61,14 @@ export type ParallGatewayOptions = {
|
|
|
61
61
|
* this directory. Absent → legacy received/ack flow (openclaw / hermes).
|
|
62
62
|
*/
|
|
63
63
|
dispatchContextDir?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Live view of the agent's platform-granted capability keys (bridges wire
|
|
66
|
+
* PlatformConfigManager.capabilities().map(c => c.key)). Read at
|
|
67
|
+
* channel-event build time so the reply hint routes to the capability
|
|
68
|
+
* affordance (e.g. feishu-cli → lark-cli) — the single outbound path.
|
|
69
|
+
* Absent/empty → the hint states outbound is disabled.
|
|
70
|
+
*/
|
|
71
|
+
getCapabilityKeys?: () => string[];
|
|
64
72
|
onConfigUpdate?: (data: AgentConfigUpdateData) => Promise<void> | void;
|
|
65
73
|
onSessionReady?: (state: {
|
|
66
74
|
activeSessionId?: string;
|
|
@@ -86,6 +94,10 @@ export declare class ParallAgentGateway {
|
|
|
86
94
|
private readonly dispatchedTasks;
|
|
87
95
|
private readonly channelConnectionProviders;
|
|
88
96
|
private readonly dispatchedMessages;
|
|
97
|
+
readonly typedRedriveBackoff: Map<string, {
|
|
98
|
+
failures: number;
|
|
99
|
+
until: number;
|
|
100
|
+
}>;
|
|
89
101
|
private readonly forkStates;
|
|
90
102
|
private readonly dispatchState;
|
|
91
103
|
private sessionId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-base.d.ts","sourceRoot":"","sources":["../src/gateway-base.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiC,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,KAAK,EACV,qBAAqB,EAkBtB,MAAM,aAAa,CAAC;AAOrB,OAAO,EAGL,KAAK,eAAe,EAGpB,KAAK,aAAa,EAEnB,MAAM,uBAAuB,CAAC;AAqC/B,OAAO,KAAK,EAAiB,WAAW,EAAE,MAAM,YAAY,CAAC;AAwB7D,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACtC,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAC/B;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,GAC1C;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;AAExB,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,YAAY,CAAC;IACrB,EAAE,EAAE,QAAQ,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE;QACN,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,eAAe,EAAE,eAAe,CAAC;IACjC,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,kGAAkG;IAClG,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAI3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,yBAAyB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACvE,0FAA0F;IAC1F,wBAAwB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACtE;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACvE,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QACvB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,EAAE,EAAE,QAAQ,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;KACpB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3B,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE;QACzB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,gBAAgB,EAAE,MAAM,CAAC;QACzB,cAAc,EAAE,MAAM,CAAC;KACxB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAChD,YAAY,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACnE,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC/D,CAAC;AAkBF,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAKnF;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAK/E;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAKnF;AAsFD,qBAAa,kBAAkB;
|
|
1
|
+
{"version":3,"file":"gateway-base.d.ts","sourceRoot":"","sources":["../src/gateway-base.ts"],"names":[],"mappings":"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"}
|