@compilr-dev/cli 0.6.1 → 0.6.3

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.
Files changed (64) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +12 -0
  3. package/dist/commands-v2/handlers/core.js +2 -2
  4. package/dist/commands-v2/handlers/index.d.ts +1 -0
  5. package/dist/commands-v2/handlers/index.js +5 -2
  6. package/dist/commands-v2/handlers/perf.d.ts +9 -0
  7. package/dist/commands-v2/handlers/perf.js +66 -0
  8. package/dist/commands-v2/handlers/project.js +2 -3
  9. package/dist/compilr-diff-companion.vsix +0 -0
  10. package/dist/index.js +14 -8
  11. package/dist/repl-v2.js +5 -1
  12. package/dist/session/project-session-manager.js +1 -1
  13. package/dist/slash-autocomplete.js +18 -16
  14. package/dist/tabbed-menu.js +8 -7
  15. package/dist/ui/base/overlay-base.js +2 -1
  16. package/dist/ui/overlay/impl/artifact-detail-overlay-v2.js +12 -7
  17. package/dist/ui/overlay/impl/config-overlay-v2.js +2 -2
  18. package/dist/ui/overlay/impl/document-detail-overlay-v2.js +12 -8
  19. package/dist/ui/overlay/impl/pending-overlay-v2.js +4 -1
  20. package/dist/ui/overlay-manager.js +7 -6
  21. package/dist/ui/terminal-render-item.js +2 -1
  22. package/dist/ui/terminal-renderer.js +1 -2
  23. package/dist/ui/terminal-ui.js +6 -4
  24. package/dist/ui/terminal.d.ts +9 -0
  25. package/dist/ui/terminal.js +28 -15
  26. package/dist/utils/update-checker.d.ts +6 -1
  27. package/dist/utils/update-checker.js +16 -1
  28. package/package.json +5 -4
  29. package/dist/.tsbuildinfo.app +0 -1
  30. package/dist/.tsbuildinfo.data +0 -1
  31. package/dist/.tsbuildinfo.domain +0 -1
  32. package/dist/.tsbuildinfo.foundation +0 -1
  33. package/dist/guide/guide-content.d.ts +0 -23
  34. package/dist/guide/guide-content.js +0 -196
  35. package/dist/multi-agent/activity.d.ts +0 -21
  36. package/dist/multi-agent/activity.js +0 -34
  37. package/dist/multi-agent/agent-selection.d.ts +0 -55
  38. package/dist/multi-agent/agent-selection.js +0 -90
  39. package/dist/multi-agent/artifacts.d.ts +0 -197
  40. package/dist/multi-agent/artifacts.js +0 -379
  41. package/dist/multi-agent/collision-utils.d.ts +0 -16
  42. package/dist/multi-agent/collision-utils.js +0 -28
  43. package/dist/multi-agent/context-resolver.d.ts +0 -97
  44. package/dist/multi-agent/context-resolver.js +0 -316
  45. package/dist/multi-agent/mention-parser.d.ts +0 -64
  46. package/dist/multi-agent/mention-parser.js +0 -146
  47. package/dist/multi-agent/shared-context.d.ts +0 -293
  48. package/dist/multi-agent/shared-context.js +0 -671
  49. package/dist/multi-agent/skill-requirements.d.ts +0 -66
  50. package/dist/multi-agent/skill-requirements.js +0 -178
  51. package/dist/multi-agent/task-assignment.d.ts +0 -69
  52. package/dist/multi-agent/task-assignment.js +0 -123
  53. package/dist/multi-agent/task-suggestion.d.ts +0 -31
  54. package/dist/multi-agent/task-suggestion.js +0 -72
  55. package/dist/multi-agent/team-agent.d.ts +0 -201
  56. package/dist/multi-agent/team-agent.js +0 -488
  57. package/dist/multi-agent/team.d.ts +0 -286
  58. package/dist/multi-agent/team.js +0 -610
  59. package/dist/multi-agent/tool-config.d.ts +0 -110
  60. package/dist/multi-agent/tool-config.js +0 -661
  61. package/dist/multi-agent/types.d.ts +0 -211
  62. package/dist/multi-agent/types.js +0 -617
  63. package/dist/tools/guide-tool.d.ts +0 -12
  64. package/dist/tools/guide-tool.js +0 -59
