contextos-agents 2.2.0 → 2.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/.agents/AGENTS.md +53 -396
- package/.agents/adapters/aider/export.js +11 -16
- package/.agents/adapters/claude/export.js +13 -13
- package/.agents/adapters/copilot/export.js +29 -8
- package/.agents/adapters/cursor/export.js +9 -18
- package/.agents/adapters/gemini/export.js +11 -46
- package/.agents/adapters/pure-compiler.js +65 -42
- package/.agents/adapters/shared.js +35 -1
- package/.agents/adapters/zed/export.js +2 -2
- package/.agents/compiled/registry.v2.json +30 -18
- package/.agents/compiled/registry.v2.sha256 +1 -1
- package/.agents/compiler/manifest-compiler.js +5 -29
- package/.agents/core/skills/context-os/references/project-graph.md +3 -3
- package/.agents/core/skills/engineering-workflow/SKILL.md +11 -316
- package/.agents/core/skills/engineering-workflow/references/workflow.md +336 -0
- package/.agents/core/skills/engineering-workflow/skill.yaml +2 -4
- package/.agents/core/skills/gstack-roles/SKILL.md +11 -128
- package/.agents/core/skills/gstack-roles/references/roles.md +149 -0
- package/.agents/core/skills/gstack-roles/skill.yaml +2 -4
- package/.agents/core/skills/ponytail-mindset/SKILL.md +13 -165
- package/.agents/core/skills/ponytail-mindset/references/minimalism.md +186 -0
- package/.agents/core/skills/ponytail-mindset/skill.yaml +2 -5
- package/.agents/core/skills/security/skill.yaml +1 -0
- package/.agents/ctx.js +13 -13
- package/.agents/customization-dx.js +13 -9
- package/.agents/doctor.js +2 -2
- package/.agents/generated/claude/skills/context-manager/EXAMPLES.md +19 -0
- package/.agents/generated/claude/skills/context-manager/SKILL.md +0 -29
- package/.agents/generated/claude/skills/context-manager/TROUBLESHOOTING.md +7 -0
- package/.agents/generated/claude/skills/context-manager/VALIDATION.json +12 -0
- package/.agents/generated/claude/skills/context-manager/references/context-rules.md +59 -0
- package/.agents/generated/claude/skills/context-os/EXAMPLES.md +21 -0
- package/.agents/generated/claude/skills/context-os/SKILL.md +0 -31
- package/.agents/generated/claude/skills/context-os/TROUBLESHOOTING.md +7 -0
- package/.agents/generated/claude/skills/context-os/VALIDATION.json +12 -0
- package/.agents/generated/claude/skills/context-os/packs.yaml +59 -0
- package/.agents/generated/claude/skills/context-os/references/context-rules.md +68 -0
- package/.agents/generated/claude/skills/context-os/references/pipeline.md +119 -0
- package/.agents/generated/claude/skills/context-os/references/project-graph.md +103 -0
- package/.agents/generated/claude/skills/context-os/rules.yaml +135 -0
- package/.agents/generated/claude/skills/engineering-workflow/EXAMPLES.md +57 -0
- package/.agents/generated/claude/skills/engineering-workflow/SKILL.md +10 -391
- package/.agents/generated/claude/skills/engineering-workflow/TROUBLESHOOTING.md +19 -0
- package/.agents/generated/claude/skills/engineering-workflow/VALIDATION.json +12 -0
- package/.agents/generated/claude/skills/engineering-workflow/references/workflow.md +336 -0
- package/.agents/generated/claude/skills/gemini-precision/EXAMPLES.md +72 -0
- package/.agents/generated/claude/skills/gemini-precision/SKILL.md +0 -100
- package/.agents/generated/claude/skills/gemini-precision/TROUBLESHOOTING.md +25 -0
- package/.agents/generated/claude/skills/gemini-precision/VALIDATION.json +12 -0
- package/.agents/generated/claude/skills/gstack-roles/EXAMPLES.md +23 -0
- package/.agents/generated/claude/skills/gstack-roles/SKILL.md +10 -164
- package/.agents/generated/claude/skills/gstack-roles/TROUBLESHOOTING.md +13 -0
- package/.agents/generated/claude/skills/gstack-roles/VALIDATION.json +12 -0
- package/.agents/generated/claude/skills/gstack-roles/references/roles.md +149 -0
- package/.agents/generated/claude/skills/ponytail-mindset/EXAMPLES.md +45 -0
- package/.agents/generated/claude/skills/ponytail-mindset/SKILL.md +12 -228
- package/.agents/generated/claude/skills/ponytail-mindset/TROUBLESHOOTING.md +19 -0
- package/.agents/generated/claude/skills/ponytail-mindset/VALIDATION.json +12 -0
- package/.agents/generated/claude/skills/ponytail-mindset/references/minimalism.md +186 -0
- package/.agents/generated/claude/skills/security/EXAMPLES.md +64 -0
- package/.agents/generated/claude/skills/security/SKILL.md +0 -86
- package/.agents/generated/claude/skills/security/TROUBLESHOOTING.md +19 -0
- package/.agents/generated/claude/skills/security/VALIDATION.json +12 -0
- package/.agents/generated/gemini/skills/context-manager/EXAMPLES.md +19 -0
- package/.agents/generated/gemini/skills/context-manager/SKILL.md +1 -33
- package/.agents/generated/gemini/skills/context-manager/TROUBLESHOOTING.md +7 -0
- package/.agents/generated/gemini/skills/context-manager/VALIDATION.json +12 -0
- package/.agents/generated/gemini/skills/context-manager/references/context-rules.md +59 -0
- package/.agents/generated/gemini/skills/context-os/EXAMPLES.md +21 -0
- package/.agents/generated/gemini/skills/context-os/SKILL.md +0 -35
- package/.agents/generated/gemini/skills/context-os/TROUBLESHOOTING.md +7 -0
- package/.agents/generated/gemini/skills/context-os/VALIDATION.json +12 -0
- package/.agents/generated/gemini/skills/context-os/packs.yaml +59 -0
- package/.agents/generated/gemini/skills/context-os/references/context-rules.md +68 -0
- package/.agents/generated/gemini/skills/context-os/references/pipeline.md +119 -0
- package/.agents/generated/gemini/skills/context-os/references/project-graph.md +103 -0
- package/.agents/generated/gemini/skills/context-os/rules.yaml +135 -0
- package/.agents/generated/gemini/skills/engineering-workflow/EXAMPLES.md +57 -0
- package/.agents/generated/gemini/skills/engineering-workflow/SKILL.md +11 -396
- package/.agents/generated/gemini/skills/engineering-workflow/TROUBLESHOOTING.md +19 -0
- package/.agents/generated/gemini/skills/engineering-workflow/VALIDATION.json +12 -0
- package/.agents/generated/gemini/skills/engineering-workflow/references/workflow.md +336 -0
- package/.agents/generated/gemini/skills/gemini-precision/EXAMPLES.md +72 -0
- package/.agents/generated/gemini/skills/gemini-precision/SKILL.md +0 -104
- package/.agents/generated/gemini/skills/gemini-precision/TROUBLESHOOTING.md +25 -0
- package/.agents/generated/gemini/skills/gemini-precision/VALIDATION.json +12 -0
- package/.agents/generated/gemini/skills/gstack-roles/EXAMPLES.md +23 -0
- package/.agents/generated/gemini/skills/gstack-roles/SKILL.md +11 -169
- package/.agents/generated/gemini/skills/gstack-roles/TROUBLESHOOTING.md +13 -0
- package/.agents/generated/gemini/skills/gstack-roles/VALIDATION.json +12 -0
- package/.agents/generated/gemini/skills/gstack-roles/references/roles.md +149 -0
- package/.agents/generated/gemini/skills/ponytail-mindset/EXAMPLES.md +45 -0
- package/.agents/generated/gemini/skills/ponytail-mindset/SKILL.md +13 -233
- package/.agents/generated/gemini/skills/ponytail-mindset/TROUBLESHOOTING.md +19 -0
- package/.agents/generated/gemini/skills/ponytail-mindset/VALIDATION.json +12 -0
- package/.agents/generated/gemini/skills/ponytail-mindset/references/minimalism.md +186 -0
- package/.agents/generated/gemini/skills/security/EXAMPLES.md +64 -0
- package/.agents/generated/gemini/skills/security/SKILL.md +2 -92
- package/.agents/generated/gemini/skills/security/TROUBLESHOOTING.md +19 -0
- package/.agents/generated/gemini/skills/security/VALIDATION.json +12 -0
- package/.agents/plugins.js +24 -5
- package/.agents/resolver/canonical-resolver.js +43 -7
- package/.agents/resolver/resolve-args.js +31 -0
- package/.agents/stats.js +8 -11
- package/.agents/workspace/workspace-graph.js +16 -6
- package/README.md +48 -18
- package/bin/index.js +1 -1
- package/bin/lib/ui.js +2 -2
- package/package.json +89 -86
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const fs = require('fs');
|
|
7
7
|
const path = require('path');
|
|
8
|
-
const { collectSkillDirectories, extractYamlField, stripFrontmatter } = require('../shared.js');
|
|
8
|
+
const { getSkillEntrypointPath, collectSkillDirectories, extractYamlField, stripFrontmatter } = require('../shared.js');
|
|
9
9
|
const { registerAdapter, applyArtifacts, createProvenanceHeader } = require('../pure-compiler.js');
|
|
10
10
|
|
|
11
11
|
const GENERATOR_ID = 'copilot@2';
|
|
@@ -19,9 +19,9 @@ function describe() {
|
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
function buildSkillSection(skillDir) {
|
|
22
|
+
function buildSkillSection(skillDir, context) {
|
|
23
23
|
const skillName = path.basename(skillDir);
|
|
24
|
-
const skillMdPath =
|
|
24
|
+
const skillMdPath = getSkillEntrypointPath(skillDir);
|
|
25
25
|
const yamlPath = path.join(skillDir, 'skill.yaml');
|
|
26
26
|
|
|
27
27
|
let title = skillName;
|
|
@@ -43,7 +43,8 @@ function buildSkillSection(skillDir) {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
const descLine = description ? `> ${description.replace(/\r?\n+/g, ' ').trim()}\n` : '';
|
|
46
|
-
const
|
|
46
|
+
const sourcePath = path.relative(context?.projectRoot || '.', skillMdPath).split(path.sep).join('/');
|
|
47
|
+
const skillRef = `*Source: \`${sourcePath}\` (Read on demand)*\n`;
|
|
47
48
|
return `\n### ${title}\n${descLine}${skillRef}`;
|
|
48
49
|
}
|
|
49
50
|
|
|
@@ -62,7 +63,7 @@ function render(context) {
|
|
|
62
63
|
`# GitHub Copilot Instructions — ContextOS\n\n` +
|
|
63
64
|
`## Project Rules\n\n` +
|
|
64
65
|
`### Step 0 — Identify Before Acting\n\n` +
|
|
65
|
-
`
|
|
66
|
+
`When useful for substantial work, identify:\n` +
|
|
66
67
|
`\`\`\`\n1. WHAT DOMAIN? → Frontend / Backend / Architecture / Full-Stack / DevOps\n2. WHAT PHASE? → Define / Plan / Build / Verify / Review / Ship\n3. WHAT ROLE? → Declare specialist role for this phase\n\`\`\`\n\n` +
|
|
67
68
|
`> **Anti-Spam Invariant**: Declare this strictly once at the start of a task or phase. Never repeat before intermediate tool calls or step updates.\n\n` +
|
|
68
69
|
`### Non-Negotiable Rules\n\n` +
|
|
@@ -89,22 +90,42 @@ function render(context) {
|
|
|
89
90
|
const rawTags = extractYamlField(yaml, 'tags');
|
|
90
91
|
if (rawTags) tags = rawTags.replace(/[\[\]]/g, '');
|
|
91
92
|
}
|
|
92
|
-
const relPath =
|
|
93
|
+
const relPath = path.relative(context?.projectRoot || '.', getSkillEntrypointPath(skill)).replace(/\\/g, '/');
|
|
93
94
|
lines.push(`| \`${tags}\` | **${skillName}** | \`${relPath}\` |\n`);
|
|
94
95
|
}
|
|
95
96
|
lines.push(`\n---\n`);
|
|
96
97
|
|
|
97
98
|
for (const skill of skills) {
|
|
98
|
-
const section = buildSkillSection(skill);
|
|
99
|
+
const section = buildSkillSection(skill, context);
|
|
99
100
|
if (section) {
|
|
100
101
|
lines.push(section);
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
104
|
|
|
105
|
+
const target = path.join(context?.projectRoot || '.', '.github/copilot-instructions.md');
|
|
106
|
+
const existing = fs.existsSync(target) ? fs.readFileSync(target, 'utf8') : '';
|
|
107
|
+
const start = '<!-- CONTEXTOS:START -->';
|
|
108
|
+
const end = '<!-- CONTEXTOS:END -->';
|
|
109
|
+
const block = `${start}\n${lines.join('').replace(/\r\n/g, '\n')}${end}`;
|
|
110
|
+
let content;
|
|
111
|
+
if (existing.includes(start) || existing.includes(end)) {
|
|
112
|
+
if (existing.split(start).length !== 2 || existing.split(end).length !== 2 || existing.indexOf(end) < existing.indexOf(start)) {
|
|
113
|
+
throw new Error('Malformed ContextOS block in Copilot instructions; refusing to overwrite.');
|
|
114
|
+
}
|
|
115
|
+
content = existing.slice(0, existing.indexOf(start)) + block + existing.slice(existing.indexOf(end) + end.length);
|
|
116
|
+
} else {
|
|
117
|
+
const { LockfileV2Manager, computeExactHash } = require('../../filesystem/index.js');
|
|
118
|
+
const managed = new LockfileV2Manager(context?.projectRoot || '.').read()?.managedFiles?.['.github/copilot-instructions.md'];
|
|
119
|
+
const legacyManaged = managed?.generator === GENERATOR_ID && managed.exactSha256 === computeExactHash(Buffer.from(existing));
|
|
120
|
+
content = legacyManaged ? block + '\n' : existing + (existing && !existing.endsWith('\n') ? '\n' : '') + (existing ? '\n' : '') + block + '\n';
|
|
121
|
+
}
|
|
122
|
+
|
|
104
123
|
return [
|
|
105
124
|
{
|
|
106
125
|
path: '.github/copilot-instructions.md',
|
|
107
|
-
content
|
|
126
|
+
content,
|
|
127
|
+
preservesUserContent: true,
|
|
128
|
+
expectedBeforeHash: fs.existsSync(target) ? require('../../filesystem/index.js').computeExactHash(Buffer.from(existing)) : 'NONE',
|
|
108
129
|
mediaType: 'text/markdown',
|
|
109
130
|
kind: 'generated-adapter',
|
|
110
131
|
generator: GENERATOR_ID,
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const fs = require('fs');
|
|
7
7
|
const path = require('path');
|
|
8
|
-
const { AGENTS_MD_PATH, collectSkillDirectories, extractYamlField, stripFrontmatter
|
|
8
|
+
const { getSkillEntrypointPath, AGENTS_MD_PATH, collectSkillDirectories, extractYamlField, stripFrontmatter } = require('../shared.js');
|
|
9
9
|
const { registerAdapter, applyArtifacts, createProvenanceHeader } = require('../pure-compiler.js');
|
|
10
10
|
|
|
11
11
|
const GENERATOR_ID = 'cursor@2';
|
|
@@ -20,11 +20,6 @@ function describe() {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function getSkillGlobsAndFlags(skillName, skillDir = null) {
|
|
23
|
-
const ALWAYS_APPLY_SKILLS = ['engineering-workflow', 'gstack-roles', 'ponytail-mindset', 'gemini-precision'];
|
|
24
|
-
if (ALWAYS_APPLY_SKILLS.includes(skillName)) {
|
|
25
|
-
return { globs: '', alwaysApply: true };
|
|
26
|
-
}
|
|
27
|
-
|
|
28
23
|
// 1. Dynamic extraction from skill.yaml if available
|
|
29
24
|
if (skillDir) {
|
|
30
25
|
const yamlPath = path.join(skillDir, 'skill.yaml');
|
|
@@ -78,7 +73,7 @@ function getSkillGlobsAndFlags(skillName, skillDir = null) {
|
|
|
78
73
|
|
|
79
74
|
function buildSkillSection(skillDir) {
|
|
80
75
|
const skillName = path.basename(skillDir);
|
|
81
|
-
const skillMdPath =
|
|
76
|
+
const skillMdPath = getSkillEntrypointPath(skillDir);
|
|
82
77
|
const yamlPath = path.join(skillDir, 'skill.yaml');
|
|
83
78
|
|
|
84
79
|
let title = skillName;
|
|
@@ -92,7 +87,7 @@ function buildSkillSection(skillDir) {
|
|
|
92
87
|
if (!fs.existsSync(skillMdPath)) return null;
|
|
93
88
|
|
|
94
89
|
const raw = fs.readFileSync(skillMdPath, 'utf8');
|
|
95
|
-
const body = stripFrontmatter(raw);
|
|
90
|
+
const body = stripFrontmatter(raw).trimEnd();
|
|
96
91
|
|
|
97
92
|
if (!description) {
|
|
98
93
|
const firstLine = body.split(/\r?\n/).map(l => l.trim()).find(l => l && !l.startsWith('#'));
|
|
@@ -103,9 +98,9 @@ function buildSkillSection(skillDir) {
|
|
|
103
98
|
return `\n## Skill: ${title}\n${descLine}*Rule file: \`.cursor/rules/${skillName}.mdc\` (load on demand)*\n`;
|
|
104
99
|
}
|
|
105
100
|
|
|
106
|
-
function generateCursorMdc(skillDir) {
|
|
101
|
+
function generateCursorMdc(skillDir, context) {
|
|
107
102
|
const skillName = path.basename(skillDir);
|
|
108
|
-
const skillMdPath =
|
|
103
|
+
const skillMdPath = getSkillEntrypointPath(skillDir);
|
|
109
104
|
const yamlPath = path.join(skillDir, 'skill.yaml');
|
|
110
105
|
|
|
111
106
|
if (!fs.existsSync(skillMdPath)) return null;
|
|
@@ -120,13 +115,7 @@ function generateCursorMdc(skillDir) {
|
|
|
120
115
|
}
|
|
121
116
|
|
|
122
117
|
let raw = fs.readFileSync(skillMdPath, 'utf8');
|
|
123
|
-
const
|
|
124
|
-
if (examples) raw += '\n\n' + examples;
|
|
125
|
-
|
|
126
|
-
const troubleshooting = readMeaningfulMarkdown(path.join(skillDir, 'TROUBLESHOOTING.md'));
|
|
127
|
-
if (troubleshooting) raw += '\n\n' + troubleshooting;
|
|
128
|
-
|
|
129
|
-
const body = stripFrontmatter(raw);
|
|
118
|
+
const body = stripFrontmatter(raw).trimEnd();
|
|
130
119
|
const { globs, alwaysApply } = getSkillGlobsAndFlags(skillName, skillDir);
|
|
131
120
|
|
|
132
121
|
let cleanDescription = description.replace(/\r?\n+/g, ' ').replace(/"/g, "'").trim();
|
|
@@ -141,6 +130,8 @@ alwaysApply: ${alwaysApply}
|
|
|
141
130
|
|
|
142
131
|
# Skill: ${title}
|
|
143
132
|
|
|
133
|
+
Resolve supporting resource paths relative to \`${path.relative(context?.projectRoot || process.cwd(), skillDir).replace(/\\/g, '/')}\`. Read examples and references only when needed.
|
|
134
|
+
|
|
144
135
|
${body}
|
|
145
136
|
`;
|
|
146
137
|
|
|
@@ -189,7 +180,7 @@ ${agentsMd}
|
|
|
189
180
|
|
|
190
181
|
const skills = collectSkillDirectories(context?.profile, context?.projectRoot);
|
|
191
182
|
for (const skill of skills) {
|
|
192
|
-
const mdc = generateCursorMdc(skill);
|
|
183
|
+
const mdc = generateCursorMdc(skill, context);
|
|
193
184
|
if (mdc) {
|
|
194
185
|
const fullMdc = mdc.mdcContent.replace(/\r\n/g, '\n');
|
|
195
186
|
artifacts.push({
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const fs = require('fs');
|
|
7
7
|
const path = require('path');
|
|
8
|
-
const {
|
|
8
|
+
const { getSkillEntrypointPath, readSkillManifest, collectSkillDirectories, renderSkillResources } = require('../shared.js');
|
|
9
9
|
const { registerAdapter, applyArtifacts } = require('../pure-compiler.js');
|
|
10
10
|
|
|
11
11
|
const GENERATOR_ID = 'gemini@2';
|
|
@@ -21,61 +21,23 @@ function describe() {
|
|
|
21
21
|
|
|
22
22
|
function renderGeminiSkill(skillDir, context) {
|
|
23
23
|
const skillName = path.basename(skillDir);
|
|
24
|
-
const
|
|
25
|
-
const existingSkillMdPath =
|
|
24
|
+
const manifest = readSkillManifest(skillDir);
|
|
25
|
+
const existingSkillMdPath = getSkillEntrypointPath(skillDir);
|
|
26
26
|
|
|
27
|
-
if (!fs.existsSync(existingSkillMdPath)
|
|
27
|
+
if (!fs.existsSync(existingSkillMdPath)) {
|
|
28
28
|
return [];
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (fs.existsSync(yamlPath)) {
|
|
35
|
-
const yamlText = fs.readFileSync(yamlPath, 'utf8');
|
|
36
|
-
name = extractYamlField(yamlText, 'name') || skillName;
|
|
37
|
-
description = extractYamlField(yamlText, 'description');
|
|
38
|
-
if (!description) {
|
|
39
|
-
const descRegex = new RegExp(`^description:\\s*>\\s*\\n\\s*([^\\n]+)`, 'm');
|
|
40
|
-
const descMatch = yamlText.match(descRegex);
|
|
41
|
-
if (descMatch) description = descMatch[1].trim();
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
description = description || `ContextOS skill for ${name}`;
|
|
45
|
-
|
|
46
|
-
const files = fs.readdirSync(skillDir).sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }));
|
|
47
|
-
const mdFiles = files.filter(f => f.endsWith('.md'));
|
|
48
|
-
|
|
49
|
-
const primaryMd = mdFiles.includes('SKILL.md')
|
|
50
|
-
? 'SKILL.md'
|
|
51
|
-
: (mdFiles.find(f => f === `${skillName}.md`) || mdFiles[0]);
|
|
52
|
-
|
|
53
|
-
let mergedContent = '';
|
|
54
|
-
if (primaryMd) {
|
|
55
|
-
let primaryText = fs.readFileSync(path.join(skillDir, primaryMd), 'utf8');
|
|
56
|
-
primaryText = primaryText.replace(/^---[\s\S]*?---\r?\n/, '');
|
|
57
|
-
mergedContent += primaryText;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const otherTopicFiles = mdFiles.filter(f => f !== primaryMd && f !== 'EXAMPLES.md' && f !== 'TROUBLESHOOTING.md');
|
|
61
|
-
const orderedExtras = [...otherTopicFiles];
|
|
62
|
-
if (mdFiles.includes('EXAMPLES.md') && primaryMd !== 'EXAMPLES.md') orderedExtras.push('EXAMPLES.md');
|
|
63
|
-
if (mdFiles.includes('TROUBLESHOOTING.md') && primaryMd !== 'TROUBLESHOOTING.md') orderedExtras.push('TROUBLESHOOTING.md');
|
|
64
|
-
|
|
65
|
-
for (const mdFile of orderedExtras) {
|
|
66
|
-
if (mergedContent.includes(`<!-- Source: ${mdFile} -->`)) continue;
|
|
67
|
-
const extraContent = readMeaningfulMarkdown(path.join(skillDir, mdFile));
|
|
68
|
-
if (extraContent) {
|
|
69
|
-
mergedContent += `\n\n<!-- Source: ${mdFile} -->\n\n` + extraContent;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
31
|
+
const name = skillName;
|
|
32
|
+
const description = manifest?.description || `ContextOS skill for ${name}`;
|
|
33
|
+
const mergedContent = fs.readFileSync(existingSkillMdPath, 'utf8').replace(/^---[\s\S]*?---\r?\n/, '');
|
|
72
34
|
|
|
73
35
|
const outputContent = `---
|
|
74
36
|
name: ${name}
|
|
75
37
|
description: >
|
|
76
38
|
${description}
|
|
77
39
|
---
|
|
78
|
-
${mergedContent.
|
|
40
|
+
${mergedContent.trim()}
|
|
79
41
|
`.replace(/\r\n/g, '\n');
|
|
80
42
|
|
|
81
43
|
const artifacts = [
|
|
@@ -99,6 +61,9 @@ ${mergedContent.trimStart()}
|
|
|
99
61
|
},
|
|
100
62
|
];
|
|
101
63
|
|
|
64
|
+
artifacts.push(...renderSkillResources(skillDir, [
|
|
65
|
+
`.agents/generated/gemini/skills/${skillName}`, `.agents/skills/${skillName}`,
|
|
66
|
+
], { kind: 'generated-adapter', generator: GENERATOR_ID, sourceSkillIds: [skillName], inputsHash: context?.sourceGraphHash || 'none' }));
|
|
102
67
|
return artifacts;
|
|
103
68
|
}
|
|
104
69
|
|
|
@@ -107,8 +107,8 @@ function loadCompilerContext(projectRoot, options = {}) {
|
|
|
107
107
|
// 3. Workspace Graph
|
|
108
108
|
let workspace = null;
|
|
109
109
|
try {
|
|
110
|
-
const {
|
|
111
|
-
workspace =
|
|
110
|
+
const { WorkspaceGraphBuilder } = require('../workspace/workspace-graph.js');
|
|
111
|
+
workspace = new WorkspaceGraphBuilder({ rootDir: absRoot }).build();
|
|
112
112
|
} catch {
|
|
113
113
|
workspace = null;
|
|
114
114
|
}
|
|
@@ -256,6 +256,11 @@ function applyArtifacts(projectRoot, artifacts, options = {}) {
|
|
|
256
256
|
});
|
|
257
257
|
|
|
258
258
|
let hasModifications = false;
|
|
259
|
+
const legacyLockPath = path.join(absRoot, '.agents', 'contextos.lock.json');
|
|
260
|
+
let legacyLock = null;
|
|
261
|
+
if (fs.existsSync(legacyLockPath)) {
|
|
262
|
+
try { legacyLock = JSON.parse(fs.readFileSync(legacyLockPath, 'utf8')); } catch {}
|
|
263
|
+
}
|
|
259
264
|
|
|
260
265
|
for (const art of artifacts) {
|
|
261
266
|
const exactSha256 = computeExactHash(art.content);
|
|
@@ -272,15 +277,27 @@ function applyArtifacts(projectRoot, artifacts, options = {}) {
|
|
|
272
277
|
}
|
|
273
278
|
|
|
274
279
|
const absPath = path.resolve(absRoot, art.path);
|
|
280
|
+
let diskHash = 'NONE';
|
|
275
281
|
if (fs.existsSync(absPath)) {
|
|
276
282
|
const diskBuf = fs.readFileSync(absPath);
|
|
277
|
-
|
|
283
|
+
diskHash = computeExactHash(diskBuf);
|
|
284
|
+
if (diskHash === exactSha256) {
|
|
278
285
|
needsWrite = false;
|
|
279
286
|
}
|
|
287
|
+
if (needsWrite && !art.preservesUserContent) {
|
|
288
|
+
const legacyRecord = legacyLock?.managedFiles?.[art.path] || legacyLock?.files?.[art.path];
|
|
289
|
+
const legacyOwned = legacyRecord?.managed && legacyRecord.sha256 === computeSemanticHash(diskBuf).replace('sha256:', '');
|
|
290
|
+
const textEquivalent = /^text\/|yaml/.test(art.mediaType || '') && existingRecord?.semanticTextSha256 === computeSemanticHash(diskBuf);
|
|
291
|
+
if ((!existingRecord && !legacyOwned) || (existingRecord && diskHash !== existingRecord.exactSha256 && !textEquivalent)) {
|
|
292
|
+
const err = new Error(`Refusing to overwrite user-owned or modified file '${art.path}'. Move custom rules into a project override or restore the managed artifact before exporting.`);
|
|
293
|
+
err.code = 'CTX_ADAPTER_OWNERSHIP_CONFLICT';
|
|
294
|
+
throw err;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
280
297
|
}
|
|
281
298
|
|
|
282
299
|
if (needsWrite) {
|
|
283
|
-
tx.stageWrite(art.path, art.content, { mode: art.mode || 420 });
|
|
300
|
+
tx.stageWrite(art.path, art.content, { mode: art.mode || 420, expectedBeforeHash: art.expectedBeforeHash || diskHash });
|
|
284
301
|
hasModifications = true;
|
|
285
302
|
}
|
|
286
303
|
|
|
@@ -310,13 +327,21 @@ function applyArtifacts(projectRoot, artifacts, options = {}) {
|
|
|
310
327
|
} catch {}
|
|
311
328
|
}
|
|
312
329
|
|
|
330
|
+
const prunedPaths = new Set();
|
|
313
331
|
// 1. Prune stale files recorded in Lockfile v2
|
|
314
332
|
if (lockfileData && lockfileData.managedFiles) {
|
|
315
333
|
for (const [recordedPath, meta] of Object.entries(lockfileData.managedFiles)) {
|
|
316
334
|
if (activeGenerators.has(meta.generator) && !activePaths.has(recordedPath)) {
|
|
317
335
|
const absRecPath = path.resolve(absRoot, recordedPath);
|
|
318
336
|
if (fs.existsSync(absRecPath)) {
|
|
319
|
-
|
|
337
|
+
const beforeHash = computeExactHash(fs.readFileSync(absRecPath));
|
|
338
|
+
if (beforeHash !== meta.exactSha256) {
|
|
339
|
+
const err = new Error(`Refusing to prune modified managed file '${recordedPath}'.`);
|
|
340
|
+
err.code = 'CTX_ADAPTER_OWNERSHIP_CONFLICT';
|
|
341
|
+
throw err;
|
|
342
|
+
}
|
|
343
|
+
tx.stageDelete(recordedPath, { expectedBeforeHash: beforeHash });
|
|
344
|
+
prunedPaths.add(recordedPath);
|
|
320
345
|
hasModifications = true;
|
|
321
346
|
}
|
|
322
347
|
lockfileManager.removeManagedFile(lockfileData, recordedPath);
|
|
@@ -332,21 +357,14 @@ function applyArtifacts(projectRoot, artifacts, options = {}) {
|
|
|
332
357
|
for (const file of fs.readdirSync(cursorRulesDir)) {
|
|
333
358
|
if (file.endsWith('.mdc')) {
|
|
334
359
|
const relPath = toPosix(path.relative(absRoot, path.join(cursorRulesDir, file)));
|
|
335
|
-
if (!activePaths.has(relPath)) {
|
|
360
|
+
if (!activePaths.has(relPath) && !prunedPaths.has(relPath)) {
|
|
336
361
|
const isManagedInV1 = Boolean(v1Data?.files?.[relPath]?.managed || v1Data?.managedFiles?.[relPath]?.managed);
|
|
337
362
|
const isManagedInV2 = Boolean(lockfileData?.managedFiles?.[relPath]);
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
const
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
content.includes('<!-- Auto-generated by: node .agents/ctx.js export cursor -->') ||
|
|
344
|
-
content.includes('ContextOS — Project Operating System Rules') ||
|
|
345
|
-
content.includes('contextos:generator');
|
|
346
|
-
} catch {}
|
|
347
|
-
|
|
348
|
-
if (isManagedInV1 || isManagedInV2 || hasContextosMarker) {
|
|
349
|
-
tx.stageDelete(relPath);
|
|
363
|
+
if (isManagedInV1 || isManagedInV2) {
|
|
364
|
+
const beforeHash = computeExactHash(fs.readFileSync(path.join(absRoot, relPath)));
|
|
365
|
+
const expected = lockfileData?.managedFiles?.[relPath]?.exactSha256 || `sha256:${(v1Data?.files?.[relPath] || v1Data?.managedFiles?.[relPath])?.sha256}`;
|
|
366
|
+
if (beforeHash !== expected && computeSemanticHash(fs.readFileSync(path.join(absRoot, relPath))) !== expected) throw new Error(`Refusing to prune modified legacy artifact '${relPath}'.`);
|
|
367
|
+
tx.stageDelete(relPath, { expectedBeforeHash: beforeHash });
|
|
350
368
|
hasModifications = true;
|
|
351
369
|
if (v1Data?.files?.[relPath]) { delete v1Data.files[relPath]; hasModifications = true; }
|
|
352
370
|
if (v1Data?.managedFiles?.[relPath]) { delete v1Data.managedFiles[relPath]; hasModifications = true; }
|
|
@@ -365,21 +383,14 @@ function applyArtifacts(projectRoot, artifacts, options = {}) {
|
|
|
365
383
|
for (const file of fs.readdirSync(zedPromptsDir)) {
|
|
366
384
|
if (file.endsWith('.md')) {
|
|
367
385
|
const relPath = toPosix(path.relative(absRoot, path.join(zedPromptsDir, file)));
|
|
368
|
-
if (!activePaths.has(relPath)) {
|
|
386
|
+
if (!activePaths.has(relPath) && !prunedPaths.has(relPath)) {
|
|
369
387
|
const isManagedInV1 = Boolean(v1Data?.files?.[relPath]?.managed || v1Data?.managedFiles?.[relPath]?.managed);
|
|
370
388
|
const isManagedInV2 = Boolean(lockfileData?.managedFiles?.[relPath]);
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
content.includes('# ContextOS —') ||
|
|
377
|
-
content.includes('# ContextOS Master Prompt') ||
|
|
378
|
-
content.includes('contextos:generator');
|
|
379
|
-
} catch {}
|
|
380
|
-
|
|
381
|
-
if (isManagedInV1 || isManagedInV2 || hasContextosMarker) {
|
|
382
|
-
tx.stageDelete(relPath);
|
|
389
|
+
if (isManagedInV1 || isManagedInV2) {
|
|
390
|
+
const beforeHash = computeExactHash(fs.readFileSync(path.join(absRoot, relPath)));
|
|
391
|
+
const expected = lockfileData?.managedFiles?.[relPath]?.exactSha256 || `sha256:${(v1Data?.files?.[relPath] || v1Data?.managedFiles?.[relPath])?.sha256}`;
|
|
392
|
+
if (beforeHash !== expected && computeSemanticHash(fs.readFileSync(path.join(absRoot, relPath))) !== expected) throw new Error(`Refusing to prune modified legacy artifact '${relPath}'.`);
|
|
393
|
+
tx.stageDelete(relPath, { expectedBeforeHash: beforeHash });
|
|
383
394
|
hasModifications = true;
|
|
384
395
|
if (v1Data?.files?.[relPath]) { delete v1Data.files[relPath]; hasModifications = true; }
|
|
385
396
|
if (v1Data?.managedFiles?.[relPath]) { delete v1Data.managedFiles[relPath]; hasModifications = true; }
|
|
@@ -392,10 +403,9 @@ function applyArtifacts(projectRoot, artifacts, options = {}) {
|
|
|
392
403
|
}
|
|
393
404
|
|
|
394
405
|
// Clean up empty/orphan skill directories in generated paths
|
|
395
|
-
const cleanupDirs = [
|
|
396
|
-
|
|
397
|
-
path.join(absRoot, '.agents', 'generated',
|
|
398
|
-
];
|
|
406
|
+
const cleanupDirs = ['gemini', 'claude']
|
|
407
|
+
.filter(name => activeGenerators.has(`${name}@2`))
|
|
408
|
+
.map(name => path.join(absRoot, '.agents', 'generated', name, 'skills'));
|
|
399
409
|
for (const parentDir of cleanupDirs) {
|
|
400
410
|
if (fs.existsSync(parentDir)) {
|
|
401
411
|
for (const entry of fs.readdirSync(parentDir)) {
|
|
@@ -403,13 +413,26 @@ function applyArtifacts(projectRoot, artifacts, options = {}) {
|
|
|
403
413
|
if (fs.statSync(entryPath).isDirectory()) {
|
|
404
414
|
const relMd = toPosix(path.relative(absRoot, path.join(entryPath, 'SKILL.md')));
|
|
405
415
|
if (!activePaths.has(relMd)) {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
416
|
+
const pruneDirectory = (dir) => {
|
|
417
|
+
for (const child of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
418
|
+
const absChild = path.join(dir, child.name);
|
|
419
|
+
const relChild = toPosix(path.relative(absRoot, absChild));
|
|
420
|
+
if (child.isDirectory()) { pruneDirectory(absChild); continue; }
|
|
421
|
+
if (prunedPaths.has(relChild)) continue;
|
|
422
|
+
const v1Record = v1Data?.files?.[relChild] || v1Data?.managedFiles?.[relChild];
|
|
423
|
+
if (!v1Record?.managed) {
|
|
424
|
+
const err = new Error(`Refusing to prune untracked file '${relChild}' from an orphan skill.`);
|
|
425
|
+
err.code = 'CTX_ADAPTER_OWNERSHIP_CONFLICT';
|
|
426
|
+
throw err;
|
|
427
|
+
}
|
|
428
|
+
const before = fs.readFileSync(absChild);
|
|
429
|
+
const beforeHash = computeExactHash(before);
|
|
430
|
+
if (`sha256:${v1Record.sha256}` !== beforeHash && `sha256:${v1Record.sha256}` !== computeSemanticHash(before)) throw new Error(`Refusing to prune modified legacy resource '${relChild}'.`);
|
|
431
|
+
tx.stageDelete(relChild, { expectedBeforeHash: beforeHash });
|
|
432
|
+
}
|
|
433
|
+
tx.stageDeleteDir(toPosix(path.relative(absRoot, dir)));
|
|
434
|
+
};
|
|
435
|
+
pruneDirectory(entryPath);
|
|
413
436
|
hasModifications = true;
|
|
414
437
|
}
|
|
415
438
|
}
|
|
@@ -115,6 +115,38 @@ function readMeaningfulMarkdown(filePath) {
|
|
|
115
115
|
return content;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
/** Read the same manifest precedence and entrypoint used by the compiler. */
|
|
119
|
+
function readSkillManifest(skillDir) {
|
|
120
|
+
const manifestPath = ['skill.v2.yaml', 'skill.yaml'].map(name => path.join(skillDir, name)).find(file => fs.existsSync(file));
|
|
121
|
+
return manifestPath ? require('../compiler/vendor/yaml.js').parse(fs.readFileSync(manifestPath, 'utf8')) : {};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function getSkillEntrypointPath(skillDir) {
|
|
125
|
+
const manifest = readSkillManifest(skillDir);
|
|
126
|
+
return require('../filesystem/index.js').resolveManagedPath(skillDir, manifest?.entrypoint || 'SKILL.md').resolvedPath;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Copy declared resources beside exported entrypoints without inlining them. */
|
|
130
|
+
function renderSkillResources(skillDir, destinations, metadata) {
|
|
131
|
+
const manifest = readSkillManifest(skillDir);
|
|
132
|
+
const resources = manifest?.resources || [];
|
|
133
|
+
const { resolveManagedPath } = require('../filesystem/index.js');
|
|
134
|
+
const artifacts = [];
|
|
135
|
+
const seen = new Set();
|
|
136
|
+
for (const resource of resources) {
|
|
137
|
+
const rel = typeof resource === 'string' ? resource : resource.path;
|
|
138
|
+
if (rel === 'SKILL.md' || rel === manifest?.entrypoint || seen.has(rel)) continue;
|
|
139
|
+
seen.add(rel);
|
|
140
|
+
const { resolvedPath, relativePosixPath } = resolveManagedPath(skillDir, rel);
|
|
141
|
+
if (!fs.statSync(resolvedPath).isFile()) throw new Error(`Skill resource must be a file: ${rel}`);
|
|
142
|
+
for (const destination of destinations) {
|
|
143
|
+
const mediaType = /\.(md|txt|js|ts|py)$/i.test(rel) ? 'text/plain' : /\.ya?ml$/i.test(rel) ? 'application/yaml' : /\.json$/i.test(rel) ? 'text/plain' : 'application/octet-stream';
|
|
144
|
+
artifacts.push({ ...metadata, path: `${destination}/${relativePosixPath}`, content: fs.readFileSync(resolvedPath), mediaType });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return artifacts;
|
|
148
|
+
}
|
|
149
|
+
|
|
118
150
|
module.exports = {
|
|
119
151
|
AGENTS_DIR,
|
|
120
152
|
AGENTS_MD_PATH,
|
|
@@ -124,5 +156,7 @@ module.exports = {
|
|
|
124
156
|
readMeaningfulMarkdown,
|
|
125
157
|
resetDirectory,
|
|
126
158
|
stripFrontmatter,
|
|
159
|
+
renderSkillResources,
|
|
160
|
+
readSkillManifest,
|
|
161
|
+
getSkillEntrypointPath,
|
|
127
162
|
};
|
|
128
|
-
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const fs = require('fs');
|
|
7
7
|
const path = require('path');
|
|
8
|
-
const { AGENTS_MD_PATH, collectSkillDirectories, extractYamlField, stripFrontmatter } = require('../shared.js');
|
|
8
|
+
const { getSkillEntrypointPath, AGENTS_MD_PATH, collectSkillDirectories, extractYamlField, stripFrontmatter } = require('../shared.js');
|
|
9
9
|
const { registerAdapter, applyArtifacts, createProvenanceHeader } = require('../pure-compiler.js');
|
|
10
10
|
|
|
11
11
|
const GENERATOR_ID = 'zed@2';
|
|
@@ -21,7 +21,7 @@ function describe() {
|
|
|
21
21
|
|
|
22
22
|
function buildSkillSection(skillDir) {
|
|
23
23
|
const skillName = path.basename(skillDir);
|
|
24
|
-
const skillMdPath =
|
|
24
|
+
const skillMdPath = getSkillEntrypointPath(skillDir);
|
|
25
25
|
const yamlPath = path.join(skillDir, 'skill.yaml');
|
|
26
26
|
|
|
27
27
|
let title = skillName;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"compilerVersion": "2.0.0",
|
|
4
|
-
"sourceGraphHash": "sha256:
|
|
4
|
+
"sourceGraphHash": "sha256:efcac8692b9208232aa09a065009438cd7b151e7f4d19366d75b699645cddf94",
|
|
5
5
|
"skills": {
|
|
6
6
|
"context-manager": {
|
|
7
7
|
"id": "context-manager",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"type": "compiler",
|
|
68
68
|
"entrypoint": "SKILL.md",
|
|
69
69
|
"entrypointHash": "sha256:ab14bcd603573c975a69cb95b5ef8a305de8eb888c81c20c994121313f017239",
|
|
70
|
-
"resourceTreeHash": "sha256:
|
|
70
|
+
"resourceTreeHash": "sha256:1f9422adff6b9e69772dfeff2e1c9c9f8615b5fae56f8b60d2d7bef4a5c1c7fb",
|
|
71
71
|
"estimatedTokens": 1365,
|
|
72
72
|
"source": ".agents/core/skills/context-os/skill.yaml",
|
|
73
73
|
"signals": {
|
|
@@ -133,13 +133,13 @@
|
|
|
133
133
|
"id": "engineering-workflow",
|
|
134
134
|
"displayName": "engineering-workflow",
|
|
135
135
|
"version": "1.0.0",
|
|
136
|
-
"description": "
|
|
136
|
+
"description": "Scope implementation work, verify behavior, and report evidence using a proportional lifecycle.",
|
|
137
137
|
"category": "general",
|
|
138
138
|
"type": "instruction-only",
|
|
139
139
|
"entrypoint": "SKILL.md",
|
|
140
|
-
"entrypointHash": "sha256:
|
|
141
|
-
"resourceTreeHash": "sha256:
|
|
142
|
-
"estimatedTokens":
|
|
140
|
+
"entrypointHash": "sha256:e729b3bc21cecef2a39b64f0b301715974697600524629fa05609fd2d9175b48",
|
|
141
|
+
"resourceTreeHash": "sha256:6371d58615c6b5ba47c1523f6f99c106dcd9d99c5abc30338b4a3504271a23f1",
|
|
142
|
+
"estimatedTokens": 418,
|
|
143
143
|
"source": ".agents/core/skills/engineering-workflow/skill.yaml",
|
|
144
144
|
"signals": {
|
|
145
145
|
"aliases": [
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
},
|
|
157
157
|
"context": {
|
|
158
158
|
"priority": 50,
|
|
159
|
-
"estimatedTokens":
|
|
159
|
+
"estimatedTokens": 418
|
|
160
160
|
},
|
|
161
161
|
"resources": [
|
|
162
162
|
{
|
|
@@ -174,6 +174,10 @@
|
|
|
174
174
|
{
|
|
175
175
|
"path": "VALIDATION.json",
|
|
176
176
|
"mode": "on-demand"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"path": "references/workflow.md",
|
|
180
|
+
"mode": "on-demand"
|
|
177
181
|
}
|
|
178
182
|
],
|
|
179
183
|
"deprecated": false,
|
|
@@ -235,13 +239,13 @@
|
|
|
235
239
|
"id": "gstack-roles",
|
|
236
240
|
"displayName": "gstack-roles",
|
|
237
241
|
"version": "1.0.0",
|
|
238
|
-
"description": "
|
|
242
|
+
"description": "Compatibility alias for engineering-workflow with optional specialist review perspectives.",
|
|
239
243
|
"category": "general",
|
|
240
244
|
"type": "instruction-only",
|
|
241
245
|
"entrypoint": "SKILL.md",
|
|
242
|
-
"entrypointHash": "sha256:
|
|
243
|
-
"resourceTreeHash": "sha256:
|
|
244
|
-
"estimatedTokens":
|
|
246
|
+
"entrypointHash": "sha256:baeb5f187b8ea491f4854e6287c29d5c58b436c327e8df46c04651e6deb43513",
|
|
247
|
+
"resourceTreeHash": "sha256:d720b3727681e63f5212e97687b9ad32326685f22493214edc8750a3f504347a",
|
|
248
|
+
"estimatedTokens": 343,
|
|
245
249
|
"source": ".agents/core/skills/gstack-roles/skill.yaml",
|
|
246
250
|
"signals": {
|
|
247
251
|
"aliases": [
|
|
@@ -258,7 +262,7 @@
|
|
|
258
262
|
},
|
|
259
263
|
"context": {
|
|
260
264
|
"priority": 50,
|
|
261
|
-
"estimatedTokens":
|
|
265
|
+
"estimatedTokens": 343
|
|
262
266
|
},
|
|
263
267
|
"resources": [
|
|
264
268
|
{
|
|
@@ -276,6 +280,10 @@
|
|
|
276
280
|
{
|
|
277
281
|
"path": "VALIDATION.json",
|
|
278
282
|
"mode": "on-demand"
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"path": "references/roles.md",
|
|
286
|
+
"mode": "on-demand"
|
|
279
287
|
}
|
|
280
288
|
],
|
|
281
289
|
"deprecated": true,
|
|
@@ -286,13 +294,13 @@
|
|
|
286
294
|
"id": "ponytail-mindset",
|
|
287
295
|
"displayName": "ponytail-mindset",
|
|
288
296
|
"version": "1.0.0",
|
|
289
|
-
"description": "
|
|
297
|
+
"description": "Choose a minimal maintainable implementation for substantive Build tasks while preserving safety and verification.",
|
|
290
298
|
"category": "general",
|
|
291
299
|
"type": "instruction-only",
|
|
292
300
|
"entrypoint": "SKILL.md",
|
|
293
|
-
"entrypointHash": "sha256:
|
|
294
|
-
"resourceTreeHash": "sha256:
|
|
295
|
-
"estimatedTokens":
|
|
301
|
+
"entrypointHash": "sha256:837795e41d09af94040fb9ae318126c6ff3a24bf35b43bbf4cb2888a5067a950",
|
|
302
|
+
"resourceTreeHash": "sha256:3a4d757373ad00ae321c25d0774d35d0f8c9f25b1e95d58303ffb68d0128fd59",
|
|
303
|
+
"estimatedTokens": 413,
|
|
296
304
|
"source": ".agents/core/skills/ponytail-mindset/skill.yaml",
|
|
297
305
|
"signals": {
|
|
298
306
|
"aliases": [
|
|
@@ -309,7 +317,7 @@
|
|
|
309
317
|
},
|
|
310
318
|
"context": {
|
|
311
319
|
"priority": 50,
|
|
312
|
-
"estimatedTokens":
|
|
320
|
+
"estimatedTokens": 413
|
|
313
321
|
},
|
|
314
322
|
"resources": [
|
|
315
323
|
{
|
|
@@ -327,6 +335,10 @@
|
|
|
327
335
|
{
|
|
328
336
|
"path": "VALIDATION.json",
|
|
329
337
|
"mode": "on-demand"
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
"path": "references/minimalism.md",
|
|
341
|
+
"mode": "on-demand"
|
|
330
342
|
}
|
|
331
343
|
],
|
|
332
344
|
"deprecated": false,
|
|
@@ -337,7 +349,7 @@
|
|
|
337
349
|
"id": "security",
|
|
338
350
|
"displayName": "Application Security",
|
|
339
351
|
"version": "1.0.0",
|
|
340
|
-
"description": "
|
|
352
|
+
"description": "Protect authentication, authorization, sensitive data, untrusted input, external integrations, and agent tool execution.",
|
|
341
353
|
"category": "backend",
|
|
342
354
|
"type": "instruction-only",
|
|
343
355
|
"entrypoint": "SKILL.md",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
sha256:
|
|
1
|
+
sha256:efcac8692b9208232aa09a065009438cd7b151e7f4d19366d75b699645cddf94 registry.v2.json
|