@launchchair/agent
Advanced tools
+2
-1
@@ -90,2 +90,3 @@ # LaunchChair Agent Bootstrap | ||
| `launchchair login` is the recommended token path. It saves the token to `~/.launchchair/config.json`, and `launchchair mcp-server` reads that saved token. Use `LAUNCHCHAIR_AGENT_TOKEN` only as a manual fallback when browser login is skipped or a per-client token override is needed. | ||
| The packaged MCP and local bridges also read the same saved CLI config as a fallback, so a desktop MCP launch should not require pasting a token into Codex or Claude config after browser login. | ||
@@ -116,3 +117,3 @@ For Codex Desktop local runs: | ||
| args = ["mcp-server"] | ||
| required = true | ||
| required = false | ||
| startup_timeout_sec = 20 | ||
@@ -119,0 +120,0 @@ tool_timeout_sec = 3600 |
@@ -18,3 +18,3 @@ #!/usr/bin/env node | ||
| const VERSION = "0.4.2"; | ||
| const VERSION = "0.4.3"; | ||
| const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url)); | ||
@@ -21,0 +21,0 @@ const DEFAULT_BASE_URL = "https://www.launchchair.io"; |
+33
-7
@@ -13,2 +13,4 @@ #!/usr/bin/env node | ||
| import { spawn } from "node:child_process"; | ||
| import { existsSync, readFileSync } from "node:fs"; | ||
| import os from "node:os"; | ||
| import path from "node:path"; | ||
@@ -19,5 +21,9 @@ import process from "node:process"; | ||
| const VERSION = "0.4.0"; | ||
| const VERSION = "0.4.3"; | ||
| const CLIENT_TYPES = ["codex", "chatgpt", "claude", "claude_code", "other"]; | ||
| const AGENT_SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url)); | ||
| const CONFIG_DIR = process.env.LAUNCHCHAIR_CONFIG_DIR?.trim() | ||
| ? path.resolve(process.env.LAUNCHCHAIR_CONFIG_DIR.trim()) | ||
| : path.join(os.homedir() || process.cwd(), ".launchchair"); | ||
| const CONFIG_PATH = path.join(CONFIG_DIR, "config.json"); | ||
@@ -38,2 +44,19 @@ function nodeScriptCommand(scriptName) { | ||
| function loadSavedConfig() { | ||
| try { | ||
| if (!existsSync(CONFIG_PATH)) return {}; | ||
| const parsed = JSON.parse(readFileSync(CONFIG_PATH, "utf8")); | ||
| return parsed && typeof parsed === "object" ? parsed : {}; | ||
| } catch { | ||
| return {}; | ||
| } | ||
| } | ||
| const savedConfig = loadSavedConfig(); | ||
| function savedConfigValue(key, fallback = "") { | ||
| const value = savedConfig[key]; | ||
| return typeof value === "string" && value.trim().length > 0 ? value.trim() : fallback; | ||
| } | ||
| function hasArg(name) { | ||
@@ -98,4 +121,5 @@ return process.argv.includes(name); | ||
| Required env: | ||
| LAUNCHCHAIR_AGENT_TOKEN | ||
| Token: | ||
| Recommended: run launchchair login once to save ~/.launchchair/config.json | ||
| Optional env fallback: LAUNCHCHAIR_AGENT_TOKEN or LAUNCHCHAIR_API_KEY | ||
@@ -160,5 +184,5 @@ Optional env: | ||
| const config = { | ||
| baseUrl: env("LAUNCHCHAIR_BASE_URL", "http://localhost:3000").replace(/\/+$/, ""), | ||
| token: env("LAUNCHCHAIR_AGENT_TOKEN", env("LAUNCHCHAIR_API_KEY")), | ||
| projectId: env("LAUNCHCHAIR_PROJECT_ID") || null, | ||
| baseUrl: env("LAUNCHCHAIR_BASE_URL", savedConfigValue("baseUrl", "http://localhost:3000")).replace(/\/+$/, ""), | ||
| token: env("LAUNCHCHAIR_AGENT_TOKEN", env("LAUNCHCHAIR_API_KEY", savedConfigValue("agentToken"))), | ||
| projectId: env("LAUNCHCHAIR_PROJECT_ID", savedConfigValue("projectId")) || null, | ||
| clientName: env("LC_AGENT_CLIENT_NAME", "Local Bridge"), | ||
@@ -195,3 +219,5 @@ clientType: env("LC_AGENT_CLIENT_TYPE", "auto"), | ||
| // eslint-disable-next-line no-console | ||
| console.error("Missing LAUNCHCHAIR_AGENT_TOKEN. LAUNCHCHAIR_API_KEY is also supported as an alias."); | ||
| console.error( | ||
| `Missing LaunchChair Agent API token. Run "launchchair login" or set LAUNCHCHAIR_AGENT_TOKEN. Checked ${CONFIG_PATH}.`, | ||
| ); | ||
| printHelp(); | ||
@@ -198,0 +224,0 @@ process.exit(1); |
@@ -15,2 +15,4 @@ #!/usr/bin/env node | ||
| import { spawn } from "node:child_process"; | ||
| import { existsSync, readFileSync } from "node:fs"; | ||
| import os from "node:os"; | ||
| import path from "node:path"; | ||
@@ -21,5 +23,9 @@ import process from "node:process"; | ||
| const VERSION = "0.4.0"; | ||
| const VERSION = "0.4.3"; | ||
| const SERVER_NAME = "launchchair-agent-mcp"; | ||
| const AGENT_SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url)); | ||
| const CONFIG_DIR = process.env.LAUNCHCHAIR_CONFIG_DIR?.trim() | ||
| ? path.resolve(process.env.LAUNCHCHAIR_CONFIG_DIR.trim()) | ||
| : path.join(os.homedir() || process.cwd(), ".launchchair"); | ||
| const CONFIG_PATH = path.join(CONFIG_DIR, "config.json"); | ||
| const BASE_SERVER_INSTRUCTIONS = | ||
@@ -37,2 +43,19 @@ "Use LaunchChair MCP tools—not web browsing—for LaunchChair project discovery, creation, planning, and loops. Call the most specific available tool. If a requested workflow is unavailable, explain the access or setup issue instead of silently substituting another project type or workflow."; | ||
| function loadSavedConfig() { | ||
| try { | ||
| if (!existsSync(CONFIG_PATH)) return {}; | ||
| const parsed = JSON.parse(readFileSync(CONFIG_PATH, "utf8")); | ||
| return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {}; | ||
| } catch (_error) { | ||
| return {}; | ||
| } | ||
| } | ||
| const savedConfig = loadSavedConfig(); | ||
| function savedConfigValue(key, fallback = "") { | ||
| const value = savedConfig[key]; | ||
| return typeof value === "string" && value.trim().length > 0 ? value.trim() : fallback; | ||
| } | ||
| function toInt(value, fallback) { | ||
@@ -90,5 +113,5 @@ const parsed = Number.parseInt(String(value ?? ""), 10); | ||
| const config = { | ||
| baseUrl: env("LAUNCHCHAIR_BASE_URL", "http://localhost:3000").replace(/\/+$/, ""), | ||
| token: env("LAUNCHCHAIR_AGENT_TOKEN", env("LAUNCHCHAIR_API_KEY")), | ||
| projectId: env("LAUNCHCHAIR_PROJECT_ID") || null, | ||
| baseUrl: env("LAUNCHCHAIR_BASE_URL", savedConfigValue("baseUrl", "http://localhost:3000")).replace(/\/+$/, ""), | ||
| token: env("LAUNCHCHAIR_AGENT_TOKEN", env("LAUNCHCHAIR_API_KEY", savedConfigValue("agentToken"))), | ||
| projectId: env("LAUNCHCHAIR_PROJECT_ID", savedConfigValue("projectId")) || null, | ||
| clientName: env("LC_AGENT_CLIENT_NAME", "MCP Bridge"), | ||
@@ -113,4 +136,4 @@ clientType: env("LC_AGENT_CLIENT_TYPE", "other"), | ||
| localRepoPaths: { | ||
| codex: env("LC_AGENT_CODEX_CWD", process.cwd()), | ||
| claudeCode: env("LC_AGENT_CLAUDE_CODE_CWD", process.cwd()), | ||
| codex: env("LC_AGENT_CODEX_CWD", savedConfigValue("codexCwd", process.cwd())), | ||
| claudeCode: env("LC_AGENT_CLAUDE_CODE_CWD", savedConfigValue("claudeCodeCwd", process.cwd())), | ||
| }, | ||
@@ -121,3 +144,5 @@ }; | ||
| // eslint-disable-next-line no-console | ||
| console.error("Missing LAUNCHCHAIR_AGENT_TOKEN for MCP bridge. LAUNCHCHAIR_API_KEY is also supported as an alias."); | ||
| console.error( | ||
| `Missing LaunchChair Agent API token. Run "launchchair login" or set LAUNCHCHAIR_AGENT_TOKEN. Checked ${CONFIG_PATH}.`, | ||
| ); | ||
| process.exit(1); | ||
@@ -124,0 +149,0 @@ } |
+1
-1
| { | ||
| "name": "@launchchair/agent", | ||
| "version": "0.4.2", | ||
| "version": "0.4.3", | ||
| "description": "LaunchChair Agent CLI, MCP bridge, local bridge, and runners for Codex, Claude Code, ChatGPT, Claude, and Hermes workflows.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
149028
1.51%3377
1.35%45
12.5%