@@ -1,379 +0,0 @@
1
- /**
2
- * ArtifactStore - Storage for team artifacts
3
- *
4
- * Artifacts are named pieces of work that agents can publish and reference:
5
- * - design: Architecture, API specs, data models
6
- * - plan: Sprint plans, task breakdowns, timelines
7
- * - review: Code reviews, security audits, feedback
8
- * - decision: Architectural decisions, trade-off analysis
9
- * - note: General notes, meeting summaries
10
- */
11
- import * as fs from 'node:fs';
12
- import * as path from 'node:path';
13
- import { truncatePlain as truncate } from '@compilr-dev/ui-core/utils';
14
- // =============================================================================
15
- // Constants
16
- // =============================================================================
17
- const MAX_SUMMARY_LENGTH = 200;
18
- const ARTIFACTS_DIR = 'artifacts';
19
- const INDEX_FILE = 'index.json';
20
- // =============================================================================
21
- // ArtifactStore
22
- // =============================================================================
23
- /**
24
- * Manages artifact storage and retrieval
25
- */
26
- export class ArtifactStore {
27
- basePath;
28
- artifacts = new Map();
29
- nameToId = new Map(); // name -> id lookup
30
- updatedAt = new Date();
31
- constructor(basePath) {
32
- this.basePath = basePath;
33
- }
34
- // ---------------------------------------------------------------------------
35
- // Path Helpers
36
- // ---------------------------------------------------------------------------
37
- /**
38
- * Get the artifacts directory path
39
- */
40
- getArtifactsDir() {
41
- return path.join(this.basePath, ARTIFACTS_DIR);
42
- }
43
- /**
44
- * Get the index file path
45
- */
46
- getIndexPath() {
47
- return path.join(this.getArtifactsDir(), INDEX_FILE);
48
- }
49
- /**
50
- * Get the path for an artifact file
51
- */
52
- getArtifactPath(id) {
53
- return path.join(this.getArtifactsDir(), `${id}.json`);
54
- }
55
- /**
56
- * Ensure artifacts directory exists
57
- */
58
- ensureDir() {
59
- const dir = this.getArtifactsDir();
60
- if (!fs.existsSync(dir)) {
61
- fs.mkdirSync(dir, { recursive: true });
62
- }
63
- }
64
- // ---------------------------------------------------------------------------
65
- // CRUD Operations
66
- // ---------------------------------------------------------------------------
67
- /**
68
- * Create a new artifact
69
- */
70
- create(options) {
71
- const id = `art-${String(Date.now())}-${Math.random().toString(36).slice(2, 8)}`;
72
- // Generate summary if not provided
73
- const summary = options.summary ?? this.generateSummary(options.content);
74
- const artifact = {
75
- id,
76
- name: options.name,
77
- agent: options.agent,
78
- type: options.type,
79
- content: options.content,
80
- summary,
81
- version: 1,
82
- createdAt: new Date(),
83
- updatedAt: new Date(),
84
- mentions: [],
85
- referencedBy: [],
86
- };
87
- this.artifacts.set(id, artifact);
88
- this.nameToId.set(options.name.toLowerCase(), id);
89
- this.updatedAt = new Date();
90
- return artifact;
91
- }
92
- /**
93
- * Get an artifact by ID
94
- */
95
- get(id) {
96
- return this.artifacts.get(id);
97
- }
98
- /**
99
- * Get an artifact by name (case-insensitive)
100
- */
101
- getByName(name) {
102
- const id = this.nameToId.get(name.toLowerCase());
103
- if (id) {
104
- return this.artifacts.get(id);
105
- }
106
- return undefined;
107
- }
108
- /**
109
- * Update an artifact
110
- */
111
- update(id, options) {
112
- const artifact = this.artifacts.get(id);
113
- if (!artifact) {
114
- return undefined;
115
- }
116
- if (options.content !== undefined) {
117
- artifact.content = options.content;
118
- // Regenerate summary if content changed and no new summary provided
119
- if (options.summary === undefined) {
120
- artifact.summary = this.generateSummary(options.content);
121
- }
122
- }
123
- if (options.summary !== undefined) {
124
- artifact.summary = options.summary;
125
- }
126
- if (options.type !== undefined) {
127
- artifact.type = options.type;
128
- }
129
- artifact.version++;
130
- artifact.updatedAt = new Date();
131
- this.updatedAt = new Date();
132
- return artifact;
133
- }
134
- /**
135
- * Delete an artifact
136
- */
137
- delete(id) {
138
- const artifact = this.artifacts.get(id);
139
- if (!artifact) {
140
- return false;
141
- }
142
- this.nameToId.delete(artifact.name.toLowerCase());
143
- this.artifacts.delete(id);
144
- this.updatedAt = new Date();
145
- // Remove file if persisted
146
- const filePath = this.getArtifactPath(id);
147
- if (fs.existsSync(filePath)) {
148
- fs.unlinkSync(filePath);
149
- }
150
- return true;
151
- }
152
- /**
153
- * Rename an artifact
154
- */
155
- rename(id, newName) {
156
- const artifact = this.artifacts.get(id);
157
- if (!artifact) {
158
- return undefined;
159
- }
160
- // Update name lookup
161
- this.nameToId.delete(artifact.name.toLowerCase());
162
- artifact.name = newName;
163
- this.nameToId.set(newName.toLowerCase(), id);
164
- artifact.updatedAt = new Date();
165
- this.updatedAt = new Date();
166
- return artifact;
167
- }
168
- // ---------------------------------------------------------------------------
169
- // Query Operations
170
- // ---------------------------------------------------------------------------
171
- /**
172
- * List all artifacts
173
- */
174
- list() {
175
- return Array.from(this.artifacts.values());
176
- }
177
- /**
178
- * List artifacts by agent
179
- */
180
- listByAgent(agent) {
181
- return this.list().filter(a => a.agent === agent);
182
- }
183
- /**
184
- * List artifacts by type
185
- */
186
- listByType(type) {
187
- return this.list().filter(a => a.type === type);
188
- }
189
- /**
190
- * Search artifacts by name or content
191
- */
192
- search(query) {
193
- const lowerQuery = query.toLowerCase();
194
- return this.list().filter(a => a.name.toLowerCase().includes(lowerQuery) ||
195
- a.content.toLowerCase().includes(lowerQuery) ||
196
- a.summary.toLowerCase().includes(lowerQuery));
197
- }
198
- /**
199
- * Get artifact count
200
- */
201
- get size() {
202
- return this.artifacts.size;
203
- }
204
- /**
205
- * Check if an artifact exists by name
206
- */
207
- has(name) {
208
- return this.nameToId.has(name.toLowerCase());
209
- }
210
- /**
211
- * Check if an artifact exists by ID
212
- */
213
- hasId(id) {
214
- return this.artifacts.has(id);
215
- }
216
- // ---------------------------------------------------------------------------
217
- // Summary Generation
218
- // ---------------------------------------------------------------------------
219
- /**
220
- * Generate a summary from content
221
- * Simple extraction of first meaningful lines
222
- */
223
- generateSummary(content) {
224
- // Remove markdown headers and get first meaningful content
225
- const lines = content
226
- .split('\n')
227
- .map(line => line.trim())
228
- .filter(line => line.length > 0 && !line.startsWith('#'));
229
- const summary = lines.slice(0, 3).join(' ');
230
- if (summary.length > MAX_SUMMARY_LENGTH) {
231
- return truncate(summary, MAX_SUMMARY_LENGTH);
232
- }
233
- return summary || 'No summary available';
234
- }
235
- // ---------------------------------------------------------------------------
236
- // Index for Shared Context
237
- // ---------------------------------------------------------------------------
238
- /**
239
- * Get summaries for shared context injection
240
- */
241
- getSummaries() {
242
- return this.list()
243
- .sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime())
244
- .map(a => ({
245
- id: a.id,
246
- name: a.name,
247
- agent: a.agent,
248
- type: a.type,
249
- summary: a.summary,
250
- updatedAt: a.updatedAt,
251
- }));
252
- }
253
- // ---------------------------------------------------------------------------
254
- // Persistence
255
- // ---------------------------------------------------------------------------
256
- /**
257
- * Save all artifacts to disk
258
- */
259
- save() {
260
- this.ensureDir();
261
- // Save each artifact
262
- for (const artifact of this.artifacts.values()) {
263
- const filePath = this.getArtifactPath(artifact.id);
264
- const serialized = {
265
- id: artifact.id,
266
- name: artifact.name,
267
- agent: artifact.agent,
268
- type: artifact.type,
269
- content: artifact.content,
270
- summary: artifact.summary,
271
- version: artifact.version,
272
- createdAt: artifact.createdAt.toISOString(),
273
- updatedAt: artifact.updatedAt.toISOString(),
274
- mentions: artifact.mentions,
275
- referencedBy: artifact.referencedBy,
276
- };
277
- fs.writeFileSync(filePath, JSON.stringify(serialized, null, 2), 'utf-8');
278
- }
279
- // Save index
280
- this.saveIndex();
281
- }
282
- /**
283
- * Save just the index file
284
- */
285
- saveIndex() {
286
- this.ensureDir();
287
- const index = {
288
- version: 1,
289
- artifacts: this.getSummaries().map(a => ({
290
- id: a.id,
291
- name: a.name,
292
- agent: a.agent,
293
- type: a.type,
294
- summary: a.summary,
295
- updatedAt: a.updatedAt.toISOString(),
296
- })),
297
- updatedAt: this.updatedAt.toISOString(),
298
- };
299
- fs.writeFileSync(this.getIndexPath(), JSON.stringify(index, null, 2), 'utf-8');
300
- }
301
- /**
302
- * Load artifacts from disk
303
- */
304
- load() {
305
- const dir = this.getArtifactsDir();
306
- if (!fs.existsSync(dir)) {
307
- return;
308
- }
309
- // Load index first to get list of artifacts
310
- const indexPath = this.getIndexPath();
311
- if (!fs.existsSync(indexPath)) {
312
- return;
313
- }
314
- try {
315
- const indexContent = fs.readFileSync(indexPath, 'utf-8');
316
- const index = JSON.parse(indexContent);
317
- // Load each artifact file
318
- for (const entry of index.artifacts) {
319
- const filePath = this.getArtifactPath(entry.id);
320
- if (fs.existsSync(filePath)) {
321
- try {
322
- const content = fs.readFileSync(filePath, 'utf-8');
323
- const serialized = JSON.parse(content);
324
- const artifact = {
325
- id: serialized.id,
326
- name: serialized.name,
327
- agent: serialized.agent,
328
- type: serialized.type,
329
- content: serialized.content,
330
- summary: serialized.summary,
331
- version: serialized.version,
332
- createdAt: new Date(serialized.createdAt),
333
- updatedAt: new Date(serialized.updatedAt),
334
- mentions: serialized.mentions ?? [],
335
- referencedBy: serialized.referencedBy ?? [],
336
- };
337
- this.artifacts.set(artifact.id, artifact);
338
- this.nameToId.set(artifact.name.toLowerCase(), artifact.id);
339
- }
340
- catch {
341
- // Skip invalid artifact files
342
- }
343
- }
344
- }
345
- this.updatedAt = new Date(index.updatedAt);
346
- }
347
- catch {
348
- // Index corrupted, start fresh
349
- this.artifacts.clear();
350
- this.nameToId.clear();
351
- }
352
- }
353
- /**
354
- * Clear all artifacts (including from disk)
355
- */
356
- clear() {
357
- // Delete all artifact files
358
- for (const id of this.artifacts.keys()) {
359
- const filePath = this.getArtifactPath(id);
360
- if (fs.existsSync(filePath)) {
361
- fs.unlinkSync(filePath);
362
- }
363
- }
364
- // Delete index
365
- const indexPath = this.getIndexPath();
366
- if (fs.existsSync(indexPath)) {
367
- fs.unlinkSync(indexPath);
368
- }
369
- this.artifacts.clear();
370
- this.nameToId.clear();
371
- this.updatedAt = new Date();
372
- }
373
- /**
374
- * Get the last update timestamp
375
- */
376
- getLastUpdated() {
377
- return this.updatedAt;
378
- }
379
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * Agent ID Collision Prevention
3
- *
4
- * When multiple terminals work on the same project, they may try to add
5
- * agents with the same ID (e.g., both run `/add pm`). This module detects
6
- * and resolves such collisions by querying the session registry for agent
7
- * IDs already in use by other terminals.
8
- */
9
- /**
10
- * Check if an agent ID is in use by another terminal and resolve collisions.
11
- * Returns the original ID if available, or a suffixed variant (e.g., "pm_2").
12
- */
13
- export declare function resolveAgentIdCollision(requestedId: string, localTeamIds: string[], globalAgentIds: string[]): {
14
- id: string;
15
- wasCollision: boolean;
16
- };
@@ -1,28 +0,0 @@
1
- /**
2
- * Agent ID Collision Prevention
3
- *
4
- * When multiple terminals work on the same project, they may try to add
5
- * agents with the same ID (e.g., both run `/add pm`). This module detects
6
- * and resolves such collisions by querying the session registry for agent
7
- * IDs already in use by other terminals.
8
- */
9
- import * as crypto from 'node:crypto';
10
- /**
11
- * Check if an agent ID is in use by another terminal and resolve collisions.
12
- * Returns the original ID if available, or a suffixed variant (e.g., "pm_2").
13
- */
14
- export function resolveAgentIdCollision(requestedId, localTeamIds, globalAgentIds) {
15
- if (!globalAgentIds.includes(requestedId)) {
16
- return { id: requestedId, wasCollision: false };
17
- }
18
- // Try suffixes: pm_2, pm_3, etc.
19
- for (let i = 2; i <= 10; i++) {
20
- const candidate = `${requestedId}_${String(i)}`;
21
- if (!localTeamIds.includes(candidate) && !globalAgentIds.includes(candidate)) {
22
- return { id: candidate, wasCollision: true };
23
- }
24
- }
25
- // Fallback: UUID suffix
26
- const fallback = `${requestedId}_${crypto.randomUUID().slice(0, 4)}`;
27
- return { id: fallback, wasCollision: true };
28
- }
@@ -1,97 +0,0 @@
1
- /**
2
- * ContextResolver - Resolve $agent mentions to actual content
3
- *
4
- * Resolution strategy:
5
- * 1. Check for explicit artifact reference in context hint
6
- * 2. Search artifacts by name/content matching context hint
7
- * 3. Fall back to recent conversation history
8
- *
9
- * Token budgets:
10
- * - Single mention: 2000 tokens max
11
- * - Multiple mentions: 3000 tokens total, split among mentions
12
- */
13
- import type { AgentTeam } from './team.js';
14
- import type { ArtifactStore } from './artifacts.js';
15
- import type { ParsedMention } from './mention-parser.js';
16
- /**
17
- * Resolution source type
18
- */
19
- export type ResolutionSource = 'artifact' | 'history' | 'decision' | 'not_found';
20
- /**
21
- * Resolved mention with content
22
- */
23
- export interface ResolvedMention {
24
- /** Original mention */
25
- mention: ParsedMention;
26
- /** Resolution status */
27
- resolved: boolean;
28
- /** Source of resolution */
29
- source: ResolutionSource;
30
- /** Source name (artifact name, "recent history", etc.) */
31
- sourceName: string;
32
- /** Resolved content to inject */
33
- content: string;
34
- /** Approximate token count */
35
- tokenCount: number;
36
- }
37
- /**
38
- * Options for resolution
39
- */
40
- export interface ResolveOptions {
41
- /** Max tokens per mention (default: 2000) */
42
- maxTokensPerMention?: number;
43
- /** Max total tokens for all mentions (default: 3000) */
44
- maxTotalTokens?: number;
45
- /** Include artifact content (not just summary) */
46
- includeFullArtifact?: boolean;
47
- /** Max history messages to search */
48
- maxHistoryMessages?: number;
49
- }
50
- /**
51
- * Resolve mentions to actual content
52
- */
53
- export declare class ContextResolver {
54
- private readonly team;
55
- private readonly artifactStore;
56
- constructor(team: AgentTeam, artifactStore: ArtifactStore);
57
- /**
58
- * Resolve multiple mentions
59
- */
60
- resolveAll(mentions: ParsedMention[], options?: ResolveOptions): Map<string, ResolvedMention>;
61
- /**
62
- * Resolve a single mention
63
- */
64
- resolveMention(mention: ParsedMention, options?: ResolveOptions): ResolvedMention;
65
- /**
66
- * Resolve from artifacts
67
- */
68
- private resolveFromArtifacts;
69
- /**
70
- * Resolve from conversation history
71
- */
72
- private resolveFromHistory;
73
- /**
74
- * Extract relevant content from messages based on context hint
75
- */
76
- private extractRelevantContent;
77
- /**
78
- * Format a message for injection
79
- */
80
- private formatMessage;
81
- /**
82
- * Format artifact with full content
83
- */
84
- private formatArtifactFull;
85
- /**
86
- * Format artifact with summary only
87
- */
88
- private formatArtifactSummary;
89
- /**
90
- * Truncate content to approximate token count
91
- */
92
- private truncateToTokens;
93
- }
94
- /**
95
- * Build a context map from resolved mentions
96
- */
97
- export declare function buildContextMap(resolved: Map<string, ResolvedMention>): Map<string, string>;