@compilr-dev/sdk 0.1.28 → 0.2.1

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 (41) hide show
  1. package/dist/agent.js +16 -4
  2. package/dist/config.d.ts +12 -1
  3. package/dist/index.d.ts +6 -2
  4. package/dist/index.js +27 -1
  5. package/dist/team/activity.d.ts +21 -0
  6. package/dist/team/activity.js +34 -0
  7. package/dist/team/agent-selection.d.ts +53 -0
  8. package/dist/team/agent-selection.js +88 -0
  9. package/dist/team/artifacts.d.ts +175 -0
  10. package/dist/team/artifacts.js +279 -0
  11. package/dist/team/collision-utils.d.ts +16 -0
  12. package/dist/team/collision-utils.js +28 -0
  13. package/dist/team/context-resolver.d.ts +97 -0
  14. package/dist/team/context-resolver.js +322 -0
  15. package/dist/team/custom-agents.d.ts +68 -0
  16. package/dist/team/custom-agents.js +150 -0
  17. package/dist/team/delegation-tracker.d.ts +147 -0
  18. package/dist/team/delegation-tracker.js +215 -0
  19. package/dist/team/index.d.ts +34 -0
  20. package/dist/team/index.js +30 -0
  21. package/dist/team/interfaces.d.ts +36 -0
  22. package/dist/team/interfaces.js +7 -0
  23. package/dist/team/mention-parser.d.ts +64 -0
  24. package/dist/team/mention-parser.js +138 -0
  25. package/dist/team/shared-context.d.ts +293 -0
  26. package/dist/team/shared-context.js +673 -0
  27. package/dist/team/skill-requirements.d.ts +66 -0
  28. package/dist/team/skill-requirements.js +178 -0
  29. package/dist/team/task-assignment.d.ts +69 -0
  30. package/dist/team/task-assignment.js +123 -0
  31. package/dist/team/task-suggestion.d.ts +31 -0
  32. package/dist/team/task-suggestion.js +84 -0
  33. package/dist/team/team-agent.d.ts +201 -0
  34. package/dist/team/team-agent.js +492 -0
  35. package/dist/team/team.d.ts +297 -0
  36. package/dist/team/team.js +615 -0
  37. package/dist/team/tool-config.d.ts +110 -0
  38. package/dist/team/tool-config.js +739 -0
  39. package/dist/team/types.d.ts +211 -0
  40. package/dist/team/types.js +638 -0
  41. package/package.json +1 -1
