@agents-uni/core 0.1.1 → 0.1.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.
@@ -0,0 +1,323 @@
1
+ /**
2
+ * Agency-Agents Bridge
3
+ *
4
+ * 导入 agency-agents 项目的 Agent .md 文件,转换为 agents-uni 的
5
+ * AgentDefinition + SOUL.md 格式,让 193 个高质量 Agent 人格为我所用。
6
+ *
7
+ * 支持两种用法:
8
+ * 1. CLI: `uni import ./path/to/agency-agents/engineering/ --name my-team`
9
+ * 2. API: `importAgencyAgents('./engineering/', { name: 'my-team' })`
10
+ */
11
+ import { readFileSync, readdirSync, statSync } from 'node:fs';
12
+ import { join, basename, extname } from 'node:path';
13
+ // ─── Parsing ─────────────────────────────────
14
+ /**
15
+ * Parse a single agency-agents .md file
16
+ */
17
+ export function parseAgencyAgentFile(filePath) {
18
+ const raw = readFileSync(filePath, 'utf-8');
19
+ const { frontmatter, body } = parseFrontmatter(raw);
20
+ const sections = parseSections(body);
21
+ // Derive ID from filename: "engineering-backend-architect.md" → "backend-architect"
22
+ let id = basename(filePath, extname(filePath));
23
+ // Strip common prefixes (engineering-, design-, marketing-, etc.)
24
+ id = id.replace(/^(engineering|design|marketing|sales|product|testing|support|specialized|spatial-computing|game-development|strategy|academic|paid-media|project-management)-/, '');
25
+ return { filePath, frontmatter, body, sections, id };
26
+ }
27
+ /**
28
+ * Parse YAML frontmatter from markdown
29
+ */
30
+ function parseFrontmatter(raw) {
31
+ const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
32
+ if (!match) {
33
+ return {
34
+ frontmatter: { name: 'Unknown', description: '' },
35
+ body: raw,
36
+ };
37
+ }
38
+ const yamlBlock = match[1];
39
+ const body = match[2];
40
+ // Simple YAML parser for flat key-value (avoids dependency)
41
+ const fm = {};
42
+ for (const line of yamlBlock.split('\n')) {
43
+ const kv = line.match(/^(\w+):\s*(.+)$/);
44
+ if (kv) {
45
+ fm[kv[1]] = kv[2].trim();
46
+ }
47
+ }
48
+ return {
49
+ frontmatter: {
50
+ name: fm.name ?? 'Unknown',
51
+ description: fm.description ?? '',
52
+ emoji: fm.emoji,
53
+ color: fm.color,
54
+ vibe: fm.vibe,
55
+ },
56
+ body,
57
+ };
58
+ }
59
+ /**
60
+ * Extract sections by H2 headers
61
+ */
62
+ function parseSections(body) {
63
+ const sections = new Map();
64
+ const lines = body.split('\n');
65
+ let currentHeader = '';
66
+ let currentContent = [];
67
+ for (const line of lines) {
68
+ const headerMatch = line.match(/^##\s+(.+)$/);
69
+ if (headerMatch) {
70
+ if (currentHeader) {
71
+ sections.set(currentHeader, currentContent.join('\n').trim());
72
+ }
73
+ currentHeader = headerMatch[1].trim();
74
+ currentContent = [];
75
+ }
76
+ else {
77
+ currentContent.push(line);
78
+ }
79
+ }
80
+ if (currentHeader) {
81
+ sections.set(currentHeader, currentContent.join('\n').trim());
82
+ }
83
+ return sections;
84
+ }
85
+ // ─── Conversion ──────────────────────────────
86
+ /**
87
+ * Convert an AgencyAgentFile to an agents-uni AgentDefinition
88
+ */
89
+ export function toAgentDefinition(agent, opts) {
90
+ const rank = opts?.rank ?? 50;
91
+ const department = opts?.department;
92
+ // Extract duties from Core Mission section
93
+ const missionSection = findSection(agent.sections, 'Core Mission') ??
94
+ findSection(agent.sections, 'Mission');
95
+ const duties = extractDuties(missionSection);
96
+ // Infer traits from Identity section
97
+ const traits = {};
98
+ if (opts?.inferTraits !== false) {
99
+ const identitySection = findSection(agent.sections, 'Identity') ??
100
+ findSection(agent.sections, 'Memory');
101
+ if (identitySection) {
102
+ Object.assign(traits, inferTraitsFromText(identitySection));
103
+ }
104
+ }
105
+ return {
106
+ id: agent.id,
107
+ name: agent.frontmatter.name,
108
+ role: {
109
+ title: agent.frontmatter.name,
110
+ duties,
111
+ permissions: [],
112
+ ...(department ? { department } : {}),
113
+ },
114
+ rank,
115
+ ...(Object.keys(traits).length > 0 ? { traits } : {}),
116
+ metadata: {
117
+ source: 'agency-agents',
118
+ emoji: agent.frontmatter.emoji ?? '',
119
+ vibe: agent.frontmatter.vibe ?? '',
120
+ originalFile: agent.filePath,
121
+ },
122
+ };
123
+ }
124
+ /**
125
+ * Generate a SOUL.md that preserves the original agency-agents personality
126
+ * and wraps it with agents-uni organizational context
127
+ */
128
+ export function toSoulMd(agent, opts) {
129
+ const lang = opts?.language ?? 'en';
130
+ const uni = opts?.universe;
131
+ const lines = [];
132
+ // Header
133
+ lines.push(`# ${agent.frontmatter.emoji ?? '🤖'} ${agent.frontmatter.name}`);
134
+ lines.push('');
135
+ if (agent.frontmatter.vibe) {
136
+ lines.push(`> ${agent.frontmatter.vibe}`);
137
+ lines.push('');
138
+ }
139
+ // Organizational context (if universe provided)
140
+ if (uni) {
141
+ const header = lang === 'zh' ? '## 组织背景' : '## Organizational Context';
142
+ lines.push(header);
143
+ lines.push('');
144
+ lines.push(lang === 'zh'
145
+ ? `你是 **${uni.name}** 组织中的一员。`
146
+ : `You are a member of the **${uni.name}** organization.`);
147
+ if (uni.ruler) {
148
+ lines.push('');
149
+ lines.push(lang === 'zh'
150
+ ? `你的一切行动服务于用户(${uni.ruler.title ?? '决策者'})。用户是整个关系网络的核心。`
151
+ : `All your actions serve the user (${uni.ruler.title ?? 'the decision maker'}). The user is at the center of the entire relationship network.`);
152
+ }
153
+ lines.push('');
154
+ }
155
+ // Preserve original personality content
156
+ const divider = lang === 'zh'
157
+ ? '## 核心人格(来自 agency-agents)'
158
+ : '## Core Personality (from agency-agents)';
159
+ lines.push(divider);
160
+ lines.push('');
161
+ lines.push(agent.body.trim());
162
+ lines.push('');
163
+ return lines.join('\n');
164
+ }
165
+ // ─── Batch Import ────────────────────────────
166
+ /**
167
+ * Import all .md agents from a directory (or multiple directories)
168
+ * and generate a UniverseConfig
169
+ */
170
+ export function importAgencyAgents(dirs, opts) {
171
+ const dirList = Array.isArray(dirs) ? dirs : [dirs];
172
+ const warnings = [];
173
+ const agents = [];
174
+ for (const dir of dirList) {
175
+ let files;
176
+ try {
177
+ files = readdirSync(dir).filter((f) => f.endsWith('.md') && !f.startsWith('README'));
178
+ }
179
+ catch {
180
+ warnings.push(`Cannot read directory: ${dir}`);
181
+ continue;
182
+ }
183
+ for (const file of files) {
184
+ const filePath = join(dir, file);
185
+ try {
186
+ if (!statSync(filePath).isFile())
187
+ continue;
188
+ const agent = parseAgencyAgentFile(filePath);
189
+ // Skip files without valid frontmatter (docs, guides, etc.)
190
+ if (agent.frontmatter.name === 'Unknown' && !agent.frontmatter.description) {
191
+ warnings.push(`Skipped non-agent file: ${file}`);
192
+ continue;
193
+ }
194
+ agents.push(agent);
195
+ }
196
+ catch (e) {
197
+ warnings.push(`Failed to parse ${file}: ${e}`);
198
+ }
199
+ }
200
+ }
201
+ // Check for duplicate IDs
202
+ const idCounts = new Map();
203
+ for (const a of agents) {
204
+ idCounts.set(a.id, (idCounts.get(a.id) ?? 0) + 1);
205
+ }
206
+ for (const [id, count] of idCounts) {
207
+ if (count > 1) {
208
+ // Disambiguate by prepending directory name
209
+ let idx = 0;
210
+ for (const a of agents) {
211
+ if (a.id === id) {
212
+ if (idx > 0) {
213
+ const dirName = basename(join(a.filePath, '..'));
214
+ a.id = `${dirName}-${a.id}`;
215
+ }
216
+ idx++;
217
+ }
218
+ }
219
+ }
220
+ }
221
+ // Derive department from directory name
222
+ const department = opts?.department ?? (dirList.length === 1 ? basename(dirList[0]) : undefined);
223
+ // Build AgentDefinitions
224
+ const agentDefs = agents.map((a) => toAgentDefinition(a, {
225
+ rank: opts?.defaultRank ?? 50,
226
+ department,
227
+ inferTraits: opts?.inferTraits,
228
+ }));
229
+ // Build relationships
230
+ const relationships = [];
231
+ if (opts?.relationships === 'peer') {
232
+ // All agents are peers
233
+ for (let i = 0; i < agentDefs.length; i++) {
234
+ for (let j = i + 1; j < agentDefs.length; j++) {
235
+ relationships.push({
236
+ from: agentDefs[i].id,
237
+ to: agentDefs[j].id,
238
+ type: 'peer',
239
+ weight: 0.5,
240
+ });
241
+ }
242
+ }
243
+ }
244
+ else if (opts?.relationships === 'competitive') {
245
+ for (let i = 0; i < agentDefs.length; i++) {
246
+ for (let j = i + 1; j < agentDefs.length; j++) {
247
+ relationships.push({
248
+ from: agentDefs[i].id,
249
+ to: agentDefs[j].id,
250
+ type: 'competitive',
251
+ weight: 0.5,
252
+ });
253
+ }
254
+ }
255
+ }
256
+ const config = {
257
+ name: opts?.name ?? 'imported-universe',
258
+ version: '1.0.0',
259
+ type: opts?.type ?? 'flat',
260
+ description: `Imported from agency-agents (${agents.length} agents)`,
261
+ agents: agentDefs,
262
+ relationships,
263
+ protocols: [],
264
+ governance: {
265
+ decisionModel: opts?.type === 'competitive' ? 'meritocratic' : 'democratic',
266
+ permissionMatrix: [],
267
+ reviewPolicy: { mandatory: false, reviewers: [], maxRounds: 1 },
268
+ escalationRules: [],
269
+ },
270
+ };
271
+ return { config, agents, warnings };
272
+ }
273
+ // ─── Helpers ─────────────────────────────────
274
+ function findSection(sections, keyword) {
275
+ for (const [key, value] of sections) {
276
+ if (key.toLowerCase().includes(keyword.toLowerCase())) {
277
+ return value;
278
+ }
279
+ }
280
+ return undefined;
281
+ }
282
+ function extractDuties(section) {
283
+ if (!section)
284
+ return [];
285
+ const duties = [];
286
+ for (const line of section.split('\n')) {
287
+ const match = line.match(/^###\s+(.+)$/);
288
+ if (match) {
289
+ duties.push(match[1].trim());
290
+ }
291
+ }
292
+ // If no H3 headers found, try bullet points
293
+ if (duties.length === 0) {
294
+ for (const line of section.split('\n')) {
295
+ const match = line.match(/^[-*]\s+\*\*(.+?)\*\*/);
296
+ if (match) {
297
+ duties.push(match[1].trim());
298
+ }
299
+ }
300
+ }
301
+ return duties.slice(0, 8); // Cap at 8 duties
302
+ }
303
+ function inferTraitsFromText(text) {
304
+ const traits = {};
305
+ const lower = text.toLowerCase();
306
+ const traitKeywords = {
307
+ creativity: ['creative', 'innovative', 'imaginative', 'artistic', 'design'],
308
+ precision: ['detail', 'precise', 'meticulous', 'accurate', 'pixel-perfect'],
309
+ speed: ['fast', 'rapid', 'quick', 'agile', 'efficient'],
310
+ collaboration: ['team', 'collaborat', 'cooperat', 'communicate'],
311
+ strategy: ['strateg', 'planning', 'architect', 'systematic'],
312
+ security: ['security', 'secure', 'protect', 'compliance', 'defense'],
313
+ reliability: ['reliable', 'robust', 'stable', 'resilient', 'consistent'],
314
+ };
315
+ for (const [trait, keywords] of Object.entries(traitKeywords)) {
316
+ const hits = keywords.filter((kw) => lower.includes(kw)).length;
317
+ if (hits > 0) {
318
+ traits[trait] = Math.min(0.5 + hits * 0.15, 0.95);
319
+ }
320
+ }
321
+ return traits;
322
+ }
323
+ //# sourceMappingURL=agency-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agency-import.js","sourceRoot":"","sources":["../../src/bridge/agency-import.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Agency-Agents Registry
3
+ *
4
+ * 管理 agency-agents 仓库的本地生命周期:
5
+ * - init: 克隆到 ~/.agents-uni/agency-agents/
6
+ * - update: git pull 拉取最新
7
+ * - list: 列出所有可用分类及 agent 数量
8
+ * - resolve: 将分类名转为目录路径
9
+ *
10
+ * 让用户无需手动 clone 和管理路径。
11
+ */
12
+ /**
13
+ * Categories that contain actual agent .md files
14
+ * (excludes examples, integrations, scripts)
15
+ */
16
+ declare const AGENT_CATEGORIES: readonly ["academic", "design", "engineering", "game-development", "marketing", "paid-media", "product", "project-management", "sales", "spatial-computing", "specialized", "strategy", "support", "testing"];
17
+ export type AgencyCategory = typeof AGENT_CATEGORIES[number];
18
+ export interface AgencyCategoryInfo {
19
+ /** Category name (directory name) */
20
+ name: string;
21
+ /** Number of agent .md files */
22
+ agentCount: number;
23
+ /** Absolute path to the category directory */
24
+ path: string;
25
+ }
26
+ export interface AgencyStatus {
27
+ /** Whether agency-agents is installed locally */
28
+ installed: boolean;
29
+ /** Local directory path */
30
+ dir: string;
31
+ /** Current git commit hash (short) */
32
+ commit?: string;
33
+ /** Last update time (from git log) */
34
+ lastUpdated?: string;
35
+ /** Total agent count across all categories */
36
+ totalAgents?: number;
37
+ /** Category breakdown */
38
+ categories?: AgencyCategoryInfo[];
39
+ }
40
+ export interface AgencyUpdateResult {
41
+ /** Whether new commits were pulled */
42
+ updated: boolean;
43
+ /** Previous commit hash */
44
+ oldCommit: string;
45
+ /** New commit hash */
46
+ newCommit: string;
47
+ /** Summary of changes (git log --oneline) */
48
+ changelog: string[];
49
+ }
50
+ /**
51
+ * Get the local agency-agents directory path
52
+ */
53
+ export declare function getAgencyDir(): string;
54
+ /**
55
+ * Check if agency-agents is installed locally
56
+ */
57
+ export declare function isAgencyInstalled(): boolean;
58
+ /**
59
+ * Clone agency-agents repo to ~/.agents-uni/agency-agents/
60
+ *
61
+ * @param shallow - Use shallow clone (--depth 1) for faster download. Default: true
62
+ * @throws If git is not available or clone fails
63
+ */
64
+ export declare function agencyInit(shallow?: boolean): void;
65
+ /**
66
+ * Pull latest changes from agency-agents repo
67
+ *
68
+ * @returns Update result with old/new commit hashes and changelog
69
+ * @throws If not installed or git pull fails
70
+ */
71
+ export declare function agencyUpdate(): AgencyUpdateResult;
72
+ /**
73
+ * List all available agent categories with agent counts
74
+ */
75
+ export declare function agencyListCategories(): AgencyCategoryInfo[];
76
+ /**
77
+ * Get full status of the local agency-agents installation
78
+ */
79
+ export declare function agencyStatus(): AgencyStatus;
80
+ /**
81
+ * Resolve category names to absolute directory paths
82
+ *
83
+ * @param categories - Category names (e.g., ['engineering', 'design']) or ['all']
84
+ * @returns Array of absolute directory paths
85
+ * @throws If agency-agents is not installed or a category doesn't exist
86
+ */
87
+ export declare function resolveAgencyCategories(categories: string[]): string[];
88
+ /**
89
+ * Get list of valid category names
90
+ */
91
+ export declare function getAvailableCategories(): readonly string[];
92
+ export {};
93
+ //# sourceMappingURL=agency-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agency-registry.d.ts","sourceRoot":"","sources":["../../src/bridge/agency-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH;;;GAGG;AACH,QAAA,MAAM,gBAAgB,+MAeZ,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAI7D,MAAM,WAAW,kBAAkB;IACjC,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,SAAS,EAAE,OAAO,CAAC;IACnB,2BAA2B;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yBAAyB;IACzB,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IACjC,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAID;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,OAAO,UAAO,GAAG,IAAI,CAkB/C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,kBAAkB,CAqDjD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,kBAAkB,EAAE,CAsC3D;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,YAAY,CAoB3C;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CA0BtE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,SAAS,MAAM,EAAE,CAE1D"}
@@ -0,0 +1,250 @@
1
+ /**
2
+ * Agency-Agents Registry
3
+ *
4
+ * 管理 agency-agents 仓库的本地生命周期:
5
+ * - init: 克隆到 ~/.agents-uni/agency-agents/
6
+ * - update: git pull 拉取最新
7
+ * - list: 列出所有可用分类及 agent 数量
8
+ * - resolve: 将分类名转为目录路径
9
+ *
10
+ * 让用户无需手动 clone 和管理路径。
11
+ */
12
+ import { existsSync, readdirSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
13
+ import { join } from 'node:path';
14
+ import { execSync } from 'node:child_process';
15
+ import { homedir } from 'node:os';
16
+ // ─── Constants ───────────────────────────────
17
+ const AGENCY_REPO_URL = 'https://github.com/msitarzewski/agency-agents.git';
18
+ const AGENTS_UNI_HOME = join(homedir(), '.agents-uni');
19
+ const AGENCY_DIR = join(AGENTS_UNI_HOME, 'agency-agents');
20
+ /**
21
+ * Categories that contain actual agent .md files
22
+ * (excludes examples, integrations, scripts)
23
+ */
24
+ const AGENT_CATEGORIES = [
25
+ 'academic',
26
+ 'design',
27
+ 'engineering',
28
+ 'game-development',
29
+ 'marketing',
30
+ 'paid-media',
31
+ 'product',
32
+ 'project-management',
33
+ 'sales',
34
+ 'spatial-computing',
35
+ 'specialized',
36
+ 'strategy',
37
+ 'support',
38
+ 'testing',
39
+ ];
40
+ // ─── Core Functions ──────────────────────────
41
+ /**
42
+ * Get the local agency-agents directory path
43
+ */
44
+ export function getAgencyDir() {
45
+ return AGENCY_DIR;
46
+ }
47
+ /**
48
+ * Check if agency-agents is installed locally
49
+ */
50
+ export function isAgencyInstalled() {
51
+ return existsSync(join(AGENCY_DIR, '.git'));
52
+ }
53
+ /**
54
+ * Clone agency-agents repo to ~/.agents-uni/agency-agents/
55
+ *
56
+ * @param shallow - Use shallow clone (--depth 1) for faster download. Default: true
57
+ * @throws If git is not available or clone fails
58
+ */
59
+ export function agencyInit(shallow = true) {
60
+ if (isAgencyInstalled()) {
61
+ throw new Error(`agency-agents is already installed at ${AGENCY_DIR}. Use agencyUpdate() to pull latest.`);
62
+ }
63
+ // Ensure parent directory exists
64
+ mkdirSync(AGENTS_UNI_HOME, { recursive: true });
65
+ const depthFlag = shallow ? '--depth 1' : '';
66
+ execSync(`git clone ${depthFlag} ${AGENCY_REPO_URL} "${AGENCY_DIR}"`, {
67
+ stdio: 'pipe',
68
+ encoding: 'utf-8',
69
+ });
70
+ // Write metadata
71
+ writeAgencyMeta({ installedAt: new Date().toISOString() });
72
+ }
73
+ /**
74
+ * Pull latest changes from agency-agents repo
75
+ *
76
+ * @returns Update result with old/new commit hashes and changelog
77
+ * @throws If not installed or git pull fails
78
+ */
79
+ export function agencyUpdate() {
80
+ if (!isAgencyInstalled()) {
81
+ throw new Error('agency-agents is not installed. Run `uni agency init` first.');
82
+ }
83
+ const oldCommit = getGitCommit();
84
+ // For shallow clones, unshallow first to enable proper pull
85
+ try {
86
+ const isShallow = existsSync(join(AGENCY_DIR, '.git', 'shallow'));
87
+ if (isShallow) {
88
+ execSync('git fetch --unshallow', { cwd: AGENCY_DIR, stdio: 'pipe' });
89
+ }
90
+ }
91
+ catch {
92
+ // Already unshallowed or not applicable, continue
93
+ }
94
+ execSync('git pull origin main', {
95
+ cwd: AGENCY_DIR,
96
+ stdio: 'pipe',
97
+ encoding: 'utf-8',
98
+ });
99
+ const newCommit = getGitCommit();
100
+ // Get changelog between old and new
101
+ let changelog = [];
102
+ if (oldCommit !== newCommit) {
103
+ try {
104
+ const log = execSync(`git log --oneline ${oldCommit}..${newCommit}`, { cwd: AGENCY_DIR, stdio: 'pipe', encoding: 'utf-8' }).trim();
105
+ changelog = log ? log.split('\n') : [];
106
+ }
107
+ catch {
108
+ changelog = ['(unable to retrieve changelog)'];
109
+ }
110
+ }
111
+ // Update metadata
112
+ writeAgencyMeta({
113
+ ...readAgencyMeta(),
114
+ lastUpdatedAt: new Date().toISOString(),
115
+ });
116
+ return {
117
+ updated: oldCommit !== newCommit,
118
+ oldCommit,
119
+ newCommit,
120
+ changelog,
121
+ };
122
+ }
123
+ /**
124
+ * List all available agent categories with agent counts
125
+ */
126
+ export function agencyListCategories() {
127
+ if (!isAgencyInstalled()) {
128
+ throw new Error('agency-agents is not installed. Run `uni agency init` first.');
129
+ }
130
+ const categories = [];
131
+ for (const cat of AGENT_CATEGORIES) {
132
+ const catDir = join(AGENCY_DIR, cat);
133
+ if (!existsSync(catDir))
134
+ continue;
135
+ const files = readdirSync(catDir).filter((f) => f.endsWith('.md') && !f.startsWith('README'));
136
+ // Count only files with valid frontmatter (actual agents)
137
+ let agentCount = 0;
138
+ for (const file of files) {
139
+ try {
140
+ const content = readFileSync(join(catDir, file), 'utf-8');
141
+ if (content.startsWith('---\n')) {
142
+ agentCount++;
143
+ }
144
+ }
145
+ catch {
146
+ // Skip unreadable files
147
+ }
148
+ }
149
+ categories.push({
150
+ name: cat,
151
+ agentCount,
152
+ path: catDir,
153
+ });
154
+ }
155
+ return categories;
156
+ }
157
+ /**
158
+ * Get full status of the local agency-agents installation
159
+ */
160
+ export function agencyStatus() {
161
+ const installed = isAgencyInstalled();
162
+ if (!installed) {
163
+ return { installed, dir: AGENCY_DIR };
164
+ }
165
+ const commit = getGitCommit();
166
+ const lastUpdated = getGitLastDate();
167
+ const categories = agencyListCategories();
168
+ const totalAgents = categories.reduce((sum, c) => sum + c.agentCount, 0);
169
+ return {
170
+ installed,
171
+ dir: AGENCY_DIR,
172
+ commit,
173
+ lastUpdated,
174
+ totalAgents,
175
+ categories,
176
+ };
177
+ }
178
+ /**
179
+ * Resolve category names to absolute directory paths
180
+ *
181
+ * @param categories - Category names (e.g., ['engineering', 'design']) or ['all']
182
+ * @returns Array of absolute directory paths
183
+ * @throws If agency-agents is not installed or a category doesn't exist
184
+ */
185
+ export function resolveAgencyCategories(categories) {
186
+ if (!isAgencyInstalled()) {
187
+ throw new Error('agency-agents is not installed. Run `uni agency init` first.');
188
+ }
189
+ // Handle --all / 'all'
190
+ if (categories.length === 1 && categories[0] === 'all') {
191
+ return AGENT_CATEGORIES
192
+ .map((cat) => join(AGENCY_DIR, cat))
193
+ .filter((p) => existsSync(p));
194
+ }
195
+ const paths = [];
196
+ for (const cat of categories) {
197
+ const catDir = join(AGENCY_DIR, cat);
198
+ if (!existsSync(catDir)) {
199
+ throw new Error(`Category "${cat}" not found. Available: ${AGENT_CATEGORIES.join(', ')}`);
200
+ }
201
+ paths.push(catDir);
202
+ }
203
+ return paths;
204
+ }
205
+ /**
206
+ * Get list of valid category names
207
+ */
208
+ export function getAvailableCategories() {
209
+ return AGENT_CATEGORIES;
210
+ }
211
+ // ─── Internal Helpers ────────────────────────
212
+ function getGitCommit() {
213
+ try {
214
+ return execSync('git rev-parse --short HEAD', {
215
+ cwd: AGENCY_DIR,
216
+ stdio: 'pipe',
217
+ encoding: 'utf-8',
218
+ }).trim();
219
+ }
220
+ catch {
221
+ return 'unknown';
222
+ }
223
+ }
224
+ function getGitLastDate() {
225
+ try {
226
+ return execSync('git log -1 --format=%ci', {
227
+ cwd: AGENCY_DIR,
228
+ stdio: 'pipe',
229
+ encoding: 'utf-8',
230
+ }).trim();
231
+ }
232
+ catch {
233
+ return 'unknown';
234
+ }
235
+ }
236
+ function readAgencyMeta() {
237
+ const metaPath = join(AGENTS_UNI_HOME, 'agency-meta.json');
238
+ try {
239
+ return JSON.parse(readFileSync(metaPath, 'utf-8'));
240
+ }
241
+ catch {
242
+ return {};
243
+ }
244
+ }
245
+ function writeAgencyMeta(meta) {
246
+ const metaPath = join(AGENTS_UNI_HOME, 'agency-meta.json');
247
+ mkdirSync(AGENTS_UNI_HOME, { recursive: true });
248
+ writeFileSync(metaPath, JSON.stringify(meta, null, 2), 'utf-8');
249
+ }
250
+ //# sourceMappingURL=agency-registry.js.map