Merge branch 'main' into setup-headless-auth-message
This commit is contained in:
@@ -84,21 +84,28 @@ describe('credentials detection', () => {
|
||||
const content =
|
||||
'SOME_KEY=value\nANTHROPIC_API_KEY=sk-ant-test123\nOTHER=foo';
|
||||
const hasCredentials =
|
||||
/^(CLAUDE_CODE_OAUTH_TOKEN|ANTHROPIC_API_KEY)=/m.test(content);
|
||||
/^(CLAUDE_CODE_OAUTH_TOKEN|ANTHROPIC_API_KEY|ANTHROPIC_AUTH_TOKEN|ONECLI_URL)=/m.test(content);
|
||||
expect(hasCredentials).toBe(true);
|
||||
});
|
||||
|
||||
it('detects CLAUDE_CODE_OAUTH_TOKEN in env content', () => {
|
||||
const content = 'CLAUDE_CODE_OAUTH_TOKEN=token123';
|
||||
const hasCredentials =
|
||||
/^(CLAUDE_CODE_OAUTH_TOKEN|ANTHROPIC_API_KEY)=/m.test(content);
|
||||
/^(CLAUDE_CODE_OAUTH_TOKEN|ANTHROPIC_API_KEY|ANTHROPIC_AUTH_TOKEN|ONECLI_URL)=/m.test(content);
|
||||
expect(hasCredentials).toBe(true);
|
||||
});
|
||||
|
||||
it('detects ANTHROPIC_AUTH_TOKEN in env content', () => {
|
||||
const content = 'ANTHROPIC_AUTH_TOKEN=token123\nANTHROPIC_BASE_URL=http://localhost:8080';
|
||||
const hasCredentials =
|
||||
/^(CLAUDE_CODE_OAUTH_TOKEN|ANTHROPIC_API_KEY|ANTHROPIC_AUTH_TOKEN|ONECLI_URL)=/m.test(content);
|
||||
expect(hasCredentials).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false when no credentials', () => {
|
||||
const content = 'ASSISTANT_NAME="Andy"\nOTHER=foo';
|
||||
const hasCredentials =
|
||||
/^(CLAUDE_CODE_OAUTH_TOKEN|ANTHROPIC_API_KEY)=/m.test(content);
|
||||
/^(CLAUDE_CODE_OAUTH_TOKEN|ANTHROPIC_API_KEY|ANTHROPIC_AUTH_TOKEN|ONECLI_URL)=/m.test(content);
|
||||
expect(hasCredentials).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
import fs from 'fs';
|
||||
|
||||
import * as p from '@clack/prompts';
|
||||
import { styleText } from 'node:util';
|
||||
|
||||
const CHANNELS = [
|
||||
{ value: 'telegram', label: 'Telegram' },
|
||||
@@ -47,7 +48,7 @@ async function main(): Promise<void> {
|
||||
}
|
||||
|
||||
const selected = await p.multiselect({
|
||||
message: 'Which channels do you want to set up?',
|
||||
message: 'Which channels do you want to set up?\n' + styleText('dim', ' space to select, enter to confirm') + '\n',
|
||||
options: CHANNELS,
|
||||
required: false,
|
||||
});
|
||||
|
||||
@@ -115,9 +115,43 @@ function installOnecliCliOnly(): { stdout: string; ok: boolean } {
|
||||
return { stdout: upstream.stdout + (upstream.stderr ?? '') + '\n' + fallback.stdout, ok: fallback.ok };
|
||||
}
|
||||
|
||||
// Remove containers in the "onecli" compose project whose service name isn't
|
||||
// in the v2 set. Pre-v2 OneCLI used service "app" (container onecli-app-1);
|
||||
// v2 uses "onecli". Compose flags the old container as an orphan but won't
|
||||
// stop it without --remove-orphans, leaving port 10254 bound and crashing
|
||||
// the new bring-up. Filed upstream; this is the downstream workaround.
|
||||
function removeLegacyOnecliContainers(): string {
|
||||
const out: string[] = [];
|
||||
let list = '';
|
||||
try {
|
||||
list = execSync(
|
||||
`docker ps -a --filter "label=com.docker.compose.project=onecli" --format '{{.Names}}|{{.Label "com.docker.compose.service"}}'`,
|
||||
{ encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] },
|
||||
).trim();
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
if (!list) return '';
|
||||
const v2Services = new Set(['onecli', 'postgres']);
|
||||
for (const line of list.split('\n')) {
|
||||
const [name, service] = line.split('|');
|
||||
if (!name || !service || v2Services.has(service)) continue;
|
||||
out.push(`Removing legacy OneCLI container: ${name} (service=${service})`);
|
||||
try {
|
||||
execSync(`docker rm -f ${JSON.stringify(name)}`, { stdio: ['ignore', 'pipe', 'pipe'] });
|
||||
} catch (err) {
|
||||
out.push(` rm failed (continuing): ${(err as Error).message}`);
|
||||
}
|
||||
}
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
function installOnecli(): { stdout: string; ok: boolean } {
|
||||
let stdout = '';
|
||||
|
||||
const cleanup = removeLegacyOnecliContainers();
|
||||
if (cleanup) stdout += cleanup + '\n';
|
||||
|
||||
// Gateway install (docker-compose based, no rate-limit concerns).
|
||||
const gw = runInstall('curl -fsSL onecli.sh/install | sh');
|
||||
stdout += gw.stdout;
|
||||
|
||||
@@ -139,7 +139,7 @@ export async function run(_args: string[]): Promise<void> {
|
||||
const envFile = path.join(projectRoot, '.env');
|
||||
if (fs.existsSync(envFile)) {
|
||||
const envContent = fs.readFileSync(envFile, 'utf-8');
|
||||
if (/^(CLAUDE_CODE_OAUTH_TOKEN|ANTHROPIC_API_KEY|ONECLI_URL)=/m.test(envContent)) {
|
||||
if (/^(CLAUDE_CODE_OAUTH_TOKEN|ANTHROPIC_API_KEY|ANTHROPIC_AUTH_TOKEN|ONECLI_URL)=/m.test(envContent)) {
|
||||
credentials = 'configured';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user