@compilr-dev/cli 0.5.12 → 0.5.14

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.
@@ -4,6 +4,6 @@
4
4
  * Re-exports the project-anchors API for managing persistent
5
5
  * critical information that survives context compaction.
6
6
  */
7
- export { getAnchorManager, getGlobalAnchorManager, clearProjectAnchors, getFormattedAnchors, addAnchor, getAllAnchors, getProjectsWithAnchors, getAnchorStats, clearManagerCache, } from './project-anchors.js';
7
+ export { getAnchorManager, getGlobalAnchorManager, getAnchorStore, setAnchorStore, clearProjectAnchors, getFormattedAnchors, addAnchor, getAllAnchors, getProjectsWithAnchors, getAnchorStats, clearManagerCache, } from './project-anchors.js';
8
8
  export type { Anchor, AnchorInput, AnchorQueryOptions } from './project-anchors.js';
9
9
  export { AnchorManager } from '@compilr-dev/sdk';
@@ -4,6 +4,6 @@
4
4
  * Re-exports the project-anchors API for managing persistent
5
5
  * critical information that survives context compaction.
6
6
  */
7
- export { getAnchorManager, getGlobalAnchorManager, clearProjectAnchors, getFormattedAnchors, addAnchor, getAllAnchors, getProjectsWithAnchors, getAnchorStats, clearManagerCache, } from './project-anchors.js';
7
+ export { getAnchorManager, getGlobalAnchorManager, getAnchorStore, setAnchorStore, clearProjectAnchors, getFormattedAnchors, addAnchor, getAllAnchors, getProjectsWithAnchors, getAnchorStats, clearManagerCache, } from './project-anchors.js';
8
8
  // Re-export the AnchorManager type from agents for consumers
9
9
  export { AnchorManager } from '@compilr-dev/sdk';
@@ -1,79 +1,28 @@
1
1
  /**
2
- * Project Anchors - CLI wrapper for @compilr-dev/agents AnchorManager
2
+ * Project Anchors Thin wrapper around SDK's ProjectAnchorStore.
3
3
  *
4
- * Manages per-project anchor isolation using the library's AnchorManager
5
- * with project-scoped persistence based on CLI's dataPath configuration.
6
- *
7
- * Storage structure:
8
- * {dataPath}/anchors/
9
- * ├── global.json # Non-project anchors
10
- * └── project-{id}.json # Per-project anchors
4
+ * Provides the same function-level API the CLI has always used,
5
+ * backed by the shared ProjectAnchorStore from @compilr-dev/sdk.
11
6
  */
12
- import { AnchorManager } from '@compilr-dev/sdk';
13
- import type { Anchor, AnchorInput, AnchorQueryOptions } from '@compilr-dev/sdk';
7
+ import { ProjectAnchorStore } from '@compilr-dev/sdk';
8
+ import type { Anchor, AnchorInput, AnchorQueryOptions, AnchorManager } from '@compilr-dev/sdk';
14
9
  export type { Anchor, AnchorInput, AnchorQueryOptions };
15
- /**
16
- * Get anchor manager for a project (or global if projectId is null)
17
- *
18
- * Creates a new manager if one doesn't exist, using file-based persistence.
19
- *
20
- * @param projectId - Project ID, or null for global anchors
21
- * @returns AnchorManager instance
22
- */
10
+ /** Get the singleton store (exposed for platform-adapter to use directly). */
11
+ export declare function getAnchorStore(): ProjectAnchorStore;
12
+ /** Replace the singleton store (for platform-adapter to inject one with getCurrentProjectId). */
13
+ export declare function setAnchorStore(s: ProjectAnchorStore): void;
23
14
  export declare function getAnchorManager(projectId: string | null): AnchorManager;
24
- /**
25
- * Get the global anchor manager
26
- */
27
15
  export declare function getGlobalAnchorManager(): AnchorManager;
28
- /**
29
- * Clear all anchors for a project
30
- *
31
- * Should be called when a project is deleted.
32
- *
33
- * @param projectId - Project ID to clear
34
- * @returns Number of anchors removed
35
- */
36
16
  export declare function clearProjectAnchors(projectId: string): number;
37
- /**
38
- * Get formatted anchor content for injection into system prompt
39
- *
40
- * Combines global anchors with project-specific anchors.
41
- *
42
- * @param projectId - Optional project ID to include project anchors
43
- * @returns Formatted anchor string for system prompt
44
- */
45
17
  export declare function getFormattedAnchors(projectId?: string): string;
