@rulemetric/cli 0.6.0 → 0.6.2
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/chunk-3AEVHOTS.js +33 -0
- package/dist/chunk-3AEVHOTS.js.map +7 -0
- package/dist/{chunk-WLFX4PYR.js → chunk-6TPJGYFF.js} +4 -4
- package/dist/{chunk-4LHEN2FS.js → chunk-CVMRMSV4.js} +14 -14
- package/dist/{chunk-H3C6EGR2.js → chunk-MUOUV5LY.js} +4 -4
- package/dist/{chunk-OVGP4OGK.js → chunk-OTPC2LXW.js} +6 -4
- package/dist/chunk-OTPC2LXW.js.map +7 -0
- package/dist/{chunk-JCYCAQ6U.js → chunk-TXHL3AUA.js} +86 -93
- package/dist/chunk-TXHL3AUA.js.map +7 -0
- package/dist/{chunk-7K4ILWS7.js → chunk-UPXIO7CG.js} +4 -4
- package/dist/{chunk-IATQXFJA.js → chunk-VBGUNFKY.js} +4 -4
- package/dist/{chunk-BCIUSUEV.js → chunk-VIYUIQHW.js} +4 -4
- package/dist/{chunk-HWGRTIXN.js → chunk-XN23W5HL.js} +9 -6
- package/dist/chunk-XN23W5HL.js.map +7 -0
- package/dist/commands/auth/login.js +4 -0
- package/dist/commands/auth/login.js.map +2 -2
- package/dist/commands/auth/signup.js +81 -0
- package/dist/commands/auth/signup.js.map +7 -0
- package/dist/commands/evals/agent.js +10 -10
- package/dist/commands/gateway/ensure.js +1 -1
- package/dist/commands/hooks/install.js +10 -4
- package/dist/commands/hooks/install.js.map +2 -2
- package/dist/commands/hooks/uninstall.js +2 -2
- package/dist/commands/proxy/env.js +1 -1
- package/dist/commands/proxy/start.js +10 -8
- package/dist/commands/proxy/start.js.map +2 -2
- package/dist/commands/proxy/status.js +1 -1
- package/dist/commands/proxy/stop.js +4 -2
- package/dist/commands/proxy/stop.js.map +2 -2
- package/dist/commands/setup.js +3 -3
- package/dist/dashboard/Dashboard.js +11 -11
- package/dist/dashboard/launcher/LauncherOverlay.js +3 -3
- package/dist/lib/agent-loop.js +10 -10
- package/dist/lib/ensure-api-key.js +10 -0
- package/dist/lib/ensure-api-key.js.map +7 -0
- package/dist/lib/gateway-lifecycle.js +1 -1
- package/dist/lib/handlers/cron-suggest-instructions.js +2 -2
- package/dist/lib/handlers/process-announcement.js +2 -2
- package/dist/lib/handlers/process-run-cleanup.js +2 -2
- package/dist/lib/handlers/process-session-goal.js +2 -2
- package/dist/lib/hooks-config.js +1 -1
- package/dist/lib/manual-tasks.js +2 -2
- package/dist/lib/setup-steps.js +3 -3
- package/oclif.manifest.json +53 -2
- package/package.json +9 -6
- package/dist/chunk-HWGRTIXN.js.map +0 -7
- package/dist/chunk-JCYCAQ6U.js.map +0 -7
- package/dist/chunk-OVGP4OGK.js.map +0 -7
- /package/dist/{chunk-WLFX4PYR.js.map → chunk-6TPJGYFF.js.map} +0 -0
- /package/dist/{chunk-4LHEN2FS.js.map → chunk-CVMRMSV4.js.map} +0 -0
- /package/dist/{chunk-H3C6EGR2.js.map → chunk-MUOUV5LY.js.map} +0 -0
- /package/dist/{chunk-7K4ILWS7.js.map → chunk-UPXIO7CG.js.map} +0 -0
- /package/dist/{chunk-IATQXFJA.js.map → chunk-VBGUNFKY.js.map} +0 -0
- /package/dist/{chunk-BCIUSUEV.js.map → chunk-VIYUIQHW.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/commands/proxy/start.ts"],
|
|
4
|
-
"sourcesContent": ["import { Flags } from '@oclif/core';\nimport { execSync, spawn, spawnSync } from 'node:child_process';\nimport { appendFileSync, existsSync, mkdirSync, openSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\nimport { BaseCommand } from '../../base-command.js';\nimport { isAuthenticated } from '../../lib/auth.js';\nimport { findBinary } from '../../lib/which.js';\n\nconst DEFAULT_PORT = 8788;\nconst CONFIG_DIR = join(homedir(), '.config', 'rulemetric');\nconst PID_FILE = join(CONFIG_DIR, 'proxy.pid');\nconst LOG_FILE = join(CONFIG_DIR, 'proxy.log');\nconst DOCKER_IMAGE = 'rulemetric/proxy';\nconst DOCKER_CONTAINER = 'rulemetric-proxy';\n\nfunction findAddonPath(): string {\n const candidates = [\n resolve(import.meta.dirname, '../../../../../packages/proxy/addon/rulemetric_addon.py'),\n resolve(import.meta.dirname, '../../../node_modules/@rulemetric/proxy/addon/rulemetric_addon.py'),\n resolve(import.meta.dirname, '../../../../../node_modules/@rulemetric/proxy/addon/rulemetric_addon.py'),\n ];\n for (const p of candidates) {\n if (existsSync(p)) return p;\n }\n throw new Error(\n 'Could not find rulemetric_addon.py. Is @rulemetric/proxy installed?\\n' +\n 'Searched:\\n' + candidates.map(c => ` ${c}`).join('\\n'),\n );\n}\n\nfunction findDockerfilePath(): string {\n const candidates = [\n resolve(import.meta.dirname, '../../../../../packages/proxy'),\n resolve(import.meta.dirname, '../../../node_modules/@rulemetric/proxy'),\n resolve(import.meta.dirname, '../../../../../node_modules/@rulemetric/proxy'),\n ];\n for (const p of candidates) {\n if (existsSync(join(p, 'Dockerfile'))) return p;\n }\n throw new Error('Could not find proxy Dockerfile. Is @rulemetric/proxy installed?');\n}\n\nfunction dockerImageExists(): boolean {\n const result = spawnSync('docker', ['image', 'inspect', DOCKER_IMAGE], { stdio: 'ignore' });\n return result.status === 0;\n}\n\nfunction dockerContainerRunning(): boolean {\n const result = spawnSync('docker', ['container', 'inspect', '-f', '{{.State.Running}}', DOCKER_CONTAINER], {\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n });\n return result.status === 0 && result.stdout?.trim() === 'true';\n}\n\nexport default class ProxyStart extends BaseCommand {\n static override description = 'Start context capture proxy';\n\n static override examples = [\n '<%= config.bin %> proxy start',\n '<%= config.bin %> proxy start --docker',\n '<%= config.bin %> proxy start --port 9090',\n '<%= config.bin %> proxy start --web',\n ];\n\n static override flags = {\n port: Flags.integer({ char: 'p', default: DEFAULT_PORT, description: 'Proxy listen port' }),\n docker: Flags.boolean({ char: 'd', default: false, description: 'Run proxy in Docker (no local mitmproxy needed)' }),\n web: Flags.boolean({ default: false, description: 'Launch mitmweb debug UI instead of mitmdump (local mode only)' }),\n 'skip-checks': Flags.boolean({ default: false, description: 'Skip prerequisite checks' }),\n build: Flags.boolean({ default: false, description: 'Force rebuild Docker image' }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(ProxyStart);\n const port = flags.port;\n\n if (flags.docker) {\n await this.startDocker(port, flags.build);\n } else {\n await this.startLocal(port, flags.web, flags['skip-checks']);\n }\n }\n\n private async startDocker(port: number, forceBuild: boolean): Promise<void> {\n // Check Docker is available\n try {\n execSync('docker info', { stdio: 'ignore' });\n } catch {\n this.error('Docker is not running. Start Docker Desktop and try again.');\n }\n\n // Check if already running\n if (dockerContainerRunning()) {\n this.error(`Proxy container already running. Stop it first: rulemetric proxy stop`);\n }\n\n // Find the compose file (monorepo root or project root)\n const composeFile = this.findComposeFile();\n\n // Ensure mount dirs exist\n const certDir = join(homedir(), '.mitmproxy');\n mkdirSync(certDir, { recursive: true });\n const tmpDir = process.env.TMPDIR || '/tmp';\n mkdirSync(join(tmpDir, 'rulemetric'), { recursive: true });\n\n // Load auth from env file if not in environment\n const envOverrides: Record<string, string> = {\n PROXY_PORT: String(port),\n RULEMETRIC_PROJECT_PATH: process.cwd(),\n };\n\n if (!process.env.RULEMETRIC_API_KEY && !process.env.RULEMETRIC_ACCESS_TOKEN) {\n const envFile = join(homedir(), '.config', 'rulemetric', 'env');\n if (existsSync(envFile)) {\n for (const line of readFileSync(envFile, 'utf-8').split('\\n')) {\n const trimmed = line.trim();\n if (trimmed && !trimmed.startsWith('#') && trimmed.includes('=')) {\n const [key, ...rest] = trimmed.split('=');\n envOverrides[key] = rest.join('=');\n }\n }\n }\n }\n\n if (composeFile) {\n // Use docker compose\n const composeEnv = { ...process.env, ...envOverrides };\n const buildFlag = forceBuild ? '--build' : '';\n const args = ['compose', '-f', composeFile, 'up', '-d', 'proxy'];\n if (forceBuild) args.splice(4, 0, '--build');\n\n this.log(forceBuild ? 'Building and starting proxy via Docker Compose...' : 'Starting proxy via Docker Compose...');\n const result = spawnSync('docker', args, {\n env: composeEnv,\n stdio: 'inherit',\n });\n\n if (result.status !== 0) {\n this.error('Docker Compose failed. Try: docker compose -f docker-compose.yml up proxy');\n }\n } else {\n // Fallback: raw docker run\n if (forceBuild || !dockerImageExists()) {\n const proxyDir = findDockerfilePath();\n this.log('Building proxy Docker image...');\n const build = spawnSync('docker', ['build', '-t', DOCKER_IMAGE, proxyDir], { stdio: 'inherit' });\n if (build.status !== 0) {\n this.error('Docker build failed');\n }\n }\n\n spawnSync('docker', ['rm', '-f', DOCKER_CONTAINER], { stdio: 'ignore' });\n\n const envArgs: string[] = [];\n for (const [key, val] of Object.entries(envOverrides)) {\n envArgs.push('-e', `${key}=${val}`);\n }\n // Pass through from current env\n for (const key of ['RULEMETRIC_API_URL', 'RULEMETRIC_API_KEY', 'RULEMETRIC_ACCESS_TOKEN']) {\n if (process.env[key]) envArgs.push('-e', `${key}=${process.env[key]}`);\n }\n\n const dockerArgs = [\n 'run', '-d',\n '--name', DOCKER_CONTAINER,\n '-p', `${port}:8787`,\n '-v', `${certDir}:/root/.mitmproxy`,\n '-v', `${join(tmpDir, 'rulemetric')}:/tmp/rulemetric:ro`,\n ...envArgs,\n DOCKER_IMAGE,\n ];\n\n const result = spawnSync('docker', dockerArgs, { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] });\n if (result.status !== 0) {\n this.error(`Failed to start container: ${result.stderr}`);\n }\n }\n\n // Write marker so proxy stop knows it's Docker\n mkdirSync(CONFIG_DIR, { recursive: true });\n writeFileSync(PID_FILE, `docker:${DOCKER_CONTAINER}`);\n\n // Wait for container to be ready\n await new Promise(resolve => setTimeout(resolve, 2000));\n\n const inspectResult = spawnSync('docker', ['container', 'inspect', '-f', '{{.Id}}', DOCKER_CONTAINER], {\n encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'],\n });\n const containerId = inspectResult.stdout?.trim().slice(0, 12) || 'unknown';\n\n this.log(`Proxy running in Docker on localhost:${port} (container: ${containerId})`);\n\n this.log('');\n this.log('View logs: rulemetric proxy logs -f');\n }\n\n private findComposeFile(): string | null {\n const candidates = [\n join(process.cwd(), 'docker-compose.yml'),\n resolve(import.meta.dirname, '../../../../../docker-compose.yml'),\n ];\n for (const p of candidates) {\n if (existsSync(p)) return p;\n }\n return null;\n }\n\n private async startLocal(port: number, useWeb: boolean, skipChecks: boolean): Promise<void> {\n // Check if already running\n if (existsSync(PID_FILE)) {\n const content = readFileSync(PID_FILE, 'utf-8').trim();\n if (content.startsWith('docker:')) {\n this.error('Proxy is running in Docker. Stop it first: rulemetric proxy stop');\n }\n const pid = Number.parseInt(content, 10);\n if (!Number.isNaN(pid)) {\n try {\n process.kill(pid, 0);\n this.error(`Proxy already running (PID ${pid}). Stop it first: rulemetric proxy stop`);\n } catch { /* stale PID, continue */ }\n }\n }\n\n // Check mitmproxy is installed (portable PATH scan \u2014 Windows has no `which`)\n const binary = useWeb ? 'mitmweb' : 'mitmdump';\n if (!findBinary(binary)) {\n this.error(\n `${binary} not found. Use Docker mode instead:\\n` +\n ' rulemetric proxy start --docker\\n\\n' +\n 'Or install mitmproxy locally:\\n' +\n ' pipx install mitmproxy\\n' +\n ' brew install mitmproxy',\n );\n }\n\n // Prerequisite warnings (non-blocking)\n if (!skipChecks) {\n const warnings: string[] = [];\n\n if (!isAuthenticated() && !process.env.RULEMETRIC_API_KEY) {\n const envFile = join(homedir(), '.config', 'rulemetric', 'env');\n let hasEnvAuth = false;\n if (existsSync(envFile)) {\n const content = readFileSync(envFile, 'utf-8');\n hasEnvAuth = content.includes('RULEMETRIC_API_KEY') || content.includes('RULEMETRIC_ACCESS_TOKEN');\n }\n if (!hasEnvAuth) {\n warnings.push('Not authenticated \u2014 snapshots cannot be stored. Run `rulemetric auth login`.');\n }\n }\n\n const certPath = join(homedir(), '.mitmproxy', 'mitmproxy-ca-cert.pem');\n if (!existsSync(certPath)) {\n warnings.push('CA cert not found \u2014 HTTPS interception may fail. Run `rulemetric proxy setup`.');\n }\n\n const settingsPath = join(process.cwd(), '.claude', 'settings.json');\n if (!existsSync(settingsPath)) {\n warnings.push('Session hooks not installed \u2014 snapshots won\\'t link to sessions. Run `rulemetric hooks install`.');\n }\n\n if (warnings.length > 0) {\n for (const w of warnings) {\n this.log(` Warning: ${w}`);\n }\n this.log('');\n }\n }\n\n // Find addon\n const addonPath = findAddonPath();\n\n // Build env \u2014 pass through auth credentials for the reporter\n const env: Record<string, string | undefined> = {\n ...process.env,\n RULEMETRIC_PROJECT_PATH: process.cwd(),\n // Bound to this CLI binary's version. The addon writes this to a\n // version file the gateway watches; on drift the gateway restarts\n // mitmproxy so an upgraded CLI doesn't sit next to a stale proxy.\n RULEMETRIC_CLI_VERSION: this.config.version,\n };\n\n // Load auth from env file if not already in environment\n if (!env.RULEMETRIC_API_KEY && !env.RULEMETRIC_ACCESS_TOKEN) {\n const envFile = join(homedir(), '.config', 'rulemetric', 'env');\n if (existsSync(envFile)) {\n for (const line of readFileSync(envFile, 'utf-8').split('\\n')) {\n const trimmed = line.trim();\n if (trimmed && !trimmed.startsWith('#') && trimmed.includes('=')) {\n const [key, ...rest] = trimmed.split('=');\n env[key] = rest.join('=');\n }\n }\n }\n }\n\n // Ensure config dir exists\n mkdirSync(CONFIG_DIR, { recursive: true });\n\n // Open log file for proxy output (fd for spawn stdio)\n appendFileSync(LOG_FILE, `\\n--- Proxy started at ${new Date().toISOString()} (port ${port}) ---\\n`);\n const logFd = openSync(LOG_FILE, 'a');\n\n // Spawn mitmproxy with output redirected to log file\n const args = [\n '--listen-port', String(port),\n '-s', addonPath,\n '--set', 'console_eventlog_verbosity=info',\n ];\n const child = spawn(binary, args, {\n env,\n stdio: ['ignore', logFd, logFd],\n detached: true,\n });\n\n child.unref();\n\n if (!child.pid) {\n this.error('Failed to start proxy process');\n }\n\n // Brief wait to check if process crashes immediately\n await new Promise<void>((resolve) => {\n let exited = false;\n child.once('exit', (code) => {\n exited = true;\n this.error(`Proxy exited immediately with code ${code}. Check logs:\\n ${LOG_FILE}`);\n });\n setTimeout(() => {\n if (!exited) resolve();\n }, 500);\n });\n\n // Write PID file\n writeFileSync(PID_FILE, String(child.pid));\n\n this.log(`Proxy running on localhost:${port} (PID ${child.pid})`);\n this.log(`Log file: ${LOG_FILE}`);\n\n if (useWeb) {\n this.log('');\n this.log('Debug UI: http://localhost:8081');\n }\n\n this.log('');\n this.log('View logs: rulemetric proxy logs -f');\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;AAAA,SAAS,aAAa;AACtB,SAAS,UAAU,OAAO,iBAAiB;AAC3C,SAAS,gBAAgB,YAAY,WAAW,UAAU,cAAc,qBAAqB;AAC7F,SAAS,eAAe;AACxB,SAAS,MAAM,eAAe;
|
|
4
|
+
"sourcesContent": ["import { Flags } from '@oclif/core';\nimport { execSync, spawn, spawnSync } from 'node:child_process';\nimport { appendFileSync, existsSync, mkdirSync, openSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { BaseCommand } from '../../base-command.js';\nimport { isAuthenticated } from '../../lib/auth.js';\nimport { findBinary } from '../../lib/which.js';\n\n// import.meta.dirname is undefined on Node < 20.11 (breaks resolve()); derive\n// portably. See onboarding field report 2026-07-07 F1.\nconst MODULE_DIR = dirname(fileURLToPath(import.meta.url));\n\nconst DEFAULT_PORT = 8788;\nconst CONFIG_DIR = join(homedir(), '.config', 'rulemetric');\nconst PID_FILE = join(CONFIG_DIR, 'proxy.pid');\nconst LOG_FILE = join(CONFIG_DIR, 'proxy.log');\nconst DOCKER_IMAGE = 'rulemetric/proxy';\nconst DOCKER_CONTAINER = 'rulemetric-proxy';\n\nfunction findAddonPath(): string {\n const candidates = [\n resolve(MODULE_DIR, '../../../../../packages/proxy/addon/rulemetric_addon.py'),\n resolve(MODULE_DIR, '../../../node_modules/@rulemetric/proxy/addon/rulemetric_addon.py'),\n resolve(MODULE_DIR, '../../../../../node_modules/@rulemetric/proxy/addon/rulemetric_addon.py'),\n ];\n for (const p of candidates) {\n if (existsSync(p)) return p;\n }\n throw new Error(\n 'Could not find rulemetric_addon.py. Is @rulemetric/proxy installed?\\n' +\n 'Searched:\\n' + candidates.map(c => ` ${c}`).join('\\n'),\n );\n}\n\nfunction findDockerfilePath(): string {\n const candidates = [\n resolve(MODULE_DIR, '../../../../../packages/proxy'),\n resolve(MODULE_DIR, '../../../node_modules/@rulemetric/proxy'),\n resolve(MODULE_DIR, '../../../../../node_modules/@rulemetric/proxy'),\n ];\n for (const p of candidates) {\n if (existsSync(join(p, 'Dockerfile'))) return p;\n }\n throw new Error('Could not find proxy Dockerfile. Is @rulemetric/proxy installed?');\n}\n\nfunction dockerImageExists(): boolean {\n const result = spawnSync('docker', ['image', 'inspect', DOCKER_IMAGE], { stdio: 'ignore' });\n return result.status === 0;\n}\n\nfunction dockerContainerRunning(): boolean {\n const result = spawnSync('docker', ['container', 'inspect', '-f', '{{.State.Running}}', DOCKER_CONTAINER], {\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n });\n return result.status === 0 && result.stdout?.trim() === 'true';\n}\n\nexport default class ProxyStart extends BaseCommand {\n static override description = 'Start context capture proxy';\n\n static override examples = [\n '<%= config.bin %> proxy start',\n '<%= config.bin %> proxy start --docker',\n '<%= config.bin %> proxy start --port 9090',\n '<%= config.bin %> proxy start --web',\n ];\n\n static override flags = {\n port: Flags.integer({ char: 'p', default: DEFAULT_PORT, description: 'Proxy listen port' }),\n docker: Flags.boolean({ char: 'd', default: false, description: 'Run proxy in Docker (no local mitmproxy needed)' }),\n web: Flags.boolean({ default: false, description: 'Launch mitmweb debug UI instead of mitmdump (local mode only)' }),\n 'skip-checks': Flags.boolean({ default: false, description: 'Skip prerequisite checks' }),\n build: Flags.boolean({ default: false, description: 'Force rebuild Docker image' }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(ProxyStart);\n const port = flags.port;\n\n if (flags.docker) {\n await this.startDocker(port, flags.build);\n } else {\n await this.startLocal(port, flags.web, flags['skip-checks']);\n }\n }\n\n private async startDocker(port: number, forceBuild: boolean): Promise<void> {\n // Check Docker is available\n try {\n execSync('docker info', { stdio: 'ignore' });\n } catch {\n this.error('Docker is not running. Start Docker Desktop and try again.');\n }\n\n // Check if already running\n if (dockerContainerRunning()) {\n this.error(`Proxy container already running. Stop it first: rulemetric proxy stop`);\n }\n\n // Find the compose file (monorepo root or project root)\n const composeFile = this.findComposeFile();\n\n // Ensure mount dirs exist\n const certDir = join(homedir(), '.mitmproxy');\n mkdirSync(certDir, { recursive: true });\n const tmpDir = process.env.TMPDIR || '/tmp';\n mkdirSync(join(tmpDir, 'rulemetric'), { recursive: true });\n\n // Load auth from env file if not in environment\n const envOverrides: Record<string, string> = {\n PROXY_PORT: String(port),\n RULEMETRIC_PROJECT_PATH: process.cwd(),\n };\n\n if (!process.env.RULEMETRIC_API_KEY && !process.env.RULEMETRIC_ACCESS_TOKEN) {\n const envFile = join(homedir(), '.config', 'rulemetric', 'env');\n if (existsSync(envFile)) {\n for (const line of readFileSync(envFile, 'utf-8').split('\\n')) {\n const trimmed = line.trim();\n if (trimmed && !trimmed.startsWith('#') && trimmed.includes('=')) {\n const [key, ...rest] = trimmed.split('=');\n envOverrides[key] = rest.join('=');\n }\n }\n }\n }\n\n if (composeFile) {\n // Use docker compose\n const composeEnv = { ...process.env, ...envOverrides };\n const buildFlag = forceBuild ? '--build' : '';\n const args = ['compose', '-f', composeFile, 'up', '-d', 'proxy'];\n if (forceBuild) args.splice(4, 0, '--build');\n\n this.log(forceBuild ? 'Building and starting proxy via Docker Compose...' : 'Starting proxy via Docker Compose...');\n const result = spawnSync('docker', args, {\n env: composeEnv,\n stdio: 'inherit',\n });\n\n if (result.status !== 0) {\n this.error('Docker Compose failed. Try: docker compose -f docker-compose.yml up proxy');\n }\n } else {\n // Fallback: raw docker run\n if (forceBuild || !dockerImageExists()) {\n const proxyDir = findDockerfilePath();\n this.log('Building proxy Docker image...');\n const build = spawnSync('docker', ['build', '-t', DOCKER_IMAGE, proxyDir], { stdio: 'inherit' });\n if (build.status !== 0) {\n this.error('Docker build failed');\n }\n }\n\n spawnSync('docker', ['rm', '-f', DOCKER_CONTAINER], { stdio: 'ignore' });\n\n const envArgs: string[] = [];\n for (const [key, val] of Object.entries(envOverrides)) {\n envArgs.push('-e', `${key}=${val}`);\n }\n // Pass through from current env\n for (const key of ['RULEMETRIC_API_URL', 'RULEMETRIC_API_KEY', 'RULEMETRIC_ACCESS_TOKEN']) {\n if (process.env[key]) envArgs.push('-e', `${key}=${process.env[key]}`);\n }\n\n const dockerArgs = [\n 'run', '-d',\n '--name', DOCKER_CONTAINER,\n '-p', `${port}:8787`,\n '-v', `${certDir}:/root/.mitmproxy`,\n '-v', `${join(tmpDir, 'rulemetric')}:/tmp/rulemetric:ro`,\n ...envArgs,\n DOCKER_IMAGE,\n ];\n\n const result = spawnSync('docker', dockerArgs, { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] });\n if (result.status !== 0) {\n this.error(`Failed to start container: ${result.stderr}`);\n }\n }\n\n // Write marker so proxy stop knows it's Docker\n mkdirSync(CONFIG_DIR, { recursive: true });\n writeFileSync(PID_FILE, `docker:${DOCKER_CONTAINER}`);\n\n // Wait for container to be ready\n await new Promise(resolve => setTimeout(resolve, 2000));\n\n const inspectResult = spawnSync('docker', ['container', 'inspect', '-f', '{{.Id}}', DOCKER_CONTAINER], {\n encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'],\n });\n const containerId = inspectResult.stdout?.trim().slice(0, 12) || 'unknown';\n\n this.log(`Proxy running in Docker on localhost:${port} (container: ${containerId})`);\n\n this.log('');\n this.log('View logs: rulemetric proxy logs -f');\n }\n\n private findComposeFile(): string | null {\n const candidates = [\n join(process.cwd(), 'docker-compose.yml'),\n resolve(MODULE_DIR, '../../../../../docker-compose.yml'),\n ];\n for (const p of candidates) {\n if (existsSync(p)) return p;\n }\n return null;\n }\n\n private async startLocal(port: number, useWeb: boolean, skipChecks: boolean): Promise<void> {\n // Check if already running\n if (existsSync(PID_FILE)) {\n const content = readFileSync(PID_FILE, 'utf-8').trim();\n if (content.startsWith('docker:')) {\n this.error('Proxy is running in Docker. Stop it first: rulemetric proxy stop');\n }\n const pid = Number.parseInt(content, 10);\n if (!Number.isNaN(pid)) {\n try {\n process.kill(pid, 0);\n this.error(`Proxy already running (PID ${pid}). Stop it first: rulemetric proxy stop`);\n } catch { /* stale PID, continue */ }\n }\n }\n\n // Check mitmproxy is installed (portable PATH scan \u2014 Windows has no `which`)\n const binary = useWeb ? 'mitmweb' : 'mitmdump';\n if (!findBinary(binary)) {\n this.error(\n `${binary} not found. Use Docker mode instead:\\n` +\n ' rulemetric proxy start --docker\\n\\n' +\n 'Or install mitmproxy locally:\\n' +\n ' pipx install mitmproxy\\n' +\n ' brew install mitmproxy',\n );\n }\n\n // Prerequisite warnings (non-blocking)\n if (!skipChecks) {\n const warnings: string[] = [];\n\n if (!isAuthenticated() && !process.env.RULEMETRIC_API_KEY) {\n const envFile = join(homedir(), '.config', 'rulemetric', 'env');\n let hasEnvAuth = false;\n if (existsSync(envFile)) {\n const content = readFileSync(envFile, 'utf-8');\n hasEnvAuth = content.includes('RULEMETRIC_API_KEY') || content.includes('RULEMETRIC_ACCESS_TOKEN');\n }\n if (!hasEnvAuth) {\n warnings.push('Not authenticated \u2014 snapshots cannot be stored. Run `rulemetric auth login`.');\n }\n }\n\n const certPath = join(homedir(), '.mitmproxy', 'mitmproxy-ca-cert.pem');\n if (!existsSync(certPath)) {\n warnings.push('CA cert not found \u2014 HTTPS interception may fail. Run `rulemetric proxy setup`.');\n }\n\n const settingsPath = join(process.cwd(), '.claude', 'settings.json');\n if (!existsSync(settingsPath)) {\n warnings.push('Session hooks not installed \u2014 snapshots won\\'t link to sessions. Run `rulemetric hooks install`.');\n }\n\n if (warnings.length > 0) {\n for (const w of warnings) {\n this.log(` Warning: ${w}`);\n }\n this.log('');\n }\n }\n\n // Find addon\n const addonPath = findAddonPath();\n\n // Build env \u2014 pass through auth credentials for the reporter\n const env: Record<string, string | undefined> = {\n ...process.env,\n RULEMETRIC_PROJECT_PATH: process.cwd(),\n // Bound to this CLI binary's version. The addon writes this to a\n // version file the gateway watches; on drift the gateway restarts\n // mitmproxy so an upgraded CLI doesn't sit next to a stale proxy.\n RULEMETRIC_CLI_VERSION: this.config.version,\n };\n\n // Load auth from env file if not already in environment\n if (!env.RULEMETRIC_API_KEY && !env.RULEMETRIC_ACCESS_TOKEN) {\n const envFile = join(homedir(), '.config', 'rulemetric', 'env');\n if (existsSync(envFile)) {\n for (const line of readFileSync(envFile, 'utf-8').split('\\n')) {\n const trimmed = line.trim();\n if (trimmed && !trimmed.startsWith('#') && trimmed.includes('=')) {\n const [key, ...rest] = trimmed.split('=');\n env[key] = rest.join('=');\n }\n }\n }\n }\n\n // Ensure config dir exists\n mkdirSync(CONFIG_DIR, { recursive: true });\n\n // Open log file for proxy output (fd for spawn stdio)\n appendFileSync(LOG_FILE, `\\n--- Proxy started at ${new Date().toISOString()} (port ${port}) ---\\n`);\n const logFd = openSync(LOG_FILE, 'a');\n\n // Spawn mitmproxy with output redirected to log file\n const args = [\n '--listen-port', String(port),\n '-s', addonPath,\n '--set', 'console_eventlog_verbosity=info',\n ];\n const child = spawn(binary, args, {\n env,\n stdio: ['ignore', logFd, logFd],\n detached: true,\n });\n\n child.unref();\n\n if (!child.pid) {\n this.error('Failed to start proxy process');\n }\n\n // Brief wait to check if process crashes immediately\n await new Promise<void>((resolve) => {\n let exited = false;\n child.once('exit', (code) => {\n exited = true;\n this.error(`Proxy exited immediately with code ${code}. Check logs:\\n ${LOG_FILE}`);\n });\n setTimeout(() => {\n if (!exited) resolve();\n }, 500);\n });\n\n // Write PID file\n writeFileSync(PID_FILE, String(child.pid));\n\n this.log(`Proxy running on localhost:${port} (PID ${child.pid})`);\n this.log(`Log file: ${LOG_FILE}`);\n\n if (useWeb) {\n this.log('');\n this.log('Debug UI: http://localhost:8081');\n }\n\n this.log('');\n this.log('View logs: rulemetric proxy logs -f');\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["resolve"]
|
|
7
7
|
}
|
|
@@ -12,7 +12,9 @@ import "../../chunk-NSBPE2FW.js";
|
|
|
12
12
|
import { spawnSync } from "node:child_process";
|
|
13
13
|
import { existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
14
14
|
import { homedir } from "node:os";
|
|
15
|
-
import { join, resolve } from "node:path";
|
|
15
|
+
import { dirname, join, resolve } from "node:path";
|
|
16
|
+
import { fileURLToPath } from "node:url";
|
|
17
|
+
var MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
16
18
|
var CONFIG_DIR = join(homedir(), ".config", "rulemetric");
|
|
17
19
|
var PID_FILE = join(CONFIG_DIR, "proxy.pid");
|
|
18
20
|
var ProxyStop = class _ProxyStop extends BaseCommand {
|
|
@@ -69,7 +71,7 @@ var ProxyStop = class _ProxyStop extends BaseCommand {
|
|
|
69
71
|
findComposeFile() {
|
|
70
72
|
const candidates = [
|
|
71
73
|
join(process.cwd(), "docker-compose.yml"),
|
|
72
|
-
resolve(
|
|
74
|
+
resolve(MODULE_DIR, "../../../../../docker-compose.yml")
|
|
73
75
|
];
|
|
74
76
|
for (const p of candidates) {
|
|
75
77
|
if (existsSync(p)) return p;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/commands/proxy/stop.ts"],
|
|
4
|
-
"sourcesContent": ["import { spawnSync } from 'node:child_process';\nimport { existsSync, readFileSync, unlinkSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\nimport { BaseCommand } from '../../base-command.js';\n\nconst CONFIG_DIR = join(homedir(), '.config', 'rulemetric');\nconst PID_FILE = join(CONFIG_DIR, 'proxy.pid');\n\nexport default class ProxyStop extends BaseCommand {\n static override description = 'Stop the context capture proxy';\n\n static override examples = ['<%= config.bin %> proxy stop'];\n\n async run(): Promise<void> {\n await this.parse(ProxyStop);\n\n if (!existsSync(PID_FILE)) {\n this.log('No proxy process found (no PID file).');\n return;\n }\n\n const content = readFileSync(PID_FILE, 'utf-8').trim();\n\n // Docker mode: PID file contains \"docker:<container-name>\"\n if (content.startsWith('docker:')) {\n const containerName = content.slice('docker:'.length);\n // Try docker compose first, fall back to docker stop\n const composeFile = this.findComposeFile();\n if (composeFile) {\n spawnSync('docker', ['compose', '-f', composeFile, 'stop', 'proxy'], { stdio: 'inherit' });\n spawnSync('docker', ['compose', '-f', composeFile, 'rm', '-f', 'proxy'], { stdio: 'ignore' });\n } else {\n spawnSync('docker', ['stop', containerName], { stdio: 'ignore' });\n spawnSync('docker', ['rm', containerName], { stdio: 'ignore' });\n }\n this.log(`Proxy container stopped.`);\n try { unlinkSync(PID_FILE); } catch { /* already gone */ }\n return;\n }\n\n // Local mode: PID file contains a process ID\n const pid = Number.parseInt(content, 10);\n\n if (Number.isNaN(pid)) {\n unlinkSync(PID_FILE);\n this.log('Invalid PID file removed.');\n return;\n }\n\n try {\n process.kill(pid, 'SIGTERM');\n this.log(`Proxy stopped (PID ${pid}).`);\n } catch (err: unknown) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ESRCH') {\n this.log('Proxy process not running (stale PID file removed).');\n } else {\n this.error(`Failed to stop proxy: ${(err as Error).message}`);\n }\n }\n\n try { unlinkSync(PID_FILE); } catch { /* already gone */ }\n\n this.log('');\n this.log('Gateway is still running \u2014 Claude Code will route direct until proxy restarts.');\n }\n\n private findComposeFile(): string | null {\n const candidates = [\n join(process.cwd(), 'docker-compose.yml'),\n resolve(
|
|
5
|
-
"mappings": ";;;;;;;;;;;AAAA,SAAS,iBAAiB;AAC1B,SAAS,YAAY,cAAc,kBAAkB;AACrD,SAAS,eAAe;AACxB,SAAS,MAAM,eAAe;
|
|
4
|
+
"sourcesContent": ["import { spawnSync } from 'node:child_process';\nimport { existsSync, readFileSync, unlinkSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { BaseCommand } from '../../base-command.js';\n\n// MODULE_DIR is undefined on Node < 20.11 (breaks resolve()); derive\n// portably. See onboarding field report 2026-07-07 F1.\nconst MODULE_DIR = dirname(fileURLToPath(import.meta.url));\n\nconst CONFIG_DIR = join(homedir(), '.config', 'rulemetric');\nconst PID_FILE = join(CONFIG_DIR, 'proxy.pid');\n\nexport default class ProxyStop extends BaseCommand {\n static override description = 'Stop the context capture proxy';\n\n static override examples = ['<%= config.bin %> proxy stop'];\n\n async run(): Promise<void> {\n await this.parse(ProxyStop);\n\n if (!existsSync(PID_FILE)) {\n this.log('No proxy process found (no PID file).');\n return;\n }\n\n const content = readFileSync(PID_FILE, 'utf-8').trim();\n\n // Docker mode: PID file contains \"docker:<container-name>\"\n if (content.startsWith('docker:')) {\n const containerName = content.slice('docker:'.length);\n // Try docker compose first, fall back to docker stop\n const composeFile = this.findComposeFile();\n if (composeFile) {\n spawnSync('docker', ['compose', '-f', composeFile, 'stop', 'proxy'], { stdio: 'inherit' });\n spawnSync('docker', ['compose', '-f', composeFile, 'rm', '-f', 'proxy'], { stdio: 'ignore' });\n } else {\n spawnSync('docker', ['stop', containerName], { stdio: 'ignore' });\n spawnSync('docker', ['rm', containerName], { stdio: 'ignore' });\n }\n this.log(`Proxy container stopped.`);\n try { unlinkSync(PID_FILE); } catch { /* already gone */ }\n return;\n }\n\n // Local mode: PID file contains a process ID\n const pid = Number.parseInt(content, 10);\n\n if (Number.isNaN(pid)) {\n unlinkSync(PID_FILE);\n this.log('Invalid PID file removed.');\n return;\n }\n\n try {\n process.kill(pid, 'SIGTERM');\n this.log(`Proxy stopped (PID ${pid}).`);\n } catch (err: unknown) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ESRCH') {\n this.log('Proxy process not running (stale PID file removed).');\n } else {\n this.error(`Failed to stop proxy: ${(err as Error).message}`);\n }\n }\n\n try { unlinkSync(PID_FILE); } catch { /* already gone */ }\n\n this.log('');\n this.log('Gateway is still running \u2014 Claude Code will route direct until proxy restarts.');\n }\n\n private findComposeFile(): string | null {\n const candidates = [\n join(process.cwd(), 'docker-compose.yml'),\n resolve(MODULE_DIR, '../../../../../docker-compose.yml'),\n ];\n for (const p of candidates) {\n if (existsSync(p)) return p;\n }\n return null;\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;AAAA,SAAS,iBAAiB;AAC1B,SAAS,YAAY,cAAc,kBAAkB;AACrD,SAAS,eAAe;AACxB,SAAS,SAAS,MAAM,eAAe;AACvC,SAAS,qBAAqB;AAK9B,IAAM,aAAa,QAAQ,cAAc,YAAY,GAAG,CAAC;AAEzD,IAAM,aAAa,KAAK,QAAQ,GAAG,WAAW,YAAY;AAC1D,IAAM,WAAW,KAAK,YAAY,WAAW;AAE7C,IAAqB,YAArB,MAAqB,mBAAkB,YAAY;AAAA,EACjD,OAAgB,cAAc;AAAA,EAE9B,OAAgB,WAAW,CAAC,8BAA8B;AAAA,EAE1D,MAAM,MAAqB;AACzB,UAAM,KAAK,MAAM,UAAS;AAE1B,QAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,WAAK,IAAI,uCAAuC;AAChD;AAAA,IACF;AAEA,UAAM,UAAU,aAAa,UAAU,OAAO,EAAE,KAAK;AAGrD,QAAI,QAAQ,WAAW,SAAS,GAAG;AACjC,YAAM,gBAAgB,QAAQ,MAAM,UAAU,MAAM;AAEpD,YAAM,cAAc,KAAK,gBAAgB;AACzC,UAAI,aAAa;AACf,kBAAU,UAAU,CAAC,WAAW,MAAM,aAAa,QAAQ,OAAO,GAAG,EAAE,OAAO,UAAU,CAAC;AACzF,kBAAU,UAAU,CAAC,WAAW,MAAM,aAAa,MAAM,MAAM,OAAO,GAAG,EAAE,OAAO,SAAS,CAAC;AAAA,MAC9F,OAAO;AACL,kBAAU,UAAU,CAAC,QAAQ,aAAa,GAAG,EAAE,OAAO,SAAS,CAAC;AAChE,kBAAU,UAAU,CAAC,MAAM,aAAa,GAAG,EAAE,OAAO,SAAS,CAAC;AAAA,MAChE;AACA,WAAK,IAAI,0BAA0B;AACnC,UAAI;AAAE,mBAAW,QAAQ;AAAA,MAAG,QAAQ;AAAA,MAAqB;AACzD;AAAA,IACF;AAGA,UAAM,MAAM,OAAO,SAAS,SAAS,EAAE;AAEvC,QAAI,OAAO,MAAM,GAAG,GAAG;AACrB,iBAAW,QAAQ;AACnB,WAAK,IAAI,2BAA2B;AACpC;AAAA,IACF;AAEA,QAAI;AACF,cAAQ,KAAK,KAAK,SAAS;AAC3B,WAAK,IAAI,sBAAsB,GAAG,IAAI;AAAA,IACxC,SAAS,KAAc;AACrB,YAAM,OAAQ,IAA8B;AAC5C,UAAI,SAAS,SAAS;AACpB,aAAK,IAAI,qDAAqD;AAAA,MAChE,OAAO;AACL,aAAK,MAAM,yBAA0B,IAAc,OAAO,EAAE;AAAA,MAC9D;AAAA,IACF;AAEA,QAAI;AAAE,iBAAW,QAAQ;AAAA,IAAG,QAAQ;AAAA,IAAqB;AAEzD,SAAK,IAAI,EAAE;AACX,SAAK,IAAI,qFAAgF;AAAA,EAC3F;AAAA,EAEQ,kBAAiC;AACvC,UAAM,aAAa;AAAA,MACjB,KAAK,QAAQ,IAAI,GAAG,oBAAoB;AAAA,MACxC,QAAQ,YAAY,mCAAmC;AAAA,IACzD;AACA,eAAW,KAAK,YAAY;AAC1B,UAAI,WAAW,CAAC,EAAG,QAAO;AAAA,IAC5B;AACA,WAAO;AAAA,EACT;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/commands/setup.js
CHANGED
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
getStep,
|
|
7
7
|
isStepId,
|
|
8
8
|
renderDiff
|
|
9
|
-
} from "../chunk-
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
9
|
+
} from "../chunk-TXHL3AUA.js";
|
|
10
|
+
import "../chunk-XN23W5HL.js";
|
|
11
|
+
import "../chunk-OTPC2LXW.js";
|
|
12
12
|
import {
|
|
13
13
|
BaseCommand
|
|
14
14
|
} from "../chunk-SZ7VDCD6.js";
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
InsightsPanel
|
|
3
|
+
} from "../chunk-4SCZK7AL.js";
|
|
1
4
|
import {
|
|
2
5
|
InstructionsPanel
|
|
3
6
|
} from "../chunk-BT6Z6545.js";
|
|
@@ -9,30 +12,27 @@ import {
|
|
|
9
12
|
} from "../chunk-IJGF2ETG.js";
|
|
10
13
|
import {
|
|
11
14
|
LauncherOverlay
|
|
12
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-UPXIO7CG.js";
|
|
16
|
+
import "../chunk-QD6X4L4L.js";
|
|
13
17
|
import "../chunk-DTFXCHHI.js";
|
|
18
|
+
import "../chunk-RH7NHVSK.js";
|
|
14
19
|
import "../chunk-YSEQWCN4.js";
|
|
15
20
|
import "../chunk-W4MZXKZ2.js";
|
|
16
21
|
import {
|
|
17
22
|
FrictionPanel
|
|
18
23
|
} from "../chunk-XC6M4CSW.js";
|
|
19
|
-
import {
|
|
20
|
-
InsightsPanel
|
|
21
|
-
} from "../chunk-4SCZK7AL.js";
|
|
22
24
|
import "../chunk-DQ3KELXD.js";
|
|
23
|
-
import {
|
|
24
|
-
loadApiInsights,
|
|
25
|
-
loadLinkedInstructions,
|
|
26
|
-
loadLocalStats
|
|
27
|
-
} from "../chunk-ZSGKRCKD.js";
|
|
28
|
-
import "../chunk-QD6X4L4L.js";
|
|
29
|
-
import "../chunk-RH7NHVSK.js";
|
|
30
25
|
import {
|
|
31
26
|
DIM,
|
|
32
27
|
ORANGE,
|
|
33
28
|
PERIODS,
|
|
34
29
|
PERIOD_LABELS
|
|
35
30
|
} from "../chunk-QJQS6TUN.js";
|
|
31
|
+
import {
|
|
32
|
+
loadApiInsights,
|
|
33
|
+
loadLinkedInstructions,
|
|
34
|
+
loadLocalStats
|
|
35
|
+
} from "../chunk-ZSGKRCKD.js";
|
|
36
36
|
import "../chunk-F5N6CLJJ.js";
|
|
37
37
|
import {
|
|
38
38
|
readActiveOrg
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
LauncherOverlay
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-UPXIO7CG.js";
|
|
4
|
+
import "../../chunk-QD6X4L4L.js";
|
|
4
5
|
import "../../chunk-DTFXCHHI.js";
|
|
6
|
+
import "../../chunk-RH7NHVSK.js";
|
|
5
7
|
import "../../chunk-YSEQWCN4.js";
|
|
6
8
|
import "../../chunk-W4MZXKZ2.js";
|
|
7
|
-
import "../../chunk-QD6X4L4L.js";
|
|
8
|
-
import "../../chunk-RH7NHVSK.js";
|
|
9
9
|
import "../../chunk-QJQS6TUN.js";
|
|
10
10
|
import "../../chunk-ZRLYHBPN.js";
|
|
11
11
|
import "../../chunk-W2YERO7E.js";
|
package/dist/lib/agent-loop.js
CHANGED
|
@@ -3,25 +3,25 @@ import {
|
|
|
3
3
|
HANDLERS,
|
|
4
4
|
pollForWork,
|
|
5
5
|
runAgentLoop
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-CVMRMSV4.js";
|
|
7
7
|
import "../chunk-JEJ3J5J6.js";
|
|
8
|
+
import "../chunk-RCMXTLQF.js";
|
|
9
|
+
import "../chunk-N5A2IQAK.js";
|
|
8
10
|
import "../chunk-OTOWLUOJ.js";
|
|
9
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-6TPJGYFF.js";
|
|
10
12
|
import "../chunk-Y4BJXXYV.js";
|
|
11
13
|
import "../chunk-W53GKIZQ.js";
|
|
12
|
-
import "../chunk-
|
|
14
|
+
import "../chunk-MUOUV5LY.js";
|
|
15
|
+
import "../chunk-XZXS2W24.js";
|
|
13
16
|
import "../chunk-RQ2TMLKG.js";
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
17
|
+
import "../chunk-VBGUNFKY.js";
|
|
18
|
+
import "../chunk-FZKLLNDS.js";
|
|
19
|
+
import "../chunk-VIYUIQHW.js";
|
|
20
|
+
import "../chunk-DGHWRQXL.js";
|
|
16
21
|
import "../chunk-E3BIT53W.js";
|
|
17
22
|
import "../chunk-QSN77T7C.js";
|
|
18
23
|
import "../chunk-QNSVCSHG.js";
|
|
19
24
|
import "../chunk-3POYC5NA.js";
|
|
20
|
-
import "../chunk-RCMXTLQF.js";
|
|
21
|
-
import "../chunk-N5A2IQAK.js";
|
|
22
|
-
import "../chunk-XZXS2W24.js";
|
|
23
|
-
import "../chunk-FZKLLNDS.js";
|
|
24
|
-
import "../chunk-DGHWRQXL.js";
|
|
25
25
|
import "../chunk-DR5WLIOU.js";
|
|
26
26
|
import "../chunk-J7N3DLH6.js";
|
|
27
27
|
import "../chunk-52WIYRZH.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
cronSuggestInstructions
|
|
3
|
-
} from "../../chunk-
|
|
4
|
-
import "../../chunk-E3BIT53W.js";
|
|
3
|
+
} from "../../chunk-VBGUNFKY.js";
|
|
5
4
|
import "../../chunk-FZKLLNDS.js";
|
|
5
|
+
import "../../chunk-E3BIT53W.js";
|
|
6
6
|
import "../../chunk-OQSQC7VB.js";
|
|
7
7
|
import "../../chunk-EKP32DLN.js";
|
|
8
8
|
import "../../chunk-KRBQLMOP.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
processAnnouncement
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-VIYUIQHW.js";
|
|
4
|
+
import "../../chunk-DGHWRQXL.js";
|
|
4
5
|
import "../../chunk-QSN77T7C.js";
|
|
5
6
|
import "../../chunk-QNSVCSHG.js";
|
|
6
|
-
import "../../chunk-DGHWRQXL.js";
|
|
7
7
|
import "../../chunk-NSBPE2FW.js";
|
|
8
8
|
export {
|
|
9
9
|
processAnnouncement
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
processRunCleanup
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-6TPJGYFF.js";
|
|
4
4
|
import "../../chunk-Y4BJXXYV.js";
|
|
5
|
-
import "../../chunk-QNSVCSHG.js";
|
|
6
5
|
import "../../chunk-DGHWRQXL.js";
|
|
6
|
+
import "../../chunk-QNSVCSHG.js";
|
|
7
7
|
import "../../chunk-F5N6CLJJ.js";
|
|
8
8
|
import "../../chunk-KRBQLMOP.js";
|
|
9
9
|
import "../../chunk-NSBPE2FW.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
processSessionGoal
|
|
3
|
-
} from "../../chunk-
|
|
4
|
-
import "../../chunk-QNSVCSHG.js";
|
|
3
|
+
} from "../../chunk-MUOUV5LY.js";
|
|
5
4
|
import "../../chunk-FZKLLNDS.js";
|
|
5
|
+
import "../../chunk-QNSVCSHG.js";
|
|
6
6
|
import "../../chunk-KRBQLMOP.js";
|
|
7
7
|
import "../../chunk-NSBPE2FW.js";
|
|
8
8
|
export {
|
package/dist/lib/hooks-config.js
CHANGED
package/dist/lib/manual-tasks.js
CHANGED
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
} from "../chunk-RQ2TMLKG.js";
|
|
7
7
|
import {
|
|
8
8
|
cronSuggestInstructions
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-VBGUNFKY.js";
|
|
10
|
+
import "../chunk-FZKLLNDS.js";
|
|
10
11
|
import "../chunk-E3BIT53W.js";
|
|
11
12
|
import "../chunk-QSN77T7C.js";
|
|
12
13
|
import "../chunk-QNSVCSHG.js";
|
|
13
|
-
import "../chunk-FZKLLNDS.js";
|
|
14
14
|
import "../chunk-OQSQC7VB.js";
|
|
15
15
|
import "../chunk-EKP32DLN.js";
|
|
16
16
|
import "../chunk-KRBQLMOP.js";
|
package/dist/lib/setup-steps.js
CHANGED
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
isStepId,
|
|
10
10
|
maskToken,
|
|
11
11
|
renderDiff
|
|
12
|
-
} from "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
12
|
+
} from "../chunk-TXHL3AUA.js";
|
|
13
|
+
import "../chunk-XN23W5HL.js";
|
|
14
|
+
import "../chunk-OTPC2LXW.js";
|
|
15
15
|
import "../chunk-ZRLYHBPN.js";
|
|
16
16
|
import "../chunk-W2YERO7E.js";
|
|
17
17
|
import "../chunk-NSBPE2FW.js";
|
package/oclif.manifest.json
CHANGED
|
@@ -315,7 +315,7 @@
|
|
|
315
315
|
"aliases": [],
|
|
316
316
|
"args": {
|
|
317
317
|
"target": {
|
|
318
|
-
"description": "\"plan\" or a step id (install, auth, hooks, worker
|
|
318
|
+
"description": "\"plan\" or a step id (install, auth, hooks, worker)",
|
|
319
319
|
"name": "target",
|
|
320
320
|
"required": false
|
|
321
321
|
}
|
|
@@ -630,6 +630,57 @@
|
|
|
630
630
|
"revoke-key.js"
|
|
631
631
|
]
|
|
632
632
|
},
|
|
633
|
+
"auth:signup": {
|
|
634
|
+
"aliases": [],
|
|
635
|
+
"args": {},
|
|
636
|
+
"description": "Create a RuleMetric account from the CLI",
|
|
637
|
+
"examples": [
|
|
638
|
+
"<%= config.bin %> auth signup",
|
|
639
|
+
"<%= config.bin %> auth signup -e user@example.com"
|
|
640
|
+
],
|
|
641
|
+
"flags": {
|
|
642
|
+
"api-url": {
|
|
643
|
+
"description": "Override API base URL",
|
|
644
|
+
"env": "RULEMETRIC_API_URL",
|
|
645
|
+
"hidden": true,
|
|
646
|
+
"name": "api-url",
|
|
647
|
+
"hasDynamicHelp": false,
|
|
648
|
+
"multiple": false,
|
|
649
|
+
"type": "option"
|
|
650
|
+
},
|
|
651
|
+
"email": {
|
|
652
|
+
"char": "e",
|
|
653
|
+
"description": "Email address",
|
|
654
|
+
"name": "email",
|
|
655
|
+
"hasDynamicHelp": false,
|
|
656
|
+
"multiple": false,
|
|
657
|
+
"type": "option"
|
|
658
|
+
},
|
|
659
|
+
"password": {
|
|
660
|
+
"char": "p",
|
|
661
|
+
"description": "Password (min 8 chars; for non-interactive use)",
|
|
662
|
+
"name": "password",
|
|
663
|
+
"hasDynamicHelp": false,
|
|
664
|
+
"multiple": false,
|
|
665
|
+
"type": "option"
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
"hasDynamicHelp": false,
|
|
669
|
+
"hiddenAliases": [],
|
|
670
|
+
"id": "auth:signup",
|
|
671
|
+
"pluginAlias": "@rulemetric/cli",
|
|
672
|
+
"pluginName": "@rulemetric/cli",
|
|
673
|
+
"pluginType": "core",
|
|
674
|
+
"strict": true,
|
|
675
|
+
"enableJsonFlag": false,
|
|
676
|
+
"isESM": true,
|
|
677
|
+
"relativePath": [
|
|
678
|
+
"dist",
|
|
679
|
+
"commands",
|
|
680
|
+
"auth",
|
|
681
|
+
"signup.js"
|
|
682
|
+
]
|
|
683
|
+
},
|
|
633
684
|
"auth:status": {
|
|
634
685
|
"aliases": [],
|
|
635
686
|
"args": {},
|
|
@@ -4015,5 +4066,5 @@
|
|
|
4015
4066
|
]
|
|
4016
4067
|
}
|
|
4017
4068
|
},
|
|
4018
|
-
"version": "0.6.
|
|
4069
|
+
"version": "0.6.2"
|
|
4019
4070
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulemetric/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
7
|
"type": "module",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=18.18"
|
|
10
|
+
},
|
|
8
11
|
"bin": {
|
|
9
12
|
"rulemetric": "./bin/run.js"
|
|
10
13
|
},
|
|
@@ -70,9 +73,9 @@
|
|
|
70
73
|
"postgres": "^3.4.0",
|
|
71
74
|
"react": "^19.0.0",
|
|
72
75
|
"zod": "^3.24.0",
|
|
73
|
-
"@rulemetric/hooks": "0.6.
|
|
74
|
-
"@rulemetric/proxy": "0.6.
|
|
75
|
-
"@rulemetric/skills-registry": "0.6.
|
|
76
|
+
"@rulemetric/hooks": "0.6.2",
|
|
77
|
+
"@rulemetric/proxy": "0.6.2",
|
|
78
|
+
"@rulemetric/skills-registry": "0.6.2"
|
|
76
79
|
},
|
|
77
80
|
"//deps": "Worker (`evals agent`) runtime deps: the @opentelemetry/* set, @sentry/node, and postgres are STATIC top-level imports loaded at worker startup (via bundled @rulemetric/{telemetry,db}) — they MUST be runtime deps or a clean `npm i -g` crashes with ModuleLoadError. `better-sqlite3` is optionalDependencies (below): it's a native module, lazy `require()`'d inside a try/catch (packages/session providers cursor/opencode) so a missing binary degrades gracefully — making it a hard dep would break `npm i -g` on platforms without prebuilt binaries. `resend` stays a devDep: lazy `await import('resend')` guarded by RESEND_API_KEY, which end-user workers never set (provider falls back to noop). Classification verified via import-graph scan of dist/commands/evals/agent.js + per-importer static/lazy check.",
|
|
78
81
|
"optionalDependencies": {
|
|
@@ -90,12 +93,12 @@
|
|
|
90
93
|
"tsx": "^4.19.0",
|
|
91
94
|
"typescript": "^5.9.0",
|
|
92
95
|
"vitest": "^3.2.0",
|
|
96
|
+
"@rulemetric/api": "0.0.1",
|
|
97
|
+
"@rulemetric/core": "0.0.1",
|
|
93
98
|
"@rulemetric/db": "0.0.1",
|
|
94
99
|
"@rulemetric/email": "0.0.1",
|
|
95
100
|
"@rulemetric/session": "0.2.1",
|
|
96
|
-
"@rulemetric/api": "0.0.1",
|
|
97
101
|
"@rulemetric/telemetry": "0.0.1",
|
|
98
|
-
"@rulemetric/core": "0.0.1",
|
|
99
102
|
"@rulemetric/typescript-config": "0.0.0"
|
|
100
103
|
},
|
|
101
104
|
"scripts": {
|