@agent-relay/cloud 0.1.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/api/admin.d.ts +8 -0
- package/dist/api/admin.d.ts.map +1 -0
- package/dist/api/admin.js +225 -0
- package/dist/api/admin.js.map +1 -0
- package/dist/api/auth.d.ts +20 -0
- package/dist/api/auth.d.ts.map +1 -0
- package/dist/api/auth.js +136 -0
- package/dist/api/auth.js.map +1 -0
- package/dist/api/billing.d.ts +7 -0
- package/dist/api/billing.d.ts.map +1 -0
- package/dist/api/billing.js +564 -0
- package/dist/api/billing.js.map +1 -0
- package/dist/api/cli-pty-runner.d.ts +53 -0
- package/dist/api/cli-pty-runner.d.ts.map +1 -0
- package/dist/api/cli-pty-runner.js +193 -0
- package/dist/api/cli-pty-runner.js.map +1 -0
- package/dist/api/codex-auth-helper.d.ts +21 -0
- package/dist/api/codex-auth-helper.d.ts.map +1 -0
- package/dist/api/codex-auth-helper.js +327 -0
- package/dist/api/codex-auth-helper.js.map +1 -0
- package/dist/api/consensus.d.ts +13 -0
- package/dist/api/consensus.d.ts.map +1 -0
- package/dist/api/consensus.js +261 -0
- package/dist/api/consensus.js.map +1 -0
- package/dist/api/coordinators.d.ts +8 -0
- package/dist/api/coordinators.d.ts.map +1 -0
- package/dist/api/coordinators.js +750 -0
- package/dist/api/coordinators.js.map +1 -0
- package/dist/api/daemons.d.ts +12 -0
- package/dist/api/daemons.d.ts.map +1 -0
- package/dist/api/daemons.js +535 -0
- package/dist/api/daemons.js.map +1 -0
- package/dist/api/generic-webhooks.d.ts +8 -0
- package/dist/api/generic-webhooks.d.ts.map +1 -0
- package/dist/api/generic-webhooks.js +129 -0
- package/dist/api/generic-webhooks.js.map +1 -0
- package/dist/api/git.d.ts +8 -0
- package/dist/api/git.d.ts.map +1 -0
- package/dist/api/git.js +269 -0
- package/dist/api/git.js.map +1 -0
- package/dist/api/github-app.d.ts +11 -0
- package/dist/api/github-app.d.ts.map +1 -0
- package/dist/api/github-app.js +223 -0
- package/dist/api/github-app.js.map +1 -0
- package/dist/api/middleware/planLimits.d.ts +43 -0
- package/dist/api/middleware/planLimits.d.ts.map +1 -0
- package/dist/api/middleware/planLimits.js +202 -0
- package/dist/api/middleware/planLimits.js.map +1 -0
- package/dist/api/monitoring.d.ts +11 -0
- package/dist/api/monitoring.d.ts.map +1 -0
- package/dist/api/monitoring.js +578 -0
- package/dist/api/monitoring.js.map +1 -0
- package/dist/api/nango-auth.d.ts +9 -0
- package/dist/api/nango-auth.d.ts.map +1 -0
- package/dist/api/nango-auth.js +674 -0
- package/dist/api/nango-auth.js.map +1 -0
- package/dist/api/onboarding.d.ts +15 -0
- package/dist/api/onboarding.d.ts.map +1 -0
- package/dist/api/onboarding.js +679 -0
- package/dist/api/onboarding.js.map +1 -0
- package/dist/api/policy.d.ts +8 -0
- package/dist/api/policy.d.ts.map +1 -0
- package/dist/api/policy.js +229 -0
- package/dist/api/policy.js.map +1 -0
- package/dist/api/provider-env.d.ts +14 -0
- package/dist/api/provider-env.d.ts.map +1 -0
- package/dist/api/provider-env.js +75 -0
- package/dist/api/provider-env.js.map +1 -0
- package/dist/api/providers.d.ts +7 -0
- package/dist/api/providers.d.ts.map +1 -0
- package/dist/api/providers.js +564 -0
- package/dist/api/providers.js.map +1 -0
- package/dist/api/repos.d.ts +8 -0
- package/dist/api/repos.d.ts.map +1 -0
- package/dist/api/repos.js +577 -0
- package/dist/api/repos.js.map +1 -0
- package/dist/api/sessions.d.ts +11 -0
- package/dist/api/sessions.d.ts.map +1 -0
- package/dist/api/sessions.js +302 -0
- package/dist/api/sessions.js.map +1 -0
- package/dist/api/teams.d.ts +7 -0
- package/dist/api/teams.d.ts.map +1 -0
- package/dist/api/teams.js +281 -0
- package/dist/api/teams.js.map +1 -0
- package/dist/api/test-helpers.d.ts +10 -0
- package/dist/api/test-helpers.d.ts.map +1 -0
- package/dist/api/test-helpers.js +745 -0
- package/dist/api/test-helpers.js.map +1 -0
- package/dist/api/usage.d.ts +7 -0
- package/dist/api/usage.d.ts.map +1 -0
- package/dist/api/usage.js +111 -0
- package/dist/api/usage.js.map +1 -0
- package/dist/api/webhooks.d.ts +8 -0
- package/dist/api/webhooks.d.ts.map +1 -0
- package/dist/api/webhooks.js +645 -0
- package/dist/api/webhooks.js.map +1 -0
- package/dist/api/workspaces.d.ts +25 -0
- package/dist/api/workspaces.d.ts.map +1 -0
- package/dist/api/workspaces.js +1799 -0
- package/dist/api/workspaces.js.map +1 -0
- package/dist/billing/index.d.ts +9 -0
- package/dist/billing/index.d.ts.map +1 -0
- package/dist/billing/index.js +9 -0
- package/dist/billing/index.js.map +1 -0
- package/dist/billing/plans.d.ts +39 -0
- package/dist/billing/plans.d.ts.map +1 -0
- package/dist/billing/plans.js +245 -0
- package/dist/billing/plans.js.map +1 -0
- package/dist/billing/service.d.ts +80 -0
- package/dist/billing/service.d.ts.map +1 -0
- package/dist/billing/service.js +388 -0
- package/dist/billing/service.js.map +1 -0
- package/dist/billing/types.d.ts +141 -0
- package/dist/billing/types.d.ts.map +1 -0
- package/dist/billing/types.js +7 -0
- package/dist/billing/types.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +5 -0
- package/dist/config.js.map +1 -0
- package/dist/db/bulk-ingest.d.ts +89 -0
- package/dist/db/bulk-ingest.d.ts.map +1 -0
- package/dist/db/bulk-ingest.js +268 -0
- package/dist/db/bulk-ingest.js.map +1 -0
- package/dist/db/drizzle.d.ts +256 -0
- package/dist/db/drizzle.d.ts.map +1 -0
- package/dist/db/drizzle.js +1286 -0
- package/dist/db/drizzle.js.map +1 -0
- package/dist/db/index.d.ts +55 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +68 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema.d.ts +4873 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +620 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/provisioner/index.d.ts +207 -0
- package/dist/provisioner/index.d.ts.map +1 -0
- package/dist/provisioner/index.js +2114 -0
- package/dist/provisioner/index.js.map +1 -0
- package/dist/server.d.ts +17 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +1924 -0
- package/dist/server.js.map +1 -0
- package/dist/services/auto-scaler.d.ts +152 -0
- package/dist/services/auto-scaler.d.ts.map +1 -0
- package/dist/services/auto-scaler.js +439 -0
- package/dist/services/auto-scaler.js.map +1 -0
- package/dist/services/capacity-manager.d.ts +148 -0
- package/dist/services/capacity-manager.d.ts.map +1 -0
- package/dist/services/capacity-manager.js +449 -0
- package/dist/services/capacity-manager.js.map +1 -0
- package/dist/services/ci-agent-spawner.d.ts +49 -0
- package/dist/services/ci-agent-spawner.d.ts.map +1 -0
- package/dist/services/ci-agent-spawner.js +373 -0
- package/dist/services/ci-agent-spawner.js.map +1 -0
- package/dist/services/cloud-message-bus.d.ts +28 -0
- package/dist/services/cloud-message-bus.d.ts.map +1 -0
- package/dist/services/cloud-message-bus.js +19 -0
- package/dist/services/cloud-message-bus.js.map +1 -0
- package/dist/services/compute-enforcement.d.ts +57 -0
- package/dist/services/compute-enforcement.d.ts.map +1 -0
- package/dist/services/compute-enforcement.js +175 -0
- package/dist/services/compute-enforcement.js.map +1 -0
- package/dist/services/coordinator.d.ts +62 -0
- package/dist/services/coordinator.d.ts.map +1 -0
- package/dist/services/coordinator.js +389 -0
- package/dist/services/coordinator.js.map +1 -0
- package/dist/services/index.d.ts +17 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +25 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/intro-expiration.d.ts +60 -0
- package/dist/services/intro-expiration.d.ts.map +1 -0
- package/dist/services/intro-expiration.js +252 -0
- package/dist/services/intro-expiration.js.map +1 -0
- package/dist/services/mention-handler.d.ts +65 -0
- package/dist/services/mention-handler.d.ts.map +1 -0
- package/dist/services/mention-handler.js +405 -0
- package/dist/services/mention-handler.js.map +1 -0
- package/dist/services/nango.d.ts +201 -0
- package/dist/services/nango.d.ts.map +1 -0
- package/dist/services/nango.js +392 -0
- package/dist/services/nango.js.map +1 -0
- package/dist/services/persistence.d.ts +131 -0
- package/dist/services/persistence.d.ts.map +1 -0
- package/dist/services/persistence.js +200 -0
- package/dist/services/persistence.js.map +1 -0
- package/dist/services/planLimits.d.ts +147 -0
- package/dist/services/planLimits.d.ts.map +1 -0
- package/dist/services/planLimits.js +335 -0
- package/dist/services/planLimits.js.map +1 -0
- package/dist/services/presence-registry.d.ts +56 -0
- package/dist/services/presence-registry.d.ts.map +1 -0
- package/dist/services/presence-registry.js +91 -0
- package/dist/services/presence-registry.js.map +1 -0
- package/dist/services/scaling-orchestrator.d.ts +159 -0
- package/dist/services/scaling-orchestrator.d.ts.map +1 -0
- package/dist/services/scaling-orchestrator.js +502 -0
- package/dist/services/scaling-orchestrator.js.map +1 -0
- package/dist/services/scaling-policy.d.ts +121 -0
- package/dist/services/scaling-policy.d.ts.map +1 -0
- package/dist/services/scaling-policy.js +415 -0
- package/dist/services/scaling-policy.js.map +1 -0
- package/dist/services/ssh-security.d.ts +31 -0
- package/dist/services/ssh-security.d.ts.map +1 -0
- package/dist/services/ssh-security.js +63 -0
- package/dist/services/ssh-security.js.map +1 -0
- package/dist/services/workspace-keepalive.d.ts +76 -0
- package/dist/services/workspace-keepalive.d.ts.map +1 -0
- package/dist/services/workspace-keepalive.js +234 -0
- package/dist/services/workspace-keepalive.js.map +1 -0
- package/dist/shims/consensus.d.ts +23 -0
- package/dist/shims/consensus.d.ts.map +1 -0
- package/dist/shims/consensus.js +5 -0
- package/dist/shims/consensus.js.map +1 -0
- package/dist/webhooks/index.d.ts +24 -0
- package/dist/webhooks/index.d.ts.map +1 -0
- package/dist/webhooks/index.js +29 -0
- package/dist/webhooks/index.js.map +1 -0
- package/dist/webhooks/parsers/github.d.ts +8 -0
- package/dist/webhooks/parsers/github.d.ts.map +1 -0
- package/dist/webhooks/parsers/github.js +234 -0
- package/dist/webhooks/parsers/github.js.map +1 -0
- package/dist/webhooks/parsers/index.d.ts +23 -0
- package/dist/webhooks/parsers/index.d.ts.map +1 -0
- package/dist/webhooks/parsers/index.js +30 -0
- package/dist/webhooks/parsers/index.js.map +1 -0
- package/dist/webhooks/parsers/linear.d.ts +9 -0
- package/dist/webhooks/parsers/linear.d.ts.map +1 -0
- package/dist/webhooks/parsers/linear.js +258 -0
- package/dist/webhooks/parsers/linear.js.map +1 -0
- package/dist/webhooks/parsers/slack.d.ts +9 -0
- package/dist/webhooks/parsers/slack.d.ts.map +1 -0
- package/dist/webhooks/parsers/slack.js +214 -0
- package/dist/webhooks/parsers/slack.js.map +1 -0
- package/dist/webhooks/responders/github.d.ts +8 -0
- package/dist/webhooks/responders/github.d.ts.map +1 -0
- package/dist/webhooks/responders/github.js +73 -0
- package/dist/webhooks/responders/github.js.map +1 -0
- package/dist/webhooks/responders/index.d.ts +23 -0
- package/dist/webhooks/responders/index.d.ts.map +1 -0
- package/dist/webhooks/responders/index.js +30 -0
- package/dist/webhooks/responders/index.js.map +1 -0
- package/dist/webhooks/responders/linear.d.ts +9 -0
- package/dist/webhooks/responders/linear.d.ts.map +1 -0
- package/dist/webhooks/responders/linear.js +149 -0
- package/dist/webhooks/responders/linear.js.map +1 -0
- package/dist/webhooks/responders/slack.d.ts +20 -0
- package/dist/webhooks/responders/slack.d.ts.map +1 -0
- package/dist/webhooks/responders/slack.js +178 -0
- package/dist/webhooks/responders/slack.js.map +1 -0
- package/dist/webhooks/router.d.ts +25 -0
- package/dist/webhooks/router.d.ts.map +1 -0
- package/dist/webhooks/router.js +504 -0
- package/dist/webhooks/router.js.map +1 -0
- package/dist/webhooks/rules-engine.d.ts +24 -0
- package/dist/webhooks/rules-engine.d.ts.map +1 -0
- package/dist/webhooks/rules-engine.js +287 -0
- package/dist/webhooks/rules-engine.js.map +1 -0
- package/dist/webhooks/types.d.ts +186 -0
- package/dist/webhooks/types.d.ts.map +1 -0
- package/dist/webhooks/types.js +8 -0
- package/dist/webhooks/types.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI PTY Runner
|
|
3
|
+
*
|
|
4
|
+
* Shared module for running CLI auth flows via PTY.
|
|
5
|
+
* Used by both production (onboarding.ts) and tests (ci-test-real-clis.ts).
|
|
6
|
+
*
|
|
7
|
+
* Uses the relay-pty Rust binary for PTY emulation.
|
|
8
|
+
*/
|
|
9
|
+
import { spawn } from 'node:child_process';
|
|
10
|
+
import { existsSync } from 'node:fs';
|
|
11
|
+
import { join, dirname } from 'node:path';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
import { randomUUID } from 'node:crypto';
|
|
14
|
+
// Get the directory where this module is located
|
|
15
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
16
|
+
const __dirname = dirname(__filename);
|
|
17
|
+
// Import shared config and utilities
|
|
18
|
+
import { CLI_AUTH_CONFIG, stripAnsiCodes, matchesSuccessPattern, findMatchingPrompt, validateProviderConfig, validateAllProviderConfigs as validateAllConfigs, getSupportedProviders, } from '@agent-relay/config/cli-auth-config';
|
|
19
|
+
// Re-export everything from shared config for backward compatibility
|
|
20
|
+
export { CLI_AUTH_CONFIG, stripAnsiCodes, matchesSuccessPattern, findMatchingPrompt, validateProviderConfig, getSupportedProviders, };
|
|
21
|
+
// Wrapper that throws instead of returning array (backward compatible)
|
|
22
|
+
export function validateAllProviderConfigs() {
|
|
23
|
+
const errors = validateAllConfigs();
|
|
24
|
+
if (errors.length > 0) {
|
|
25
|
+
throw new Error(`Invalid provider configurations:\n${errors.join('\n')}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Find the relay-pty binary path.
|
|
30
|
+
* Returns null if not found.
|
|
31
|
+
*/
|
|
32
|
+
function findRelayPtyBinary() {
|
|
33
|
+
// Get the project root (five levels up from packages/cloud/dist/api/)
|
|
34
|
+
// packages/cloud/dist/api/ -> packages/cloud/dist -> packages/cloud -> packages -> project root
|
|
35
|
+
const projectRoot = join(__dirname, '..', '..', '..', '..', '..');
|
|
36
|
+
const candidates = [
|
|
37
|
+
// Primary: installed by postinstall from platform-specific binary
|
|
38
|
+
join(projectRoot, 'bin', 'relay-pty'),
|
|
39
|
+
// Development: local Rust build
|
|
40
|
+
join(projectRoot, 'relay-pty', 'target', 'release', 'relay-pty'),
|
|
41
|
+
join(projectRoot, 'relay-pty', 'target', 'debug', 'relay-pty'),
|
|
42
|
+
// Local build in cwd (for development)
|
|
43
|
+
join(process.cwd(), 'relay-pty', 'target', 'release', 'relay-pty'),
|
|
44
|
+
// Installed globally
|
|
45
|
+
'/usr/local/bin/relay-pty',
|
|
46
|
+
// In node_modules (when installed as dependency)
|
|
47
|
+
join(process.cwd(), 'node_modules', 'agent-relay', 'bin', 'relay-pty'),
|
|
48
|
+
];
|
|
49
|
+
for (const candidate of candidates) {
|
|
50
|
+
if (existsSync(candidate)) {
|
|
51
|
+
return candidate;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Run CLI auth flow via PTY using relay-pty binary
|
|
58
|
+
*
|
|
59
|
+
* This is the core PTY runner used by both production and tests.
|
|
60
|
+
* It handles:
|
|
61
|
+
* - Spawning the CLI with proper TTY emulation via relay-pty
|
|
62
|
+
* - Auto-responding to interactive prompts
|
|
63
|
+
* - Extracting auth URLs from output
|
|
64
|
+
* - Detecting success patterns
|
|
65
|
+
*
|
|
66
|
+
* @param config - CLI auth configuration for the provider
|
|
67
|
+
* @param options - Optional callbacks and overrides
|
|
68
|
+
* @returns Promise resolving to auth result
|
|
69
|
+
*/
|
|
70
|
+
export async function runCLIAuthViaPTY(config, options = {}) {
|
|
71
|
+
const result = {
|
|
72
|
+
authUrl: null,
|
|
73
|
+
success: false,
|
|
74
|
+
promptsHandled: [],
|
|
75
|
+
output: '',
|
|
76
|
+
exitCode: null,
|
|
77
|
+
};
|
|
78
|
+
const respondedPrompts = new Set();
|
|
79
|
+
// Find relay-pty binary
|
|
80
|
+
const relayPtyPath = findRelayPtyBinary();
|
|
81
|
+
if (!relayPtyPath) {
|
|
82
|
+
result.error = 'relay-pty binary not found. Build with: cd relay-pty && cargo build --release';
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
return new Promise((resolve) => {
|
|
86
|
+
try {
|
|
87
|
+
// Generate unique name for this auth session
|
|
88
|
+
const sessionName = `auth-${randomUUID().substring(0, 8)}`;
|
|
89
|
+
// Build relay-pty arguments
|
|
90
|
+
const relayArgs = [
|
|
91
|
+
'--name', sessionName,
|
|
92
|
+
'--rows', '30',
|
|
93
|
+
'--cols', '120',
|
|
94
|
+
'--log-level', 'error', // Suppress relay-pty logs
|
|
95
|
+
'--', config.command,
|
|
96
|
+
...config.args,
|
|
97
|
+
];
|
|
98
|
+
const proc = spawn(relayPtyPath, relayArgs, {
|
|
99
|
+
cwd: options.cwd || process.cwd(),
|
|
100
|
+
env: {
|
|
101
|
+
...process.env,
|
|
102
|
+
NO_COLOR: '1',
|
|
103
|
+
TERM: 'xterm-256color',
|
|
104
|
+
// Prevent CLIs from trying to open browsers
|
|
105
|
+
BROWSER: 'echo',
|
|
106
|
+
DISPLAY: '',
|
|
107
|
+
...options.env,
|
|
108
|
+
},
|
|
109
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
110
|
+
});
|
|
111
|
+
// Timeout handler
|
|
112
|
+
const timeout = setTimeout(() => {
|
|
113
|
+
proc.kill();
|
|
114
|
+
result.error = 'Timeout waiting for auth URL';
|
|
115
|
+
resolve(result);
|
|
116
|
+
}, config.waitTimeout + 5000);
|
|
117
|
+
// Handle stdout (main PTY output)
|
|
118
|
+
proc.stdout?.on('data', (data) => {
|
|
119
|
+
const text = data.toString();
|
|
120
|
+
result.output += text;
|
|
121
|
+
options.onOutput?.(text);
|
|
122
|
+
// Check for matching prompts and auto-respond
|
|
123
|
+
const matchingPrompt = findMatchingPrompt(text, config.prompts, respondedPrompts);
|
|
124
|
+
if (matchingPrompt) {
|
|
125
|
+
respondedPrompts.add(matchingPrompt.description);
|
|
126
|
+
result.promptsHandled.push(matchingPrompt.description);
|
|
127
|
+
options.onPromptHandled?.(matchingPrompt.description);
|
|
128
|
+
const delay = matchingPrompt.delay ?? 100;
|
|
129
|
+
setTimeout(() => {
|
|
130
|
+
try {
|
|
131
|
+
proc.stdin?.write(matchingPrompt.response);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// Process may have exited
|
|
135
|
+
}
|
|
136
|
+
}, delay);
|
|
137
|
+
}
|
|
138
|
+
// Look for auth URL
|
|
139
|
+
const cleanText = stripAnsiCodes(text);
|
|
140
|
+
const match = cleanText.match(config.urlPattern);
|
|
141
|
+
if (match && match[1] && !result.authUrl) {
|
|
142
|
+
result.authUrl = match[1];
|
|
143
|
+
if (result.authUrl) {
|
|
144
|
+
options.onAuthUrl?.(result.authUrl);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Check for success indicators
|
|
148
|
+
if (matchesSuccessPattern(text, config.successPatterns)) {
|
|
149
|
+
result.success = true;
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
// Handle stderr (relay-pty logs, usually minimal)
|
|
153
|
+
proc.stderr?.on('data', (data) => {
|
|
154
|
+
const text = data.toString();
|
|
155
|
+
// Also check stderr for output (some CLIs write to stderr)
|
|
156
|
+
result.output += text;
|
|
157
|
+
options.onOutput?.(text);
|
|
158
|
+
// Check stderr for auth URLs too
|
|
159
|
+
const cleanText = stripAnsiCodes(text);
|
|
160
|
+
const match = cleanText.match(config.urlPattern);
|
|
161
|
+
if (match && match[1] && !result.authUrl) {
|
|
162
|
+
result.authUrl = match[1];
|
|
163
|
+
if (result.authUrl) {
|
|
164
|
+
options.onAuthUrl?.(result.authUrl);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
proc.on('exit', (code) => {
|
|
169
|
+
clearTimeout(timeout);
|
|
170
|
+
result.exitCode = code;
|
|
171
|
+
// Consider it a success if we got a URL (main goal)
|
|
172
|
+
// or if exit code was 0 with success pattern
|
|
173
|
+
if (result.authUrl || (code === 0 && result.success)) {
|
|
174
|
+
result.success = true;
|
|
175
|
+
}
|
|
176
|
+
if (!result.authUrl && !result.success && !result.error) {
|
|
177
|
+
result.error = 'Failed to extract auth URL from CLI output';
|
|
178
|
+
}
|
|
179
|
+
resolve(result);
|
|
180
|
+
});
|
|
181
|
+
proc.on('error', (err) => {
|
|
182
|
+
clearTimeout(timeout);
|
|
183
|
+
result.error = err.message;
|
|
184
|
+
resolve(result);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
result.error = err instanceof Error ? err.message : 'Unknown error';
|
|
189
|
+
resolve(result);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=cli-pty-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-pty-runner.js","sourceRoot":"","sources":["../../src/api/cli-pty-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex Auth Helper API
|
|
3
|
+
*
|
|
4
|
+
* Provides endpoints for the `npx agent-relay codex-auth` CLI command.
|
|
5
|
+
* Uses SSH tunneling to forward localhost:1455 to the workspace container,
|
|
6
|
+
* allowing the Codex CLI's OAuth callback to work in remote/container environments.
|
|
7
|
+
*
|
|
8
|
+
* Flow:
|
|
9
|
+
* 1. CLI gets workspace SSH info via /tunnel-info
|
|
10
|
+
* 2. CLI establishes SSH tunnel: local:1455 -> container:1455
|
|
11
|
+
* 3. User completes OAuth, browser redirects to localhost:1455
|
|
12
|
+
* 4. Tunnel forwards to container's Codex CLI server
|
|
13
|
+
* 5. Codex CLI exchanges code for tokens internally
|
|
14
|
+
* 6. CLI polls for auth completion
|
|
15
|
+
*/
|
|
16
|
+
export declare const codexAuthHelperRouter: import("express-serve-static-core").Router;
|
|
17
|
+
/**
|
|
18
|
+
* Stop the cleanup interval. Call this on server shutdown.
|
|
19
|
+
*/
|
|
20
|
+
export declare function stopCodexAuthCleanup(): void;
|
|
21
|
+
//# sourceMappingURL=codex-auth-helper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-auth-helper.d.ts","sourceRoot":"","sources":["../../src/api/codex-auth-helper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAQH,eAAO,MAAM,qBAAqB,4CAAW,CAAC;AA2C9C;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex Auth Helper API
|
|
3
|
+
*
|
|
4
|
+
* Provides endpoints for the `npx agent-relay codex-auth` CLI command.
|
|
5
|
+
* Uses SSH tunneling to forward localhost:1455 to the workspace container,
|
|
6
|
+
* allowing the Codex CLI's OAuth callback to work in remote/container environments.
|
|
7
|
+
*
|
|
8
|
+
* Flow:
|
|
9
|
+
* 1. CLI gets workspace SSH info via /tunnel-info
|
|
10
|
+
* 2. CLI establishes SSH tunnel: local:1455 -> container:1455
|
|
11
|
+
* 3. User completes OAuth, browser redirects to localhost:1455
|
|
12
|
+
* 4. Tunnel forwards to container's Codex CLI server
|
|
13
|
+
* 5. Codex CLI exchanges code for tokens internally
|
|
14
|
+
* 6. CLI polls for auth completion
|
|
15
|
+
*/
|
|
16
|
+
import { Router } from 'express';
|
|
17
|
+
import crypto from 'crypto';
|
|
18
|
+
import { requireAuth } from './auth.js';
|
|
19
|
+
import { db } from '../db/index.js';
|
|
20
|
+
import { deriveSshPassword } from '../services/ssh-security.js';
|
|
21
|
+
export const codexAuthHelperRouter = Router();
|
|
22
|
+
const WORKSPACE_SSH_PORT = 3022;
|
|
23
|
+
const pendingAuthSessions = new Map();
|
|
24
|
+
const pendingCliTokens = new Map();
|
|
25
|
+
// Clean up old sessions every minute
|
|
26
|
+
const cleanupInterval = setInterval(() => {
|
|
27
|
+
const now = Date.now();
|
|
28
|
+
for (const [id, session] of pendingAuthSessions) {
|
|
29
|
+
// Remove sessions older than 10 minutes
|
|
30
|
+
if (now - session.createdAt.getTime() > 10 * 60 * 1000) {
|
|
31
|
+
pendingAuthSessions.delete(id);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Also clean up CLI tokens
|
|
35
|
+
for (const [id, token] of pendingCliTokens) {
|
|
36
|
+
// Remove tokens older than 10 minutes
|
|
37
|
+
if (now - token.createdAt.getTime() > 10 * 60 * 1000) {
|
|
38
|
+
pendingCliTokens.delete(id);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}, 60000);
|
|
42
|
+
/**
|
|
43
|
+
* Stop the cleanup interval. Call this on server shutdown.
|
|
44
|
+
*/
|
|
45
|
+
export function stopCodexAuthCleanup() {
|
|
46
|
+
clearInterval(cleanupInterval);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* POST /api/auth/codex-helper/cli-session
|
|
50
|
+
* Create a new auth session for the CLI command.
|
|
51
|
+
* Returns workspace info and CLI command for SSH tunnel approach.
|
|
52
|
+
*/
|
|
53
|
+
codexAuthHelperRouter.post('/cli-session', requireAuth, async (req, res) => {
|
|
54
|
+
const userId = req.session.userId;
|
|
55
|
+
const { workspaceId, authUrl, sessionId: onboardingSessionId } = req.body;
|
|
56
|
+
// If workspace ID provided, return SSH tunnel command
|
|
57
|
+
if (workspaceId) {
|
|
58
|
+
try {
|
|
59
|
+
const workspace = await db.workspaces.findById(workspaceId);
|
|
60
|
+
if (!workspace || workspace.userId !== userId) {
|
|
61
|
+
return res.status(404).json({ error: 'Workspace not found' });
|
|
62
|
+
}
|
|
63
|
+
// Generate a one-time CLI token for authentication
|
|
64
|
+
const cliToken = crypto.randomUUID();
|
|
65
|
+
pendingCliTokens.set(cliToken, {
|
|
66
|
+
userId,
|
|
67
|
+
workspaceId,
|
|
68
|
+
createdAt: new Date(),
|
|
69
|
+
authUrl, // Store authUrl so CLI can retrieve it
|
|
70
|
+
sessionId: onboardingSessionId, // Store sessionId for credential storage
|
|
71
|
+
});
|
|
72
|
+
console.log(`[codex-helper] Created CLI session for workspace ${workspaceId} with token ${cliToken.slice(0, 8)}...`);
|
|
73
|
+
const cloudUrl = process.env.PUBLIC_URL || 'https://agent-relay.com';
|
|
74
|
+
// Generate the CLI command with workspace ID and token
|
|
75
|
+
res.json({
|
|
76
|
+
workspaceId: workspace.id,
|
|
77
|
+
workspaceName: workspace.name,
|
|
78
|
+
expiresIn: 600, // 10 minutes
|
|
79
|
+
command: `npx agent-relay codex-auth --workspace=${workspaceId} --token=${cliToken}`,
|
|
80
|
+
commandWithUrl: `npx agent-relay codex-auth --workspace=${workspaceId} --token=${cliToken} --cloud-url=${cloudUrl}`,
|
|
81
|
+
});
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error('[codex-helper] Error creating CLI session:', error);
|
|
86
|
+
return res.status(500).json({ error: 'Failed to create CLI session' });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Legacy: token-based session (for backwards compatibility)
|
|
90
|
+
const authSessionId = crypto.randomUUID();
|
|
91
|
+
pendingAuthSessions.set(authSessionId, {
|
|
92
|
+
userId,
|
|
93
|
+
createdAt: new Date(),
|
|
94
|
+
});
|
|
95
|
+
console.log(`[codex-helper] Created legacy CLI session ${authSessionId} for user ${userId}`);
|
|
96
|
+
res.json({
|
|
97
|
+
authSessionId,
|
|
98
|
+
expiresIn: 600, // 10 minutes
|
|
99
|
+
command: `npx agent-relay codex-auth --token=${authSessionId}`,
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
/**
|
|
103
|
+
* POST /api/auth/codex-helper/callback
|
|
104
|
+
* Receives the auth code from the CLI.
|
|
105
|
+
* No auth required - validated by authSessionId.
|
|
106
|
+
*/
|
|
107
|
+
codexAuthHelperRouter.post('/callback', async (req, res) => {
|
|
108
|
+
const { authSessionId, code, state, error } = req.body;
|
|
109
|
+
if (!authSessionId) {
|
|
110
|
+
return res.status(400).json({ error: 'Missing authSessionId' });
|
|
111
|
+
}
|
|
112
|
+
const session = pendingAuthSessions.get(authSessionId);
|
|
113
|
+
if (!session) {
|
|
114
|
+
return res.status(404).json({ error: 'Session not found or expired' });
|
|
115
|
+
}
|
|
116
|
+
if (error) {
|
|
117
|
+
console.log(`[codex-helper] Auth error for session ${authSessionId}:`, error);
|
|
118
|
+
pendingAuthSessions.delete(authSessionId);
|
|
119
|
+
return res.json({ success: false, error });
|
|
120
|
+
}
|
|
121
|
+
if (!code) {
|
|
122
|
+
return res.status(400).json({ error: 'Missing auth code' });
|
|
123
|
+
}
|
|
124
|
+
// Store the code and state so the polling endpoint can retrieve them
|
|
125
|
+
session.code = code;
|
|
126
|
+
session.state = state; // Store state for CSRF validation
|
|
127
|
+
pendingAuthSessions.set(authSessionId, session);
|
|
128
|
+
console.log(`[codex-helper] Auth code received for session ${authSessionId}`);
|
|
129
|
+
res.json({ success: true, message: 'Auth code received. You can close this terminal.' });
|
|
130
|
+
});
|
|
131
|
+
/**
|
|
132
|
+
* GET /api/auth/codex-helper/status/:authSessionId
|
|
133
|
+
* Check if auth code has been received.
|
|
134
|
+
* The dashboard polls this to know when the CLI has captured the callback.
|
|
135
|
+
*/
|
|
136
|
+
codexAuthHelperRouter.get('/status/:authSessionId', requireAuth, async (req, res) => {
|
|
137
|
+
const authSessionId = req.params.authSessionId;
|
|
138
|
+
const session = pendingAuthSessions.get(authSessionId);
|
|
139
|
+
if (!session || session.userId !== req.session.userId) {
|
|
140
|
+
return res.status(404).json({ error: 'Session not found or expired' });
|
|
141
|
+
}
|
|
142
|
+
if (session.code) {
|
|
143
|
+
// Clean up session after successful retrieval (code is single-use)
|
|
144
|
+
const code = session.code;
|
|
145
|
+
const state = session.state;
|
|
146
|
+
pendingAuthSessions.delete(authSessionId);
|
|
147
|
+
return res.json({
|
|
148
|
+
ready: true,
|
|
149
|
+
code,
|
|
150
|
+
state, // Return state for CSRF validation
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
res.json({ ready: false });
|
|
154
|
+
});
|
|
155
|
+
/**
|
|
156
|
+
* GET /api/auth/codex-helper/tunnel-info/:workspaceId
|
|
157
|
+
* Get SSH tunnel info for establishing port forwarding to a workspace.
|
|
158
|
+
* Returns host, port, user, and password for SSH connection.
|
|
159
|
+
*
|
|
160
|
+
* Authentication: Requires either session auth OR a valid CLI token.
|
|
161
|
+
*/
|
|
162
|
+
codexAuthHelperRouter.get('/tunnel-info/:workspaceId', async (req, res) => {
|
|
163
|
+
const workspaceId = req.params.workspaceId;
|
|
164
|
+
const { token } = req.query;
|
|
165
|
+
// Authenticate via CLI token or session
|
|
166
|
+
let userId;
|
|
167
|
+
if (token && typeof token === 'string') {
|
|
168
|
+
// CLI token authentication
|
|
169
|
+
const cliToken = pendingCliTokens.get(token);
|
|
170
|
+
if (!cliToken) {
|
|
171
|
+
return res.status(401).json({ error: 'Invalid or expired token' });
|
|
172
|
+
}
|
|
173
|
+
if (cliToken.workspaceId !== workspaceId) {
|
|
174
|
+
return res.status(403).json({ error: 'Token does not match workspace' });
|
|
175
|
+
}
|
|
176
|
+
userId = cliToken.userId;
|
|
177
|
+
// Don't delete token - it's also used for auth-status polling
|
|
178
|
+
// Cleanup interval will remove it after 10 minutes
|
|
179
|
+
console.log(`[codex-helper] CLI token used for workspace ${workspaceId}`);
|
|
180
|
+
}
|
|
181
|
+
else if (req.session?.userId) {
|
|
182
|
+
// Session authentication
|
|
183
|
+
userId = req.session.userId;
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
return res.status(401).json({ error: 'Authentication required. Provide token query parameter or valid session.' });
|
|
187
|
+
}
|
|
188
|
+
try {
|
|
189
|
+
const workspace = await db.workspaces.findById(workspaceId);
|
|
190
|
+
if (!workspace || workspace.userId !== userId) {
|
|
191
|
+
return res.status(404).json({ error: 'Workspace not found' });
|
|
192
|
+
}
|
|
193
|
+
if (workspace.status !== 'running') {
|
|
194
|
+
return res.status(400).json({ error: 'Workspace is not running' });
|
|
195
|
+
}
|
|
196
|
+
// Parse workspace URL to get host
|
|
197
|
+
const publicUrl = workspace.publicUrl;
|
|
198
|
+
if (!publicUrl) {
|
|
199
|
+
return res.status(400).json({ error: 'Workspace URL not available' });
|
|
200
|
+
}
|
|
201
|
+
const url = new URL(publicUrl);
|
|
202
|
+
const host = url.hostname;
|
|
203
|
+
const apiPort = parseInt(url.port, 10) || 80;
|
|
204
|
+
// SSH connection info varies by environment:
|
|
205
|
+
// - Fly.io: Use public fly.dev hostname with port 3022 (exposed via TCP service)
|
|
206
|
+
// - Local Docker: Use localhost with derived SSH port (22000 + apiPort - 3000)
|
|
207
|
+
const isOnFly = !!process.env.FLY_APP_NAME;
|
|
208
|
+
const isLocalDocker = (host === 'localhost' || host === '127.0.0.1') && apiPort >= 3000;
|
|
209
|
+
let sshHost;
|
|
210
|
+
let sshPort;
|
|
211
|
+
if (isOnFly) {
|
|
212
|
+
// Fly.io public hostname - SSH is exposed as a public TCP service on port 3022
|
|
213
|
+
// Users can SSH directly from their machine to {app}.fly.dev:3022
|
|
214
|
+
const appName = `ar-${workspace.id.substring(0, 8)}`;
|
|
215
|
+
sshHost = `${appName}.fly.dev`;
|
|
216
|
+
sshPort = WORKSPACE_SSH_PORT;
|
|
217
|
+
}
|
|
218
|
+
else if (isLocalDocker) {
|
|
219
|
+
// Local Docker: SSH port is derived from API port
|
|
220
|
+
// API port 3500 -> SSH port 22500 (formula: 22000 + apiPort - 3000)
|
|
221
|
+
sshHost = 'localhost';
|
|
222
|
+
sshPort = 22000 + (apiPort - 3000);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
// Default fallback
|
|
226
|
+
sshHost = host;
|
|
227
|
+
sshPort = WORKSPACE_SSH_PORT;
|
|
228
|
+
}
|
|
229
|
+
// SSH password is derived per-workspace for security
|
|
230
|
+
// Each workspace gets a unique password based on its ID + secret salt
|
|
231
|
+
const sshPassword = deriveSshPassword(workspace.id);
|
|
232
|
+
// Get authUrl from CLI token if available
|
|
233
|
+
let authUrl;
|
|
234
|
+
if (token && typeof token === 'string') {
|
|
235
|
+
const cliToken = pendingCliTokens.get(token);
|
|
236
|
+
authUrl = cliToken?.authUrl;
|
|
237
|
+
}
|
|
238
|
+
res.json({
|
|
239
|
+
host: sshHost,
|
|
240
|
+
port: sshPort,
|
|
241
|
+
user: 'workspace',
|
|
242
|
+
password: sshPassword,
|
|
243
|
+
tunnelPort: 1455, // Codex OAuth callback port
|
|
244
|
+
workspaceId: workspace.id,
|
|
245
|
+
workspaceName: workspace.name,
|
|
246
|
+
authUrl, // OAuth URL if available (set by dashboard)
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
console.error('[codex-helper] Error getting tunnel info:', error);
|
|
251
|
+
res.status(500).json({ error: 'Failed to get tunnel info' });
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
/**
|
|
255
|
+
* GET /api/auth/codex-helper/auth-status/:workspaceId
|
|
256
|
+
* Poll for Codex authentication completion in a workspace.
|
|
257
|
+
* The CLI uses this after establishing the tunnel to know when auth is done.
|
|
258
|
+
*
|
|
259
|
+
* Authentication: Requires either session auth OR a valid CLI token.
|
|
260
|
+
*/
|
|
261
|
+
codexAuthHelperRouter.get('/auth-status/:workspaceId', async (req, res) => {
|
|
262
|
+
const workspaceId = req.params.workspaceId;
|
|
263
|
+
const { token } = req.query;
|
|
264
|
+
// Authenticate via CLI token or session
|
|
265
|
+
let userId;
|
|
266
|
+
if (token && typeof token === 'string') {
|
|
267
|
+
// CLI token authentication
|
|
268
|
+
const cliToken = pendingCliTokens.get(token);
|
|
269
|
+
if (!cliToken) {
|
|
270
|
+
return res.status(401).json({ error: 'Invalid or expired token' });
|
|
271
|
+
}
|
|
272
|
+
if (cliToken.workspaceId !== workspaceId) {
|
|
273
|
+
return res.status(403).json({ error: 'Token does not match workspace' });
|
|
274
|
+
}
|
|
275
|
+
userId = cliToken.userId;
|
|
276
|
+
}
|
|
277
|
+
else if (req.session?.userId) {
|
|
278
|
+
// Session authentication
|
|
279
|
+
userId = req.session.userId;
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
return res.status(401).json({ error: 'Authentication required. Provide token query parameter or valid session.' });
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
const workspace = await db.workspaces.findById(workspaceId);
|
|
286
|
+
if (!workspace || workspace.userId !== userId) {
|
|
287
|
+
return res.status(404).json({ error: 'Workspace not found' });
|
|
288
|
+
}
|
|
289
|
+
if (!workspace.publicUrl) {
|
|
290
|
+
return res.status(400).json({ error: 'Workspace URL not available' });
|
|
291
|
+
}
|
|
292
|
+
// Check with workspace daemon if Codex is authenticated for this specific user
|
|
293
|
+
// Pass userId to enable per-user credential checking (multiple users can share a workspace)
|
|
294
|
+
const checkUrl = new URL(`${workspace.publicUrl}/auth/cli/openai/check`);
|
|
295
|
+
checkUrl.searchParams.set('userId', userId);
|
|
296
|
+
const response = await fetch(checkUrl.toString(), {
|
|
297
|
+
method: 'GET',
|
|
298
|
+
signal: AbortSignal.timeout(5000),
|
|
299
|
+
});
|
|
300
|
+
if (response.ok) {
|
|
301
|
+
const data = await response.json();
|
|
302
|
+
// When authentication is detected, mark the provider as connected in the database
|
|
303
|
+
// This ensures the dashboard shows correct per-user connection status
|
|
304
|
+
if (data.authenticated && userId) {
|
|
305
|
+
try {
|
|
306
|
+
await db.credentials.upsert({
|
|
307
|
+
userId,
|
|
308
|
+
provider: 'codex', // Codex provider for OpenAI
|
|
309
|
+
scopes: [],
|
|
310
|
+
});
|
|
311
|
+
console.log(`[codex-helper] Marked codex as connected for user ${userId}`);
|
|
312
|
+
}
|
|
313
|
+
catch (dbError) {
|
|
314
|
+
console.error('[codex-helper] Failed to mark provider as connected:', dbError);
|
|
315
|
+
// Don't fail the request if DB update fails
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return res.json({ authenticated: data.authenticated });
|
|
319
|
+
}
|
|
320
|
+
res.json({ authenticated: false });
|
|
321
|
+
}
|
|
322
|
+
catch (_error) {
|
|
323
|
+
// Workspace might not be reachable, return false
|
|
324
|
+
res.json({ authenticated: false });
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
//# sourceMappingURL=codex-auth-helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-auth-helper.js","sourceRoot":"","sources":["../../src/api/codex-auth-helper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consensus API Routes (Read-Only)
|
|
3
|
+
*
|
|
4
|
+
* Provides API endpoints for observing multi-agent consensus decisions.
|
|
5
|
+
* The dashboard is read-only - agents handle all consensus activity via relay messages.
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* - Agents create proposals and vote via ->relay:_consensus messages
|
|
9
|
+
* - The daemon processes these and syncs state to cloud via /sync endpoint
|
|
10
|
+
* - Dashboard reads consensus state for display only
|
|
11
|
+
*/
|
|
12
|
+
export declare const consensusRouter: import("express-serve-static-core").Router;
|
|
13
|
+
//# sourceMappingURL=consensus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consensus.d.ts","sourceRoot":"","sources":["../../src/api/consensus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAeH,eAAO,MAAM,eAAe,4CAAW,CAAC"}
|