46
- /**
47
- * Add an anchor
48
- *
49
- * Convenience function that routes to the appropriate manager.
50
- *
51
- * @param input - Anchor input with optional projectId
52
- * @returns Created anchor
53
- */
54
18
  export declare function addAnchor(input: AnchorInput & {
55
19
  projectId?: string;
56
20
  }): Anchor;
57
- /**
58
- * Get all anchors across all managers
59
- *
60
- * @param options - Query options
61
- * @returns Array of all anchors
62
- */
63
21
  export declare function getAllAnchors(options?: AnchorQueryOptions): Anchor[];
64
- /**
65
- * Get list of project IDs that have anchor files
66
- */
67
22
  export declare function getProjectsWithAnchors(): string[];
68
- /**
69
- * Get anchor statistics
70
- */
71
23
  export declare function getAnchorStats(): {
72
24
  globalCount: number;
73
25
  projectCounts: Map<string, number>;
74
26
  totalTokens: number;
75
27
  };
76
- /**
77
- * Clear all cached managers (useful for testing or refresh)
78
- */
79
28
  export declare function clearManagerCache(): void;
@@ -1,202 +1,60 @@
1
1
  /**
2
- * Project Anchors - CLI wrapper for @compilr-dev/agents AnchorManager
2
+ * Project Anchors Thin wrapper around SDK's ProjectAnchorStore.
3
3
  *
4
- * Manages per-project anchor isolation using the library's AnchorManager
5
- * with project-scoped persistence based on CLI's dataPath configuration.
6
- *
7
- * Storage structure:
8
- * {dataPath}/anchors/
9
- * ├── global.json # Non-project anchors
10
- * └── project-{id}.json # Per-project anchors
4
+ * Provides the same function-level API the CLI has always used,
5
+ * backed by the shared ProjectAnchorStore from @compilr-dev/sdk.
11
6
  */
12
- import * as fs from 'fs';
13
- import * as path from 'path';
14
- import { AnchorManager } from '@compilr-dev/sdk';
7
+ import { join } from 'path';
8
+ import { ProjectAnchorStore } from '@compilr-dev/sdk';
15
9
  import { getDataPath } from '../settings/paths.js';
16
10
  // =============================================================================
17
- // State
18
- // =============================================================================
19
- /**
20
- * Cache of anchor managers by project ID (null = global)
21
- */
22
- const managers = new Map();
11
+ // Singleton Store
23
12
  // =============================================================================
