daedalion 0.0.2 → 0.3.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.
- package/README.md +39 -44
- package/bin/daedalion.js +12 -6
- package/dist/commands/build.d.ts +3 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +193 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/clean.d.ts +2 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +106 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +88 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/validate.d.ts +2 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +119 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +101 -0
- package/dist/config.js.map +1 -0
- package/dist/generators/agent.d.ts +3 -0
- package/dist/generators/agent.d.ts.map +1 -0
- package/dist/generators/agent.js +114 -0
- package/dist/generators/agent.js.map +1 -0
- package/dist/generators/agents-index.d.ts +3 -0
- package/dist/generators/agents-index.d.ts.map +1 -0
- package/dist/generators/agents-index.js +29 -0
- package/dist/generators/agents-index.js.map +1 -0
- package/dist/generators/instructions.d.ts +3 -0
- package/dist/generators/instructions.d.ts.map +1 -0
- package/dist/generators/instructions.js +72 -0
- package/dist/generators/instructions.js.map +1 -0
- package/dist/generators/pattern-instructions.d.ts +3 -0
- package/dist/generators/pattern-instructions.d.ts.map +1 -0
- package/dist/generators/pattern-instructions.js +28 -0
- package/dist/generators/pattern-instructions.js.map +1 -0
- package/dist/generators/prompt.d.ts +4 -0
- package/dist/generators/prompt.d.ts.map +1 -0
- package/{src → dist}/generators/prompt.js +96 -102
- package/dist/generators/prompt.js.map +1 -0
- package/dist/generators/skill.d.ts +3 -0
- package/dist/generators/skill.d.ts.map +1 -0
- package/dist/generators/skill.js +98 -0
- package/dist/generators/skill.js.map +1 -0
- package/dist/generators/tools.d.ts +3 -0
- package/dist/generators/tools.d.ts.map +1 -0
- package/dist/generators/tools.js +192 -0
- package/dist/generators/tools.js.map +1 -0
- package/dist/generators/workflow.d.ts +3 -0
- package/dist/generators/workflow.d.ts.map +1 -0
- package/{src → dist}/generators/workflow.js +47 -53
- package/dist/generators/workflow.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/{src → dist}/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/proposal.d.ts +3 -0
- package/dist/parsers/proposal.d.ts.map +1 -0
- package/dist/parsers/proposal.js +50 -0
- package/dist/parsers/proposal.js.map +1 -0
- package/dist/parsers/spec.d.ts +3 -0
- package/dist/parsers/spec.d.ts.map +1 -0
- package/dist/parsers/spec.js +87 -0
- package/dist/parsers/spec.js.map +1 -0
- package/dist/parsers/tasks.d.ts +4 -0
- package/dist/parsers/tasks.d.ts.map +1 -0
- package/dist/parsers/tasks.js +39 -0
- package/dist/parsers/tasks.js.map +1 -0
- package/dist/types.d.ts +108 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +46 -0
- package/dist/utils.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +47 -0
- package/dist/version.js.map +1 -0
- package/package.json +20 -5
- package/templates/init/.github/prompts/daedalion-compile.prompt.md +36 -0
- package/templates/init/daedalion.yaml +1 -11
- package/src/commands/build.js +0 -198
- package/src/commands/clean.js +0 -85
- package/src/commands/init.js +0 -101
- package/src/commands/validate.js +0 -141
- package/src/config.js +0 -50
- package/src/generators/agent.js +0 -121
- package/src/generators/instructions.js +0 -65
- package/src/generators/skill.js +0 -108
- package/src/generators/tools.js +0 -183
- package/src/parsers/proposal.js +0 -52
- package/src/parsers/spec.js +0 -105
- package/src/parsers/tasks.js +0 -46
- package/src/utils.js +0 -51
- package/src/version.js +0 -60
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { existsSync, readdirSync, statSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { VERSION } from '../version.js';
|
|
5
|
+
import { glob } from 'glob';
|
|
6
|
+
import { loadConfig, resolveOpenspecPath, resolveOutputPath } from '../config.js';
|
|
7
|
+
import { parseSpec } from '../parsers/spec.js';
|
|
8
|
+
import { parseProposal } from '../parsers/proposal.js';
|
|
9
|
+
export async function validate(cwd) {
|
|
10
|
+
console.log();
|
|
11
|
+
console.log(chalk.bold(` Daedalion v${VERSION} - Validate`));
|
|
12
|
+
console.log();
|
|
13
|
+
const config = loadConfig(cwd);
|
|
14
|
+
const openspecDir = resolveOpenspecPath(cwd, config);
|
|
15
|
+
const outputDir = resolveOutputPath(cwd, config);
|
|
16
|
+
const errors = [];
|
|
17
|
+
const specs = await findAndParseSpecs(openspecDir);
|
|
18
|
+
const changes = await findAndParseChanges(openspecDir);
|
|
19
|
+
// Rule 1: Every spec has ≥1 requirement
|
|
20
|
+
for (const spec of specs) {
|
|
21
|
+
if (spec.requirements.length === 0) {
|
|
22
|
+
errors.push({
|
|
23
|
+
rule: 'spec-has-requirements',
|
|
24
|
+
message: `Spec "${spec.path}" has no requirements.\n Add at least one "### Requirement:" section.`
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Rule 2: Every requirement has ≥1 scenario
|
|
29
|
+
for (const spec of specs) {
|
|
30
|
+
for (const req of spec.requirements) {
|
|
31
|
+
if (req.scenarios.length === 0) {
|
|
32
|
+
errors.push({
|
|
33
|
+
rule: 'requirement-has-scenarios',
|
|
34
|
+
message: `Requirement "${req.name}" in ${spec.domain} lacks scenarios.\n Add at least one "#### Scenario:" section.`
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Rule 3: Generated skill exists for each spec
|
|
40
|
+
for (const spec of specs) {
|
|
41
|
+
const skillPath = join(outputDir, 'skills', spec.domain, 'SKILL.md');
|
|
42
|
+
if (!existsSync(skillPath)) {
|
|
43
|
+
errors.push({
|
|
44
|
+
rule: 'skill-exists-for-spec',
|
|
45
|
+
message: `Missing skill for spec ${spec.domain}.\n Run 'daedalion build' to generate.`
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Rule 4: Generated prompt exists for each active change
|
|
50
|
+
for (const change of changes) {
|
|
51
|
+
const promptPath = join(outputDir, 'prompts', `${change.changeName}.prompt.md`);
|
|
52
|
+
if (!existsSync(promptPath)) {
|
|
53
|
+
errors.push({
|
|
54
|
+
rule: 'prompt-exists-for-change',
|
|
55
|
+
message: `Missing prompt for change ${change.changeName}.\n Run 'daedalion build' to generate.`
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Rule 5: No orphaned skills
|
|
60
|
+
const skillsDir = join(outputDir, 'skills');
|
|
61
|
+
if (existsSync(skillsDir)) {
|
|
62
|
+
const skillDirs = readdirSync(skillsDir).filter((name) => {
|
|
63
|
+
const fullPath = join(skillsDir, name);
|
|
64
|
+
return statSync(fullPath).isDirectory();
|
|
65
|
+
});
|
|
66
|
+
for (const skillName of skillDirs) {
|
|
67
|
+
const hasSpec = specs.some((s) => s.domain === skillName);
|
|
68
|
+
if (!hasSpec) {
|
|
69
|
+
errors.push({
|
|
70
|
+
rule: 'no-orphan-skills',
|
|
71
|
+
message: `Orphan skill: ${skillName} has no source spec.\n Remove .github/skills/${skillName}/ or create openspec/specs/${skillName}/spec.md`
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (errors.length === 0) {
|
|
77
|
+
console.log(chalk.green(' ✓ All validations passed'));
|
|
78
|
+
console.log();
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
console.log(chalk.red(` ✗ ${errors.length} validation error(s) found:`));
|
|
82
|
+
console.log();
|
|
83
|
+
for (const error of errors) {
|
|
84
|
+
console.log(chalk.red(` Error: ${error.message}`));
|
|
85
|
+
console.log();
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
async function findAndParseSpecs(openspecDir) {
|
|
90
|
+
const specsDir = join(openspecDir, 'specs');
|
|
91
|
+
if (!existsSync(specsDir)) {
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
const specFiles = await glob('*/spec.md', { cwd: specsDir });
|
|
95
|
+
return specFiles.map((file) => parseSpec(join(specsDir, file)));
|
|
96
|
+
}
|
|
97
|
+
async function findAndParseChanges(openspecDir) {
|
|
98
|
+
const changesDir = join(openspecDir, 'changes');
|
|
99
|
+
if (!existsSync(changesDir)) {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
const changes = [];
|
|
103
|
+
const changeDirs = readdirSync(changesDir).filter((name) => {
|
|
104
|
+
const fullPath = join(changesDir, name);
|
|
105
|
+
return statSync(fullPath).isDirectory();
|
|
106
|
+
});
|
|
107
|
+
for (const changeDir of changeDirs) {
|
|
108
|
+
const proposalPath = join(changesDir, changeDir, 'proposal.md');
|
|
109
|
+
if (existsSync(proposalPath)) {
|
|
110
|
+
const proposal = parseProposal(proposalPath);
|
|
111
|
+
changes.push({
|
|
112
|
+
changeName: proposal.changeName,
|
|
113
|
+
path: proposalPath
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return changes;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DaedalionConfig } from './types.js';
|
|
2
|
+
export declare function loadConfig(cwd: string): DaedalionConfig;
|
|
3
|
+
export declare function resolveOpenspecPath(cwd: string, config: DaedalionConfig): string;
|
|
4
|
+
export declare function resolveOutputPath(cwd: string, config: DaedalionConfig): string;
|
|
5
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAwFlD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAwBvD;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,MAAM,CAEhF;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,MAAM,CAE9E"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'fs';
|
|
2
|
+
import { join, resolve, relative } from 'path';
|
|
3
|
+
import yaml from 'yaml';
|
|
4
|
+
const KNOWN_TOP_LEVEL_KEYS = new Set([
|
|
5
|
+
'version',
|
|
6
|
+
'target',
|
|
7
|
+
'openspec',
|
|
8
|
+
'output',
|
|
9
|
+
'ci',
|
|
10
|
+
'agents',
|
|
11
|
+
'tools',
|
|
12
|
+
]);
|
|
13
|
+
const DEFAULT_CONFIG = {
|
|
14
|
+
version: 1,
|
|
15
|
+
target: 'github',
|
|
16
|
+
openspec: './openspec',
|
|
17
|
+
output: './.github',
|
|
18
|
+
ci: {
|
|
19
|
+
auto_commit: false,
|
|
20
|
+
commit_message: 'chore: regenerate agents from specs',
|
|
21
|
+
},
|
|
22
|
+
agents: {
|
|
23
|
+
target: 'ide',
|
|
24
|
+
tools: null,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Validate that a resolved path does not escape the project root.
|
|
29
|
+
* Throws if the path traverses outside `root`.
|
|
30
|
+
*/
|
|
31
|
+
function safePath(root, unsafePath) {
|
|
32
|
+
const resolved = resolve(root, unsafePath);
|
|
33
|
+
const rel = relative(root, resolved);
|
|
34
|
+
if (rel.startsWith('..') || resolve(root, rel) !== resolved) {
|
|
35
|
+
throw new Error(`Path "${unsafePath}" resolves outside the project root ("${root}").`);
|
|
36
|
+
}
|
|
37
|
+
return resolved;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Validate user-supplied config values. Throws on hard errors;
|
|
41
|
+
* warns (console.warn) for unknown top-level keys.
|
|
42
|
+
*/
|
|
43
|
+
function validateConfig(userConfig) {
|
|
44
|
+
// Warn for unknown top-level keys
|
|
45
|
+
for (const key of Object.keys(userConfig)) {
|
|
46
|
+
if (!KNOWN_TOP_LEVEL_KEYS.has(key)) {
|
|
47
|
+
console.warn(`daedalion: unknown config key "${key}" — ignoring.`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// version must be 1
|
|
51
|
+
if (userConfig.version !== undefined && userConfig.version !== 1) {
|
|
52
|
+
throw new Error(`Unsupported config version: ${String(userConfig.version)}. Only version 1 is supported.`);
|
|
53
|
+
}
|
|
54
|
+
// agents.target must be 'ide' or 'sdk'
|
|
55
|
+
const agents = userConfig.agents;
|
|
56
|
+
if (agents?.target !== undefined) {
|
|
57
|
+
if (agents.target !== 'ide' && agents.target !== 'sdk') {
|
|
58
|
+
throw new Error(`Invalid agents.target: "${String(agents.target)}". Must be "ide" or "sdk".`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// openspec must be a non-empty string
|
|
62
|
+
if (userConfig.openspec !== undefined) {
|
|
63
|
+
if (typeof userConfig.openspec !== 'string' || userConfig.openspec.trim() === '') {
|
|
64
|
+
throw new Error('Config "openspec" must be a non-empty string.');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// output must be a non-empty string
|
|
68
|
+
if (userConfig.output !== undefined) {
|
|
69
|
+
if (typeof userConfig.output !== 'string' || userConfig.output.trim() === '') {
|
|
70
|
+
throw new Error('Config "output" must be a non-empty string.');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export function loadConfig(cwd) {
|
|
75
|
+
const configPath = join(cwd, 'daedalion.yaml');
|
|
76
|
+
if (!existsSync(configPath)) {
|
|
77
|
+
return { ...DEFAULT_CONFIG };
|
|
78
|
+
}
|
|
79
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
80
|
+
const userConfig = yaml.parse(content) || {};
|
|
81
|
+
validateConfig(userConfig);
|
|
82
|
+
return {
|
|
83
|
+
...DEFAULT_CONFIG,
|
|
84
|
+
...userConfig,
|
|
85
|
+
ci: {
|
|
86
|
+
...DEFAULT_CONFIG.ci,
|
|
87
|
+
...(userConfig.ci || {}),
|
|
88
|
+
},
|
|
89
|
+
agents: {
|
|
90
|
+
...DEFAULT_CONFIG.agents,
|
|
91
|
+
...(userConfig.agents || {}),
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export function resolveOpenspecPath(cwd, config) {
|
|
96
|
+
return safePath(cwd, config.openspec);
|
|
97
|
+
}
|
|
98
|
+
export function resolveOutputPath(cwd, config) {
|
|
99
|
+
return safePath(cwd, config.output);
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/generators/agent.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,IAAI,EAAW,MAAM,aAAa,CAAC;AAE/F,wBAAgB,aAAa,CAC3B,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,YAAiB,EAC1B,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM,GACpC,aAAa,CAgDf"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { ensureDir } from '../utils.js';
|
|
2
|
+
import { writeFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
export function generateAgent(spec, outputDir, options = {}, config = {}) {
|
|
5
|
+
const agentPath = join(outputDir, 'agents', `${spec.domain}.agent.md`);
|
|
6
|
+
const skillDescription = generateSkillDescription(spec);
|
|
7
|
+
const agentConfig = config.agents || {};
|
|
8
|
+
const target = agentConfig.target || 'ide';
|
|
9
|
+
let tools;
|
|
10
|
+
let workflow;
|
|
11
|
+
if (target === 'sdk') {
|
|
12
|
+
const specTools = extractTools(spec);
|
|
13
|
+
tools = specTools.length > 0 ? specTools.map(t => t.name) : (agentConfig.tools || []);
|
|
14
|
+
workflow = generateSDKWorkflow(spec, tools);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
// IDE mode — use valid GitHub Copilot tool aliases
|
|
18
|
+
// 'execute' is the correct alias for terminal/shell access (replaces invalid 'terminal')
|
|
19
|
+
// Spec frontmatter 'agent_tools' overrides the defaults for this domain
|
|
20
|
+
const frontmatterTools = spec.frontmatter?.agent_tools;
|
|
21
|
+
if (Array.isArray(frontmatterTools) && frontmatterTools.length > 0) {
|
|
22
|
+
tools = frontmatterTools.filter((t) => typeof t === 'string');
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
tools = ['edit', 'search', 'execute'];
|
|
26
|
+
}
|
|
27
|
+
workflow = generateIDEWorkflow(spec);
|
|
28
|
+
}
|
|
29
|
+
const toolsYaml = tools.length > 0
|
|
30
|
+
? `tools: [${tools.map(t => `'${t}'`).join(', ')}]`
|
|
31
|
+
: '';
|
|
32
|
+
const content = `---
|
|
33
|
+
name: ${spec.domain}
|
|
34
|
+
description: Implements ${spec.domain} features following specifications
|
|
35
|
+
${toolsYaml}
|
|
36
|
+
---
|
|
37
|
+
# ${spec.domain} Agent
|
|
38
|
+
|
|
39
|
+
${workflow}
|
|
40
|
+
`;
|
|
41
|
+
if (options.dryRun) {
|
|
42
|
+
return { path: agentPath, content };
|
|
43
|
+
}
|
|
44
|
+
ensureDir(agentPath);
|
|
45
|
+
writeFileSync(agentPath, content);
|
|
46
|
+
return { path: agentPath, content };
|
|
47
|
+
}
|
|
48
|
+
function extractTools(spec) {
|
|
49
|
+
const tools = [];
|
|
50
|
+
const frontmatter = spec.frontmatter || {};
|
|
51
|
+
if (frontmatter.tools && Array.isArray(frontmatter.tools)) {
|
|
52
|
+
for (const tool of frontmatter.tools) {
|
|
53
|
+
if (typeof tool === 'string') {
|
|
54
|
+
tools.push({ name: tool });
|
|
55
|
+
}
|
|
56
|
+
else if (typeof tool === 'object' && tool !== null && 'name' in tool) {
|
|
57
|
+
tools.push(tool);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return tools;
|
|
62
|
+
}
|
|
63
|
+
function generateIDEWorkflow(spec) {
|
|
64
|
+
const skillDescription = generateSkillDescription(spec);
|
|
65
|
+
return `You implement ${spec.domain} features following the specification.
|
|
66
|
+
|
|
67
|
+
## Available Skills
|
|
68
|
+
- **#${spec.domain}** — ${skillDescription}
|
|
69
|
+
|
|
70
|
+
## Workflow
|
|
71
|
+
1. Read the #${spec.domain} skill for requirements
|
|
72
|
+
2. Implement following acceptance criteria
|
|
73
|
+
3. Verify all scenarios pass
|
|
74
|
+
`;
|
|
75
|
+
}
|
|
76
|
+
function generateSDKWorkflow(spec, tools) {
|
|
77
|
+
const skillDescription = generateSkillDescription(spec);
|
|
78
|
+
if (tools.length === 0) {
|
|
79
|
+
return `You implement ${spec.domain} features following the specification.
|
|
80
|
+
|
|
81
|
+
## Available Skills
|
|
82
|
+
- **#${spec.domain}** — ${skillDescription}
|
|
83
|
+
|
|
84
|
+
## Workflow
|
|
85
|
+
1. Read the #${spec.domain} skill for requirements
|
|
86
|
+
2. Implement following acceptance criteria
|
|
87
|
+
3. Verify all scenarios pass
|
|
88
|
+
`;
|
|
89
|
+
}
|
|
90
|
+
return `You implement ${spec.domain} features following the specification.
|
|
91
|
+
|
|
92
|
+
## Available Skills
|
|
93
|
+
- **#${spec.domain}** — ${skillDescription}
|
|
94
|
+
|
|
95
|
+
## Available Tools
|
|
96
|
+
${tools.map(t => `- **${t}**`).join('\n')}
|
|
97
|
+
|
|
98
|
+
## Workflow
|
|
99
|
+
1. Read the #${spec.domain} skill for requirements
|
|
100
|
+
2. Use available tools to implement following acceptance criteria
|
|
101
|
+
3. Verify all scenarios pass
|
|
102
|
+
`;
|
|
103
|
+
}
|
|
104
|
+
function generateSkillDescription(spec) {
|
|
105
|
+
if (spec.requirements.length === 0) {
|
|
106
|
+
return `${spec.title} requirements and acceptance criteria`;
|
|
107
|
+
}
|
|
108
|
+
const reqNames = spec.requirements
|
|
109
|
+
.slice(0, 3)
|
|
110
|
+
.map(r => r.name.toLowerCase())
|
|
111
|
+
.join(', ');
|
|
112
|
+
return `${spec.title} - ${reqNames}`;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/generators/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-index.d.ts","sourceRoot":"","sources":["../../src/generators/agents-index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAErE,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,EAAE,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,YAAiB,GACzB,aAAa,CA4Bf"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ensureDir } from '../utils.js';
|
|
2
|
+
import { writeFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
export function generateAgentsIndex(specs, outputDir, options = {}) {
|
|
5
|
+
const agentsPath = join(outputDir, 'AGENTS.md');
|
|
6
|
+
let content = `# Agents\n\n> Auto-generated by Daedalion. Edit the specs in \`openspec/\` and run \`daedalion build\`.\n\n`;
|
|
7
|
+
if (specs.length === 0) {
|
|
8
|
+
content += `No agents compiled yet.\n`;
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
content += `| Domain | Description | Agent file |\n`;
|
|
12
|
+
content += `|--------|-------------|------------|\n`;
|
|
13
|
+
for (const spec of specs) {
|
|
14
|
+
const description = spec.requirements.length > 0
|
|
15
|
+
? spec.requirements[0].name
|
|
16
|
+
: spec.title;
|
|
17
|
+
const agentFile = `.github/agents/${spec.domain}.agent.md`;
|
|
18
|
+
content += `| ${spec.domain} | ${description} | [${spec.domain}.agent.md](${agentFile}) |\n`;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
content += '\n';
|
|
22
|
+
if (options.dryRun) {
|
|
23
|
+
return { path: agentsPath, content };
|
|
24
|
+
}
|
|
25
|
+
ensureDir(agentsPath);
|
|
26
|
+
writeFileSync(agentsPath, content);
|
|
27
|
+
return { path: agentsPath, content };
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=agents-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-index.js","sourceRoot":"","sources":["../../src/generators/agents-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,SAAiB,EACjB,UAAwB,EAAE;IAE1B,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAEhD,IAAI,OAAO,GAAG,6GAA6G,CAAC;IAE5H,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,2BAA2B,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,yCAAyC,CAAC;QACrD,OAAO,IAAI,yCAAyC,CAAC;QACrD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;gBAC9C,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI;gBAC3B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YACf,MAAM,SAAS,GAAG,kBAAkB,IAAI,CAAC,MAAM,WAAW,CAAC;YAC3D,OAAO,IAAI,KAAK,IAAI,CAAC,MAAM,MAAM,WAAW,OAAO,IAAI,CAAC,MAAM,cAAc,SAAS,OAAO,CAAC;QAC/F,CAAC;IACH,CAAC;IAED,OAAO,IAAI,IAAI,CAAC;IAEhB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;IACvC,CAAC;IAED,SAAS,CAAC,UAAU,CAAC,CAAC;IACtB,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/generators/instructions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAErE,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,YAAiB,EAC1B,KAAK,GAAE,IAAI,EAAO,GACjB,aAAa,CAcf"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'fs';
|
|
2
|
+
import { writeFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { ensureDir } from '../utils.js';
|
|
5
|
+
export function generateInstructions(openspecDir, outputDir, options = {}, specs = []) {
|
|
6
|
+
const projectPath = join(openspecDir, 'project.md');
|
|
7
|
+
const instructionsPath = join(outputDir, 'copilot-instructions.md');
|
|
8
|
+
const conventionsSection = extractConventionsSection(projectPath);
|
|
9
|
+
const content = buildInstructionsContent(specs, conventionsSection);
|
|
10
|
+
if (options.dryRun) {
|
|
11
|
+
return { path: instructionsPath, content };
|
|
12
|
+
}
|
|
13
|
+
ensureDir(instructionsPath);
|
|
14
|
+
writeFileSync(instructionsPath, content);
|
|
15
|
+
return { path: instructionsPath, content };
|
|
16
|
+
}
|
|
17
|
+
function extractConventionsSection(projectPath) {
|
|
18
|
+
if (!existsSync(projectPath)) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
const projectContent = readFileSync(projectPath, 'utf-8');
|
|
22
|
+
const lines = projectContent.split('\n');
|
|
23
|
+
let inConventions = false;
|
|
24
|
+
const conventionLines = [];
|
|
25
|
+
for (const line of lines) {
|
|
26
|
+
if (/^## Conventions\s*$/.test(line)) {
|
|
27
|
+
inConventions = true;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (inConventions) {
|
|
31
|
+
// Stop at the next ## heading
|
|
32
|
+
if (/^## /.test(line)) {
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
conventionLines.push(line);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (conventionLines.length === 0) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
// Trim leading/trailing blank lines from the captured block
|
|
42
|
+
const trimmed = conventionLines.join('\n').trim();
|
|
43
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
44
|
+
}
|
|
45
|
+
function buildInstructionsContent(specs, conventions) {
|
|
46
|
+
const lines = [];
|
|
47
|
+
lines.push('# Copilot Instructions');
|
|
48
|
+
lines.push('');
|
|
49
|
+
lines.push('> Auto-generated by Daedalion. Do not edit — rebuild with `daedalion build`.');
|
|
50
|
+
if (specs.length > 0) {
|
|
51
|
+
lines.push('');
|
|
52
|
+
lines.push('## Project Domains');
|
|
53
|
+
lines.push('');
|
|
54
|
+
lines.push('This project has the following spec domains:');
|
|
55
|
+
for (const spec of specs) {
|
|
56
|
+
lines.push(`- **${spec.domain}** — use \`#${spec.domain}\` skill or \`.github/agents/${spec.domain}.agent.md\``);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (conventions !== null) {
|
|
60
|
+
lines.push('');
|
|
61
|
+
lines.push('## Conventions');
|
|
62
|
+
lines.push('');
|
|
63
|
+
lines.push(conventions);
|
|
64
|
+
}
|
|
65
|
+
lines.push('');
|
|
66
|
+
lines.push('## Working with Specs');
|
|
67
|
+
lines.push('');
|
|
68
|
+
lines.push('Specifications are in `openspec/`. Use `.github/skills/` for implementation guidance and `.github/agents/` for domain agents.');
|
|
69
|
+
lines.push('');
|
|
70
|
+
return lines.join('\n');
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=instructions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instructions.js","sourceRoot":"","sources":["../../src/generators/instructions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-instructions.d.ts","sourceRoot":"","sources":["../../src/generators/pattern-instructions.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,IAAI,EAAe,MAAM,aAAa,CAAC;AAElF,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,YAAiB,GACzB,aAAa,CA2Bf"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ensureDir } from '../utils.js';
|
|
2
|
+
import { writeFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
export function generatePatternInstructions(spec, outputDir, options = {}) {
|
|
5
|
+
const instructionsPath = join(outputDir, 'instructions', `${spec.domain}.instructions.md`);
|
|
6
|
+
const requirementsSummary = spec.requirements
|
|
7
|
+
.slice(0, 5)
|
|
8
|
+
.map((r) => `- **${r.name}**: ${r.description}`)
|
|
9
|
+
.join('\n');
|
|
10
|
+
const content = `---
|
|
11
|
+
applyTo: "**"
|
|
12
|
+
---
|
|
13
|
+
# ${spec.title}
|
|
14
|
+
|
|
15
|
+
Domain: \`${spec.domain}\` · Skill: \`#${spec.domain}\`
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
${requirementsSummary || `See \`.github/skills/${spec.domain}/SKILL.md\` for full requirements.`}
|
|
20
|
+
`;
|
|
21
|
+
if (options.dryRun) {
|
|
22
|
+
return { path: instructionsPath, content };
|
|
23
|
+
}
|
|
24
|
+
ensureDir(instructionsPath);
|
|
25
|
+
writeFileSync(instructionsPath, content);
|
|
26
|
+
return { path: instructionsPath, content };
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=pattern-instructions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-instructions.js","sourceRoot":"","sources":["../../src/generators/pattern-instructions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,MAAM,UAAU,2BAA2B,CACzC,IAAU,EACV,SAAiB,EACjB,UAAwB,EAAE;IAE1B,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,MAAM,kBAAkB,CAAC,CAAC;IAE3F,MAAM,mBAAmB,GAAG,IAAI,CAAC,YAAY;SAC1C,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAc,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;SAC5D,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,OAAO,GAAG;;;IAGd,IAAI,CAAC,KAAK;;YAEF,IAAI,CAAC,MAAM,kBAAkB,IAAI,CAAC,MAAM;;;;EAIlD,mBAAmB,IAAI,wBAAwB,IAAI,CAAC,MAAM,oCAAoC;CAC/F,CAAC;IAEA,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;IAC7C,CAAC;IAED,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC5B,aAAa,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;IACzC,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { BuildOptions, GeneratedFile, Proposal, TasksSummary } from '../types.js';
|
|
2
|
+
export declare function generatePrompt(proposal: Proposal, tasks: TasksSummary, domain: string, outputDir: string, options?: BuildOptions): GeneratedFile;
|
|
3
|
+
export declare function generateCyclePrompt(outputDir: string, options?: BuildOptions): GeneratedFile;
|
|
4
|
+
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/generators/prompt.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvF,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,YAAiB,GACzB,aAAa,CAkCf;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,YAAiB,GACzB,aAAa,CAwEf"}
|