@deimoscloud/coreai 0.1.15 → 0.1.17
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.
- package/agents/_templates/master-context.md +76 -0
- package/agents/_templates/master-protocols.md +39 -0
- package/agents/android-engineer.md +177 -0
- package/agents/backend-engineer.md +175 -0
- package/agents/database-administrator.md +177 -0
- package/agents/devops-engineer.md +211 -0
- package/agents/{examples/engineering-manager.md → engineering-manager.md} +208 -171
- package/agents/frontend-engineer.md +175 -0
- package/agents/product-manager.md +371 -0
- package/agents/react-engineer.md +177 -0
- package/agents/react-native-engineer.md +177 -0
- package/agents/software-security-engineer.md +339 -0
- package/agents/software-solutions-architect.md +469 -0
- package/agents/sre-huawei-cloud-architect.md +177 -0
- package/agents/sre-iac-specialist.md +177 -0
- package/agents/sre-kubernetes-specialist.md +177 -0
- package/agents/sre-network-specialist.md +177 -0
- package/agents/wearos-engineer.md +177 -0
- package/dist/cli/index.js +494 -826
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +75 -84
- package/dist/index.js +437 -784
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/agents/android-engineer.yaml +0 -108
- package/agents/backend-engineer.yaml +0 -106
- package/agents/database-administrator.yaml +0 -108
- package/agents/devops-engineer.yaml +0 -106
- package/agents/engineering-manager.yaml +0 -104
- package/agents/examples/android-engineer.md +0 -302
- package/agents/examples/backend-engineer.md +0 -320
- package/agents/examples/devops-engineer.md +0 -742
- package/agents/examples/frontend-engineer.md +0 -58
- package/agents/examples/product-manager.md +0 -315
- package/agents/examples/qa-engineer.md +0 -371
- package/agents/examples/security-engineer.md +0 -525
- package/agents/examples/solutions-architect.md +0 -351
- package/agents/examples/wearos-engineer.md +0 -359
- package/agents/frontend-engineer.yaml +0 -106
- package/agents/product-manager.yaml +0 -109
- package/agents/react-engineer.yaml +0 -108
- package/agents/react-native-engineer.yaml +0 -108
- package/agents/software-security-engineer.yaml +0 -108
- package/agents/software-solutions-architect.yaml +0 -107
- package/agents/sre-huawei-cloud-architect.yaml +0 -108
- package/agents/sre-iac-specialist.yaml +0 -108
- package/agents/sre-kubernetes-specialist.yaml +0 -108
- package/agents/sre-network-specialist.yaml +0 -108
- package/agents/wearos-engineer.yaml +0 -108
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import { readFileSync as
|
|
3
|
-
import { dirname as
|
|
2
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
3
|
+
import { dirname as dirname6, join as join8 } from "path";
|
|
4
4
|
import { fileURLToPath } from "url";
|
|
5
5
|
|
|
6
6
|
// src/config/loader.ts
|
|
@@ -149,6 +149,61 @@ var AgentError = class extends Error {
|
|
|
149
149
|
this.name = "AgentError";
|
|
150
150
|
}
|
|
151
151
|
};
|
|
152
|
+
function extractFrontmatter(content) {
|
|
153
|
+
const match = content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
154
|
+
if (!match) {
|
|
155
|
+
throw new AgentError(
|
|
156
|
+
"No YAML frontmatter found. Agent MD files must start with YAML frontmatter (---)",
|
|
157
|
+
"PARSE_ERROR"
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
const frontmatterYaml = match[1];
|
|
161
|
+
const body = match[2] ?? "";
|
|
162
|
+
let frontmatter;
|
|
163
|
+
try {
|
|
164
|
+
frontmatter = parseYaml2(frontmatterYaml);
|
|
165
|
+
} catch (error) {
|
|
166
|
+
const message = error instanceof Error ? error.message : "Unknown parse error";
|
|
167
|
+
throw new AgentError(`Failed to parse YAML frontmatter: ${message}`, "PARSE_ERROR", error);
|
|
168
|
+
}
|
|
169
|
+
if (!frontmatter || typeof frontmatter !== "object") {
|
|
170
|
+
throw new AgentError("Invalid frontmatter: expected an object", "PARSE_ERROR");
|
|
171
|
+
}
|
|
172
|
+
return { frontmatter, body };
|
|
173
|
+
}
|
|
174
|
+
function loadAgentFromMdFile(filePath) {
|
|
175
|
+
if (!existsSync2(filePath)) {
|
|
176
|
+
throw new AgentError(`Agent file not found: ${filePath}`, "NOT_FOUND");
|
|
177
|
+
}
|
|
178
|
+
let content;
|
|
179
|
+
try {
|
|
180
|
+
content = readFileSync2(filePath, "utf-8");
|
|
181
|
+
} catch (error) {
|
|
182
|
+
const message = error instanceof Error ? error.message : "Unknown read error";
|
|
183
|
+
throw new AgentError(`Failed to read agent file ${filePath}: ${message}`, "READ_ERROR", error);
|
|
184
|
+
}
|
|
185
|
+
const { frontmatter } = extractFrontmatter(content);
|
|
186
|
+
const role = frontmatter.name || getRoleFromFilename(filePath);
|
|
187
|
+
if (!role) {
|
|
188
|
+
throw new AgentError(
|
|
189
|
+
`Agent MD file must have a 'name' field in frontmatter or a valid filename: ${filePath}`,
|
|
190
|
+
"VALIDATION_ERROR"
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
const description = frontmatter.description || "";
|
|
194
|
+
const tools = typeof frontmatter.tools === "string" ? frontmatter.tools.split(",").map((t) => t.trim()).filter(Boolean) : void 0;
|
|
195
|
+
const definition = {
|
|
196
|
+
role,
|
|
197
|
+
type: "ic-engineer",
|
|
198
|
+
// Default, actual identity is in the MD content
|
|
199
|
+
display_name: role.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" "),
|
|
200
|
+
description
|
|
201
|
+
};
|
|
202
|
+
if (tools) {
|
|
203
|
+
definition.tools = tools;
|
|
204
|
+
}
|
|
205
|
+
return definition;
|
|
206
|
+
}
|
|
152
207
|
function parseAgentYaml(content, filePath) {
|
|
153
208
|
try {
|
|
154
209
|
return parseYaml2(content);
|
|
@@ -180,7 +235,7 @@ function validateAgentDefinition(agent) {
|
|
|
180
235
|
}
|
|
181
236
|
return agent;
|
|
182
237
|
}
|
|
183
|
-
function
|
|
238
|
+
function loadAgentFromYamlFile(filePath) {
|
|
184
239
|
if (!existsSync2(filePath)) {
|
|
185
240
|
throw new AgentError(`Agent file not found: ${filePath}`, "NOT_FOUND");
|
|
186
241
|
}
|
|
@@ -194,18 +249,36 @@ function loadAgentFromFile(filePath) {
|
|
|
194
249
|
const parsed = parseAgentYaml(content, filePath);
|
|
195
250
|
return validateAgentDefinition(parsed);
|
|
196
251
|
}
|
|
197
|
-
function
|
|
252
|
+
function loadAgentFromFile(filePath) {
|
|
253
|
+
const ext = extname(filePath).toLowerCase();
|
|
254
|
+
if (ext === ".md") {
|
|
255
|
+
return loadAgentFromMdFile(filePath);
|
|
256
|
+
}
|
|
257
|
+
if (ext === ".yaml" || ext === ".yml") {
|
|
258
|
+
console.warn(
|
|
259
|
+
`Warning: YAML agent definitions are deprecated and will be removed in a future version.
|
|
260
|
+
Please migrate ${basename(filePath)} to Markdown format.`
|
|
261
|
+
);
|
|
262
|
+
return loadAgentFromYamlFile(filePath);
|
|
263
|
+
}
|
|
264
|
+
throw new AgentError(
|
|
265
|
+
`Unsupported agent file format: ${ext}. Use .md (recommended) or .yaml/.yml (deprecated)`,
|
|
266
|
+
"PARSE_ERROR"
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
function listAgentFiles(dir) {
|
|
198
270
|
if (!existsSync2(dir)) {
|
|
199
271
|
return [];
|
|
200
272
|
}
|
|
201
273
|
return readdirSync(dir).filter((file) => {
|
|
274
|
+
if (file.startsWith("_")) return false;
|
|
202
275
|
const ext = extname(file).toLowerCase();
|
|
203
|
-
return ext === ".yaml" || ext === ".yml";
|
|
276
|
+
return ext === ".md" || ext === ".yaml" || ext === ".yml";
|
|
204
277
|
}).map((file) => join2(dir, file));
|
|
205
278
|
}
|
|
206
279
|
function loadAgentsFromDirectory(dir, source) {
|
|
207
280
|
const agents = /* @__PURE__ */ new Map();
|
|
208
|
-
const files =
|
|
281
|
+
const files = listAgentFiles(dir);
|
|
209
282
|
for (const filePath of files) {
|
|
210
283
|
try {
|
|
211
284
|
const definition = loadAgentFromFile(filePath);
|
|
@@ -372,193 +445,73 @@ function resolveAgentDefinition(agent, config, options = {}) {
|
|
|
372
445
|
}
|
|
373
446
|
|
|
374
447
|
// src/agents/compiler.ts
|
|
375
|
-
import { existsSync as existsSync3, mkdirSync, writeFileSync } from "fs";
|
|
376
|
-
import { join as join3, dirname as dirname2 } from "path";
|
|
448
|
+
import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
449
|
+
import { join as join3, dirname as dirname2, extname as extname2, isAbsolute } from "path";
|
|
450
|
+
import { parse as parseYaml3, stringify as stringifyYaml } from "yaml";
|
|
377
451
|
function buildAgentTools(agent, mcpServers) {
|
|
378
452
|
const tools = agent.tools ? [...agent.tools] : [...DEFAULT_AGENT_TOOLS];
|
|
379
453
|
if (mcpServers && mcpServers.length > 0) {
|
|
380
454
|
for (const server of mcpServers) {
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
return tools.join(", ");
|
|
385
|
-
}
|
|
386
|
-
function generateKnowledgeLibrarySection(agent, lines) {
|
|
387
|
-
const kl = agent.knowledge_library;
|
|
388
|
-
if (!kl) return;
|
|
389
|
-
lines.push("## Knowledge Library Structure");
|
|
390
|
-
lines.push("");
|
|
391
|
-
if (kl.shared) {
|
|
392
|
-
lines.push("### Shared Context (Root - All Agents)");
|
|
393
|
-
lines.push("```");
|
|
394
|
-
lines.push("/KnowledgeLibrary/");
|
|
395
|
-
if (kl.shared.context) {
|
|
396
|
-
const filename = kl.shared.context.split("/").pop() ?? "context.txt";
|
|
397
|
-
lines.push(`\u251C\u2500\u2500 ${filename}`);
|
|
398
|
-
}
|
|
399
|
-
if (kl.shared.architecture) {
|
|
400
|
-
const filename = kl.shared.architecture.split("/").pop() ?? "architecture.txt";
|
|
401
|
-
lines.push(`\u251C\u2500\u2500 ${filename}`);
|
|
402
|
-
}
|
|
403
|
-
if (kl.shared.prd) {
|
|
404
|
-
const filename = kl.shared.prd.split("/").pop() ?? "prd.txt";
|
|
405
|
-
lines.push(`\u2514\u2500\u2500 ${filename}`);
|
|
406
|
-
}
|
|
407
|
-
lines.push("```");
|
|
408
|
-
if (kl.shared.remote && kl.shared.remote.length > 0) {
|
|
409
|
-
lines.push("");
|
|
410
|
-
lines.push("**Remote Documentation:**");
|
|
411
|
-
for (const remote of kl.shared.remote) {
|
|
412
|
-
lines.push(`- ${remote}`);
|
|
455
|
+
const mcpTool = `mcp__${server}`;
|
|
456
|
+
if (!tools.includes(mcpTool)) {
|
|
457
|
+
tools.push(mcpTool);
|
|
413
458
|
}
|
|
414
459
|
}
|
|
415
|
-
lines.push("");
|
|
416
460
|
}
|
|
417
|
-
|
|
418
|
-
lines.push(`### Personal Context (${agent.role})`);
|
|
419
|
-
lines.push("```");
|
|
420
|
-
lines.push(`/KnowledgeLibrary/${agent.role}/`);
|
|
421
|
-
if (kl.personal.context) {
|
|
422
|
-
lines.push("\u251C\u2500\u2500 context/");
|
|
423
|
-
lines.push("\u2502 \u2514\u2500\u2500 current.txt # Your current state, priorities, decisions, issues");
|
|
424
|
-
}
|
|
425
|
-
if (kl.personal.history) {
|
|
426
|
-
lines.push("\u251C\u2500\u2500 history/");
|
|
427
|
-
lines.push("\u2502 \u2514\u2500\u2500 [archived context files, timestamped]");
|
|
428
|
-
}
|
|
429
|
-
if (kl.personal.inbox) {
|
|
430
|
-
lines.push("\u251C\u2500\u2500 inbox/");
|
|
431
|
-
lines.push("\u2502 \u2514\u2500\u2500 YYYYMMDD_HHMM-[agent-name]-[topic].txt # Messages from other agents");
|
|
432
|
-
}
|
|
433
|
-
if (kl.personal.outbox) {
|
|
434
|
-
lines.push("\u251C\u2500\u2500 outbox/");
|
|
435
|
-
lines.push("\u2502 \u2514\u2500\u2500 YYYYMMDD_HHMM-to-[agent-name]-[topic].txt # Copies of sent messages");
|
|
436
|
-
}
|
|
437
|
-
if (kl.personal.tech) {
|
|
438
|
-
lines.push("\u251C\u2500\u2500 tech/");
|
|
439
|
-
lines.push("\u2502 \u2514\u2500\u2500 [Technical docs, implementation details, working drafts]");
|
|
440
|
-
}
|
|
441
|
-
if (kl.personal.control) {
|
|
442
|
-
lines.push("\u2514\u2500\u2500 control/");
|
|
443
|
-
if (kl.personal.control.objectives) {
|
|
444
|
-
lines.push(" \u251C\u2500\u2500 objectives.txt # Current job objectives and goals");
|
|
445
|
-
}
|
|
446
|
-
if (kl.personal.control.decisions) {
|
|
447
|
-
lines.push(" \u251C\u2500\u2500 decisions.txt # Log of key decisions with rationale");
|
|
448
|
-
}
|
|
449
|
-
if (kl.personal.control.dependencies) {
|
|
450
|
-
lines.push(" \u251C\u2500\u2500 dependencies.txt # Dependencies on other jobs");
|
|
451
|
-
}
|
|
452
|
-
if (kl.personal.control.index) {
|
|
453
|
-
lines.push(" \u2514\u2500\u2500 index.txt # Optional index of files/folders");
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
lines.push("```");
|
|
457
|
-
lines.push("");
|
|
458
|
-
}
|
|
459
|
-
lines.push("---");
|
|
460
|
-
lines.push("");
|
|
461
|
+
return tools.join(", ");
|
|
461
462
|
}
|
|
462
|
-
function
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
lines.push("## Communication");
|
|
466
|
-
lines.push("");
|
|
467
|
-
if (comm.inbox) {
|
|
468
|
-
lines.push(`**Inbox:** \`${comm.inbox}\``);
|
|
469
|
-
}
|
|
470
|
-
if (comm.outbox) {
|
|
471
|
-
lines.push(`**Outbox:** \`${comm.outbox}\``);
|
|
463
|
+
function processIncludes(template, templateDir, depth = 0, maxDepth = 3) {
|
|
464
|
+
if (depth > maxDepth) {
|
|
465
|
+
throw new Error(`Include depth exceeded maximum of ${maxDepth}`);
|
|
472
466
|
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
lines.push(`- **Inbox message naming:** \`${comm.message_format}\``);
|
|
467
|
+
const includePattern = /<!--\s*include:\s*(\S+)\s*-->/g;
|
|
468
|
+
return template.replace(includePattern, (_match, includePath) => {
|
|
469
|
+
const resolvedPath = isAbsolute(includePath) ? includePath : join3(templateDir, includePath);
|
|
470
|
+
if (!existsSync3(resolvedPath)) {
|
|
471
|
+
throw new Error(`Include file not found: ${includePath} (resolved to ${resolvedPath})`);
|
|
479
472
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
if (comm.processed_dir) {
|
|
484
|
-
lines.push(`- **Processed messages:** Move handled inbox messages to \`${comm.processed_dir}\``);
|
|
485
|
-
}
|
|
486
|
-
lines.push("");
|
|
487
|
-
}
|
|
473
|
+
const includedContent = readFileSync3(resolvedPath, "utf-8");
|
|
474
|
+
return processIncludes(includedContent, dirname2(resolvedPath), depth + 1, maxDepth);
|
|
475
|
+
});
|
|
488
476
|
}
|
|
489
|
-
function
|
|
490
|
-
const
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
lines.push("### Session Context Check");
|
|
497
|
-
lines.push("");
|
|
498
|
-
lines.push("First, determine if you have already loaded context in this session:");
|
|
499
|
-
lines.push("");
|
|
500
|
-
if (protocols.startup.first_session && protocols.startup.first_session.length > 0) {
|
|
501
|
-
lines.push("**If this is your FIRST invocation in this session** (no prior context loaded):");
|
|
502
|
-
lines.push("");
|
|
503
|
-
for (const step of protocols.startup.first_session) {
|
|
504
|
-
lines.push(`- [ ] ${step}`);
|
|
505
|
-
}
|
|
506
|
-
lines.push("");
|
|
507
|
-
lines.push('Acknowledge: "Startup protocol complete. Full context loaded."');
|
|
508
|
-
lines.push("");
|
|
477
|
+
function processAgentTemplate(templatePath, agent, config, mcpServers) {
|
|
478
|
+
const template = readFileSync3(templatePath, "utf-8");
|
|
479
|
+
const templateDir = dirname2(templatePath);
|
|
480
|
+
const expandedTemplate = processIncludes(template, templateDir);
|
|
481
|
+
const earlyMatch = expandedTemplate.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
482
|
+
if (!earlyMatch) {
|
|
483
|
+
throw new Error(`Invalid markdown format in ${templatePath}: no frontmatter found`);
|
|
509
484
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
485
|
+
const earlyFrontmatter = parseYaml3(earlyMatch[1]);
|
|
486
|
+
const reservedKeys = /* @__PURE__ */ new Set(["name", "description", "tools"]);
|
|
487
|
+
const extendedAgent = { ...agent };
|
|
488
|
+
for (const [key, value] of Object.entries(earlyFrontmatter)) {
|
|
489
|
+
if (!reservedKeys.has(key) && !(key in extendedAgent)) {
|
|
490
|
+
extendedAgent[key] = value;
|
|
515
491
|
}
|
|
516
|
-
lines.push("");
|
|
517
|
-
lines.push('Acknowledge: "Context already loaded. Checked inbox for new messages."');
|
|
518
|
-
lines.push("");
|
|
519
492
|
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
lines.push("");
|
|
524
|
-
}
|
|
525
|
-
function generateCompletionProtocolSection(agent, lines) {
|
|
526
|
-
const protocols = agent.protocols;
|
|
527
|
-
if (!protocols?.completion || protocols.completion.length === 0) return;
|
|
528
|
-
lines.push("## Before Finishing");
|
|
529
|
-
lines.push("");
|
|
530
|
-
lines.push("> **MANDATORY COMPLETION PROTOCOL** - Execute ALL steps before ending any task.");
|
|
531
|
-
lines.push("");
|
|
532
|
-
for (let i = 0; i < protocols.completion.length; i++) {
|
|
533
|
-
lines.push(`### ${i + 1}. ${protocols.completion[i]}`);
|
|
534
|
-
lines.push("");
|
|
493
|
+
const context = { agent: extendedAgent };
|
|
494
|
+
if (config) {
|
|
495
|
+
context.config = config;
|
|
535
496
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
}
|
|
541
|
-
function generateLegacyContextSourcesSection(agent, lines) {
|
|
542
|
-
if (!agent.context_sources) return;
|
|
543
|
-
if (agent.knowledge_library) return;
|
|
544
|
-
lines.push("## Context Sources");
|
|
545
|
-
lines.push("");
|
|
546
|
-
if (agent.context_sources.shared && agent.context_sources.shared.length > 0) {
|
|
547
|
-
lines.push("### Shared");
|
|
548
|
-
lines.push("");
|
|
549
|
-
for (const source of agent.context_sources.shared) {
|
|
550
|
-
lines.push(`- ${source}`);
|
|
551
|
-
}
|
|
552
|
-
lines.push("");
|
|
497
|
+
const resolved = resolveString(expandedTemplate, context);
|
|
498
|
+
const frontmatterMatch = resolved.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
499
|
+
if (!frontmatterMatch) {
|
|
500
|
+
throw new Error(`Invalid markdown format after resolution in ${templatePath}`);
|
|
553
501
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
502
|
+
const frontmatterYaml = frontmatterMatch[1];
|
|
503
|
+
const body = frontmatterMatch[2] ?? "";
|
|
504
|
+
const frontmatter = parseYaml3(frontmatterYaml);
|
|
505
|
+
const tools = buildAgentTools(agent, mcpServers);
|
|
506
|
+
frontmatter.tools = tools;
|
|
507
|
+
if (typeof frontmatter.description === "string") {
|
|
508
|
+
frontmatter.description = frontmatter.description.replace(/\n/g, " ").trim();
|
|
561
509
|
}
|
|
510
|
+
const updatedFrontmatter = stringifyYaml(frontmatter, { lineWidth: 0 }).trim();
|
|
511
|
+
return `---
|
|
512
|
+
${updatedFrontmatter}
|
|
513
|
+
---
|
|
514
|
+
${body}`;
|
|
562
515
|
}
|
|
563
516
|
function generateAgentMarkdown(agent, mcpServers) {
|
|
564
517
|
const lines = [];
|
|
@@ -581,8 +534,8 @@ function generateAgentMarkdown(agent, mcpServers) {
|
|
|
581
534
|
if (agent.responsibilities && agent.responsibilities.length > 0) {
|
|
582
535
|
lines.push("## Responsibilities");
|
|
583
536
|
lines.push("");
|
|
584
|
-
for (const
|
|
585
|
-
lines.push(`- ${
|
|
537
|
+
for (const r of agent.responsibilities) {
|
|
538
|
+
lines.push(`- ${r}`);
|
|
586
539
|
}
|
|
587
540
|
lines.push("");
|
|
588
541
|
}
|
|
@@ -600,12 +553,12 @@ function generateAgentMarkdown(agent, mcpServers) {
|
|
|
600
553
|
if (agent.expertise.tech_stack) {
|
|
601
554
|
lines.push("### Tech Stack");
|
|
602
555
|
lines.push("");
|
|
603
|
-
const
|
|
604
|
-
if (typeof
|
|
605
|
-
lines.push(
|
|
606
|
-
} else if (typeof
|
|
556
|
+
const ts = agent.expertise.tech_stack;
|
|
557
|
+
if (typeof ts === "string") {
|
|
558
|
+
lines.push(ts);
|
|
559
|
+
} else if (typeof ts === "object") {
|
|
607
560
|
lines.push("```json");
|
|
608
|
-
lines.push(JSON.stringify(
|
|
561
|
+
lines.push(JSON.stringify(ts, null, 2));
|
|
609
562
|
lines.push("```");
|
|
610
563
|
}
|
|
611
564
|
lines.push("");
|
|
@@ -624,7 +577,7 @@ function generateAgentMarkdown(agent, mcpServers) {
|
|
|
624
577
|
lines.push("");
|
|
625
578
|
for (const [category, items] of Object.entries(agent.principles)) {
|
|
626
579
|
if (items && Array.isArray(items) && items.length > 0) {
|
|
627
|
-
const title =
|
|
580
|
+
const title = category.replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
628
581
|
lines.push(`### ${title}`);
|
|
629
582
|
lines.push("");
|
|
630
583
|
for (const item of items) {
|
|
@@ -655,21 +608,161 @@ function generateAgentMarkdown(agent, mcpServers) {
|
|
|
655
608
|
lines.push("");
|
|
656
609
|
}
|
|
657
610
|
}
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
611
|
+
if (agent.knowledge_library) {
|
|
612
|
+
generateKnowledgeLibrarySection(agent, lines);
|
|
613
|
+
}
|
|
614
|
+
if (agent.communication) {
|
|
615
|
+
generateCommunicationSection(agent, lines);
|
|
616
|
+
}
|
|
617
|
+
if (agent.protocols?.startup) {
|
|
618
|
+
generateStartupProtocolSection(agent, lines);
|
|
619
|
+
}
|
|
620
|
+
if (agent.protocols?.completion) {
|
|
621
|
+
generateCompletionProtocolSection(agent, lines);
|
|
622
|
+
}
|
|
623
|
+
if (agent.context_sources && !agent.knowledge_library) {
|
|
624
|
+
lines.push("## Context Sources");
|
|
625
|
+
lines.push("");
|
|
626
|
+
if (agent.context_sources.shared?.length) {
|
|
627
|
+
lines.push("### Shared");
|
|
628
|
+
lines.push("");
|
|
629
|
+
for (const s of agent.context_sources.shared) lines.push(`- ${s}`);
|
|
630
|
+
lines.push("");
|
|
631
|
+
}
|
|
632
|
+
if (agent.context_sources.personal?.length) {
|
|
633
|
+
lines.push("### Personal");
|
|
634
|
+
lines.push("");
|
|
635
|
+
for (const p of agent.context_sources.personal) lines.push(`- ${p}`);
|
|
636
|
+
lines.push("");
|
|
637
|
+
}
|
|
638
|
+
}
|
|
663
639
|
lines.push("---");
|
|
664
640
|
lines.push("");
|
|
665
641
|
lines.push("*Generated by CoreAI*");
|
|
666
642
|
lines.push("");
|
|
667
643
|
return lines.join("\n");
|
|
668
644
|
}
|
|
669
|
-
function
|
|
670
|
-
|
|
645
|
+
function generateKnowledgeLibrarySection(agent, lines) {
|
|
646
|
+
const kl = agent.knowledge_library;
|
|
647
|
+
if (!kl) return;
|
|
648
|
+
lines.push("## Knowledge Library Structure");
|
|
649
|
+
lines.push("");
|
|
650
|
+
if (kl.shared) {
|
|
651
|
+
lines.push("### Shared Context (Root - All Agents)");
|
|
652
|
+
lines.push("```");
|
|
653
|
+
lines.push("/KnowledgeLibrary/");
|
|
654
|
+
if (kl.shared.context) lines.push(`\u251C\u2500\u2500 ${kl.shared.context.split("/").pop()}`);
|
|
655
|
+
if (kl.shared.architecture) lines.push(`\u251C\u2500\u2500 ${kl.shared.architecture.split("/").pop()}`);
|
|
656
|
+
if (kl.shared.prd) lines.push(`\u2514\u2500\u2500 ${kl.shared.prd.split("/").pop()}`);
|
|
657
|
+
lines.push("```");
|
|
658
|
+
if (kl.shared.remote?.length) {
|
|
659
|
+
lines.push("");
|
|
660
|
+
lines.push("**Remote Documentation:**");
|
|
661
|
+
for (const r of kl.shared.remote) lines.push(`- ${r}`);
|
|
662
|
+
}
|
|
663
|
+
lines.push("");
|
|
664
|
+
}
|
|
665
|
+
if (kl.personal) {
|
|
666
|
+
lines.push(`### Personal Context (${agent.role})`);
|
|
667
|
+
lines.push("```");
|
|
668
|
+
lines.push(`/KnowledgeLibrary/${agent.role}/`);
|
|
669
|
+
if (kl.personal.context) {
|
|
670
|
+
lines.push("\u251C\u2500\u2500 context/");
|
|
671
|
+
lines.push("\u2502 \u2514\u2500\u2500 current.txt");
|
|
672
|
+
}
|
|
673
|
+
if (kl.personal.history) {
|
|
674
|
+
lines.push("\u251C\u2500\u2500 history/");
|
|
675
|
+
}
|
|
676
|
+
if (kl.personal.inbox) {
|
|
677
|
+
lines.push("\u251C\u2500\u2500 inbox/");
|
|
678
|
+
}
|
|
679
|
+
if (kl.personal.outbox) {
|
|
680
|
+
lines.push("\u251C\u2500\u2500 outbox/");
|
|
681
|
+
}
|
|
682
|
+
if (kl.personal.tech) {
|
|
683
|
+
lines.push("\u251C\u2500\u2500 tech/");
|
|
684
|
+
}
|
|
685
|
+
if (kl.personal.control) {
|
|
686
|
+
lines.push("\u2514\u2500\u2500 control/");
|
|
687
|
+
if (kl.personal.control.objectives) lines.push(" \u251C\u2500\u2500 objectives.txt");
|
|
688
|
+
if (kl.personal.control.decisions) lines.push(" \u251C\u2500\u2500 decisions.txt");
|
|
689
|
+
if (kl.personal.control.dependencies) lines.push(" \u251C\u2500\u2500 dependencies.txt");
|
|
690
|
+
if (kl.personal.control.index) lines.push(" \u2514\u2500\u2500 index.txt");
|
|
691
|
+
}
|
|
692
|
+
lines.push("```");
|
|
693
|
+
lines.push("");
|
|
694
|
+
}
|
|
695
|
+
lines.push("---");
|
|
696
|
+
lines.push("");
|
|
697
|
+
}
|
|
698
|
+
function generateCommunicationSection(agent, lines) {
|
|
699
|
+
const comm = agent.communication;
|
|
700
|
+
if (!comm) return;
|
|
701
|
+
lines.push("## Communication");
|
|
702
|
+
lines.push("");
|
|
703
|
+
if (comm.inbox) lines.push(`**Inbox:** \`${comm.inbox}\``);
|
|
704
|
+
if (comm.outbox) lines.push(`**Outbox:** \`${comm.outbox}\``);
|
|
705
|
+
lines.push("");
|
|
706
|
+
if (comm.message_format || comm.outbox_format || comm.processed_dir) {
|
|
707
|
+
lines.push("### Message Conventions");
|
|
708
|
+
lines.push("");
|
|
709
|
+
if (comm.message_format) lines.push(`- **Inbox message naming:** \`${comm.message_format}\``);
|
|
710
|
+
if (comm.outbox_format) lines.push(`- **Outbox message naming:** \`${comm.outbox_format}\``);
|
|
711
|
+
if (comm.processed_dir) lines.push(`- **Processed messages:** Move handled inbox messages to \`${comm.processed_dir}\``);
|
|
712
|
+
lines.push("");
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
function generateStartupProtocolSection(agent, lines) {
|
|
716
|
+
const p = agent.protocols;
|
|
717
|
+
if (!p?.startup) return;
|
|
718
|
+
lines.push("## When Invoked");
|
|
719
|
+
lines.push("");
|
|
720
|
+
lines.push("> **MANDATORY STARTUP PROTOCOL** - Execute before proceeding with any task.");
|
|
721
|
+
lines.push("");
|
|
722
|
+
lines.push("### Session Context Check");
|
|
723
|
+
lines.push("");
|
|
724
|
+
if (p.startup.first_session?.length) {
|
|
725
|
+
lines.push("**If this is your FIRST invocation in this session:**");
|
|
726
|
+
lines.push("");
|
|
727
|
+
for (const s of p.startup.first_session) lines.push(`- [ ] ${s}`);
|
|
728
|
+
lines.push("");
|
|
729
|
+
lines.push('Acknowledge: "Startup protocol complete. Full context loaded."');
|
|
730
|
+
lines.push("");
|
|
731
|
+
}
|
|
732
|
+
if (p.startup.subsequent?.length) {
|
|
733
|
+
lines.push("**If you have ALREADY loaded context in this session:**");
|
|
734
|
+
lines.push("");
|
|
735
|
+
for (const s of p.startup.subsequent) lines.push(`- [ ] ${s}`);
|
|
736
|
+
lines.push("");
|
|
737
|
+
lines.push('Acknowledge: "Context already loaded. Checked inbox for new messages."');
|
|
738
|
+
lines.push("");
|
|
739
|
+
}
|
|
740
|
+
lines.push("Then proceed with the task.");
|
|
741
|
+
lines.push("");
|
|
742
|
+
lines.push("---");
|
|
743
|
+
lines.push("");
|
|
671
744
|
}
|
|
672
|
-
function
|
|
745
|
+
function generateCompletionProtocolSection(agent, lines) {
|
|
746
|
+
const p = agent.protocols;
|
|
747
|
+
if (!p?.completion?.length) return;
|
|
748
|
+
lines.push("## Before Finishing");
|
|
749
|
+
lines.push("");
|
|
750
|
+
lines.push("> **MANDATORY COMPLETION PROTOCOL** - Execute ALL steps before ending any task.");
|
|
751
|
+
lines.push("");
|
|
752
|
+
for (let i = 0; i < p.completion.length; i++) {
|
|
753
|
+
lines.push(`### ${i + 1}. ${p.completion[i]}`);
|
|
754
|
+
lines.push("");
|
|
755
|
+
}
|
|
756
|
+
lines.push('Acknowledge: "Completion protocol finished. Context updated."');
|
|
757
|
+
lines.push("");
|
|
758
|
+
lines.push("---");
|
|
759
|
+
lines.push("");
|
|
760
|
+
}
|
|
761
|
+
function compileAgent(agent, filePath, config, mcpServers) {
|
|
762
|
+
const ext = extname2(filePath).toLowerCase();
|
|
763
|
+
if (ext === ".md") {
|
|
764
|
+
return processAgentTemplate(filePath, agent, config, mcpServers);
|
|
765
|
+
}
|
|
673
766
|
const resolved = resolveAgentDefinition(agent, config);
|
|
674
767
|
return generateAgentMarkdown(resolved, mcpServers);
|
|
675
768
|
}
|
|
@@ -729,7 +822,12 @@ function compileAgents(config, options = {}) {
|
|
|
729
822
|
continue;
|
|
730
823
|
}
|
|
731
824
|
try {
|
|
732
|
-
const markdown = compileAgent(
|
|
825
|
+
const markdown = compileAgent(
|
|
826
|
+
metadata.definition,
|
|
827
|
+
metadata.filePath,
|
|
828
|
+
config,
|
|
829
|
+
options.mcpServers
|
|
830
|
+
);
|
|
733
831
|
const outputPath = join3(outputDir, `${role}.md`);
|
|
734
832
|
writeFileSync(outputPath, markdown, "utf-8");
|
|
735
833
|
result.compiled.push({
|
|
@@ -2596,470 +2694,124 @@ var StepTracker = class {
|
|
|
2596
2694
|
};
|
|
2597
2695
|
|
|
2598
2696
|
// src/skills/generator.ts
|
|
2599
|
-
import { existsSync as existsSync4, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as
|
|
2600
|
-
import { join as join6,
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
}
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
## Quality Gates
|
|
2718
|
-
|
|
2719
|
-
Run these checks before committing:
|
|
2720
|
-
|
|
2721
|
-
1. **Lint**: \`{{LINT_CMD}}\`
|
|
2722
|
-
2. **Tests**: \`{{TEST_CMD}}\`
|
|
2723
|
-
3. **Build**: \`{{BUILD_CMD}}\`
|
|
2724
|
-
|
|
2725
|
-
## Instructions
|
|
2726
|
-
|
|
2727
|
-
1. Stage the relevant files with \`git add\`
|
|
2728
|
-
2. Run all quality gate commands
|
|
2729
|
-
3. If any gate fails:
|
|
2730
|
-
- Fix the issues
|
|
2731
|
-
- Re-run the failed gate
|
|
2732
|
-
- Continue only when all pass
|
|
2733
|
-
4. Create the commit with the provided message
|
|
2734
|
-
5. Format: Include ticket reference if applicable
|
|
2735
|
-
|
|
2736
|
-
## Commit Message Format
|
|
2737
|
-
|
|
2738
|
-
\`\`\`
|
|
2739
|
-
<type>(<scope>): <description>
|
|
2740
|
-
|
|
2741
|
-
[optional body]
|
|
2742
|
-
|
|
2743
|
-
[optional footer]
|
|
2744
|
-
\`\`\`
|
|
2745
|
-
|
|
2746
|
-
Types: feat, fix, docs, style, refactor, test, chore
|
|
2747
|
-
|
|
2748
|
-
## Fallbacks
|
|
2749
|
-
|
|
2750
|
-
If quality gate commands are not configured:
|
|
2751
|
-
- Ask the user what commands to run
|
|
2752
|
-
- Or skip gates with user confirmation
|
|
2753
|
-
`
|
|
2754
|
-
};
|
|
2755
|
-
var prCreateSkill = {
|
|
2756
|
-
name: "pr-create",
|
|
2757
|
-
description: "Create a pull request with proper format",
|
|
2758
|
-
argumentHint: "[branch-name]",
|
|
2759
|
-
category: "core",
|
|
2760
|
-
dependencies: [{ type: "git", required: true, description: "For PR creation" }],
|
|
2761
|
-
content: `---
|
|
2762
|
-
description: Create a pull request with proper format
|
|
2763
|
-
argument-hint: [branch-name]
|
|
2764
|
-
requires: [git]
|
|
2765
|
-
---
|
|
2766
|
-
|
|
2767
|
-
# Create Pull Request
|
|
2768
|
-
|
|
2769
|
-
Create a well-formatted pull request for the current branch.
|
|
2770
|
-
|
|
2771
|
-
## Instructions
|
|
2772
|
-
|
|
2773
|
-
1. Ensure all changes are committed
|
|
2774
|
-
2. Push the branch to remote
|
|
2775
|
-
3. Create PR with proper format:
|
|
2776
|
-
|
|
2777
|
-
\`\`\`markdown
|
|
2778
|
-
## Summary
|
|
2779
|
-
<Brief description of changes>
|
|
2780
|
-
|
|
2781
|
-
## Changes
|
|
2782
|
-
- <Change 1>
|
|
2783
|
-
- <Change 2>
|
|
2784
|
-
|
|
2785
|
-
## Test Plan
|
|
2786
|
-
- [ ] <Test case 1>
|
|
2787
|
-
- [ ] <Test case 2>
|
|
2788
|
-
|
|
2789
|
-
## Related Issues
|
|
2790
|
-
Closes {{JIRA_PROJECT}}-XXX
|
|
2791
|
-
\`\`\`
|
|
2792
|
-
|
|
2793
|
-
4. Request reviewers if specified
|
|
2794
|
-
|
|
2795
|
-
## Using GitHub CLI
|
|
2796
|
-
|
|
2797
|
-
\`\`\`bash
|
|
2798
|
-
gh pr create --title "<title>" --body "<body>"
|
|
2799
|
-
\`\`\`
|
|
2800
|
-
|
|
2801
|
-
## Output
|
|
2802
|
-
|
|
2803
|
-
Provide the PR URL and summary of what was created.
|
|
2804
|
-
`
|
|
2805
|
-
};
|
|
2806
|
-
var reviewSkill = {
|
|
2807
|
-
name: "review",
|
|
2808
|
-
description: "Request or perform a code review",
|
|
2809
|
-
argumentHint: "<pr-number-or-url>",
|
|
2810
|
-
category: "core",
|
|
2811
|
-
dependencies: [{ type: "git", required: true, description: "For PR review" }],
|
|
2812
|
-
content: `---
|
|
2813
|
-
description: Request or perform a code review
|
|
2814
|
-
argument-hint: <pr-number-or-url>
|
|
2815
|
-
requires: [git]
|
|
2816
|
-
---
|
|
2817
|
-
|
|
2818
|
-
# Code Review
|
|
2819
|
-
|
|
2820
|
-
Review a pull request or delegate review to a specialist.
|
|
2821
|
-
|
|
2822
|
-
## Instructions
|
|
2823
|
-
|
|
2824
|
-
### If you are reviewing:
|
|
2825
|
-
|
|
2826
|
-
1. Fetch the PR details and diff
|
|
2827
|
-
2. Review for:
|
|
2828
|
-
- Code quality and style
|
|
2829
|
-
- Logic errors or bugs
|
|
2830
|
-
- Security concerns
|
|
2831
|
-
- Test coverage
|
|
2832
|
-
- Documentation
|
|
2833
|
-
3. Provide feedback with specific line references
|
|
2834
|
-
4. Approve, request changes, or comment
|
|
2835
|
-
|
|
2836
|
-
### If delegating to a reviewer:
|
|
2837
|
-
|
|
2838
|
-
1. Identify the appropriate reviewer based on the changes
|
|
2839
|
-
2. Create a review request message in their inbox
|
|
2840
|
-
3. Include PR link and context
|
|
2841
|
-
|
|
2842
|
-
## Review Checklist
|
|
2843
|
-
|
|
2844
|
-
- [ ] Code follows project conventions
|
|
2845
|
-
- [ ] No obvious bugs or edge cases
|
|
2846
|
-
- [ ] Tests cover the changes
|
|
2847
|
-
- [ ] Documentation updated if needed
|
|
2848
|
-
- [ ] No security vulnerabilities
|
|
2849
|
-
|
|
2850
|
-
## Output
|
|
2851
|
-
|
|
2852
|
-
Provide review summary with actionable feedback.
|
|
2853
|
-
`
|
|
2854
|
-
};
|
|
2855
|
-
var sprintStatusSkill = {
|
|
2856
|
-
name: "sprint-status",
|
|
2857
|
-
description: "Get current sprint status and progress",
|
|
2858
|
-
category: "optional",
|
|
2859
|
-
dependencies: [{ type: "issue_tracker", required: true, description: "For sprint data" }],
|
|
2860
|
-
content: `---
|
|
2861
|
-
description: Get current sprint status and progress
|
|
2862
|
-
requires: [issue_tracker]
|
|
2863
|
-
---
|
|
2864
|
-
|
|
2865
|
-
# Sprint Status
|
|
2866
|
-
|
|
2867
|
-
Get the current sprint status and team progress.
|
|
2868
|
-
|
|
2869
|
-
## Instructions
|
|
2870
|
-
|
|
2871
|
-
1. Query the active sprint for project {{JIRA_PROJECT}}
|
|
2872
|
-
2. Gather metrics:
|
|
2873
|
-
- Total story points committed
|
|
2874
|
-
- Points completed
|
|
2875
|
-
- Points in progress
|
|
2876
|
-
- Points remaining
|
|
2877
|
-
3. List tickets by status
|
|
2878
|
-
4. Identify blockers or at-risk items
|
|
2879
|
-
|
|
2880
|
-
## Output Format
|
|
2881
|
-
|
|
2882
|
-
\`\`\`
|
|
2883
|
-
Sprint: <sprint-name>
|
|
2884
|
-
Progress: XX/YY points (ZZ%)
|
|
2885
|
-
|
|
2886
|
-
## Completed
|
|
2887
|
-
- [{{JIRA_PROJECT}}-123] Task name (3 pts)
|
|
2888
|
-
|
|
2889
|
-
## In Progress
|
|
2890
|
-
- [{{JIRA_PROJECT}}-124] Task name (5 pts) - @assignee
|
|
2891
|
-
|
|
2892
|
-
## To Do
|
|
2893
|
-
- [{{JIRA_PROJECT}}-125] Task name (2 pts)
|
|
2894
|
-
|
|
2895
|
-
## Blocked
|
|
2896
|
-
- [{{JIRA_PROJECT}}-126] Task name - Reason
|
|
2897
|
-
\`\`\`
|
|
2898
|
-
|
|
2899
|
-
## Fallbacks
|
|
2900
|
-
|
|
2901
|
-
If issue tracker is unavailable:
|
|
2902
|
-
- Report that sprint data cannot be fetched
|
|
2903
|
-
- Suggest checking the issue tracker directly at {{JIRA_URL}}
|
|
2904
|
-
`
|
|
2905
|
-
};
|
|
2906
|
-
var jiraCreateSkill = {
|
|
2907
|
-
name: "jira-create",
|
|
2908
|
-
description: "Create a new Jira ticket",
|
|
2909
|
-
argumentHint: "<ticket-type> <summary>",
|
|
2910
|
-
category: "optional",
|
|
2911
|
-
dependencies: [{ type: "issue_tracker", required: true, description: "For ticket creation" }],
|
|
2912
|
-
content: `---
|
|
2913
|
-
description: Create a new Jira ticket
|
|
2914
|
-
argument-hint: <ticket-type> <summary>
|
|
2915
|
-
requires: [issue_tracker]
|
|
2916
|
-
---
|
|
2917
|
-
|
|
2918
|
-
# Create Jira Ticket
|
|
2919
|
-
|
|
2920
|
-
Create a new ticket in project {{JIRA_PROJECT}}.
|
|
2921
|
-
|
|
2922
|
-
## Instructions
|
|
2923
|
-
|
|
2924
|
-
1. Parse the ticket type and summary from arguments
|
|
2925
|
-
2. Gather additional details:
|
|
2926
|
-
- Description
|
|
2927
|
-
- Priority
|
|
2928
|
-
- Labels
|
|
2929
|
-
- Components (if applicable)
|
|
2930
|
-
3. Create the ticket via the issue tracker integration
|
|
2931
|
-
4. Return the ticket key and URL
|
|
2932
|
-
|
|
2933
|
-
## Ticket Types
|
|
2934
|
-
|
|
2935
|
-
- **Story**: User-facing feature
|
|
2936
|
-
- **Bug**: Defect to fix
|
|
2937
|
-
- **Task**: Technical work
|
|
2938
|
-
- **Spike**: Research/investigation
|
|
2939
|
-
|
|
2940
|
-
## Output
|
|
2941
|
-
|
|
2942
|
-
\`\`\`
|
|
2943
|
-
Created: {{JIRA_PROJECT}}-XXX
|
|
2944
|
-
URL: {{JIRA_URL}}/browse/{{JIRA_PROJECT}}-XXX
|
|
2945
|
-
Summary: <summary>
|
|
2946
|
-
Type: <type>
|
|
2947
|
-
\`\`\`
|
|
2948
|
-
|
|
2949
|
-
## Fallbacks
|
|
2950
|
-
|
|
2951
|
-
If issue tracker is unavailable:
|
|
2952
|
-
- Provide the user with manual creation instructions
|
|
2953
|
-
- Include all details they should enter
|
|
2954
|
-
`
|
|
2955
|
-
};
|
|
2956
|
-
var jiraTransitionSkill = {
|
|
2957
|
-
name: "jira-transition",
|
|
2958
|
-
description: "Transition a Jira ticket to a new status",
|
|
2959
|
-
argumentHint: "<ticket-key> to <status>",
|
|
2960
|
-
category: "optional",
|
|
2961
|
-
dependencies: [{ type: "issue_tracker", required: true, description: "For ticket transitions" }],
|
|
2962
|
-
content: `---
|
|
2963
|
-
description: Transition a Jira ticket to a new status
|
|
2964
|
-
argument-hint: <ticket-key> to <status>
|
|
2965
|
-
requires: [issue_tracker]
|
|
2966
|
-
---
|
|
2967
|
-
|
|
2968
|
-
# Transition Jira Ticket
|
|
2969
|
-
|
|
2970
|
-
Update the status of a ticket in {{JIRA_PROJECT}}.
|
|
2971
|
-
|
|
2972
|
-
## Status Mapping
|
|
2973
|
-
|
|
2974
|
-
| Workflow Status | Jira Status |
|
|
2975
|
-
|-----------------|-------------|
|
|
2976
|
-
| BACKLOG | Backlog |
|
|
2977
|
-
| IN_PROGRESS | In Progress |
|
|
2978
|
-
| PR_CREATED | In Review |
|
|
2979
|
-
| IN_REVIEW | In Review |
|
|
2980
|
-
| APPROVED | Ready to Merge |
|
|
2981
|
-
| MERGED | Done |
|
|
2982
|
-
| DONE | Done |
|
|
2983
|
-
|
|
2984
|
-
## Instructions
|
|
2985
|
-
|
|
2986
|
-
1. Parse ticket key and target status
|
|
2987
|
-
2. Validate the transition is allowed
|
|
2988
|
-
3. Add a comment explaining the transition
|
|
2989
|
-
4. Execute the transition
|
|
2990
|
-
|
|
2991
|
-
## Transition Comment Format
|
|
2992
|
-
|
|
2993
|
-
\`\`\`
|
|
2994
|
-
Status updated to <status>.
|
|
2995
|
-
<optional context about why>
|
|
2996
|
-
\`\`\`
|
|
2997
|
-
|
|
2998
|
-
## Fallbacks
|
|
2999
|
-
|
|
3000
|
-
If issue tracker is unavailable:
|
|
3001
|
-
- Instruct user to manually transition at {{JIRA_URL}}
|
|
3002
|
-
- Provide the target status name
|
|
3003
|
-
`
|
|
3004
|
-
};
|
|
3005
|
-
var docsUpdateSkill = {
|
|
3006
|
-
name: "docs-update",
|
|
3007
|
-
description: "Update project documentation",
|
|
3008
|
-
argumentHint: "<doc-path-or-topic>",
|
|
3009
|
-
category: "optional",
|
|
3010
|
-
dependencies: [{ type: "documentation", required: false, description: "For remote docs" }],
|
|
3011
|
-
content: `---
|
|
3012
|
-
description: Update project documentation
|
|
3013
|
-
argument-hint: <doc-path-or-topic>
|
|
3014
|
-
optional: [documentation]
|
|
3015
|
-
---
|
|
3016
|
-
|
|
3017
|
-
# Update Documentation
|
|
3018
|
-
|
|
3019
|
-
Update project documentation for a specific topic or file.
|
|
3020
|
-
|
|
3021
|
-
## Instructions
|
|
3022
|
-
|
|
3023
|
-
1. Identify the documentation to update:
|
|
3024
|
-
- Local: \`{{DOCS_PATH}}/\`
|
|
3025
|
-
- Remote: {{CONFLUENCE_SPACE}} (if configured)
|
|
3026
|
-
|
|
3027
|
-
2. Make the necessary updates:
|
|
3028
|
-
- Keep formatting consistent
|
|
3029
|
-
- Update examples if code changed
|
|
3030
|
-
- Add/update version information
|
|
3031
|
-
|
|
3032
|
-
3. For remote documentation:
|
|
3033
|
-
- Use the documentation integration
|
|
3034
|
-
- Or provide content for manual update
|
|
3035
|
-
|
|
3036
|
-
## Documentation Types
|
|
3037
|
-
|
|
3038
|
-
- **README**: Project overview and setup
|
|
3039
|
-
- **API Docs**: Endpoint documentation
|
|
3040
|
-
- **Architecture**: Design decisions
|
|
3041
|
-
- **Runbooks**: Operational procedures
|
|
3042
|
-
|
|
3043
|
-
## Fallbacks
|
|
3044
|
-
|
|
3045
|
-
If documentation integration is unavailable:
|
|
3046
|
-
- Create/update local markdown files
|
|
3047
|
-
- Provide instructions for manual remote update
|
|
3048
|
-
`
|
|
3049
|
-
};
|
|
3050
|
-
var builtInSkills = [
|
|
3051
|
-
checkInboxSkill,
|
|
3052
|
-
delegateSkill,
|
|
3053
|
-
gitCommitSkill,
|
|
3054
|
-
prCreateSkill,
|
|
3055
|
-
reviewSkill,
|
|
3056
|
-
sprintStatusSkill,
|
|
3057
|
-
jiraCreateSkill,
|
|
3058
|
-
jiraTransitionSkill,
|
|
3059
|
-
docsUpdateSkill
|
|
3060
|
-
];
|
|
3061
|
-
|
|
3062
|
-
// src/skills/generator.ts
|
|
2697
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as readFileSync4, readdirSync as readdirSync2, statSync } from "fs";
|
|
2698
|
+
import { join as join6, dirname as dirname5 } from "path";
|
|
2699
|
+
function getCoreSkillsDir() {
|
|
2700
|
+
let currentDir = dirname5(import.meta.url.replace("file://", ""));
|
|
2701
|
+
for (let i = 0; i < 5; i++) {
|
|
2702
|
+
if (existsSync4(join6(currentDir, "package.json"))) {
|
|
2703
|
+
return join6(currentDir, "skills");
|
|
2704
|
+
}
|
|
2705
|
+
currentDir = dirname5(currentDir);
|
|
2706
|
+
}
|
|
2707
|
+
return join6(dirname5(dirname5(dirname5(import.meta.url.replace("file://", "")))), "skills");
|
|
2708
|
+
}
|
|
2709
|
+
function discoverSkills(skillsDir) {
|
|
2710
|
+
const templates = [];
|
|
2711
|
+
if (!existsSync4(skillsDir)) {
|
|
2712
|
+
return templates;
|
|
2713
|
+
}
|
|
2714
|
+
const categories = readdirSync2(skillsDir);
|
|
2715
|
+
for (const category of categories) {
|
|
2716
|
+
const categoryPath = join6(skillsDir, category);
|
|
2717
|
+
const stat = statSync(categoryPath);
|
|
2718
|
+
if (!stat.isDirectory()) continue;
|
|
2719
|
+
if (category.startsWith(".") || category.startsWith("_")) continue;
|
|
2720
|
+
const skillDirs = readdirSync2(categoryPath);
|
|
2721
|
+
for (const skillName of skillDirs) {
|
|
2722
|
+
const skillDir = join6(categoryPath, skillName);
|
|
2723
|
+
const skillStat = statSync(skillDir);
|
|
2724
|
+
if (!skillStat.isDirectory()) continue;
|
|
2725
|
+
const skillFile = join6(skillDir, "SKILL.md");
|
|
2726
|
+
if (!existsSync4(skillFile)) continue;
|
|
2727
|
+
try {
|
|
2728
|
+
const content = readFileSync4(skillFile, "utf-8");
|
|
2729
|
+
const template = parseSkillFile(skillName, category, content);
|
|
2730
|
+
templates.push(template);
|
|
2731
|
+
} catch {
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
return templates;
|
|
2736
|
+
}
|
|
2737
|
+
function parseSkillFile(name, category, content) {
|
|
2738
|
+
const template = {
|
|
2739
|
+
name,
|
|
2740
|
+
description: name,
|
|
2741
|
+
category,
|
|
2742
|
+
content
|
|
2743
|
+
};
|
|
2744
|
+
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/);
|
|
2745
|
+
if (!frontmatterMatch) {
|
|
2746
|
+
return template;
|
|
2747
|
+
}
|
|
2748
|
+
const frontmatter = frontmatterMatch[1];
|
|
2749
|
+
const lines = frontmatter.split(/\r?\n/);
|
|
2750
|
+
const dependencies = [];
|
|
2751
|
+
for (const line of lines) {
|
|
2752
|
+
const colonIndex = line.indexOf(":");
|
|
2753
|
+
if (colonIndex === -1) continue;
|
|
2754
|
+
const key = line.slice(0, colonIndex).trim();
|
|
2755
|
+
let value = line.slice(colonIndex + 1).trim();
|
|
2756
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
2757
|
+
value = value.slice(1, -1);
|
|
2758
|
+
}
|
|
2759
|
+
switch (key) {
|
|
2760
|
+
case "name":
|
|
2761
|
+
template.name = value;
|
|
2762
|
+
break;
|
|
2763
|
+
case "description":
|
|
2764
|
+
template.description = value;
|
|
2765
|
+
break;
|
|
2766
|
+
case "argument-hint":
|
|
2767
|
+
template.argumentHint = value;
|
|
2768
|
+
break;
|
|
2769
|
+
case "requires":
|
|
2770
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
2771
|
+
const items = value.slice(1, -1).split(",").map((s) => s.trim().replace(/['"]/g, ""));
|
|
2772
|
+
for (const item of items) {
|
|
2773
|
+
if (item) {
|
|
2774
|
+
dependencies.push({
|
|
2775
|
+
type: mapIntegrationName(item),
|
|
2776
|
+
required: true
|
|
2777
|
+
});
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
}
|
|
2781
|
+
break;
|
|
2782
|
+
case "optional":
|
|
2783
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
2784
|
+
const items = value.slice(1, -1).split(",").map((s) => s.trim().replace(/['"]/g, ""));
|
|
2785
|
+
for (const item of items) {
|
|
2786
|
+
if (item) {
|
|
2787
|
+
dependencies.push({
|
|
2788
|
+
type: mapIntegrationName(item),
|
|
2789
|
+
required: false
|
|
2790
|
+
});
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
break;
|
|
2795
|
+
}
|
|
2796
|
+
}
|
|
2797
|
+
if (dependencies.length > 0) {
|
|
2798
|
+
template.dependencies = dependencies;
|
|
2799
|
+
}
|
|
2800
|
+
return template;
|
|
2801
|
+
}
|
|
2802
|
+
function mapIntegrationName(name) {
|
|
2803
|
+
const lower = name.toLowerCase();
|
|
2804
|
+
if (["jira", "linear", "issue_tracker", "issues", "github-issues"].includes(lower)) {
|
|
2805
|
+
return "issue_tracker";
|
|
2806
|
+
}
|
|
2807
|
+
if (["git", "github", "gitlab", "bitbucket"].includes(lower)) {
|
|
2808
|
+
return "git";
|
|
2809
|
+
}
|
|
2810
|
+
if (["docs", "documentation", "confluence", "notion", "wiki"].includes(lower)) {
|
|
2811
|
+
return "documentation";
|
|
2812
|
+
}
|
|
2813
|
+
return "state";
|
|
2814
|
+
}
|
|
3063
2815
|
function extractVariables2(config) {
|
|
3064
2816
|
const vars = {};
|
|
3065
2817
|
if (!config) {
|
|
@@ -3169,112 +2921,12 @@ function checkDependencies(skill, config) {
|
|
|
3169
2921
|
missing
|
|
3170
2922
|
};
|
|
3171
2923
|
}
|
|
3172
|
-
function loadCustomTemplates(templatesDir) {
|
|
3173
|
-
const templates = [];
|
|
3174
|
-
if (!existsSync4(templatesDir)) {
|
|
3175
|
-
return templates;
|
|
3176
|
-
}
|
|
3177
|
-
const files = readdirSync2(templatesDir);
|
|
3178
|
-
for (const file of files) {
|
|
3179
|
-
if (!file.endsWith(".md")) continue;
|
|
3180
|
-
const filePath = join6(templatesDir, file);
|
|
3181
|
-
const stat = statSync(filePath);
|
|
3182
|
-
if (!stat.isFile()) continue;
|
|
3183
|
-
try {
|
|
3184
|
-
const content = readFileSync3(filePath, "utf-8");
|
|
3185
|
-
const template = parseSkillTemplate(file, content);
|
|
3186
|
-
templates.push(template);
|
|
3187
|
-
} catch {
|
|
3188
|
-
}
|
|
3189
|
-
}
|
|
3190
|
-
return templates;
|
|
3191
|
-
}
|
|
3192
|
-
function parseSkillTemplate(filename, content) {
|
|
3193
|
-
const name = basename3(filename, ".md");
|
|
3194
|
-
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
|
|
3195
|
-
let description = name;
|
|
3196
|
-
let argumentHint;
|
|
3197
|
-
const dependencies = [];
|
|
3198
|
-
if (frontmatterMatch) {
|
|
3199
|
-
const frontmatter = frontmatterMatch[1] ?? "";
|
|
3200
|
-
const lines = frontmatter.split(/\r?\n/);
|
|
3201
|
-
for (const line of lines) {
|
|
3202
|
-
const colonIndex = line.indexOf(":");
|
|
3203
|
-
if (colonIndex === -1) continue;
|
|
3204
|
-
const key = line.slice(0, colonIndex).trim();
|
|
3205
|
-
let value = line.slice(colonIndex + 1).trim();
|
|
3206
|
-
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
3207
|
-
value = value.slice(1, -1);
|
|
3208
|
-
}
|
|
3209
|
-
switch (key) {
|
|
3210
|
-
case "description":
|
|
3211
|
-
description = value;
|
|
3212
|
-
break;
|
|
3213
|
-
case "argument-hint":
|
|
3214
|
-
argumentHint = value;
|
|
3215
|
-
break;
|
|
3216
|
-
case "requires":
|
|
3217
|
-
if (value.startsWith("[") && value.endsWith("]")) {
|
|
3218
|
-
const items = value.slice(1, -1).split(",").map((s) => s.trim().replace(/['"]/g, ""));
|
|
3219
|
-
for (const item of items) {
|
|
3220
|
-
if (item) {
|
|
3221
|
-
dependencies.push({
|
|
3222
|
-
type: mapIntegrationName(item),
|
|
3223
|
-
required: true
|
|
3224
|
-
});
|
|
3225
|
-
}
|
|
3226
|
-
}
|
|
3227
|
-
}
|
|
3228
|
-
break;
|
|
3229
|
-
case "optional":
|
|
3230
|
-
if (value.startsWith("[") && value.endsWith("]")) {
|
|
3231
|
-
const items = value.slice(1, -1).split(",").map((s) => s.trim().replace(/['"]/g, ""));
|
|
3232
|
-
for (const item of items) {
|
|
3233
|
-
if (item) {
|
|
3234
|
-
dependencies.push({
|
|
3235
|
-
type: mapIntegrationName(item),
|
|
3236
|
-
required: false
|
|
3237
|
-
});
|
|
3238
|
-
}
|
|
3239
|
-
}
|
|
3240
|
-
}
|
|
3241
|
-
break;
|
|
3242
|
-
}
|
|
3243
|
-
}
|
|
3244
|
-
}
|
|
3245
|
-
const template = {
|
|
3246
|
-
name,
|
|
3247
|
-
description,
|
|
3248
|
-
category: "custom",
|
|
3249
|
-
content
|
|
3250
|
-
};
|
|
3251
|
-
if (argumentHint) {
|
|
3252
|
-
template.argumentHint = argumentHint;
|
|
3253
|
-
}
|
|
3254
|
-
if (dependencies.length > 0) {
|
|
3255
|
-
template.dependencies = dependencies;
|
|
3256
|
-
}
|
|
3257
|
-
return template;
|
|
3258
|
-
}
|
|
3259
|
-
function mapIntegrationName(name) {
|
|
3260
|
-
const lower = name.toLowerCase();
|
|
3261
|
-
if (["jira", "linear", "issue_tracker", "issues", "github-issues"].includes(lower)) {
|
|
3262
|
-
return "issue_tracker";
|
|
3263
|
-
}
|
|
3264
|
-
if (["git", "github", "gitlab", "bitbucket"].includes(lower)) {
|
|
3265
|
-
return "git";
|
|
3266
|
-
}
|
|
3267
|
-
if (["docs", "documentation", "confluence", "notion", "wiki"].includes(lower)) {
|
|
3268
|
-
return "documentation";
|
|
3269
|
-
}
|
|
3270
|
-
return "state";
|
|
3271
|
-
}
|
|
3272
2924
|
function generateSkills(config, options = {}) {
|
|
3273
2925
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
3274
|
-
const
|
|
2926
|
+
const coreSkillsDir = options.coreSkillsDir ?? getCoreSkillsDir();
|
|
2927
|
+
const outputDir = options.outputDir ?? join6(projectRoot, ".claude", "skills");
|
|
3275
2928
|
const includeCoreSkills = options.includeCoreSkills ?? true;
|
|
3276
|
-
const
|
|
3277
|
-
const overwrite = options.overwrite ?? false;
|
|
2929
|
+
const overwrite = options.overwrite ?? true;
|
|
3278
2930
|
const result = {
|
|
3279
2931
|
generated: [],
|
|
3280
2932
|
errors: [],
|
|
@@ -3287,21 +2939,17 @@ function generateSkills(config, options = {}) {
|
|
|
3287
2939
|
result.variables = variables;
|
|
3288
2940
|
let templates = [];
|
|
3289
2941
|
if (includeCoreSkills) {
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
if (includeOptionalSkills) {
|
|
3293
|
-
templates.push(...builtInSkills.filter((s) => s.category === "optional"));
|
|
2942
|
+
const discovered = discoverSkills(coreSkillsDir);
|
|
2943
|
+
templates.push(...discovered);
|
|
3294
2944
|
}
|
|
3295
2945
|
if (options.customTemplatesDir && existsSync4(options.customTemplatesDir)) {
|
|
3296
|
-
|
|
2946
|
+
const custom = discoverSkills(options.customTemplatesDir);
|
|
2947
|
+
templates.push(...custom);
|
|
3297
2948
|
}
|
|
3298
2949
|
if (options.skills && options.skills.length > 0) {
|
|
3299
2950
|
const skillsToInclude = options.skills;
|
|
3300
2951
|
templates = templates.filter((t) => skillsToInclude.includes(t.name));
|
|
3301
2952
|
}
|
|
3302
|
-
if (!existsSync4(outputDir)) {
|
|
3303
|
-
mkdirSync2(outputDir, { recursive: true });
|
|
3304
|
-
}
|
|
3305
2953
|
for (const template of templates) {
|
|
3306
2954
|
try {
|
|
3307
2955
|
const generated = generateSkill(template, variables, config, outputDir, overwrite);
|
|
@@ -3316,7 +2964,8 @@ function generateSkills(config, options = {}) {
|
|
|
3316
2964
|
return result;
|
|
3317
2965
|
}
|
|
3318
2966
|
function generateSkill(template, variables, config, outputDir, overwrite) {
|
|
3319
|
-
const
|
|
2967
|
+
const skillDir = join6(outputDir, template.name);
|
|
2968
|
+
const outputPath = join6(skillDir, "SKILL.md");
|
|
3320
2969
|
if (existsSync4(outputPath) && !overwrite) {
|
|
3321
2970
|
return {
|
|
3322
2971
|
name: template.name,
|
|
@@ -3339,6 +2988,9 @@ function generateSkill(template, variables, config, outputDir, overwrite) {
|
|
|
3339
2988
|
}
|
|
3340
2989
|
const content = substituteVariables(template.content, variables);
|
|
3341
2990
|
const isUpdate = existsSync4(outputPath);
|
|
2991
|
+
if (!existsSync4(skillDir)) {
|
|
2992
|
+
mkdirSync2(skillDir, { recursive: true });
|
|
2993
|
+
}
|
|
3342
2994
|
writeFileSync2(outputPath, content, "utf-8");
|
|
3343
2995
|
return {
|
|
3344
2996
|
name: template.name,
|
|
@@ -3382,7 +3034,7 @@ function formatGenerateResult(result) {
|
|
|
3382
3034
|
}
|
|
3383
3035
|
const total = created.length + updated.length;
|
|
3384
3036
|
if (total > 0) {
|
|
3385
|
-
lines.push(`Generated ${total} skill(s) to .claude/
|
|
3037
|
+
lines.push(`Generated ${total} skill(s) to .claude/skills/`);
|
|
3386
3038
|
} else if (result.generated.length === 0 && result.errors.length === 0) {
|
|
3387
3039
|
lines.push("No skills to generate.");
|
|
3388
3040
|
}
|
|
@@ -3394,12 +3046,12 @@ import {
|
|
|
3394
3046
|
existsSync as existsSync5,
|
|
3395
3047
|
mkdirSync as mkdirSync3,
|
|
3396
3048
|
writeFileSync as writeFileSync3,
|
|
3397
|
-
readFileSync as
|
|
3049
|
+
readFileSync as readFileSync5,
|
|
3398
3050
|
readdirSync as readdirSync3,
|
|
3399
3051
|
renameSync,
|
|
3400
3052
|
statSync as statSync2
|
|
3401
3053
|
} from "fs";
|
|
3402
|
-
import { join as join7, basename as
|
|
3054
|
+
import { join as join7, basename as basename3 } from "path";
|
|
3403
3055
|
var DEFAULT_KNOWLEDGE_LIBRARY_PATH = "KnowledgeLibrary";
|
|
3404
3056
|
var STANDARD_FILES = {
|
|
3405
3057
|
context: "context.txt",
|
|
@@ -3649,7 +3301,7 @@ function getAgentKnowledgeState(agentName, options = {}) {
|
|
|
3649
3301
|
let context;
|
|
3650
3302
|
const currentContextPath = join7(dirs.context, "current.txt");
|
|
3651
3303
|
if (existsSync5(currentContextPath)) {
|
|
3652
|
-
const content =
|
|
3304
|
+
const content = readFileSync5(currentContextPath, "utf-8");
|
|
3653
3305
|
context = parseContextFile(content);
|
|
3654
3306
|
}
|
|
3655
3307
|
const state = {
|
|
@@ -3749,7 +3401,7 @@ function readInboxMessages(agentName, options = {}) {
|
|
|
3749
3401
|
);
|
|
3750
3402
|
for (const file of files) {
|
|
3751
3403
|
const filePath = join7(dirs.inbox, file);
|
|
3752
|
-
const rawContent =
|
|
3404
|
+
const rawContent = readFileSync5(filePath, "utf-8");
|
|
3753
3405
|
const { metadata, body } = parseMessageFrontmatter(rawContent);
|
|
3754
3406
|
if (options.type && metadata.type !== options.type) continue;
|
|
3755
3407
|
if (options.from && metadata.from !== options.from) continue;
|
|
@@ -3769,7 +3421,7 @@ function readInboxMessages(agentName, options = {}) {
|
|
|
3769
3421
|
);
|
|
3770
3422
|
for (const file of files) {
|
|
3771
3423
|
const filePath = join7(dirs.inboxProcessed, file);
|
|
3772
|
-
const rawContent =
|
|
3424
|
+
const rawContent = readFileSync5(filePath, "utf-8");
|
|
3773
3425
|
const { metadata, body } = parseMessageFrontmatter(rawContent);
|
|
3774
3426
|
if (options.type && metadata.type !== options.type) continue;
|
|
3775
3427
|
if (options.from && metadata.from !== options.from) continue;
|
|
@@ -3923,9 +3575,9 @@ function formatKnowledgeLibraryState(state) {
|
|
|
3923
3575
|
lines.push(`KnowledgeLibrary: ${state.basePath}
|
|
3924
3576
|
`);
|
|
3925
3577
|
lines.push("Global files:");
|
|
3926
|
-
lines.push(` - ${
|
|
3927
|
-
lines.push(` - ${
|
|
3928
|
-
lines.push(` - ${
|
|
3578
|
+
lines.push(` - ${basename3(state.contextPath)}`);
|
|
3579
|
+
lines.push(` - ${basename3(state.architecturePath)}`);
|
|
3580
|
+
lines.push(` - ${basename3(state.prdPath)}`);
|
|
3929
3581
|
lines.push("");
|
|
3930
3582
|
if (state.agents.length > 0) {
|
|
3931
3583
|
lines.push(`Agents (${state.agents.length}):`);
|
|
@@ -3970,18 +3622,18 @@ function formatAgentKnowledgeState(state) {
|
|
|
3970
3622
|
|
|
3971
3623
|
// src/index.ts
|
|
3972
3624
|
function findPackageJson() {
|
|
3973
|
-
let dir =
|
|
3974
|
-
while (dir !==
|
|
3625
|
+
let dir = dirname6(fileURLToPath(import.meta.url));
|
|
3626
|
+
while (dir !== dirname6(dir)) {
|
|
3975
3627
|
const pkgPath = join8(dir, "package.json");
|
|
3976
3628
|
try {
|
|
3977
|
-
const content =
|
|
3629
|
+
const content = readFileSync6(pkgPath, "utf-8");
|
|
3978
3630
|
const pkg = JSON.parse(content);
|
|
3979
3631
|
if (pkg.name === "@deimoscloud/coreai") {
|
|
3980
3632
|
return content;
|
|
3981
3633
|
}
|
|
3982
3634
|
} catch {
|
|
3983
3635
|
}
|
|
3984
|
-
dir =
|
|
3636
|
+
dir = dirname6(dir);
|
|
3985
3637
|
}
|
|
3986
3638
|
return '{"version": "unknown"}';
|
|
3987
3639
|
}
|
|
@@ -4007,7 +3659,6 @@ export {
|
|
|
4007
3659
|
StepTracker,
|
|
4008
3660
|
VERSION,
|
|
4009
3661
|
agentKnowledgeLibraryExists,
|
|
4010
|
-
builtInSkills,
|
|
4011
3662
|
checkDependencies,
|
|
4012
3663
|
cleanupContext,
|
|
4013
3664
|
compileAgent,
|
|
@@ -4021,6 +3672,7 @@ export {
|
|
|
4021
3672
|
createContextLoader,
|
|
4022
3673
|
createDegradingHandler,
|
|
4023
3674
|
createFileCacheProvider,
|
|
3675
|
+
discoverSkills,
|
|
4024
3676
|
executeWithDegradation,
|
|
4025
3677
|
extractVariables2 as extractSkillVariables,
|
|
4026
3678
|
extractVariables,
|
|
@@ -4036,6 +3688,7 @@ export {
|
|
|
4036
3688
|
getAgentKnowledgeState,
|
|
4037
3689
|
getConfigPath,
|
|
4038
3690
|
getCoreAgentsDir,
|
|
3691
|
+
getCoreSkillsDir,
|
|
4039
3692
|
getGlobalRegistry,
|
|
4040
3693
|
getKnowledgeLibraryState,
|
|
4041
3694
|
getRoleFromFilename,
|
|
@@ -4051,9 +3704,9 @@ export {
|
|
|
4051
3704
|
loadConfig,
|
|
4052
3705
|
loadConfigFromFile,
|
|
4053
3706
|
loadCoreAICommands,
|
|
4054
|
-
loadCustomTemplates,
|
|
4055
3707
|
markMessageProcessed,
|
|
4056
3708
|
parseAgentYaml,
|
|
3709
|
+
parseSkillFile,
|
|
4057
3710
|
readInboxMessages,
|
|
4058
3711
|
resetGlobalRegistry,
|
|
4059
3712
|
resolveAgentDefinition,
|