24
- // Helpers
25
- // =============================================================================
26
- /**
27
- * Get the anchors directory path
28
- */
29
- function getAnchorsDir() {
30
- return path.join(getDataPath(), 'anchors');
13
+ let store = null;
14
+ function getStore() {
15
+ if (!store) {
16
+ store = new ProjectAnchorStore({
17
+ anchorsDir: join(getDataPath(), 'anchors'),
18
+ getCurrentProjectId: () => undefined, // Overridden by platform-adapter
19
+ });
20
+ }
21
+ return store;
31
22
  }
32
- /**
33
- * Get the persist path for a project (or global)
34
- */
35
- function getPersistPath(projectId) {
36
- const anchorsDir = getAnchorsDir();
37
- const filename = projectId ? `project-${projectId}.json` : 'global.json';
38
- return path.join(anchorsDir, filename);
23
+ /** Get the singleton store (exposed for platform-adapter to use directly). */
24
+ export function getAnchorStore() {
25
+ return getStore();
39
26
  }
40
- /**
41
- * Ensure the anchors directory exists
42
- */
43
- function ensureAnchorsDir() {
44
- const anchorsDir = getAnchorsDir();
45
- if (!fs.existsSync(anchorsDir)) {
46
- fs.mkdirSync(anchorsDir, { recursive: true });
47
- }
27
+ /** Replace the singleton store (for platform-adapter to inject one with getCurrentProjectId). */
28
+ export function setAnchorStore(s) {
29
+ store = s;
48
30
  }
49
31
  // =============================================================================
50
- // Public API
32
+ // Public API (delegates to store)
51
33
  // =============================================================================
52
- /**
53
- * Get anchor manager for a project (or global if projectId is null)
54
- *
55
- * Creates a new manager if one doesn't exist, using file-based persistence.
56
- *
57
- * @param projectId - Project ID, or null for global anchors
58
- * @returns AnchorManager instance
59
- */
60
34
  export function getAnchorManager(projectId) {
61
- if (managers.has(projectId)) {
62
- const existing = managers.get(projectId);
63
- if (existing)
64
- return existing;
65
- }
66
- ensureAnchorsDir();
67
- const manager = new AnchorManager({
68
- persistPath: getPersistPath(projectId),
69
- // Only include default safety anchors for global manager
70
- includeDefaults: projectId === null,
71
- maxAnchors: 50,
72
- maxTokens: 4000,
73
- });
74
- managers.set(projectId, manager);
75
- return manager;
35
+ return getStore().getManager(projectId);
76
36
  }
77
- /**
78
- * Get the global anchor manager
79
- */
80
37
  export function getGlobalAnchorManager() {
81
- return getAnchorManager(null);
38
+ return getStore().getGlobalManager();
82
39
  }
83
- /**
84
- * Clear all anchors for a project
85
- *
86
- * Should be called when a project is deleted.
87
- *
88
- * @param projectId - Project ID to clear
89
- * @returns Number of anchors removed
90
- */
91
40
  export function clearProjectAnchors(projectId) {
92
- const manager = managers.get(projectId);
93
- let removed = 0;
94
- if (manager) {
95
- removed = manager.clear();
96
- managers.delete(projectId);
97
- }
98
- // Also delete the persistence file
99
- const filePath = getPersistPath(projectId);
100
- if (fs.existsSync(filePath)) {
101
- fs.unlinkSync(filePath);
102
- }
103
- return removed;
41
+ return getStore().clearProjectAnchors(projectId);
104
42
  }
105
- /**
106
- * Get formatted anchor content for injection into system prompt
107
- *
108
- * Combines global anchors with project-specific anchors.
109
- *
110
- * @param projectId - Optional project ID to include project anchors
111
- * @returns Formatted anchor string for system prompt
112
- */
113
43
  export function getFormattedAnchors(projectId) {
114
- const parts = [];
115
- // Get global anchors
116
- const globalManager = getGlobalAnchorManager();
117
- const globalFormatted = globalManager.format();
118
- if (globalFormatted) {
119
- parts.push(globalFormatted);
120
- }
121
- // Get project-specific anchors if project ID provided
122
- if (projectId) {
123
- const projectManager = getAnchorManager(projectId);
124
- const projectFormatted = projectManager.format();
125
- if (projectFormatted) {
126
- if (parts.length > 0) {
127
- parts.push(''); // Empty line separator
128
- parts.push(`### Project Anchors (${projectId})`);
129
- }
130
- parts.push(projectFormatted);
131
- }
132
- }
133
- return parts.join('\n');
44
+ return getStore().getFormattedAnchors(projectId);
134
45
  }
135
- /**
136
- * Add an anchor
137
- *
138
- * Convenience function that routes to the appropriate manager.
139
- *
140
- * @param input - Anchor input with optional projectId
141
- * @returns Created anchor
142
- */
143
46
  export function addAnchor(input) {
144
- const manager = getAnchorManager(input.projectId ?? null);
145
- return manager.add(input);
47
+ return getStore().addAnchor(input);
146
48
  }
147
- /**
148
- * Get all anchors across all managers
149
- *
150
- * @param options - Query options
151
- * @returns Array of all anchors
152
- */
153
49
  export function getAllAnchors(options) {
154
- const allAnchors = [];
155
- for (const manager of managers.values()) {
156
- allAnchors.push(...manager.getAll(options));
157
- }
158
- return allAnchors;
50
+ return getStore().getAllAnchors(options);
159
51
  }
160
- /**
161
- * Get list of project IDs that have anchor files
162
- */
163
52
  export function getProjectsWithAnchors() {
164
- const anchorsDir = getAnchorsDir();
165
- if (!fs.existsSync(anchorsDir)) {
166
- return [];
167
- }
168
- const files = fs.readdirSync(anchorsDir);
169
- const projectIds = [];
170
- for (const file of files) {
171
- const match = /^project-(.+)\.json$/.exec(file);
172
- if (match && match[1]) {
173
- projectIds.push(match[1]);
174
- }
175
- }
176
- return projectIds;
53
+ return getStore().getProjectsWithAnchors();
177
54
  }
178
- /**
179
- * Get anchor statistics
180
- */
181
55
  export function getAnchorStats() {
182
- const globalManager = getGlobalAnchorManager();
183
- const projectCounts = new Map();
184
- let totalTokens = globalManager.getTotalTokens();
185
- // Load all project managers to get stats
186
- for (const projectId of getProjectsWithAnchors()) {
187
- const manager = getAnchorManager(projectId);
188
- projectCounts.set(projectId, manager.size);
189
- totalTokens += manager.getTotalTokens();
190
- }
191
- return {
192
- globalCount: globalManager.size,
193
- projectCounts,
194
- totalTokens,
195
- };
56
+ return getStore().getAnchorStats();
196
57
  }
197
- /**
198
- * Clear all cached managers (useful for testing or refresh)
199
- */
200
58
  export function clearManagerCache() {
201
- managers.clear();
59
+ getStore().clearCache();
202
60
  }
Binary file
@@ -4,8 +4,8 @@
4
4
  * Centralized settings management for the CLI.
5
5
  * Persistence in ~/.compilr-dev/settings.json
6
6
  */
7
- export type PermissionMode = 'normal' | 'plan' | 'auto-accept';
8
- export type PermissionLevel = 'always' | 'session' | 'once' | 'deny';
7
+ export type { PermissionRule, PermissionMode, PermissionLevel } from '@compilr-dev/sdk';
8
+ import type { PermissionRule, PermissionMode, PermissionLevel } from '@compilr-dev/sdk';
9
9
  export type NotificationMode = 'auto' | 'bell' | 'disabled';
10
10
  export type ProviderType = 'auto' | 'claude' | 'openai' | 'gemini' | 'ollama' | 'together' | 'groq' | 'fireworks' | 'perplexity' | 'openrouter' | 'custom';
11
11
  export type StartupMode = 'menu' | 'repl';
@@ -14,16 +14,6 @@ export type MascotSetting = 'none' | 'random' | 'neutral' | 'thinking' | 'lookin
14
14
  export type ProjectSessionMode = 'auto' | 'ask' | 'fresh';
15
15
  export type CompactMode = 'active' | 'all' | 'auto';
16
16
  export type Verbosity = 'normal' | 'focused' | 'verbose';
17
- /**
18
- * Permission rule for a tool or pattern.
19
- * Supports wildcards: git_* matches git_commit, git_branch, etc.
20
- */
21
- export interface PermissionRule {
22
- toolName: string;
23
- level: PermissionLevel;
24
- description?: string;
25
- isDefault?: boolean;
26
- }
27
17
  export interface Settings {
28
18
  theme?: string;
29
19
  firstRunComplete: boolean;
@@ -220,7 +210,7 @@ export declare function setRoleTierDefault(roleId: string, tier: 'fast' | 'balan
220
210
  export declare function clearRoleTierDefault(roleId: string): void;
221
211
  /**
222
212
  * Find the permission rule that matches a tool name.
223
- * Supports wildcards: git_* matches git_commit, git_branch, etc.
213
+ * Delegates to SDK's findMatchingRule with the current settings rules.
224
214
  */
225
215
  export declare function findMatchingRule(toolName: string): PermissionRule | null;
226
216
  /**
@@ -231,4 +221,3 @@ export declare function permissionLevelToDisplay(level: PermissionLevel): string
231
221
  * Map display string to permission level
232
222
  */
233
223
  export declare function displayToPermissionLevel(display: string): PermissionLevel;
234
- export {};
@@ -7,6 +7,7 @@
7
7
  import * as fs from 'fs';
8
8
  import * as path from 'path';
9
9
  import * as os from 'os';
10
+ import { DEFAULT_PERMISSION_RULES, findMatchingRule as sdkFindMatchingRule, } from '@compilr-dev/sdk';
10
11
  // =============================================================================
11
12
  // Constants
12
13
  // =============================================================================
@@ -37,19 +38,8 @@ const DEFAULT_SETTINGS = {
37
38
  // Cycle defaults
38
39
  permissionMode: 'normal',
39
40
  notifications: 'auto',
40
- // Default permission rules
41
- permissionRules: [
42
- { toolName: 'bash', level: 'once', description: 'Execute shell commands', isDefault: true },
43
- { toolName: 'write_file', level: 'once', description: 'Write/create files', isDefault: true },
44
- { toolName: 'edit', level: 'once', description: 'Edit file contents', isDefault: true },
45
- { toolName: 'git_commit', level: 'once', description: 'Create git commits', isDefault: true },
46
- { toolName: 'git_branch', level: 'once', description: 'Create/delete branches', isDefault: true },
47
- { toolName: 'run_tests', level: 'once', description: 'Run test suite', isDefault: true },
48
- { toolName: 'run_lint', level: 'once', description: 'Run linter (may auto-fix)', isDefault: true },
49
- { toolName: 'read_file', level: 'always', description: 'Read files', isDefault: true },
50
- { toolName: 'glob', level: 'always', description: 'Find files by pattern', isDefault: true },
51
- { toolName: 'grep', level: 'always', description: 'Search file contents', isDefault: true },
52
- ],
41
+ // Default permission rules (from SDK — shared with desktop)
42
+ permissionRules: [...DEFAULT_PERMISSION_RULES],
53
43
  // Startup default
54
44
  startupMode: 'menu',
55
45
  // Project startup defaults
@@ -517,27 +507,10 @@ export function clearRoleTierDefault(roleId) {
517
507
  }
518
508
  /**
519
509
  * Find the permission rule that matches a tool name.
520
- * Supports wildcards: git_* matches git_commit, git_branch, etc.
510
+ * Delegates to SDK's findMatchingRule with the current settings rules.
521
511
  */
522
512
  export function findMatchingRule(toolName) {
523
- const rules = getPermissionRules();
524
- // First try exact match
525
- const exactMatch = rules.find(r => r.toolName === toolName);
526
- if (exactMatch)
527
- return exactMatch;
528
- // Then try wildcard patterns
529
- for (const rule of rules) {
530
- if (rule.toolName.includes('*')) {
531
- const pattern = rule.toolName
532
- .replace(/[.+?^${}()|[\]\\]/g, '\\$&') // Escape special regex chars
533
- .replace(/\*/g, '.*'); // Convert * to .*
534
- const regex = new RegExp(`^${pattern}$`);
535
- if (regex.test(toolName)) {
536
- return rule;
537
- }
538
- }
539
- }
540
- return null;
513
+ return sdkFindMatchingRule(getPermissionRules(), toolName);
541
514
  }
542
515
  /**
543
516
  * Map permission level to display string
@@ -1,49 +1,11 @@
1
1
  /**
2
- * MCP Configuration Loader
2
+ * MCP Configuration Loader — CLI wrapper
3
3
  *
4
- * Loads MCP server configs from:
5
- * 1. Global: ~/.compilr-dev/mcp.json
6
- * 2. Per-project: <projectRoot>/.compilr-dev/mcp.json
7
- *
8
- * Project config overrides global config (by server name).
9
- * Format is compatible with Claude Desktop / Gemini CLI.
10
- */
11
- /**
12
- * Single MCP server entry in the config file.
13
- * If `command` is present → stdio transport.
14
- * If `url` is present → HTTP transport.
15
- */
16
- export interface MCPServerEntry {
17
- command?: string;
18
- args?: string[];
19
- env?: Record<string, string>;
20
- cwd?: string;
21
- url?: string;
22
- headers?: Record<string, string>;
23
- disabled?: boolean;
24
- timeout?: number;
25
- }
26
- /**
27
- * Shape of the mcp.json config file.
4
+ * Types and file I/O come from @compilr-dev/sdk.
5
+ * This module adds CLI-specific path helpers (global + per-project).
28
6
  */
29
- export interface MCPConfigFile {
30
- mcpServers: Record<string, MCPServerEntry>;
31
- }
32
- /**
33
- * Resolved MCP server config ready for MCPManager.
34
- * Uses the MCPServerConfig shape from @compilr-dev/agents.
35
- */
36
- export interface ResolvedMCPServer {
37
- name: string;
38
- transport: 'stdio' | 'http';
39
- command?: string;
40
- args?: string[];
41
- env?: Record<string, string>;
42
- cwd?: string;
43
- url?: string;
44
- headers?: Record<string, string>;
45
- timeout?: number;
46
- }
7
+ import { loadMCPServers } from '@compilr-dev/sdk';
8
+ export type { MCPServerEntry, MCPConfigFile, ResolvedMCPServer } from '@compilr-dev/sdk';
47
9
  /**
48
10
  * Get the global MCP config file path.
49
11
  */
@@ -55,22 +17,13 @@ export declare function getProjectMCPConfigPath(projectRoot: string): string;
55
17
  /**
56
18
  * Load MCP server configs from global and project-level config files.
57
19
  * Project configs override global by server name.
58
- *
59
- * @param projectRoot - Optional project root for per-project config
60
- * @returns Array of resolved MCP server configs
61
20
  */
62
- export declare function loadMCPConfig(projectRoot?: string): ResolvedMCPServer[];
21
+ export declare function loadMCPConfig(projectRoot?: string): ReturnType<typeof loadMCPServers>;
63
22
  /**
64
23
  * Get existing server names from all config files.
65
- * Useful for validating uniqueness when adding a new server.
66
24
  */
67
25
  export declare function getExistingServerNames(projectRoot?: string): Set<string>;
68
26
  /**
69
27
  * Save a new MCP server entry to the config file.
70
- *
71
- * @param name - Server name (unique identifier)
72
- * @param entry - Server configuration entry
73
- * @param scope - 'global' or 'project'
74
- * @param projectRoot - Required when scope is 'project'
75
28
  */
76
- export declare function saveMCPServer(name: string, entry: MCPServerEntry, scope: 'global' | 'project', projectRoot?: string): void;
29
+ export declare function saveMCPServer(name: string, entry: import('@compilr-dev/sdk').MCPServerEntry, scope: 'global' | 'project', projectRoot?: string): void;