@deimoscloud/coreai 0.1.15 → 0.1.16

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 (47) hide show
  1. package/agents/android-engineer.md +289 -0
  2. package/agents/backend-engineer.md +287 -0
  3. package/agents/database-administrator.md +289 -0
  4. package/agents/devops-engineer.md +323 -0
  5. package/agents/{examples/engineering-manager.md → engineering-manager.md} +208 -171
  6. package/agents/frontend-engineer.md +287 -0
  7. package/agents/product-manager.md +371 -0
  8. package/agents/react-engineer.md +289 -0
  9. package/agents/react-native-engineer.md +289 -0
  10. package/agents/software-security-engineer.md +451 -0
  11. package/agents/software-solutions-architect.md +469 -0
  12. package/agents/sre-huawei-cloud-architect.md +289 -0
  13. package/agents/sre-iac-specialist.md +289 -0
  14. package/agents/sre-kubernetes-specialist.md +289 -0
  15. package/agents/sre-network-specialist.md +289 -0
  16. package/agents/wearos-engineer.md +289 -0
  17. package/dist/cli/index.js +291 -216
  18. package/dist/cli/index.js.map +1 -1
  19. package/dist/index.d.ts +41 -55
  20. package/dist/index.js +275 -205
  21. package/dist/index.js.map +1 -1
  22. package/package.json +1 -1
  23. package/agents/android-engineer.yaml +0 -108
  24. package/agents/backend-engineer.yaml +0 -106
  25. package/agents/database-administrator.yaml +0 -108
  26. package/agents/devops-engineer.yaml +0 -106
  27. package/agents/engineering-manager.yaml +0 -104
  28. package/agents/examples/android-engineer.md +0 -302
  29. package/agents/examples/backend-engineer.md +0 -320
  30. package/agents/examples/devops-engineer.md +0 -742
  31. package/agents/examples/frontend-engineer.md +0 -58
  32. package/agents/examples/product-manager.md +0 -315
  33. package/agents/examples/qa-engineer.md +0 -371
  34. package/agents/examples/security-engineer.md +0 -525
  35. package/agents/examples/solutions-architect.md +0 -351
  36. package/agents/examples/wearos-engineer.md +0 -359
  37. package/agents/frontend-engineer.yaml +0 -106
  38. package/agents/product-manager.yaml +0 -109
  39. package/agents/react-engineer.yaml +0 -108
  40. package/agents/react-native-engineer.yaml +0 -108
  41. package/agents/software-security-engineer.yaml +0 -108
  42. package/agents/software-solutions-architect.yaml +0 -107
  43. package/agents/sre-huawei-cloud-architect.yaml +0 -108
  44. package/agents/sre-iac-specialist.yaml +0 -108
  45. package/agents/sre-kubernetes-specialist.yaml +0 -108
  46. package/agents/sre-network-specialist.yaml +0 -108
  47. package/agents/wearos-engineer.yaml +0 -108
package/dist/cli/index.js CHANGED
@@ -6,7 +6,7 @@ import { fileURLToPath as fileURLToPath2 } from "url";
6
6
  import { Command } from "commander";
7
7
 
8
8
  // src/index.ts
9
- import { readFileSync as readFileSync6 } from "fs";
9
+ import { readFileSync as readFileSync7 } from "fs";
10
10
  import { dirname as dirname5, join as join8 } from "path";
11
11
  import { fileURLToPath } from "url";
12
12
 
@@ -153,6 +153,61 @@ var AgentError = class extends Error {
153
153
  this.name = "AgentError";
154
154
  }
155
155
  };
