@compilr-dev/cli 0.5.16 → 0.5.17

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/agent.js CHANGED
@@ -5,6 +5,7 @@
5
5
  * ClaudeProvider, OllamaProvider, OpenAIProvider, or GeminiProvider
6
6
  * and available tools.
7
7
  */
8
+ import { log } from './foundation/logger.js';
8
9
  import { Agent, ContextManager, DEFAULT_CONTEXT_CONFIG, createTaskTool, createSuggestTool, defaultAgentTypes, TOOL_SETS, BUILTIN_GUARDRAILS, createProviderFromType, CapabilityManager, CapabilityContext, CAPABILITY_PACKS, GIT_SAFETY_MODULE, PLATFORM_TOOL_HINTS_MODULE, FACTORY_TOOL_HINTS_MODULE, TOOL_USAGE_META_MODULE, createLoadCapabilityTool, createCapabilityHook, resolveProfileGroups, resolveUpfrontGroups, } from '@compilr-dev/sdk';
9
10
  import { isAutoCompactEnabled, isDelegationEnabled, getSetting } from './settings/index.js';
10
11
  import { getApiKey } from './utils/credentials.js';
@@ -165,10 +166,10 @@ export function createAgent(options = {}) {
165
166
  const onEvent = options.verbose
166
167
  ? (event) => {
167
168
  if (event.type === 'tool_start') {
168
- console.log(`\n[Tool: ${event.name}] Starting...`);
169
+ log.debug({ component: 'agent', tool: event.name }, 'Tool starting');
169
170
  }
170
171
  else if (event.type === 'tool_end') {
171
- console.log(`[Tool: ${event.name}] Done`);
172
+ log.debug({ component: 'agent', tool: event.name }, 'Tool done');
172
173
  }
173
174
  }
174
175
  : undefined;
@@ -475,7 +476,7 @@ ${options.systemPromptAddition}
475
476
  // Now uses toolUseId for direct correlation (no more FIFO matching!)
476
477
  onSpawn: (agentType, description, toolUseId) => {
477
478
  if (options.verbose) {
478
- console.log(`\n[Sub-agent] Spawning ${agentType}: ${description} (${toolUseId ?? 'no-id'})`);
479
+ log.debug({ component: 'agent', agentType, toolUseId }, 'Spawning sub-agent: %s', description);
479
480
  }
480
481
  // Immediately notify with toolUseId - no more queuing/matching!
481
482
  if (toolUseId) {
@@ -487,7 +488,7 @@ ${options.systemPromptAddition}
487
488
  },
488
489
  onComplete: (agentType, result, toolUseId) => {
489
490
  if (options.verbose) {
490
- console.log(`[Sub-agent] ${agentType} completed (${String(result.iterations)} iterations)`);
491
+ log.debug({ component: 'agent', agentType, iterations: result.iterations }, 'Sub-agent completed');
491
492
  }
492
493
  // Direct notification with toolUseId - no more searching!
493
494
  if (toolUseId && options.onSubagentEnd) {
@@ -4,6 +4,7 @@
4
4
  * Handles loading, saving, and managing agent definitions.
5
5
  * Loads from both project (.compilr-dev/agents/) and user (~/.compilr-dev/agents/) directories.
6
6
  */
7
+ import { log } from '../foundation/logger.js';
7
8
  import * as fs from 'fs';
8
9
  import * as path from 'path';
9
10
  import { BUILTIN_AGENTS, PROJECT_AGENTS_DIR, USER_AGENTS_DIR, isValidAgentName, isBuiltinAgentName, } from './types.js';
@@ -61,16 +62,16 @@ function loadAgentsFromDir(dir, location) {
61
62
  const content = fs.readFileSync(filePath, 'utf-8');
62
63
  const parsed = parseAgentFile(content);
63
64
  if (!parsed) {
64
- console.warn(`Invalid agent file (no frontmatter): ${filePath}`);
65
+ log.warn({ component: 'agents', filePath }, 'Invalid agent file (no frontmatter)');
65
66
  continue;
66
67
  }
67
68
  const { frontmatter, content: systemPrompt } = parsed;
68
69
  if (!frontmatter.name || !frontmatter.description) {
69
- console.warn(`Invalid agent file (missing fields): ${filePath}`);
70
+ log.warn({ component: 'agents', filePath }, 'Invalid agent file (missing name or description)');
70
71
  continue;
71
72
  }
72
73
  if (!isValidAgentName(frontmatter.name)) {
73
- console.warn(`Invalid agent name: ${frontmatter.name} in ${filePath}`);
74
+ log.warn({ component: 'agents', name: frontmatter.name, filePath }, 'Invalid agent name');
74
75
  continue;
75
76
  }
76
77
  const model = (['sonnet', 'opus', 'haiku', 'inherit'].includes(frontmatter.model || '')
@@ -86,7 +87,7 @@ function loadAgentsFromDir(dir, location) {
86
87
  });
87
88
  }
88
89
  catch (error) {
89
- console.warn(`Failed to load agent file: ${filePath}`, error);
90
+ log.warn({ component: 'agents', filePath, err: error }, 'Failed to load agent file');
90
91
  }
91
92
  }
92
93
  return agents;
@@ -10,6 +10,7 @@
10
10
  * // Show login prompt
11
11
  * }
12
12
  */
13
+ import { log } from '../foundation/logger.js';
13
14
  import { v4 as uuidv4 } from 'uuid';
14
15
  import * as os from 'os';
15
16
  import { loadAuthData, saveAuthData, clearAuthData, updateSession, hasAuthData, checkAuthFilePermissions, } from './storage.js';
@@ -314,9 +315,8 @@ class AuthManager {
314
315
  }
315
316
  const result = await apiRefreshToken(this.authData.session.refreshToken);
316
317
  if (!result.success || !result.access_token || !result.refresh_token) {
317
- // Debug: log refresh failure details
318
- console.error('[auth] Token refresh failed:', result.error ?? 'missing token fields');
319
- console.error('[auth] API_BASE_URL:', process.env.COMPILR_API_URL ?? '(not set, using compilr.dev)');
318
+ log.error({ component: 'auth', error: result.error ?? 'missing token fields' }, 'Token refresh failed');
319
+ log.error({ component: 'auth', apiBaseUrl: process.env.COMPILR_API_URL ?? '(not set, using compilr.dev)' }, 'API base URL at time of failure');
320
320
  return false;
321
321
  }
322
322
  // Calculate expiry from expires_in (seconds), default to 1 hour
@@ -4,6 +4,7 @@
4
4
  * Handles loading, saving, and managing custom command definitions.
5
5
  * Loads from both project (.compilr-dev/commands/) and user (~/.compilr-dev/commands/) directories.
6
6
  */
7
+ import { log } from '../foundation/logger.js';
7
8
  import * as fs from 'fs';
8
9
  import * as path from 'path';
9
10
  import { PROJECT_COMMANDS_DIR, USER_COMMANDS_DIR, isValidCommandName, } from './types.js';
@@ -88,11 +89,11 @@ function loadCommandsFromDir(dir, location) {
88
89
  // Name from filename (without .md extension)
89
90
  const name = path.basename(file, '.md');
90
91
  if (!isValidCommandName(name)) {
91
- console.warn(`Invalid command name: ${name} in ${filePath}`);
92
+ log.warn({ component: 'commands', name, filePath }, 'Invalid command name');
92
93
  continue;
93
94
  }
94
95
  if (!parsed.content) {
95
- console.warn(`Empty command file: ${filePath}`);
96
+ log.warn({ component: 'commands', filePath }, 'Empty command file');
96
97
  continue;
97
98
  }
98
99
  commands.push({
@@ -104,7 +105,7 @@ function loadCommandsFromDir(dir, location) {
104
105
  });
105
106
  }
106
107
  catch (error) {
107
- console.warn(`Failed to load command file: ${filePath}`, error);
108
+ log.warn({ component: 'commands', filePath, err: error }, 'Failed to load command file');
108
109
  }
109
110
  }
110
111
  return commands;
Binary file
@@ -0,0 +1,9 @@
1
+ /**
2
+ * CLI logger instance.
3
+ *
4
+ * Diagnostic logging only — NOT for user-facing terminal output.
5
+ * User-facing output uses TerminalUI/TerminalRenderer.
6
+ *
7
+ * Logs are written to ~/.compilr-dev/logs/cli.log (rotated, 10MB x 5).
8
+ */
9
+ export declare const log: import("@compilr-dev/logger").Logger;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * CLI logger instance.
3
+ *
4
+ * Diagnostic logging only — NOT for user-facing terminal output.
5
+ * User-facing output uses TerminalUI/TerminalRenderer.
6
+ *
7
+ * Logs are written to ~/.compilr-dev/logs/cli.log (rotated, 10MB x 5).
8
+ */
9
+ import { join } from 'path';
10
+ import { homedir } from 'os';
11
+ import { createLogger } from '@compilr-dev/logger';
12
+ const logDir = join(homedir(), '.compilr-dev', 'logs');
13
+ export const log = createLogger({
14
+ package: 'cli',
15
+ filePath: join(logDir, 'cli.log'),
16
+ });
package/dist/repl-v2.js CHANGED
@@ -10,6 +10,7 @@
10
10
  * Or imported and used with a real agent from index.ts
11
11
  */
12
12
  import { appendFileSync } from 'fs';
13
+ import { log } from './foundation/logger.js';
13
14
  import { generateEditDiff, generateWriteDiff } from './ui/diff.js';
14
15
  import { getPendingRequestsManager, setActiveSharedContext } from './multi-agent/index.js';
15
16
  import { parseInputForMentions, hasReferences, buildMessageWithContext, ContextResolver, buildContextMap, } from './multi-agent/index.js';
@@ -153,11 +154,11 @@ ${JSON.stringify(state.messages, null, 2)}
153
154
 
154
155
  `;
155
156
  appendFileSync(DEBUG_LOG_FILE, logEntry);
156
- console.log(`[DEBUG] Request #${String(debugRequestCount)} logged to ${DEBUG_LOG_FILE}`);
157
- console.log(`[DEBUG] Estimated: sys:${String(systemPromptTokens)}tok + msg:${String(messagesTokens)}tok + tools:${String(totalToolTokens)}tok = ${String(totalEstimate)}tok`);
157
+ log.debug({ component: 'repl', requestNum: debugRequestCount, file: DEBUG_LOG_FILE }, 'Debug request logged');
158
+ log.debug({ component: 'repl', systemPromptTokens, messagesTokens, totalToolTokens, totalEstimate }, 'Token estimate');
158
159
  }
159
160
  catch (error) {
160
- console.error('[DEBUG] Failed to log agent request:', error);
161
+ log.error({ component: 'repl', err: error }, 'Failed to log agent request');
161
162
  }
162
163
  }
