@team-semicolon/semo-cli 4.15.0 → 4.15.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.
@@ -161,9 +161,8 @@ async function syncGlobalCache(claudeDir) {
161
161
  cmdCount++;
162
162
  }
163
163
  }
164
- // 3. 에이전트 설치 (전체 교체, 대소문자 중복 제거)
164
+ // 3. 에이전트 설치 (머지 모드 로컬 YAML frontmatter 보존)
165
165
  const agentsDir = path.join(dir, 'agents');
166
- removeRecursive(agentsDir);
167
166
  fs.mkdirSync(agentsDir, { recursive: true });
168
167
  const seenAgentNames = new Set();
169
168
  const dedupedAgents = [];
@@ -174,30 +173,62 @@ async function syncGlobalCache(claudeDir) {
174
173
  dedupedAgents.push(agent);
175
174
  }
176
175
  }
176
+ // 기존 로컬 파일의 frontmatter 캐싱 (덮어쓰기 전)
177
+ const existingFrontmatters = new Map();
178
+ for (const folder of fs.readdirSync(agentsDir).filter((f) => !f.startsWith('.'))) {
179
+ const filePath = path.join(agentsDir, folder, `${folder}.md`);
180
+ if (fs.existsSync(filePath)) {
181
+ const existing = fs.readFileSync(filePath, 'utf8');
182
+ const fmMatch = existing.match(/^---\n([\s\S]*?)\n---\n/);
183
+ if (fmMatch) {
184
+ existingFrontmatters.set(folder.toLowerCase(), fmMatch[1]);
185
+ }
186
+ }
187
+ }
188
+ // DB에 없는 에이전트 폴더 정리 (orphan 제거)
189
+ const dbAgentNames = new Set(dedupedAgents.map((a) => a.name.toLowerCase()));
190
+ for (const folder of fs.readdirSync(agentsDir).filter((f) => !f.startsWith('.'))) {
191
+ const folderPath = path.join(agentsDir, folder);
192
+ if (!dbAgentNames.has(folder.toLowerCase()) && fs.statSync(folderPath).isDirectory()) {
193
+ removeRecursive(folderPath);
194
+ }
195
+ }
177
196
  for (const agent of dedupedAgents) {
178
197
  const agentFolder = path.join(agentsDir, agent.name);
179
198
  fs.mkdirSync(agentFolder, { recursive: true });
180
- let content = agent.content;
199
+ // DB content에서 frontmatter 제거 (body만 추출)
200
+ let dbBody = agent.content;
201
+ const dbFmMatch = agent.content.match(/^---\n[\s\S]*?\n---\n([\s\S]*)$/);
202
+ if (dbFmMatch) {
203
+ dbBody = dbFmMatch[1].trim();
204
+ }
181
205
  // 위임 매트릭스 주입
182
206
  const agentDelegations = delegations.filter((d) => d.from_bot_id === agent.name);
183
207
  if (agentDelegations.length > 0) {
184
208
  const delegationLines = agentDelegations
185
209
  .map((d) => `- → ${d.to_bot_id}: ${d.domains.join(', ')} (via ${d.method})`)
186
210
  .join('\n');
187
- content += `\n\n## 위임 매트릭스\n${delegationLines}\n`;
211
+ dbBody += `\n\n## 위임 매트릭스\n${delegationLines}\n`;
188
212
  }
189
- // metadata에 model/description이 있으면 YAML frontmatter 주입
190
- if (agent.metadata && (agent.metadata.model || agent.metadata.description)) {
191
- const hasFrontmatter = content.trimStart().startsWith('---');
192
- if (!hasFrontmatter) {
193
- const fm = ['---'];
194
- if (agent.metadata.description)
195
- fm.push(`description: "${agent.metadata.description}"`);
196
- if (agent.metadata.model)
197
- fm.push(`model: "${agent.metadata.model}"`);
198
- fm.push('---', '');
199
- content = fm.join('\n') + content;
200
- }
213
+ // 로컬 frontmatter 보존 (있으면) DB body와 합침
214
+ const localFm = existingFrontmatters.get(agent.name.toLowerCase());
215
+ let content;
216
+ if (localFm) {
217
+ // 로컬 frontmatter 우선 보존 + DB body 업데이트
218
+ content = `---\n${localFm}\n---\n${dbBody}`;
219
+ }
220
+ else if (agent.metadata && (agent.metadata.model || agent.metadata.description)) {
221
+ // 로컬 frontmatter 없으면 metadata에서 생성
222
+ const fm = ['---'];
223
+ if (agent.metadata.description)
224
+ fm.push(`description: "${agent.metadata.description}"`);
225
+ if (agent.metadata.model)
226
+ fm.push(`model: "${agent.metadata.model}"`);
227
+ fm.push('---', '');
228
+ content = fm.join('\n') + dbBody;
229
+ }
230
+ else {
231
+ content = dbBody;
201
232
  }
202
233
  fs.writeFileSync(path.join(agentFolder, `${agent.name}.md`), content);
203
234
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@team-semicolon/semo-cli",
3
- "version": "4.15.0",
3
+ "version": "4.15.1",
4
4
  "description": "SEMO CLI - AI Agent Orchestration Framework Installer",
5
5
  "main": "dist/index.js",
6
6
  "bin": {