156
+ function extractFrontmatter(content) {
157
+ const match = content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
158
+ if (!match) {
159
+ throw new AgentError(
160
+ "No YAML frontmatter found. Agent MD files must start with YAML frontmatter (---)",
161
+ "PARSE_ERROR"
162
+ );
163
+ }
164
+ const frontmatterYaml = match[1];
165
+ const body = match[2] ?? "";
166
+ let frontmatter;
167
+ try {
168
+ frontmatter = parseYaml2(frontmatterYaml);
169
+ } catch (error) {
170
+ const message = error instanceof Error ? error.message : "Unknown parse error";
171
+ throw new AgentError(`Failed to parse YAML frontmatter: ${message}`, "PARSE_ERROR", error);
172
+ }
173
+ if (!frontmatter || typeof frontmatter !== "object") {
174
+ throw new AgentError("Invalid frontmatter: expected an object", "PARSE_ERROR");
175
+ }
176
+ return { frontmatter, body };
177
+ }
178
+ function loadAgentFromMdFile(filePath) {
179
+ if (!existsSync2(filePath)) {
180
+ throw new AgentError(`Agent file not found: ${filePath}`, "NOT_FOUND");
181
+ }
182
+ let content;
183
+ try {
184
+ content = readFileSync2(filePath, "utf-8");
185
+ } catch (error) {
186
+ const message = error instanceof Error ? error.message : "Unknown read error";
187
+ throw new AgentError(`Failed to read agent file ${filePath}: ${message}`, "READ_ERROR", error);
188
+ }
189
+ const { frontmatter } = extractFrontmatter(content);
190
+ const role = frontmatter.name || getRoleFromFilename(filePath);
191
+ if (!role) {
192
+ throw new AgentError(
193
+ `Agent MD file must have a 'name' field in frontmatter or a valid filename: ${filePath}`,
194
+ "VALIDATION_ERROR"
195
+ );
196
+ }
197
+ const description = frontmatter.description || "";
198
+ const tools = typeof frontmatter.tools === "string" ? frontmatter.tools.split(",").map((t) => t.trim()).filter(Boolean) : void 0;
199
+ const definition = {
200
+ role,
201
+ type: "ic-engineer",
202
+ // Default, actual identity is in the MD content
203
+ display_name: role.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" "),
204
+ description
205
+ };
206
+ if (tools) {
207
+ definition.tools = tools;
208
+ }
209
+ return definition;
210
+ }
156
211
  function parseAgentYaml(content, filePath) {
157
212
  try {
158
213
  return parseYaml2(content);
@@ -184,7 +239,7 @@ function validateAgentDefinition(agent) {
184
239
  }
185
240
  return agent;
186
241
  }
187
- function loadAgentFromFile(filePath) {
242
+ function loadAgentFromYamlFile(filePath) {
188
243
  if (!existsSync2(filePath)) {
189
244
  throw new AgentError(`Agent file not found: ${filePath}`, "NOT_FOUND");
190
245
  }
@@ -198,18 +253,36 @@ function loadAgentFromFile(filePath) {
198
253
  const parsed = parseAgentYaml(content, filePath);
199
254
  return validateAgentDefinition(parsed);
200
255
  }
201
- function listYamlFiles(dir) {
256
+ function loadAgentFromFile(filePath) {
257
+ const ext = extname(filePath).toLowerCase();
258
+ if (ext === ".md") {
259
+ return loadAgentFromMdFile(filePath);
260
+ }
261
+ if (ext === ".yaml" || ext === ".yml") {
262
+ console.warn(
263
+ `Warning: YAML agent definitions are deprecated and will be removed in a future version.
264
+ Please migrate ${basename(filePath)} to Markdown format.`
265
+ );
266
+ return loadAgentFromYamlFile(filePath);
267
+ }
268
+ throw new AgentError(
269
+ `Unsupported agent file format: ${ext}. Use .md (recommended) or .yaml/.yml (deprecated)`,
270
+ "PARSE_ERROR"
271
+ );
272
+ }
273
+ function listAgentFiles(dir) {
202
274
  if (!existsSync2(dir)) {
203
275
  return [];
204
276
  }
205
277
  return readdirSync(dir).filter((file) => {
278
+ if (file.startsWith("_")) return false;
206
279
  const ext = extname(file).toLowerCase();
207
- return ext === ".yaml" || ext === ".yml";
280
+ return ext === ".md" || ext === ".yaml" || ext === ".yml";
208
281
  }).map((file) => join2(dir, file));
209
282
  }
210
283
  function loadAgentsFromDirectory(dir, source) {
211
284
  const agents2 = /* @__PURE__ */ new Map();
212
- const files = listYamlFiles(dir);
285
+ const files = listAgentFiles(dir);
213
286
  for (const filePath of files) {
214
287
  try {
215
288
  const definition = loadAgentFromFile(filePath);
@@ -225,6 +298,11 @@ function loadAgentsFromDirectory(dir, source) {
225
298
  }
226
299
  return agents2;
227
300
  }
301
+ function getRoleFromFilename(filePath) {
302
+ const fileName = basename(filePath);
303
+ const ext = extname(fileName);
304
+ return fileName.slice(0, -ext.length);
305
+ }
228
306
 
229
307
  // src/agents/resolver.ts
230
308
  var ResolutionError = class extends Error {
@@ -363,193 +441,45 @@ function resolveAgentDefinition(agent, config, options = {}) {
363
441
  }
364
442
 
365
443
  // src/agents/compiler.ts
366
- import { existsSync as existsSync3, mkdirSync, writeFileSync } from "fs";
367
- import { join as join3, dirname as dirname2 } from "path";
444
+ import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync3, writeFileSync } from "fs";
445
+ import { join as join3, dirname as dirname2, extname as extname2 } from "path";
446
+ import { parse as parseYaml3, stringify as stringifyYaml } from "yaml";
368
447
  function buildAgentTools(agent, mcpServers) {
369
448
  const tools = agent.tools ? [...agent.tools] : [...DEFAULT_AGENT_TOOLS];
370
449
  if (mcpServers && mcpServers.length > 0) {
371
450
  for (const server of mcpServers) {
372
- tools.push(`mcp__${server}`);
373
- }
374
- }
375
- return tools.join(", ");
376
- }
377
- function generateKnowledgeLibrarySection(agent, lines) {
378
- const kl = agent.knowledge_library;
379
- if (!kl) return;
380
- lines.push("## Knowledge Library Structure");
381
- lines.push("");
382
- if (kl.shared) {
383
- lines.push("### Shared Context (Root - All Agents)");
384
- lines.push("```");
385
- lines.push("/KnowledgeLibrary/");
386
- if (kl.shared.context) {
387
- const filename = kl.shared.context.split("/").pop() ?? "context.txt";
388
- lines.push(`\u251C\u2500\u2500 ${filename}`);
389
- }
390
- if (kl.shared.architecture) {
391
- const filename = kl.shared.architecture.split("/").pop() ?? "architecture.txt";
392
- lines.push(`\u251C\u2500\u2500 ${filename}`);
393
- }
394
- if (kl.shared.prd) {
395
- const filename = kl.shared.prd.split("/").pop() ?? "prd.txt";
396
- lines.push(`\u2514\u2500\u2500 ${filename}`);
397
- }
398
- lines.push("```");
399
- if (kl.shared.remote && kl.shared.remote.length > 0) {
400
- lines.push("");
401
- lines.push("**Remote Documentation:**");
402
- for (const remote of kl.shared.remote) {
403
- lines.push(`- ${remote}`);
404
- }
405
- }
406
- lines.push("");
407
- }
408
- if (kl.personal) {
409
- lines.push(`### Personal Context (${agent.role})`);
410
- lines.push("```");
411
- lines.push(`/KnowledgeLibrary/${agent.role}/`);
412
- if (kl.personal.context) {
413
- lines.push("\u251C\u2500\u2500 context/");
414
- lines.push("\u2502 \u2514\u2500\u2500 current.txt # Your current state, priorities, decisions, issues");
415
- }
416
- if (kl.personal.history) {
417
- lines.push("\u251C\u2500\u2500 history/");
418
- lines.push("\u2502 \u2514\u2500\u2500 [archived context files, timestamped]");
419
- }
420
- if (kl.personal.inbox) {
421
- lines.push("\u251C\u2500\u2500 inbox/");
422
- lines.push("\u2502 \u2514\u2500\u2500 YYYYMMDD_HHMM-[agent-name]-[topic].txt # Messages from other agents");
423
- }
424
- if (kl.personal.outbox) {
425
- lines.push("\u251C\u2500\u2500 outbox/");
426
- lines.push("\u2502 \u2514\u2500\u2500 YYYYMMDD_HHMM-to-[agent-name]-[topic].txt # Copies of sent messages");
427
- }
428
- if (kl.personal.tech) {
429
- lines.push("\u251C\u2500\u2500 tech/");
430
- lines.push("\u2502 \u2514\u2500\u2500 [Technical docs, implementation details, working drafts]");
431
- }
432
- if (kl.personal.control) {
433
- lines.push("\u2514\u2500\u2500 control/");
434
- if (kl.personal.control.objectives) {
435
- lines.push(" \u251C\u2500\u2500 objectives.txt # Current job objectives and goals");
436
- }
437
- if (kl.personal.control.decisions) {
438
- lines.push(" \u251C\u2500\u2500 decisions.txt # Log of key decisions with rationale");
451
+ const mcpTool = `mcp__${server}`;
452
+ if (!tools.includes(mcpTool)) {
453
+ tools.push(mcpTool);
439
454
  }
440
- if (kl.personal.control.dependencies) {
441
- lines.push(" \u251C\u2500\u2500 dependencies.txt # Dependencies on other jobs");
442
- }
443
- if (kl.personal.control.index) {
444
- lines.push(" \u2514\u2500\u2500 index.txt # Optional index of files/folders");
445
- }
446
- }
447
- lines.push("```");
448
- lines.push("");
449
- }
450
- lines.push("---");
451
- lines.push("");
452
- }
453
- function generateCommunicationSection(agent, lines) {
454
- const comm = agent.communication;
455
- if (!comm) return;
456
- lines.push("## Communication");
457
- lines.push("");
458
- if (comm.inbox) {
459
- lines.push(`**Inbox:** \`${comm.inbox}\``);
460
- }
461
- if (comm.outbox) {
462
- lines.push(`**Outbox:** \`${comm.outbox}\``);
463
- }
464
- lines.push("");
465
- if (comm.message_format || comm.outbox_format || comm.processed_dir) {
466
- lines.push("### Message Conventions");
467
- lines.push("");
468
- if (comm.message_format) {
469
- lines.push(`- **Inbox message naming:** \`${comm.message_format}\``);
470
- }
471
- if (comm.outbox_format) {
472
- lines.push(`- **Outbox message naming:** \`${comm.outbox_format}\``);
473
- }
474
- if (comm.processed_dir) {
475
- lines.push(`- **Processed messages:** Move handled inbox messages to \`${comm.processed_dir}\``);
476
- }
477
- lines.push("");
478
- }
479
- }
480
- function generateStartupProtocolSection(agent, lines) {
481
- const protocols = agent.protocols;
482
- if (!protocols?.startup) return;
483
- lines.push("## When Invoked");
484
- lines.push("");
485
- lines.push("> **MANDATORY STARTUP PROTOCOL** - Execute before proceeding with any task.");
486
- lines.push("");
487
- lines.push("### Session Context Check");
488
- lines.push("");
489
- lines.push("First, determine if you have already loaded context in this session:");
490
- lines.push("");
491
- if (protocols.startup.first_session && protocols.startup.first_session.length > 0) {
492
- lines.push("**If this is your FIRST invocation in this session** (no prior context loaded):");
493
- lines.push("");
494
- for (const step of protocols.startup.first_session) {
495
- lines.push(`- [ ] ${step}`);
496
- }
497
- lines.push("");
498
- lines.push('Acknowledge: "Startup protocol complete. Full context loaded."');
499
- lines.push("");
500
- }
501
- if (protocols.startup.subsequent && protocols.startup.subsequent.length > 0) {
502
- lines.push("**If you have ALREADY loaded context in this session** (subsequent invocation):");
503
- lines.push("");
504
- for (const step of protocols.startup.subsequent) {
505
- lines.push(`- [ ] ${step}`);
506
455
  }
507
- lines.push("");
508
- lines.push('Acknowledge: "Context already loaded. Checked inbox for new messages."');
509
- lines.push("");
510
456
  }
511
- lines.push("Then proceed with the task.");
512
- lines.push("");
513
- lines.push("---");
514
- lines.push("");
457
+ return tools.join(", ");
515
458
  }
516
- function generateCompletionProtocolSection(agent, lines) {
517
- const protocols = agent.protocols;
518
- if (!protocols?.completion || protocols.completion.length === 0) return;
519
- lines.push("## Before Finishing");
520
- lines.push("");
521
- lines.push("> **MANDATORY COMPLETION PROTOCOL** - Execute ALL steps before ending any task.");
522
- lines.push("");
523
- for (let i = 0; i < protocols.completion.length; i++) {
524
- lines.push(`### ${i + 1}. ${protocols.completion[i]}`);
525
- lines.push("");
459
+ function processAgentTemplate(templatePath, agent, config, mcpServers) {
460
+ const template = readFileSync3(templatePath, "utf-8");
461
+ const context = { agent };
462
+ if (config) {
463
+ context.config = config;
526
464
  }
527
- lines.push('Acknowledge: "Completion protocol finished. Context updated."');
528
- lines.push("");
529
- lines.push("---");
530
- lines.push("");
531
- }
532
- function generateLegacyContextSourcesSection(agent, lines) {
533
- if (!agent.context_sources) return;
534
- if (agent.knowledge_library) return;
535
- lines.push("## Context Sources");
536
- lines.push("");
537
- if (agent.context_sources.shared && agent.context_sources.shared.length > 0) {
538
- lines.push("### Shared");
539
- lines.push("");
540
- for (const source of agent.context_sources.shared) {
541
- lines.push(`- ${source}`);
542
- }
543
- lines.push("");
465
+ const resolved = resolveString(template, context);
466
+ const frontmatterMatch = resolved.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
467
+ if (!frontmatterMatch) {
468
+ throw new Error(`Invalid markdown format in ${templatePath}: no frontmatter found`);
544
469
  }
545
- if (agent.context_sources.personal && agent.context_sources.personal.length > 0) {
546
- lines.push("### Personal");
547
- lines.push("");
548
- for (const source of agent.context_sources.personal) {
549
- lines.push(`- ${source}`);
550
- }
551
- lines.push("");
470
+ const frontmatterYaml = frontmatterMatch[1];
471
+ const body = frontmatterMatch[2] ?? "";
472
+ const frontmatter = parseYaml3(frontmatterYaml);
473
+ const tools = buildAgentTools(agent, mcpServers);
474
+ frontmatter.tools = tools;
475
+ if (typeof frontmatter.description === "string") {
476
+ frontmatter.description = frontmatter.description.replace(/\n/g, " ").trim();
552
477
  }
478
+ const updatedFrontmatter = stringifyYaml(frontmatter, { lineWidth: 0 }).trim();
479
+ return `---
480
+ ${updatedFrontmatter}
481
+ ---
482
+ ${body}`;
553
483
  }
554
484
  function generateAgentMarkdown(agent, mcpServers) {
555
485
  const lines = [];
@@ -572,8 +502,8 @@ function generateAgentMarkdown(agent, mcpServers) {
572
502
  if (agent.responsibilities && agent.responsibilities.length > 0) {
573
503
  lines.push("## Responsibilities");
574
504
  lines.push("");
575
- for (const responsibility of agent.responsibilities) {
576
- lines.push(`- ${responsibility}`);
505
+ for (const r of agent.responsibilities) {
506
+ lines.push(`- ${r}`);
577
507
  }
578
508
  lines.push("");
579
509
  }
@@ -591,12 +521,12 @@ function generateAgentMarkdown(agent, mcpServers) {
591
521
  if (agent.expertise.tech_stack) {
592
522
  lines.push("### Tech Stack");
593
523
  lines.push("");
594
- const techStack = agent.expertise.tech_stack;
595
- if (typeof techStack === "string") {
596
- lines.push(techStack);
597
- } else if (typeof techStack === "object") {
524
+ const ts = agent.expertise.tech_stack;
525
+ if (typeof ts === "string") {
526
+ lines.push(ts);
527
+ } else if (typeof ts === "object") {
598
528
  lines.push("```json");
599
- lines.push(JSON.stringify(techStack, null, 2));
529
+ lines.push(JSON.stringify(ts, null, 2));
600
530
  lines.push("```");
601
531
  }
602
532
  lines.push("");
@@ -615,7 +545,7 @@ function generateAgentMarkdown(agent, mcpServers) {
615
545
  lines.push("");
616
546
  for (const [category, items] of Object.entries(agent.principles)) {
617
547
  if (items && Array.isArray(items) && items.length > 0) {
618
- const title = formatTitle(category);
548
+ const title = category.replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
619
549
  lines.push(`### ${title}`);
620
550
  lines.push("");
621
551
  for (const item of items) {
@@ -646,21 +576,161 @@ function generateAgentMarkdown(agent, mcpServers) {
646
576
  lines.push("");
647
577
  }
648
578
  }
649
- generateKnowledgeLibrarySection(agent, lines);
650
- generateCommunicationSection(agent, lines);
651
- generateStartupProtocolSection(agent, lines);
652
- generateCompletionProtocolSection(agent, lines);
653
- generateLegacyContextSourcesSection(agent, lines);
579
+ if (agent.knowledge_library) {
580
+ generateKnowledgeLibrarySection(agent, lines);
581
+ }
582
+ if (agent.communication) {
583
+ generateCommunicationSection(agent, lines);
584
+ }
585
+ if (agent.protocols?.startup) {
586
+ generateStartupProtocolSection(agent, lines);
587
+ }
588
+ if (agent.protocols?.completion) {
589
+ generateCompletionProtocolSection(agent, lines);
590
+ }
591
+ if (agent.context_sources && !agent.knowledge_library) {
592
+ lines.push("## Context Sources");
593
+ lines.push("");
594
+ if (agent.context_sources.shared?.length) {
595
+ lines.push("### Shared");
596
+ lines.push("");
597
+ for (const s of agent.context_sources.shared) lines.push(`- ${s}`);
598
+ lines.push("");
599
+ }
600
+ if (agent.context_sources.personal?.length) {
601
+ lines.push("### Personal");
602
+ lines.push("");
603
+ for (const p of agent.context_sources.personal) lines.push(`- ${p}`);
604
+ lines.push("");
605
+ }
606
+ }
654
607
  lines.push("---");
655
608
  lines.push("");
656
609
  lines.push("*Generated by CoreAI*");
657
610
  lines.push("");
658
611
  return lines.join("\n");
659
612
  }
660
- function formatTitle(str) {
661
- return str.replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
613
+ function generateKnowledgeLibrarySection(agent, lines) {
614
+ const kl = agent.knowledge_library;
615
+ if (!kl) return;
616
+ lines.push("## Knowledge Library Structure");
617
+ lines.push("");
618
+ if (kl.shared) {
619
+ lines.push("### Shared Context (Root - All Agents)");
620
+ lines.push("```");
621
+ lines.push("/KnowledgeLibrary/");
622
+ if (kl.shared.context) lines.push(`\u251C\u2500\u2500 ${kl.shared.context.split("/").pop()}`);
623
+ if (kl.shared.architecture) lines.push(`\u251C\u2500\u2500 ${kl.shared.architecture.split("/").pop()}`);
624
+ if (kl.shared.prd) lines.push(`\u2514\u2500\u2500 ${kl.shared.prd.split("/").pop()}`);
625
+ lines.push("```");
626
+ if (kl.shared.remote?.length) {
627
+ lines.push("");
628
+ lines.push("**Remote Documentation:**");
629
+ for (const r of kl.shared.remote) lines.push(`- ${r}`);
630
+ }
631
+ lines.push("");
632
+ }
633
+ if (kl.personal) {
634
+ lines.push(`### Personal Context (${agent.role})`);
635
+ lines.push("```");
636
+ lines.push(`/KnowledgeLibrary/${agent.role}/`);
637
+ if (kl.personal.context) {
638
+ lines.push("\u251C\u2500\u2500 context/");
639
+ lines.push("\u2502 \u2514\u2500\u2500 current.txt");
640
+ }
641
+ if (kl.personal.history) {
642
+ lines.push("\u251C\u2500\u2500 history/");
643
+ }
644
+ if (kl.personal.inbox) {
645
+ lines.push("\u251C\u2500\u2500 inbox/");
646
+ }
647
+ if (kl.personal.outbox) {
648
+ lines.push("\u251C\u2500\u2500 outbox/");
649
+ }
650
+ if (kl.personal.tech) {
651
+ lines.push("\u251C\u2500\u2500 tech/");
652
+ }
653
+ if (kl.personal.control) {
654
+ lines.push("\u2514\u2500\u2500 control/");
655
+ if (kl.personal.control.objectives) lines.push(" \u251C\u2500\u2500 objectives.txt");
656
+ if (kl.personal.control.decisions) lines.push(" \u251C\u2500\u2500 decisions.txt");
657
+ if (kl.personal.control.dependencies) lines.push(" \u251C\u2500\u2500 dependencies.txt");
658
+ if (kl.personal.control.index) lines.push(" \u2514\u2500\u2500 index.txt");
659
+ }
660
+ lines.push("```");
661
+ lines.push("");
662
+ }
663
+ lines.push("---");
664
+ lines.push("");
665
+ }
666
+ function generateCommunicationSection(agent, lines) {
667
+ const comm = agent.communication;
668
+ if (!comm) return;
669
+ lines.push("## Communication");
670
+ lines.push("");
671
+ if (comm.inbox) lines.push(`**Inbox:** \`${comm.inbox}\``);
672
+ if (comm.outbox) lines.push(`**Outbox:** \`${comm.outbox}\``);
673
+ lines.push("");
674
+ if (comm.message_format || comm.outbox_format || comm.processed_dir) {
675
+ lines.push("### Message Conventions");
676
+ lines.push("");
677
+ if (comm.message_format) lines.push(`- **Inbox message naming:** \`${comm.message_format}\``);
678
+ if (comm.outbox_format) lines.push(`- **Outbox message naming:** \`${comm.outbox_format}\``);
679
+ if (comm.processed_dir) lines.push(`- **Processed messages:** Move handled inbox messages to \`${comm.processed_dir}\``);
680
+ lines.push("");
681
+ }
662
682
  }
663
- function compileAgent(agent, config, mcpServers) {
683
+ function generateStartupProtocolSection(agent, lines) {
684
+ const p = agent.protocols;
685
+ if (!p?.startup) return;
686
+ lines.push("## When Invoked");
687
+ lines.push("");
688
+ lines.push("> **MANDATORY STARTUP PROTOCOL** - Execute before proceeding with any task.");
689
+ lines.push("");
690
+ lines.push("### Session Context Check");
691
+ lines.push("");
692
+ if (p.startup.first_session?.length) {
693
+ lines.push("**If this is your FIRST invocation in this session:**");
694
+ lines.push("");
695
+ for (const s of p.startup.first_session) lines.push(`- [ ] ${s}`);
696
+ lines.push("");
697
+ lines.push('Acknowledge: "Startup protocol complete. Full context loaded."');
698
+ lines.push("");
699
+ }
700
+ if (p.startup.subsequent?.length) {
701
+ lines.push("**If you have ALREADY loaded context in this session:**");
702
+ lines.push("");
703
+ for (const s of p.startup.subsequent) lines.push(`- [ ] ${s}`);
704
+ lines.push("");
705
+ lines.push('Acknowledge: "Context already loaded. Checked inbox for new messages."');
706
+ lines.push("");
707
+ }
708
+ lines.push("Then proceed with the task.");
709
+ lines.push("");
710
+ lines.push("---");
711
+ lines.push("");
712
+ }
713
+ function generateCompletionProtocolSection(agent, lines) {
714
+ const p = agent.protocols;
715
+ if (!p?.completion?.length) return;
716
+ lines.push("## Before Finishing");
717
+ lines.push("");
718
+ lines.push("> **MANDATORY COMPLETION PROTOCOL** - Execute ALL steps before ending any task.");
719
+ lines.push("");
720
+ for (let i = 0; i < p.completion.length; i++) {
721
+ lines.push(`### ${i + 1}. ${p.completion[i]}`);
722
+ lines.push("");
723
+ }
724
+ lines.push('Acknowledge: "Completion protocol finished. Context updated."');
725
+ lines.push("");
726
+ lines.push("---");
727
+ lines.push("");
728
+ }
729
+ function compileAgent(agent, filePath, config, mcpServers) {
730
+ const ext = extname2(filePath).toLowerCase();
731
+ if (ext === ".md") {
732
+ return processAgentTemplate(filePath, agent, config, mcpServers);
733
+ }
664
734
  const resolved = resolveAgentDefinition(agent, config);
665
735
  return generateAgentMarkdown(resolved, mcpServers);
666
736
  }
@@ -720,7 +790,12 @@ function compileAgents(config, options = {}) {
720
790
  continue;
721
791
  }
722
792
  try {
723
- const markdown = compileAgent(metadata.definition, config, options.mcpServers);
793
+ const markdown = compileAgent(
794
+ metadata.definition,
795
+ metadata.filePath,
796
+ config,
797
+ options.mcpServers
798
+ );
724
799
  const outputPath = join3(outputDir, `${role}.md`);
725
800
  writeFileSync(outputPath, markdown, "utf-8");
726
801
  result.compiled.push({
@@ -764,7 +839,7 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
764
839
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
765
840
 
766
841
  // src/adapters/mcp/discovery.ts
767
- import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
842
+ import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
768
843
  import { join as join4, dirname as dirname3 } from "path";
769
844
  import { homedir } from "os";
770
845
  var CONFIG_FILENAMES = ["mcp.json", ".mcp.json", "claude_desktop_config.json"];
@@ -813,7 +888,7 @@ function loadServersFromFile(filePath) {
813
888
  if (!existsSync4(filePath)) {
814
889
  throw new McpError(`Config file not found: ${filePath}`, "invalid_config");
815
890
  }
816
- const content = readFileSync3(filePath, "utf-8");
891
+ const content = readFileSync4(filePath, "utf-8");
817
892
  let config;
818
893
  try {
819
894
  config = JSON.parse(content);
@@ -1800,7 +1875,7 @@ var CacheManager = class {
1800
1875
  };
1801
1876
 
1802
1877
  // src/skills/generator.ts
1803
- import { existsSync as existsSync5, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as readFileSync4, readdirSync as readdirSync2, statSync } from "fs";
1878
+ import { existsSync as existsSync5, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as readFileSync5, readdirSync as readdirSync2, statSync } from "fs";
1804
1879
  import { join as join6, basename as basename2 } from "path";
1805
1880
 
1806
1881
  // src/skills/templates.ts
@@ -2385,7 +2460,7 @@ function loadCustomTemplates(templatesDir) {
2385
2460
  const stat = statSync(filePath);
2386
2461
  if (!stat.isFile()) continue;
2387
2462
  try {
2388
- const content = readFileSync4(filePath, "utf-8");
2463
+ const content = readFileSync5(filePath, "utf-8");
2389
2464
  const template = parseSkillTemplate(file, content);
2390
2465
  templates.push(template);
2391
2466
  } catch {
@@ -2598,7 +2673,7 @@ import {
2598
2673
  existsSync as existsSync6,
2599
2674
  mkdirSync as mkdirSync3,
2600
2675
  writeFileSync as writeFileSync3,
2601
- readFileSync as readFileSync5,
2676
+ readFileSync as readFileSync6,
2602
2677
  readdirSync as readdirSync3,
2603
2678
  renameSync,
2604
2679
  statSync as statSync2
@@ -2853,7 +2928,7 @@ function getAgentKnowledgeState(agentName, options = {}) {
2853
2928
  let context;
2854
2929
  const currentContextPath = join7(dirs.context, "current.txt");
2855
2930
  if (existsSync6(currentContextPath)) {
2856
- const content = readFileSync5(currentContextPath, "utf-8");
2931
+ const content = readFileSync6(currentContextPath, "utf-8");
2857
2932
  context = parseContextFile(content);
2858
2933
  }
2859
2934
  const state = {
@@ -2947,7 +3022,7 @@ function readInboxMessages(agentName, options = {}) {
2947
3022
  );
2948
3023
  for (const file of files) {
2949
3024
  const filePath = join7(dirs.inbox, file);
2950
- const rawContent = readFileSync5(filePath, "utf-8");
3025
+ const rawContent = readFileSync6(filePath, "utf-8");
2951
3026
  const { metadata, body } = parseMessageFrontmatter(rawContent);
2952
3027
  if (options.type && metadata.type !== options.type) continue;
2953
3028
  if (options.from && metadata.from !== options.from) continue;
@@ -2967,7 +3042,7 @@ function readInboxMessages(agentName, options = {}) {
2967
3042
  );
2968
3043
  for (const file of files) {
2969
3044
  const filePath = join7(dirs.inboxProcessed, file);
2970
- const rawContent = readFileSync5(filePath, "utf-8");
3045
+ const rawContent = readFileSync6(filePath, "utf-8");
2971
3046
  const { metadata, body } = parseMessageFrontmatter(rawContent);
2972
3047
  if (options.type && metadata.type !== options.type) continue;
2973
3048
  if (options.from && metadata.from !== options.from) continue;
@@ -3020,7 +3095,7 @@ function findPackageJson() {
3020
3095
  while (dir !== dirname5(dir)) {
3021
3096
  const pkgPath = join8(dir, "package.json");
3022
3097
  try {
3023
- const content = readFileSync6(pkgPath, "utf-8");
3098
+ const content = readFileSync7(pkgPath, "utf-8");
3024
3099
  const pkg = JSON.parse(content);
3025
3100
  if (pkg.name === "@deimoscloud/coreai") {
3026
3101
  return content;
@@ -3304,7 +3379,7 @@ function formatSyncResult(result) {
3304
3379
  }
3305
3380
 
3306
3381
  // src/cli/commands/init.ts
3307
- import { existsSync as existsSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync7 } from "fs";
3382
+ import { existsSync as existsSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync8 } from "fs";
3308
3383
  import { join as join11, basename as basename4 } from "path";
3309
3384
  import { execSync } from "child_process";
3310
3385
  function detectGitInfo() {
@@ -3335,7 +3410,7 @@ function detectProjectName(projectRoot) {
3335
3410
  const packageJsonPath = join11(projectRoot, "package.json");
3336
3411
  if (existsSync7(packageJsonPath)) {
3337
3412
  try {
3338
- const content = JSON.parse(readFileSync7(packageJsonPath, "utf-8"));
3413
+ const content = JSON.parse(readFileSync8(packageJsonPath, "utf-8"));
3339
3414
  if (content.name) {
3340
3415
  return content.name;
3341
3416
  }
@@ -4181,22 +4256,22 @@ function formatStatusResult(result) {
4181
4256
  }
4182
4257
 
4183
4258
  // src/cli/commands/agents.ts
4184
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
4259
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync5 } from "fs";
4185
4260
  import { join as join13, dirname as dirname6 } from "path";
4186
- import { parse as parseYaml3, stringify as stringifyYaml } from "yaml";
4261
+ import { parse as parseYaml4, stringify as stringifyYaml2 } from "yaml";
4187
4262
  function readConfigFile(configPath) {
4188
- const content = readFileSync8(configPath, "utf-8");
4189
- const parsed = parseYaml3(content);
4263
+ const content = readFileSync9(configPath, "utf-8");
4264
+ const parsed = parseYaml4(content);
4190
4265
  return { content, parsed };
4191
4266
  }
4192
4267
  function updateConfigAgents(configPath, agents2) {
4193
- const content = readFileSync8(configPath, "utf-8");
4194
- const parsed = parseYaml3(content);
4268
+ const content = readFileSync9(configPath, "utf-8");
4269
+ const parsed = parseYaml4(content);
4195
4270
  if (!parsed.team) {
4196
4271
  parsed.team = {};
4197
4272
  }
4198
4273
  parsed.team.agents = agents2;
4199
- const newContent = stringifyYaml(parsed, {
4274
+ const newContent = stringifyYaml2(parsed, {
4200
4275
  indent: 2,
4201
4276
  lineWidth: 0,
4202
4277
  singleQuote: false