163
164
  // =============================================================================
@@ -4,6 +4,7 @@
4
4
  * Centralized settings management for the CLI.
5
5
  * Persistence in ~/.compilr-dev/settings.json
6
6
  */
7
+ import { log } from '../foundation/logger.js';
7
8
  import * as fs from 'fs';
8
9
  import * as path from 'path';
9
10
  import * as os from 'os';
@@ -89,7 +90,7 @@ function saveToDisk(settings) {
89
90
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(settings, null, 2), 'utf-8');
90
91
  }
91
92
  catch (error) {
92
- console.error('Failed to save settings:', error);
93
+ log.error({ component: 'settings', err: error }, 'Failed to save settings');
93
94
  }
94
95
  }
95
96
  // =============================================================================
@@ -9,6 +9,7 @@
9
9
  * 2. Config file (~/.compilr-dev/settings.json)
10
10
  * 3. Default/derived value
11
11
  */
12
+ import { log } from '../foundation/logger.js';
12
13
  import * as fs from 'fs';
13
14
  import * as path from 'path';
14
15
  import * as os from 'os';
@@ -60,7 +61,7 @@ function savePathConfig(pathConfig) {
60
61
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2), 'utf-8');
61
62
  }
62
63
  catch (error) {
63
- console.error('Failed to save path config:', error);
64
+ log.error({ component: 'settings', err: error }, 'Failed to save path config');
64
65
  }