@@ -0,0 +1,279 @@
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
+ // =============================================================================
12
+ // Constants
13
+ // =============================================================================
14
+ const MAX_SUMMARY_LENGTH = 200;
15
+ // =============================================================================
16
+ // Utilities
17
+ // =============================================================================
18
+ function truncate(str, maxLen) {
19
+ if (str.length <= maxLen)
20
+ return str;
21
+ return str.slice(0, maxLen - 3) + '...';
22
+ }
23
+ // =============================================================================
24
+ // ArtifactStore
25
+ // =============================================================================
26
+ /**
27
+ * Manages artifact storage and retrieval
28
+ */
29
+ export class ArtifactStore {
30
+ artifacts = new Map();
31
+ nameToId = new Map(); // name -> id lookup
32
+ updatedAt = new Date();
33
+ // ---------------------------------------------------------------------------
34
+ // CRUD Operations
35
+ // ---------------------------------------------------------------------------
36
+ /**
37
+ * Create a new artifact
38
+ */
39
+ create(options) {
40
+ const id = `art-${String(Date.now())}-${Math.random().toString(36).slice(2, 8)}`;
41
+ // Generate summary if not provided
42
+ const summary = options.summary ?? this.generateSummary(options.content);
43
+ const artifact = {
44
+ id,
45
+ name: options.name,
46
+ agent: options.agent,
47
+ type: options.type,
48
+ content: options.content,
49
+ summary,
50
+ version: 1,
51
+ createdAt: new Date(),
52
+ updatedAt: new Date(),
53
+ mentions: [],
54
+ referencedBy: [],
55
+ };
56
+ this.artifacts.set(id, artifact);
57
+ this.nameToId.set(options.name.toLowerCase(), id);
58
+ this.updatedAt = new Date();
59
+ return artifact;
60
+ }
61
+ /**
62
+ * Get an artifact by ID
63
+ */
64
+ get(id) {
65
+ return this.artifacts.get(id);
66
+ }
67
+ /**
68
+ * Get an artifact by name (case-insensitive)
69
+ */
70
+ getByName(name) {
71
+ const id = this.nameToId.get(name.toLowerCase());
72
+ if (id) {
73
+ return this.artifacts.get(id);
74
+ }
75
+ return undefined;
76
+ }
77
+ /**
78
+ * Update an artifact
79
+ */
80
+ update(id, options) {
81
+ const artifact = this.artifacts.get(id);
82
+ if (!artifact) {
83
+ return undefined;
84
+ }
85
+ if (options.content !== undefined) {
86
+ artifact.content = options.content;
87
+ // Regenerate summary if content changed and no new summary provided
88
+ if (options.summary === undefined) {
89
+ artifact.summary = this.generateSummary(options.content);
90
+ }
91
+ }
92
+ if (options.summary !== undefined) {
93
+ artifact.summary = options.summary;
94
+ }
95
+ if (options.type !== undefined) {
96
+ artifact.type = options.type;
97
+ }
98
+ artifact.version++;
99
+ artifact.updatedAt = new Date();
100
+ this.updatedAt = new Date();
101
+ return artifact;
102
+ }
103
+ /**
104
+ * Delete an artifact
105
+ */
106
+ delete(id) {
107
+ const artifact = this.artifacts.get(id);
108
+ if (!artifact) {
109
+ return false;
110
+ }
111
+ this.nameToId.delete(artifact.name.toLowerCase());
112
+ this.artifacts.delete(id);
113
+ this.updatedAt = new Date();
114
+ return true;
115
+ }
116
+ /**
117
+ * Rename an artifact
118
+ */
119
+ rename(id, newName) {
120
+ const artifact = this.artifacts.get(id);
121
+ if (!artifact) {
122
+ return undefined;
123
+ }
124
+ // Update name lookup
125
+ this.nameToId.delete(artifact.name.toLowerCase());
126
+ artifact.name = newName;
127
+ this.nameToId.set(newName.toLowerCase(), id);
128
+ artifact.updatedAt = new Date();
129
+ this.updatedAt = new Date();
130
+ return artifact;
131
+ }
132
+ // ---------------------------------------------------------------------------
133
+ // Query Operations
134
+ // ---------------------------------------------------------------------------
135
+ /**
136
+ * List all artifacts
137
+ */
138
+ list() {
139
+ return Array.from(this.artifacts.values());
140
+ }
141
+ /**
142
+ * List artifacts by agent
143
+ */
144
+ listByAgent(agent) {
145
+ return this.list().filter((a) => a.agent === agent);
146
+ }
147
+ /**
148
+ * List artifacts by type
149
+ */
150
+ listByType(type) {
151
+ return this.list().filter((a) => a.type === type);
152
+ }
153
+ /**
154
+ * Search artifacts by name or content
155
+ */
156
+ search(query) {
157
+ const lowerQuery = query.toLowerCase();
158
+ return this.list().filter((a) => a.name.toLowerCase().includes(lowerQuery) ||
159
+ a.content.toLowerCase().includes(lowerQuery) ||
160
+ a.summary.toLowerCase().includes(lowerQuery));
161
+ }
162
+ /**
163
+ * Get artifact count
164
+ */
165
+ get size() {
166
+ return this.artifacts.size;
167
+ }
168
+ /**
169
+ * Check if an artifact exists by name
170
+ */
171
+ has(name) {
172
+ return this.nameToId.has(name.toLowerCase());
173
+ }
174
+ /**
175
+ * Check if an artifact exists by ID
176
+ */
177
+ hasId(id) {
178
+ return this.artifacts.has(id);
179
+ }
180
+ // ---------------------------------------------------------------------------
181
+ // Summary Generation
182
+ // ---------------------------------------------------------------------------
183
+ /**
184
+ * Generate a summary from content
185
+ * Simple extraction of first meaningful lines
186
+ */
187
+ generateSummary(content) {
188
+ // Remove markdown headers and get first meaningful content
189
+ const lines = content
190
+ .split('\n')
191
+ .map((line) => line.trim())
192
+ .filter((line) => line.length > 0 && !line.startsWith('#'));
193
+ const summary = lines.slice(0, 3).join(' ');
194
+ if (summary.length > MAX_SUMMARY_LENGTH) {
195
+ return truncate(summary, MAX_SUMMARY_LENGTH);
196
+ }
197
+ return summary || 'No summary available';
198
+ }
199
+ // ---------------------------------------------------------------------------
200
+ // Index for Shared Context
201
+ // ---------------------------------------------------------------------------
202
+ /**
203
+ * Get summaries for shared context injection
204
+ */
205
+ getSummaries() {
206
+ return this.list()
207
+ .sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime())
208
+ .map((a) => ({
209
+ id: a.id,
210
+ name: a.name,
211
+ agent: a.agent,
212
+ type: a.type,
213
+ summary: a.summary,
214
+ updatedAt: a.updatedAt,
215
+ }));
216
+ }
217
+ // ---------------------------------------------------------------------------
218
+ // Serialization
219
+ // ---------------------------------------------------------------------------
220
+ /**
221
+ * Serialize all artifacts for external persistence
222
+ */
223
+ serialize() {
224
+ return this.list().map((a) => ({
225
+ id: a.id,
226
+ name: a.name,
227
+ agent: a.agent,
228
+ type: a.type,
229
+ content: a.content,
230
+ summary: a.summary,
231
+ version: a.version,
232
+ createdAt: a.createdAt.toISOString(),
233
+ updatedAt: a.updatedAt.toISOString(),
234
+ mentions: a.mentions,
235
+ referencedBy: a.referencedBy,
236
+ }));
237
+ }
238
+ /**
239
+ * Restore artifacts from serialized data
240
+ */
241
+ restore(data) {
242
+ this.artifacts.clear();
243
+ this.nameToId.clear();
244
+ for (const serialized of data) {
245
+ const artifact = {
246
+ id: serialized.id,
247
+ name: serialized.name,
248
+ agent: serialized.agent,
249
+ type: serialized.type,
250
+ content: serialized.content,
251
+ summary: serialized.summary,
252
+ version: serialized.version,
253
+ createdAt: new Date(serialized.createdAt),
254
+ updatedAt: new Date(serialized.updatedAt),
255
+ mentions: serialized.mentions ?? [],
256
+ referencedBy: serialized.referencedBy ?? [],
257
+ };
258
+ this.artifacts.set(artifact.id, artifact);
259
+ this.nameToId.set(artifact.name.toLowerCase(), artifact.id);
260
+ }
261
+ if (data.length > 0) {
262
+ this.updatedAt = new Date(Math.max(...data.map((d) => new Date(d.updatedAt).getTime())));
263
+ }
264
+ }
265
+ /**
266
+ * Clear all artifacts
267
+ */
268
+ clear() {
269
+ this.artifacts.clear();
270
+ this.nameToId.clear();
271
+ this.updatedAt = new Date();
272
+ }
273
+ /**
274
+ * Get the last update timestamp
275
+ */
276
+ getLastUpdated() {
277
+ return this.updatedAt;
278
+ }
279
+ }
@@ -0,0 +1,16 @@
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
+ };
@@ -0,0 +1,28 @@
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 { randomUUID } from '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}_${randomUUID().slice(0, 4)}`;
27
+ return { id: fallback, wasCollision: true };
28
+ }
@@ -0,0 +1,97 @@
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>;