@foxden-app/foxclaw 0.7.2 → 0.10.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/.env.example +14 -0
- package/CHANGELOG.md +129 -0
- package/README.md +22 -2
- package/README_EN.md +22 -2
- package/dist/antigravity/adapter.d.ts +17 -0
- package/dist/antigravity/adapter.js +256 -0
- package/dist/antigravity/auth.d.ts +121 -0
- package/dist/antigravity/auth.js +896 -0
- package/dist/antigravity/client.d.ts +32 -0
- package/dist/antigravity/client.js +238 -0
- package/dist/antigravity/controller.d.ts +96 -0
- package/dist/antigravity/controller.js +1922 -0
- package/dist/antigravity/conversations.d.ts +29 -0
- package/dist/antigravity/conversations.js +289 -0
- package/dist/antigravity/events.d.ts +101 -0
- package/dist/antigravity/events.js +114 -0
- package/dist/antigravity/runtime.d.ts +47 -0
- package/dist/antigravity/runtime.js +82 -0
- package/dist/auth/cross_node_sync.js +2 -2
- package/dist/channels/telegram/telegram_channel_adapter.d.ts +10 -3
- package/dist/channels/telegram/telegram_channel_adapter.js +2 -1
- package/dist/channels/weixin/weixin_channel_adapter.d.ts +5 -1
- package/dist/codex_app/adapter.d.ts +20 -0
- package/dist/codex_app/adapter.js +213 -0
- package/dist/codex_app/client.d.ts +2 -1
- package/dist/codex_app/client.js +47 -4
- package/dist/codex_app/force_takeover.d.ts +12 -0
- package/dist/codex_app/force_takeover.js +27 -0
- package/dist/config.d.ts +12 -0
- package/dist/config.js +42 -0
- package/dist/controller/controller.d.ts +15 -5
- package/dist/controller/controller.js +252 -20
- package/dist/core/attachments.d.ts +11 -0
- package/dist/core/attachments.js +56 -0
- package/dist/core/engine_spi.d.ts +76 -0
- package/dist/core/engine_spi.js +1 -0
- package/dist/core/orchestrator.d.ts +101 -0
- package/dist/core/orchestrator.js +1404 -0
- package/dist/core/stream_preview.d.ts +29 -0
- package/dist/core/stream_preview.js +146 -0
- package/dist/core/turn_queue.d.ts +19 -0
- package/dist/core/turn_queue.js +41 -0
- package/dist/i18n.d.ts +36 -6
- package/dist/i18n.js +81 -6
- package/dist/main.js +190 -20
- package/dist/opencode/adapter.d.ts +11 -0
- package/dist/opencode/adapter.js +168 -0
- package/dist/store/database.d.ts +41 -0
- package/dist/store/database.js +242 -43
- package/dist/store/token_usage.d.ts +23 -0
- package/dist/store/token_usage.js +61 -0
- package/dist/telegram/api.js +34 -1
- package/dist/telegram/bot_home.d.ts +3 -0
- package/dist/telegram/bot_home.js +107 -0
- package/dist/telegram/gateway.d.ts +5 -0
- package/dist/telegram/gateway.js +21 -0
- package/dist/types.d.ts +1 -0
- package/dist/update.d.ts +6 -0
- package/dist/update.js +78 -6
- package/dist/voice/target.js +2 -1
- package/dist/voice/tts.js +4 -2
- package/docs/devlogs//346/212/200/346/234/257/351/200/232/350/256/257/02./347/273/237/344/270/200/351/200/232/351/201/223/350/260/203/345/272/246/345/231/250/344/270/216/345/217/257/346/217/222/346/213/224/345/274/225/346/223/216SPI/357/274/232FoxClaw/344/273/216/345/215/225/344/275/223/350/265/260/345/220/221/345/244/232Agent/345/272/225/345/272/247.md +192 -0
- package/docs/devlogs//347/254/254/344/270/200/344/272/272/347/247/260/347/211/210/02./347/257/207/344/272/214_/345/275/223/344/270/200/344/270/252/346/241/245/346/216/245/345/231/250/345/274/200/345/247/213/345/255/246/344/274/232/345/220/254/346/207/202/346/211/200/346/234/211Agent.md +45 -0
- package/docs/user-manual.md +11 -1
- package/docs/zh/2026-09-05-bot-home-migration.md +26 -0
- package/docs/zh/2026-09-05-reliability-review.md +53 -0
- package/docs/zh/troubleshooting.md +12 -0
- package/docs/zh/user-manual.md +13 -1
- package/package.json +2 -2
- package/scripts/force-takeover.py +118 -0
- package/scripts/force-takeover.test.py +122 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Logger } from '../logger.js';
|
|
2
|
+
import { type AntigravityBridgeEvent } from './events.js';
|
|
3
|
+
export interface AntigravityTurnOptions {
|
|
4
|
+
prompt: string;
|
|
5
|
+
conversationId?: string | null;
|
|
6
|
+
cwd?: string | null;
|
|
7
|
+
model?: string | null;
|
|
8
|
+
effort?: string | null;
|
|
9
|
+
mode?: string | null;
|
|
10
|
+
}
|
|
11
|
+
export interface AntigravityClientEvents {
|
|
12
|
+
event: [event: AntigravityBridgeEvent];
|
|
13
|
+
exit: [code: number | null, signal: NodeJS.Signals | null];
|
|
14
|
+
error: [error: Error];
|
|
15
|
+
}
|
|
16
|
+
export interface AntigravityTurnExecution {
|
|
17
|
+
conversationId: string | null;
|
|
18
|
+
cancel(): void;
|
|
19
|
+
waitForResult(): Promise<AntigravityBridgeEvent | null>;
|
|
20
|
+
on<E extends keyof AntigravityClientEvents>(event: E, listener: (...args: AntigravityClientEvents[E]) => void): void;
|
|
21
|
+
}
|
|
22
|
+
export declare function normalizeAgyModelId(rawId: string): string;
|
|
23
|
+
export declare class AntigravityAppClient {
|
|
24
|
+
private readonly cliBin;
|
|
25
|
+
private readonly logger;
|
|
26
|
+
private readonly childEnv;
|
|
27
|
+
private cachedModels;
|
|
28
|
+
constructor(cliBin: string, logger?: Logger, childEnv?: NodeJS.ProcessEnv | null);
|
|
29
|
+
get env(): NodeJS.ProcessEnv | null;
|
|
30
|
+
listModels(): Promise<string[]>;
|
|
31
|
+
executeTurn(options: AntigravityTurnOptions): AntigravityTurnExecution;
|
|
32
|
+
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import readline from 'node:readline';
|
|
3
|
+
import { EventEmitter } from 'node:events';
|
|
4
|
+
import { AntigravityEventNormalizer, } from './events.js';
|
|
5
|
+
export function normalizeAgyModelId(rawId) {
|
|
6
|
+
return rawId
|
|
7
|
+
.replace(/-(high|medium|low)$/, '')
|
|
8
|
+
.replace(/-thinking$/, '');
|
|
9
|
+
}
|
|
10
|
+
export class AntigravityAppClient {
|
|
11
|
+
cliBin;
|
|
12
|
+
logger;
|
|
13
|
+
childEnv;
|
|
14
|
+
cachedModels = null;
|
|
15
|
+
constructor(cliBin, logger, childEnv) {
|
|
16
|
+
this.cliBin = cliBin;
|
|
17
|
+
this.logger = logger;
|
|
18
|
+
this.childEnv = childEnv ?? null;
|
|
19
|
+
}
|
|
20
|
+
get env() {
|
|
21
|
+
return this.childEnv;
|
|
22
|
+
}
|
|
23
|
+
async listModels() {
|
|
24
|
+
if (this.cachedModels && this.cachedModels.length > 0) {
|
|
25
|
+
return this.cachedModels;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const child = spawn(this.cliBin, ['models'], {
|
|
29
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
30
|
+
env: this.childEnv ? { ...process.env, ...this.childEnv } : process.env,
|
|
31
|
+
});
|
|
32
|
+
let output = '';
|
|
33
|
+
child.stdout.on('data', (d) => {
|
|
34
|
+
output += d.toString('utf8');
|
|
35
|
+
});
|
|
36
|
+
await new Promise((resolve, reject) => {
|
|
37
|
+
child.on('close', (code) => {
|
|
38
|
+
if (code === 0)
|
|
39
|
+
resolve();
|
|
40
|
+
else
|
|
41
|
+
reject(new Error(`agy models exited with code ${code}`));
|
|
42
|
+
});
|
|
43
|
+
child.on('error', reject);
|
|
44
|
+
});
|
|
45
|
+
const lines = output.split('\n');
|
|
46
|
+
const seen = new Set();
|
|
47
|
+
const models = [];
|
|
48
|
+
for (const line of lines) {
|
|
49
|
+
const trimmed = line.trim();
|
|
50
|
+
if (!trimmed || trimmed.startsWith('⠋') || trimmed.startsWith('Fetching'))
|
|
51
|
+
continue;
|
|
52
|
+
const parts = trimmed.split(/\s+/);
|
|
53
|
+
if (parts[0]) {
|
|
54
|
+
const cleanId = normalizeAgyModelId(parts[0]);
|
|
55
|
+
if (!seen.has(cleanId)) {
|
|
56
|
+
seen.add(cleanId);
|
|
57
|
+
models.push(cleanId);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (models.length > 0) {
|
|
62
|
+
this.cachedModels = models;
|
|
63
|
+
return models;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
this.logger?.warn('antigravity.list_models_failed', {
|
|
68
|
+
error: err instanceof Error ? err.message : String(err),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
// Fallback to standard known models
|
|
72
|
+
return [
|
|
73
|
+
'gemini-3.8-flash',
|
|
74
|
+
'gemini-3.7-flash',
|
|
75
|
+
'gemini-3.6-flash',
|
|
76
|
+
'gemini-3.1-pro',
|
|
77
|
+
'claude-sonnet-4-6',
|
|
78
|
+
'claude-opus-4-6',
|
|
79
|
+
'gpt-oss-120b',
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
executeTurn(options) {
|
|
83
|
+
const emitter = new EventEmitter();
|
|
84
|
+
const normalizer = new AntigravityEventNormalizer();
|
|
85
|
+
const args = [
|
|
86
|
+
'-p',
|
|
87
|
+
'',
|
|
88
|
+
'--input-format',
|
|
89
|
+
'stream-json',
|
|
90
|
+
'--output-format',
|
|
91
|
+
'stream-json',
|
|
92
|
+
'--dangerously-skip-permissions',
|
|
93
|
+
];
|
|
94
|
+
if (options.conversationId) {
|
|
95
|
+
args.push('--conversation', options.conversationId);
|
|
96
|
+
}
|
|
97
|
+
const requestedModel = (!options.model || options.model === 'default') ? 'gemini-3.8-flash' : options.model;
|
|
98
|
+
const baseModel = normalizeAgyModelId(requestedModel);
|
|
99
|
+
let cliModel = baseModel;
|
|
100
|
+
if (baseModel === 'claude-opus-4-6') {
|
|
101
|
+
cliModel = 'claude-opus-4-6-thinking';
|
|
102
|
+
}
|
|
103
|
+
else if (baseModel === 'gpt-oss-120b') {
|
|
104
|
+
cliModel = 'gpt-oss-120b-medium';
|
|
105
|
+
}
|
|
106
|
+
args.push('--model', cliModel);
|
|
107
|
+
// Effort is only passed for models that accept it (Gemini models)
|
|
108
|
+
if (baseModel.startsWith('gemini-')) {
|
|
109
|
+
let effort = options.effort || 'high';
|
|
110
|
+
if (effort === 'xhigh' || effort === 'max' || effort === 'ultra') {
|
|
111
|
+
effort = 'high';
|
|
112
|
+
}
|
|
113
|
+
else if (effort !== 'low' && effort !== 'medium' && effort !== 'high') {
|
|
114
|
+
effort = 'high';
|
|
115
|
+
}
|
|
116
|
+
args.push('--effort', effort);
|
|
117
|
+
}
|
|
118
|
+
if (options.mode) {
|
|
119
|
+
args.push('--mode', options.mode);
|
|
120
|
+
}
|
|
121
|
+
const workingDir = options.cwd || process.cwd();
|
|
122
|
+
this.logger?.info('antigravity.turn.starting', {
|
|
123
|
+
cwd: workingDir,
|
|
124
|
+
conversationId: options.conversationId ?? null,
|
|
125
|
+
model: cliModel,
|
|
126
|
+
});
|
|
127
|
+
let child = spawn(this.cliBin, args, {
|
|
128
|
+
cwd: workingDir,
|
|
129
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
130
|
+
env: this.childEnv ? { ...process.env, ...this.childEnv } : { ...process.env },
|
|
131
|
+
});
|
|
132
|
+
let activeConversationId = options.conversationId ?? null;
|
|
133
|
+
let finalResultEvent = null;
|
|
134
|
+
if (!child.stdin || !child.stdout) {
|
|
135
|
+
throw new Error('Failed to create stdio pipes for Antigravity CLI process');
|
|
136
|
+
}
|
|
137
|
+
// Feed user prompt via stdin
|
|
138
|
+
const inputMsg = JSON.stringify({
|
|
139
|
+
event: 'user',
|
|
140
|
+
message: {
|
|
141
|
+
content: options.prompt,
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
child.stdin.write(inputMsg + '\n');
|
|
145
|
+
child.stdin.end();
|
|
146
|
+
const rl = readline.createInterface({
|
|
147
|
+
input: child.stdout,
|
|
148
|
+
crlfDelay: Infinity,
|
|
149
|
+
});
|
|
150
|
+
rl.on('line', (line) => {
|
|
151
|
+
const trimmed = line.trim();
|
|
152
|
+
if (!trimmed || !trimmed.startsWith('{'))
|
|
153
|
+
return;
|
|
154
|
+
try {
|
|
155
|
+
const parsed = JSON.parse(trimmed);
|
|
156
|
+
if (parsed.event === 'init') {
|
|
157
|
+
activeConversationId = parsed.conversation_id;
|
|
158
|
+
}
|
|
159
|
+
const bridgeEvents = normalizer.accept(parsed);
|
|
160
|
+
for (const ev of bridgeEvents) {
|
|
161
|
+
if (ev.kind === 'result') {
|
|
162
|
+
finalResultEvent = ev;
|
|
163
|
+
}
|
|
164
|
+
emitter.emit('event', ev);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
this.logger?.debug('antigravity.ndjson_parse_error', { line, error: String(e) });
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
let stderrBuffer = '';
|
|
172
|
+
child.stderr?.on('data', (data) => {
|
|
173
|
+
stderrBuffer += data.toString('utf8');
|
|
174
|
+
});
|
|
175
|
+
child.on('error', (err) => {
|
|
176
|
+
this.logger?.error('antigravity.process.error', { error: err.message });
|
|
177
|
+
emitter.emit('error', err);
|
|
178
|
+
});
|
|
179
|
+
child.on('close', (code, signal) => {
|
|
180
|
+
this.logger?.info('antigravity.process.exit', {
|
|
181
|
+
code,
|
|
182
|
+
signal,
|
|
183
|
+
conversationId: activeConversationId,
|
|
184
|
+
stderr: stderrBuffer ? stderrBuffer.slice(-200) : undefined,
|
|
185
|
+
});
|
|
186
|
+
if (!finalResultEvent && code !== 0) {
|
|
187
|
+
const errorMsg = stderrBuffer.trim() || `Process exited with code ${code}${signal ? ` (${signal})` : ''}`;
|
|
188
|
+
const errResult = {
|
|
189
|
+
kind: 'result',
|
|
190
|
+
conversationId: activeConversationId || '',
|
|
191
|
+
status: 'ERROR',
|
|
192
|
+
response: errorMsg,
|
|
193
|
+
error: errorMsg,
|
|
194
|
+
durationSeconds: 0,
|
|
195
|
+
};
|
|
196
|
+
finalResultEvent = errResult;
|
|
197
|
+
emitter.emit('event', errResult);
|
|
198
|
+
}
|
|
199
|
+
emitter.emit('exit', code, signal);
|
|
200
|
+
child = null;
|
|
201
|
+
});
|
|
202
|
+
const execution = {
|
|
203
|
+
get conversationId() {
|
|
204
|
+
return activeConversationId;
|
|
205
|
+
},
|
|
206
|
+
cancel() {
|
|
207
|
+
if (child && !child.killed) {
|
|
208
|
+
child.kill('SIGINT');
|
|
209
|
+
setTimeout(() => {
|
|
210
|
+
if (child && !child.killed) {
|
|
211
|
+
child.kill('SIGKILL');
|
|
212
|
+
}
|
|
213
|
+
}, 2000).unref();
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
waitForResult() {
|
|
217
|
+
return new Promise((resolve) => {
|
|
218
|
+
if (finalResultEvent) {
|
|
219
|
+
resolve(finalResultEvent);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
emitter.on('event', (ev) => {
|
|
223
|
+
if (ev.kind === 'result') {
|
|
224
|
+
resolve(ev);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
emitter.on('exit', () => {
|
|
228
|
+
resolve(finalResultEvent);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
},
|
|
232
|
+
on(event, listener) {
|
|
233
|
+
emitter.on(event, listener);
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
return execution;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { AppConfig } from '../config.js';
|
|
2
|
+
import { TelegramMessagingPort } from '../channels/telegram/telegram_messaging_port.js';
|
|
3
|
+
import type { Logger } from '../logger.js';
|
|
4
|
+
import type { BridgeStore } from '../store/database.js';
|
|
5
|
+
import type { RuntimeStatus } from '../types.js';
|
|
6
|
+
import type { TelegramGateway, TelegramTextEvent } from '../telegram/gateway.js';
|
|
7
|
+
import { AntigravityAppClient } from './client.js';
|
|
8
|
+
import { AntigravityAuthManager } from './auth.js';
|
|
9
|
+
import { AntigravityEngineAdapter } from './adapter.js';
|
|
10
|
+
import { CodexEngineAdapter } from '../codex_app/adapter.js';
|
|
11
|
+
import type { CodexAppClient, CodexAppServerRuntimeStatus } from '../codex_app/client.js';
|
|
12
|
+
import { OpencodeEngineAdapter } from '../opencode/adapter.js';
|
|
13
|
+
import type { OpencodeAppClient } from '../opencode/client.js';
|
|
14
|
+
import { BridgeSessionCore } from '../controller/controller.js';
|
|
15
|
+
export interface UnifiedBridgeRuntimeStatus {
|
|
16
|
+
running: boolean;
|
|
17
|
+
connected: boolean;
|
|
18
|
+
activeTurns: number;
|
|
19
|
+
botUsername: string | null;
|
|
20
|
+
codexHome: string;
|
|
21
|
+
codexAppServer?: CodexAppServerRuntimeStatus | undefined;
|
|
22
|
+
userAgent: string | null;
|
|
23
|
+
authProactiveRefresh?: RuntimeStatus['authProactiveRefresh'];
|
|
24
|
+
lastError?: string | null | undefined;
|
|
25
|
+
}
|
|
26
|
+
export interface UnifiedBridgeCoreOptions {
|
|
27
|
+
codexApp?: CodexAppClient | undefined;
|
|
28
|
+
codexAdapter?: CodexEngineAdapter | undefined;
|
|
29
|
+
codexCore?: BridgeSessionCore | undefined;
|
|
30
|
+
antigravityApp?: AntigravityAppClient | undefined;
|
|
31
|
+
antigravityAuth?: AntigravityAuthManager | undefined;
|
|
32
|
+
antigravityAdapter?: AntigravityEngineAdapter | undefined;
|
|
33
|
+
opencodeApp?: OpencodeAppClient | undefined;
|
|
34
|
+
opencodeAdapter?: OpencodeEngineAdapter | undefined;
|
|
35
|
+
defaultBackendId?: 'antigravity' | 'codex' | 'opencode' | string | undefined;
|
|
36
|
+
}
|
|
37
|
+
export declare class UnifiedBridgeCore {
|
|
38
|
+
private readonly config;
|
|
39
|
+
private readonly store;
|
|
40
|
+
private readonly logger;
|
|
41
|
+
private readonly bot;
|
|
42
|
+
private readonly app;
|
|
43
|
+
private readonly auth;
|
|
44
|
+
private readonly conversations;
|
|
45
|
+
private readonly messaging;
|
|
46
|
+
private readonly adapter;
|
|
47
|
+
private readonly codexAdapter?;
|
|
48
|
+
private readonly codexApp?;
|
|
49
|
+
readonly codexCore?: BridgeSessionCore | undefined;
|
|
50
|
+
private readonly opencodeAdapter?;
|
|
51
|
+
private readonly defaultBackendId;
|
|
52
|
+
private readonly orchestrator;
|
|
53
|
+
private readonly watchers;
|
|
54
|
+
private readonly pendingAgyRenames;
|
|
55
|
+
private readonly stalePanelDeleteTimers;
|
|
56
|
+
constructor(config: AppConfig, store: BridgeStore, logger: Logger, bot: TelegramGateway, app?: AntigravityAppClient | undefined, auth?: AntigravityAuthManager | undefined, messaging?: TelegramMessagingPort | undefined, options?: UnifiedBridgeCoreOptions);
|
|
57
|
+
private getBackendDescriptors;
|
|
58
|
+
registerInboundHandlers(): void;
|
|
59
|
+
registerTelegramInboundHandlers(): void;
|
|
60
|
+
dispatchInboundLikeTelegramText(event: TelegramTextEvent): void;
|
|
61
|
+
startCodexApp(): Promise<void>;
|
|
62
|
+
startTelegramPolling(): Promise<void>;
|
|
63
|
+
start(): Promise<void>;
|
|
64
|
+
stop(): Promise<void>;
|
|
65
|
+
getRuntimeStatus(): UnifiedBridgeRuntimeStatus;
|
|
66
|
+
isIdleForServiceUpdate(): boolean;
|
|
67
|
+
getCurrentAuthLabel(): Promise<string | null>;
|
|
68
|
+
handleExternalCodexAuthCandidateDeleted(candidateName: string, _reason?: string | null): Promise<void>;
|
|
69
|
+
validateExternalCodexAuthCandidate(_candidateName: string, _rawAuth: string, _expectedAccountId: string): Promise<{
|
|
70
|
+
ok: boolean;
|
|
71
|
+
reason?: string | null;
|
|
72
|
+
}>;
|
|
73
|
+
private sendMessage;
|
|
74
|
+
private editMessage;
|
|
75
|
+
scheduleStalePanelDeletion(scopeId: string, messageId: number): void;
|
|
76
|
+
private renderCustomStatus;
|
|
77
|
+
private renderCustomSetupRows;
|
|
78
|
+
private handleCustomInbound;
|
|
79
|
+
private handleCustomCommand;
|
|
80
|
+
private handleCustomCallback;
|
|
81
|
+
private sendThreadsPanel;
|
|
82
|
+
private openThread;
|
|
83
|
+
private sendCodexAuthMenu;
|
|
84
|
+
private switchCodexAccount;
|
|
85
|
+
private sendCodexThreadsMenu;
|
|
86
|
+
private openCodexThread;
|
|
87
|
+
private watchConversation;
|
|
88
|
+
private unwatchConversation;
|
|
89
|
+
private scheduleWatcherPoll;
|
|
90
|
+
private pollWatcher;
|
|
91
|
+
private handleWatcherTranscriptEntry;
|
|
92
|
+
private sendAuthMenu;
|
|
93
|
+
private startLoginFlow;
|
|
94
|
+
private sendEffortMenu;
|
|
95
|
+
}
|
|
96
|
+
export { UnifiedBridgeCore as AntigravityBridgeCore };
|