65
66
  }
66
67
  /**
@@ -11,6 +11,7 @@
11
11
  * Single point of terminal output. All rendering goes through this class.
12
12
  * Eliminates race conditions by ensuring only one writer.
13
13
  */
14
+ import { log } from '../foundation/logger.js';
14
15
  import { EventEmitter } from 'events';
15
16
  import { RenderMode, isValidTransition } from './render-modes.js';
16
17
  // Re-export RenderMode for convenience
@@ -721,8 +722,7 @@ export class TerminalRenderer extends EventEmitter {
721
722
  */
722
723
  log(message) {
723
724
  if (this.debug) {
724
- const timestamp = new Date().toISOString().slice(11, 23);
725
- console.error(`[TerminalRenderer ${timestamp}] ${message}`);
725
+ log.debug({ component: 'terminal-renderer' }, message);
726
726
  }
727
727
  }
728
728
  }
@@ -54,13 +54,16 @@ function getMasterKey() {
54
54
  }
55
55
  }
56
56
  /**
57
- * Derive encryption key from master key + machine identifiers
57
+ * Derive encryption key from master key + username.
58
+ * NOTE: hostname was removed from derivation because Docker/devcontainers
59
+ * generate random hostnames on each rebuild, breaking credential decryption.
60
+ * The mk is a 32-byte random value unique per installation — sufficient entropy.
58
61
  */
59
62
  function deriveKey() {
60
63
  const mk = getMasterKey();
61
- const machineId = `${os.hostname()}:${os.userInfo().username}`;
64
+ const userId = os.userInfo().username;
62
65
  // Use scrypt for key derivation (secure, slow by design)
63
- return crypto.scryptSync(`${mk}:${machineId}`, SALT, 32);
66
+ return crypto.scryptSync(`${mk}:${userId}`, SALT, 32);
64
67
  }
65
68
  // =============================================================================
66
69
  // Encryption/Decryption
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compilr-dev/cli",
3
- "version": "0.5.16",
3
+ "version": "0.5.17",
4
4
  "description": "AI-powered coding assistant CLI using @compilr-dev/agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -50,15 +50,16 @@
50
50
  "LICENSE"
51
51
  ],
52
52
  "engines": {
53
- "node": ">=20.0.0"
53
+ "node": ">=22.0.0"
54
54
  },
55
55
  "dependencies": {
56
56
  "@anthropic-ai/sdk": "^0.74.0",
57
57
  "@compilr-dev/agents": "^0.3.26",
58
58
  "@compilr-dev/agents-coding": "^1.0.4",
59
59
  "@compilr-dev/editor-core": "^0.0.2",
60
- "@compilr-dev/factory": "^0.1.12",
61
- "@compilr-dev/sdk": "^0.3.0",
60
+ "@compilr-dev/factory": "^0.1.19",
61
+ "@compilr-dev/logger": "^0.1.0",
62
+ "@compilr-dev/sdk": "^0.7.1",
62
63
  "@compilr-dev/ui-core": "^0.0.1",
63
64
  "@modelcontextprotocol/sdk": "^1.23.0",
64
65
  "better-sqlite3": "^12.5.0",