agentsys 5.2.1 → 5.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.cursor/commands/audit-project-agents.md +454 -0
- package/.cursor/commands/audit-project-github.md +141 -0
- package/.cursor/commands/audit-project.md +330 -0
- package/.cursor/commands/consult.md +417 -0
- package/.cursor/commands/debate.md +381 -0
- package/.cursor/commands/delivery-approval.md +334 -0
- package/.cursor/commands/deslop.md +142 -0
- package/.cursor/commands/drift-detect.md +259 -0
- package/.cursor/commands/enhance.md +172 -0
- package/.cursor/commands/learn.md +165 -0
- package/.cursor/commands/next-task.md +519 -0
- package/.cursor/commands/perf.md +464 -0
- package/.cursor/commands/repo-map.md +124 -0
- package/.cursor/commands/ship-ci-review-loop.md +468 -0
- package/.cursor/commands/ship-deployment.md +348 -0
- package/.cursor/commands/ship-error-handling.md +265 -0
- package/.cursor/commands/ship.md +517 -0
- package/.cursor/commands/sync-docs.md +171 -0
- package/.cursor/commands/web-ctl.md +101 -0
- package/.cursor/skills/consult/SKILL.md +425 -0
- package/.cursor/skills/debate/SKILL.md +316 -0
- package/.cursor/skills/deslop/SKILL.md +204 -0
- package/.cursor/skills/discover-tasks/SKILL.md +297 -0
- package/.cursor/skills/drift-analysis/SKILL.md +324 -0
- package/.cursor/skills/enhance-agent-prompts/SKILL.md +277 -0
- package/.cursor/skills/enhance-claude-memory/SKILL.md +387 -0
- package/.cursor/skills/enhance-cross-file/SKILL.md +110 -0
- package/.cursor/skills/enhance-docs/SKILL.md +298 -0
- package/.cursor/skills/enhance-hooks/SKILL.md +554 -0
- package/.cursor/skills/enhance-orchestrator/SKILL.md +255 -0
- package/.cursor/skills/enhance-plugins/SKILL.md +319 -0
- package/.cursor/skills/enhance-prompts/SKILL.md +340 -0
- package/.cursor/skills/enhance-skills/SKILL.md +436 -0
- package/.cursor/skills/learn/SKILL.md +349 -0
- package/.cursor/skills/orchestrate-review/SKILL.md +260 -0
- package/.cursor/skills/perf-analyzer/SKILL.md +37 -0
- package/.cursor/skills/perf-baseline-manager/SKILL.md +30 -0
- package/.cursor/skills/perf-benchmarker/SKILL.md +52 -0
- package/.cursor/skills/perf-code-paths/SKILL.md +32 -0
- package/.cursor/skills/perf-investigation-logger/SKILL.md +41 -0
- package/.cursor/skills/perf-profiler/SKILL.md +42 -0
- package/.cursor/skills/perf-theory-gatherer/SKILL.md +35 -0
- package/.cursor/skills/perf-theory-tester/SKILL.md +36 -0
- package/.cursor/skills/repo-mapping/SKILL.md +83 -0
- package/.cursor/skills/sync-docs/SKILL.md +351 -0
- package/.cursor/skills/validate-delivery/SKILL.md +186 -0
- package/.cursor/skills/web-auth/SKILL.md +177 -0
- package/.cursor/skills/web-browse/SKILL.md +516 -0
- package/.kiro/agents/agent-enhancer.json +12 -0
- package/.kiro/agents/ci-fixer.json +13 -0
- package/.kiro/agents/ci-monitor.json +12 -0
- package/.kiro/agents/claudemd-enhancer.json +12 -0
- package/.kiro/agents/consult-agent.json +13 -0
- package/.kiro/agents/cross-file-enhancer.json +12 -0
- package/.kiro/agents/debate-orchestrator.json +13 -0
- package/.kiro/agents/delivery-validator.json +12 -0
- package/.kiro/agents/deslop-agent.json +12 -0
- package/.kiro/agents/docs-enhancer.json +12 -0
- package/.kiro/agents/exploration-agent.json +12 -0
- package/.kiro/agents/hooks-enhancer.json +11 -0
- package/.kiro/agents/implementation-agent.json +13 -0
- package/.kiro/agents/learn-agent.json +12 -0
- package/.kiro/agents/map-validator.json +11 -0
- package/.kiro/agents/perf-analyzer.json +12 -0
- package/.kiro/agents/perf-code-paths.json +11 -0
- package/.kiro/agents/perf-investigation-logger.json +12 -0
- package/.kiro/agents/perf-orchestrator.json +13 -0
- package/.kiro/agents/perf-theory-gatherer.json +12 -0
- package/.kiro/agents/perf-theory-tester.json +13 -0
- package/.kiro/agents/plan-synthesizer.json +12 -0
- package/.kiro/agents/planning-agent.json +12 -0
- package/.kiro/agents/plugin-enhancer.json +12 -0
- package/.kiro/agents/prompt-enhancer.json +12 -0
- package/.kiro/agents/reviewer-perf-test.json +11 -0
- package/.kiro/agents/reviewer-quality-security.json +11 -0
- package/.kiro/agents/simple-fixer.json +13 -0
- package/.kiro/agents/skills-enhancer.json +11 -0
- package/.kiro/agents/sync-docs-agent.json +13 -0
- package/.kiro/agents/task-discoverer.json +12 -0
- package/.kiro/agents/test-coverage-checker.json +12 -0
- package/.kiro/agents/web-session.json +12 -0
- package/.kiro/agents/worktree-manager.json +13 -0
- package/.kiro/skills/consult/SKILL.md +425 -0
- package/.kiro/skills/debate/SKILL.md +316 -0
- package/.kiro/skills/deslop/SKILL.md +204 -0
- package/.kiro/skills/discover-tasks/SKILL.md +297 -0
- package/.kiro/skills/drift-analysis/SKILL.md +324 -0
- package/.kiro/skills/enhance-agent-prompts/SKILL.md +277 -0
- package/.kiro/skills/enhance-claude-memory/SKILL.md +387 -0
- package/.kiro/skills/enhance-cross-file/SKILL.md +110 -0
- package/.kiro/skills/enhance-docs/SKILL.md +298 -0
- package/.kiro/skills/enhance-hooks/SKILL.md +554 -0
- package/.kiro/skills/enhance-orchestrator/SKILL.md +255 -0
- package/.kiro/skills/enhance-plugins/SKILL.md +319 -0
- package/.kiro/skills/enhance-prompts/SKILL.md +340 -0
- package/.kiro/skills/enhance-skills/SKILL.md +436 -0
- package/.kiro/skills/learn/SKILL.md +349 -0
- package/.kiro/skills/orchestrate-review/SKILL.md +260 -0
- package/.kiro/skills/perf-analyzer/SKILL.md +37 -0
- package/.kiro/skills/perf-baseline-manager/SKILL.md +30 -0
- package/.kiro/skills/perf-benchmarker/SKILL.md +52 -0
- package/.kiro/skills/perf-code-paths/SKILL.md +32 -0
- package/.kiro/skills/perf-investigation-logger/SKILL.md +41 -0
- package/.kiro/skills/perf-profiler/SKILL.md +42 -0
- package/.kiro/skills/perf-theory-gatherer/SKILL.md +35 -0
- package/.kiro/skills/perf-theory-tester/SKILL.md +36 -0
- package/.kiro/skills/repo-mapping/SKILL.md +83 -0
- package/.kiro/skills/sync-docs/SKILL.md +351 -0
- package/.kiro/skills/validate-delivery/SKILL.md +186 -0
- package/.kiro/skills/web-auth/SKILL.md +177 -0
- package/.kiro/skills/web-browse/SKILL.md +516 -0
- package/.kiro/steering/audit-project-agents.md +459 -0
- package/.kiro/steering/audit-project-github.md +146 -0
- package/.kiro/steering/audit-project.md +330 -0
- package/.kiro/steering/consult.md +422 -0
- package/.kiro/steering/debate.md +386 -0
- package/.kiro/steering/delivery-approval.md +339 -0
- package/.kiro/steering/deslop.md +149 -0
- package/.kiro/steering/drift-detect.md +264 -0
- package/.kiro/steering/enhance.md +177 -0
- package/.kiro/steering/learn.md +166 -0
- package/.kiro/steering/next-task.md +481 -0
- package/.kiro/steering/perf.md +469 -0
- package/.kiro/steering/repo-map.md +126 -0
- package/.kiro/steering/ship-ci-review-loop.md +473 -0
- package/.kiro/steering/ship-deployment.md +353 -0
- package/.kiro/steering/ship-error-handling.md +270 -0
- package/.kiro/steering/ship.md +522 -0
- package/.kiro/steering/sync-docs.md +178 -0
- package/.kiro/steering/web-ctl.md +106 -0
- package/AGENTS.md +5 -3
- package/CHANGELOG.md +25 -1
- package/README.md +6 -5
- package/agent-knowledge/AGENTS.md +32 -2
- package/agent-knowledge/acp-with-codex-gemini-copilot-claude.md +504 -0
- package/agent-knowledge/kiro-supervised-autopilot.md +400 -0
- package/agent-knowledge/resources/acp-with-codex-gemini-copilot-claude-sources.json +408 -0
- package/agent-knowledge/resources/kiro-supervised-autopilot-sources.json +135 -0
- package/bin/cli.js +176 -9
- package/lib/adapter-transforms.js +224 -1
- package/lib/cross-platform/index.js +9 -3
- package/lib/discovery/index.js +22 -0
- package/lib/platform/state-dir.js +16 -2
- package/package.json +1 -1
- package/scripts/dev-install.js +137 -1
- package/scripts/gen-adapters.js +66 -4
- package/site/content.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -22,7 +22,7 @@ const discovery = require('../lib/discovery');
|
|
|
22
22
|
const transforms = require('../lib/adapter-transforms');
|
|
23
23
|
|
|
24
24
|
// Valid tool names
|
|
25
|
-
const VALID_TOOLS = ['claude', 'opencode', 'codex', 'cursor'];
|
|
25
|
+
const VALID_TOOLS = ['claude', 'opencode', 'codex', 'cursor', 'kiro'];
|
|
26
26
|
|
|
27
27
|
function getInstallDir() {
|
|
28
28
|
const home = process.env.HOME || process.env.USERPROFILE;
|
|
@@ -949,6 +949,9 @@ function detectInstalledPlatforms() {
|
|
|
949
949
|
// Cursor rules are project-scoped; detect only if Cursor rules/commands/skills exist in CWD
|
|
950
950
|
const cursorDir = path.join(process.cwd(), '.cursor');
|
|
951
951
|
if (fs.existsSync(path.join(cursorDir, 'rules')) || fs.existsSync(path.join(cursorDir, 'commands')) || fs.existsSync(path.join(cursorDir, 'skills'))) platforms.push('cursor');
|
|
952
|
+
// Kiro is project-scoped; detect if .kiro/ directory exists in CWD
|
|
953
|
+
const kiroDir = path.join(process.cwd(), '.kiro');
|
|
954
|
+
if (fs.existsSync(path.join(kiroDir, 'steering')) || fs.existsSync(path.join(kiroDir, 'skills')) || fs.existsSync(path.join(kiroDir, 'agents'))) platforms.push('kiro');
|
|
952
955
|
return platforms;
|
|
953
956
|
}
|
|
954
957
|
|
|
@@ -1045,7 +1048,7 @@ async function installPlugin(nameWithVersion, args) {
|
|
|
1045
1048
|
|
|
1046
1049
|
// Use cache as install source
|
|
1047
1050
|
const installDir = getInstallDir();
|
|
1048
|
-
const needsLocal = platforms.includes('opencode') || platforms.includes('codex') || platforms.includes('cursor');
|
|
1051
|
+
const needsLocal = platforms.includes('opencode') || platforms.includes('codex') || platforms.includes('cursor') || platforms.includes('kiro');
|
|
1049
1052
|
if (needsLocal && !fs.existsSync(path.join(installDir, 'lib'))) {
|
|
1050
1053
|
// Need local install for transforms
|
|
1051
1054
|
cleanOldInstallation(installDir);
|
|
@@ -1082,6 +1085,9 @@ async function installPlugin(nameWithVersion, args) {
|
|
|
1082
1085
|
if (platforms.includes('cursor') && installDir) {
|
|
1083
1086
|
installForCursor(installDir, { filter });
|
|
1084
1087
|
}
|
|
1088
|
+
if (platforms.includes('kiro') && installDir) {
|
|
1089
|
+
installForKiro(installDir, { filter });
|
|
1090
|
+
}
|
|
1085
1091
|
|
|
1086
1092
|
// Record in installed.json
|
|
1087
1093
|
for (const depName of toFetch) {
|
|
@@ -1693,6 +1699,158 @@ function installForCursor(installDir, options = {}) {
|
|
|
1693
1699
|
return true;
|
|
1694
1700
|
}
|
|
1695
1701
|
|
|
1702
|
+
function installForKiro(installDir, options = {}) {
|
|
1703
|
+
console.log('\n[INSTALL] Installing for Kiro...\n');
|
|
1704
|
+
const { filter = null } = options;
|
|
1705
|
+
const cwd = process.cwd();
|
|
1706
|
+
|
|
1707
|
+
// Create target directories (all project-scoped)
|
|
1708
|
+
const skillsDir = path.join(cwd, '.kiro', 'skills');
|
|
1709
|
+
const steeringDir = path.join(cwd, '.kiro', 'steering');
|
|
1710
|
+
const agentsDir = path.join(cwd, '.kiro', 'agents');
|
|
1711
|
+
fs.mkdirSync(skillsDir, { recursive: true });
|
|
1712
|
+
fs.mkdirSync(steeringDir, { recursive: true });
|
|
1713
|
+
fs.mkdirSync(agentsDir, { recursive: true });
|
|
1714
|
+
|
|
1715
|
+
// Cleanup old agentsys steering files (only those matching known commands)
|
|
1716
|
+
const steeringMappingsForCleanup = discovery.getKiroSteeringMappings(installDir);
|
|
1717
|
+
const knownSteeringFiles = new Set(steeringMappingsForCleanup.map(([name]) => `${name}.md`));
|
|
1718
|
+
for (const f of fs.readdirSync(steeringDir).filter(f => f.endsWith('.md'))) {
|
|
1719
|
+
if (knownSteeringFiles.has(f)) {
|
|
1720
|
+
fs.unlinkSync(path.join(steeringDir, f));
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
// Collect known skill names from discovery before cleanup
|
|
1725
|
+
const pluginDirs = discovery.discoverPlugins(installDir);
|
|
1726
|
+
const knownSkillNames = new Set();
|
|
1727
|
+
for (const pluginName of pluginDirs) {
|
|
1728
|
+
const srcSkillsDir = path.join(installDir, 'plugins', pluginName, 'skills');
|
|
1729
|
+
if (!fs.existsSync(srcSkillsDir)) continue;
|
|
1730
|
+
for (const d of fs.readdirSync(srcSkillsDir, { withFileTypes: true })) {
|
|
1731
|
+
if (d.isDirectory() && /^[a-zA-Z0-9_-]+$/.test(d.name)) knownSkillNames.add(d.name);
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
// Cleanup old agentsys skill dirs (only known names, preserve user-created skills)
|
|
1736
|
+
for (const entry of fs.readdirSync(skillsDir, { withFileTypes: true })) {
|
|
1737
|
+
if (entry.isDirectory() && knownSkillNames.has(entry.name)) {
|
|
1738
|
+
fs.rmSync(path.join(skillsDir, entry.name), { recursive: true, force: true });
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
// Cleanup old agentsys agent JSON files (only those matching known agents)
|
|
1743
|
+
const knownAgentFiles = new Set();
|
|
1744
|
+
for (const pluginName of pluginDirs) {
|
|
1745
|
+
const srcAgentsDir = path.join(installDir, 'plugins', pluginName, 'agents');
|
|
1746
|
+
if (!fs.existsSync(srcAgentsDir)) continue;
|
|
1747
|
+
for (const f of fs.readdirSync(srcAgentsDir).filter(f => f.endsWith('.md'))) {
|
|
1748
|
+
knownAgentFiles.add(f.replace(/\.md$/, '.json'));
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
for (const f of fs.readdirSync(agentsDir).filter(f => f.endsWith('.json'))) {
|
|
1752
|
+
if (knownAgentFiles.has(f)) {
|
|
1753
|
+
fs.unlinkSync(path.join(agentsDir, f));
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
|
|
1757
|
+
// Install skills
|
|
1758
|
+
let skillCount = 0;
|
|
1759
|
+
for (const pluginName of pluginDirs) {
|
|
1760
|
+
const srcSkillsDir = path.join(installDir, 'plugins', pluginName, 'skills');
|
|
1761
|
+
if (!fs.existsSync(srcSkillsDir)) continue;
|
|
1762
|
+
const entries = fs.readdirSync(srcSkillsDir, { withFileTypes: true }).filter(d => d.isDirectory());
|
|
1763
|
+
for (const entry of entries) {
|
|
1764
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(entry.name)) continue;
|
|
1765
|
+
if (filter && filter.skills && filter.skills.length > 0 && !filter.skills.includes(entry.name)) continue;
|
|
1766
|
+
const srcPath = path.join(srcSkillsDir, entry.name, 'SKILL.md');
|
|
1767
|
+
if (!fs.existsSync(srcPath)) continue;
|
|
1768
|
+
const destDir = path.join(skillsDir, entry.name);
|
|
1769
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
1770
|
+
let content = fs.readFileSync(srcPath, 'utf8');
|
|
1771
|
+
content = transforms.transformSkillForKiro(content, {
|
|
1772
|
+
pluginInstallPath: path.join(installDir, 'plugins', pluginName)
|
|
1773
|
+
});
|
|
1774
|
+
fs.writeFileSync(path.join(destDir, 'SKILL.md'), content);
|
|
1775
|
+
skillCount++;
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
// Install commands as steering files
|
|
1780
|
+
const steeringMappings = discovery.getKiroSteeringMappings(installDir);
|
|
1781
|
+
let steeringCount = 0;
|
|
1782
|
+
for (const [steeringName, plugin, sourceFile, description] of steeringMappings) {
|
|
1783
|
+
if (filter && filter.commands && filter.commands.length > 0) {
|
|
1784
|
+
if (!filter.commands.includes(steeringName)) continue;
|
|
1785
|
+
}
|
|
1786
|
+
const srcPath = path.join(installDir, 'plugins', plugin, 'commands', sourceFile);
|
|
1787
|
+
if (!fs.existsSync(srcPath)) {
|
|
1788
|
+
console.log(` [WARN] Source file not found: ${srcPath}`);
|
|
1789
|
+
continue;
|
|
1790
|
+
}
|
|
1791
|
+
let content = fs.readFileSync(srcPath, 'utf8');
|
|
1792
|
+
content = transforms.transformCommandForKiro(content, {
|
|
1793
|
+
pluginInstallPath: path.join(installDir, 'plugins', plugin),
|
|
1794
|
+
name: steeringName,
|
|
1795
|
+
description
|
|
1796
|
+
});
|
|
1797
|
+
fs.writeFileSync(path.join(steeringDir, `${steeringName}.md`), content);
|
|
1798
|
+
steeringCount++;
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
// Install agents as JSON files
|
|
1802
|
+
let agentCount = 0;
|
|
1803
|
+
for (const pluginName of pluginDirs) {
|
|
1804
|
+
const srcAgentsDir = path.join(installDir, 'plugins', pluginName, 'agents');
|
|
1805
|
+
if (!fs.existsSync(srcAgentsDir)) continue;
|
|
1806
|
+
const agentFiles = fs.readdirSync(srcAgentsDir).filter(f => f.endsWith('.md'));
|
|
1807
|
+
for (const agentFile of agentFiles) {
|
|
1808
|
+
const agentName = agentFile.replace(/\.md$/, '');
|
|
1809
|
+
if (filter && filter.agents && filter.agents.length > 0 && !filter.agents.includes(agentName)) continue;
|
|
1810
|
+
const srcPath = path.join(srcAgentsDir, agentFile);
|
|
1811
|
+
let content = fs.readFileSync(srcPath, 'utf8');
|
|
1812
|
+
const jsonContent = transforms.transformAgentForKiro(content, {
|
|
1813
|
+
pluginInstallPath: path.join(installDir, 'plugins', pluginName)
|
|
1814
|
+
});
|
|
1815
|
+
fs.writeFileSync(path.join(agentsDir, `${agentName}.json`), jsonContent);
|
|
1816
|
+
agentCount++;
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
// Generate combined reviewer agents for Kiro's 4-agent experimental limit.
|
|
1821
|
+
// These are fallback agents that merge 2 review passes into 1 agent session.
|
|
1822
|
+
const combinedReviewers = [
|
|
1823
|
+
{
|
|
1824
|
+
name: 'reviewer-quality-security',
|
|
1825
|
+
description: 'Combined code quality and security reviewer for Kiro',
|
|
1826
|
+
roles: [
|
|
1827
|
+
{ name: 'Code Quality', focus: 'Error handling, maintainability, naming, duplication, dead code, logging quality' },
|
|
1828
|
+
{ name: 'Security', focus: 'Auth vulnerabilities, input validation, injection risks, secrets exposure, OWASP top 10' },
|
|
1829
|
+
]
|
|
1830
|
+
},
|
|
1831
|
+
{
|
|
1832
|
+
name: 'reviewer-perf-test',
|
|
1833
|
+
description: 'Combined performance and test coverage reviewer for Kiro',
|
|
1834
|
+
roles: [
|
|
1835
|
+
{ name: 'Performance', focus: 'Hot paths, algorithmic complexity, unnecessary allocations, N+1 queries, caching opportunities' },
|
|
1836
|
+
{ name: 'Test Coverage', focus: 'Missing tests, edge cases, assertion quality, test isolation, mock correctness' },
|
|
1837
|
+
]
|
|
1838
|
+
},
|
|
1839
|
+
];
|
|
1840
|
+
for (const cr of combinedReviewers) {
|
|
1841
|
+
const json = transforms.generateCombinedReviewerAgent(cr.roles, cr.name, cr.description);
|
|
1842
|
+
fs.writeFileSync(path.join(agentsDir, `${cr.name}.json`), json);
|
|
1843
|
+
agentCount++;
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
console.log(`\n[OK] Kiro installation complete!`);
|
|
1847
|
+
console.log(` Skills: ${skillCount} installed to ${skillsDir}`);
|
|
1848
|
+
console.log(` Steering: ${steeringCount} installed to ${steeringDir}`);
|
|
1849
|
+
console.log(` Agents: ${agentCount} installed to ${agentsDir} (includes 2 combined reviewers)`);
|
|
1850
|
+
console.log(' All content is project-scoped under .kiro/.\n');
|
|
1851
|
+
return true;
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1696
1854
|
function removeInstallation() {
|
|
1697
1855
|
const installDir = getInstallDir();
|
|
1698
1856
|
|
|
@@ -1710,6 +1868,7 @@ function removeInstallation() {
|
|
|
1710
1868
|
console.log(' - OpenCode: Remove files under ~/.config/opencode/ (commands/*.md, agents/*.md, skills/*/SKILL.md) and ~/.config/opencode/plugins/agentsys.ts');
|
|
1711
1869
|
console.log(' - Codex: Remove ~/.codex/skills/*/');
|
|
1712
1870
|
console.log(' - Cursor: Remove .cursor/skills/, .cursor/commands/, and .cursor/rules/agentsys-*.mdc from your project');
|
|
1871
|
+
console.log(' - Kiro: Remove .kiro/skills/, .kiro/steering/, and .kiro/agents/ from your project');
|
|
1713
1872
|
}
|
|
1714
1873
|
|
|
1715
1874
|
function printSubcommandHelp(subcommand) {
|
|
@@ -1730,7 +1889,7 @@ Examples:
|
|
|
1730
1889
|
agentsys install perf@1.2.0 Install perf at version 1.2.0
|
|
1731
1890
|
|
|
1732
1891
|
Options:
|
|
1733
|
-
--tool <name> Install for a specific platform (claude, opencode, codex, cursor)
|
|
1892
|
+
--tool <name> Install for a specific platform (claude, opencode, codex, cursor, kiro)
|
|
1734
1893
|
--tools <list> Install for multiple platforms (comma-separated)
|
|
1735
1894
|
|
|
1736
1895
|
Notes:
|
|
@@ -1824,7 +1983,7 @@ agentsys v${VERSION} - Workflow automation for AI coding assistants
|
|
|
1824
1983
|
|
|
1825
1984
|
Usage:
|
|
1826
1985
|
agentsys Interactive installer (select platforms)
|
|
1827
|
-
agentsys --tool <name> Install for single tool (claude, opencode, codex, cursor)
|
|
1986
|
+
agentsys --tool <name> Install for single tool (claude, opencode, codex, cursor, kiro)
|
|
1828
1987
|
agentsys --tools <list> Install for multiple tools (comma-separated)
|
|
1829
1988
|
agentsys --only <plugins> Install only specified plugins (comma-separated, resolves deps)
|
|
1830
1989
|
agentsys --development Development mode: install to ~/.claude/plugins
|
|
@@ -1851,7 +2010,7 @@ Non-Interactive Examples:
|
|
|
1851
2010
|
agentsys --tool claude # Install for Claude Code only
|
|
1852
2011
|
agentsys --tool opencode # Install for OpenCode only
|
|
1853
2012
|
agentsys --tools "claude,opencode" # Install for both
|
|
1854
|
-
agentsys --tools claude,opencode,codex,cursor # Install for all
|
|
2013
|
+
agentsys --tools claude,opencode,codex,cursor,kiro # Install for all
|
|
1855
2014
|
agentsys --only next-task # Install next-task + its dependencies
|
|
1856
2015
|
agentsys --only "next-task,perf" # Install specific plugins + deps
|
|
1857
2016
|
|
|
@@ -1871,7 +2030,8 @@ Supported Platforms:
|
|
|
1871
2030
|
claude - Claude Code (marketplace install or development mode)
|
|
1872
2031
|
opencode - OpenCode (local commands + native plugin)
|
|
1873
2032
|
codex - Codex CLI (local skills)
|
|
1874
|
-
cursor - Cursor (project-scoped
|
|
2033
|
+
cursor - Cursor (project-scoped skills + commands)
|
|
2034
|
+
kiro - Kiro (project-scoped steering + skills + agents)
|
|
1875
2035
|
|
|
1876
2036
|
Install: npm install -g agentsys && agentsys
|
|
1877
2037
|
Update: npm update -g agentsys && agentsys
|
|
@@ -1977,7 +2137,8 @@ async function main() {
|
|
|
1977
2137
|
{ value: 'claude', label: 'Claude Code' },
|
|
1978
2138
|
{ value: 'opencode', label: 'OpenCode' },
|
|
1979
2139
|
{ value: 'codex', label: 'Codex CLI' },
|
|
1980
|
-
{ value: 'cursor', label: 'Cursor' }
|
|
2140
|
+
{ value: 'cursor', label: 'Cursor' },
|
|
2141
|
+
{ value: 'kiro', label: 'Kiro' }
|
|
1981
2142
|
];
|
|
1982
2143
|
|
|
1983
2144
|
selected = await multiSelect(
|
|
@@ -2007,7 +2168,7 @@ async function main() {
|
|
|
2007
2168
|
}
|
|
2008
2169
|
|
|
2009
2170
|
// Only copy to ~/.agentsys if OpenCode, Codex, or Cursor selected (they need local files)
|
|
2010
|
-
const needsLocalInstall = selected.includes('opencode') || selected.includes('codex') || selected.includes('cursor');
|
|
2171
|
+
const needsLocalInstall = selected.includes('opencode') || selected.includes('codex') || selected.includes('cursor') || selected.includes('kiro');
|
|
2011
2172
|
let installDir = null;
|
|
2012
2173
|
|
|
2013
2174
|
if (needsLocalInstall) {
|
|
@@ -2047,6 +2208,11 @@ async function main() {
|
|
|
2047
2208
|
failedPlatforms.push('cursor');
|
|
2048
2209
|
}
|
|
2049
2210
|
break;
|
|
2211
|
+
case 'kiro':
|
|
2212
|
+
if (!installForKiro(installDir)) {
|
|
2213
|
+
failedPlatforms.push('kiro');
|
|
2214
|
+
}
|
|
2215
|
+
break;
|
|
2050
2216
|
}
|
|
2051
2217
|
}
|
|
2052
2218
|
|
|
@@ -2100,5 +2266,6 @@ module.exports = {
|
|
|
2100
2266
|
buildFilterFromComponent,
|
|
2101
2267
|
resolvePluginSource,
|
|
2102
2268
|
parseGitHubSource,
|
|
2103
|
-
installForCursor
|
|
2269
|
+
installForCursor,
|
|
2270
|
+
installForKiro
|
|
2104
2271
|
};
|
|
@@ -429,6 +429,225 @@ function transformCommandForCursor(content, options) {
|
|
|
429
429
|
return content;
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
+
/**
|
|
433
|
+
* Transform skill content for Kiro.
|
|
434
|
+
*
|
|
435
|
+
* Minimal transform - Kiro reads standard SKILL.md format natively so we
|
|
436
|
+
* preserve it. Only replaces PLUGIN_ROOT paths and strips namespace prefixes.
|
|
437
|
+
*
|
|
438
|
+
* @param {string} content - Source SKILL.md content
|
|
439
|
+
* @param {Object} options
|
|
440
|
+
* @param {string} options.pluginInstallPath - Absolute path to plugin install dir
|
|
441
|
+
* @returns {string} Transformed skill content
|
|
442
|
+
*/
|
|
443
|
+
function transformSkillForKiro(content, options) {
|
|
444
|
+
const { pluginInstallPath } = options;
|
|
445
|
+
|
|
446
|
+
content = content.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, () => pluginInstallPath);
|
|
447
|
+
content = content.replace(/\$CLAUDE_PLUGIN_ROOT/g, () => pluginInstallPath);
|
|
448
|
+
content = content.replace(/\$\{PLUGIN_ROOT\}/g, () => pluginInstallPath);
|
|
449
|
+
content = content.replace(/\$PLUGIN_ROOT/g, () => pluginInstallPath);
|
|
450
|
+
|
|
451
|
+
content = content.replace(/(?:next-task|deslop|ship|sync-docs|audit-project|enhance|perf|repo-map|drift-detect|consult|debate|learn|web-ctl):([a-z][a-z0-9-]*)/g, '$1');
|
|
452
|
+
|
|
453
|
+
return content;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Transform command content for Kiro steering files.
|
|
458
|
+
*
|
|
459
|
+
* Strips existing frontmatter, prepends inclusion: manual frontmatter,
|
|
460
|
+
* replaces PLUGIN_ROOT paths, removes require()/Task() calls, strips namespaces.
|
|
461
|
+
*/
|
|
462
|
+
function transformCommandForKiro(content, options) {
|
|
463
|
+
const { pluginInstallPath, name = '', description = '' } = options;
|
|
464
|
+
|
|
465
|
+
if (content.startsWith('---')) {
|
|
466
|
+
content = content.replace(/^---\n[\s\S]*?\n---\n?/, '');
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
const cleanDescription = description.replace(/[\x00-\x1f\x7f]/g, ' ');
|
|
470
|
+
const escapedDescription = cleanDescription.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
471
|
+
let frontmatter = '---\n';
|
|
472
|
+
frontmatter += 'inclusion: manual\n';
|
|
473
|
+
if (name) frontmatter += `name: "${name}"\n`;
|
|
474
|
+
if (description) frontmatter += `description: "${escapedDescription}"\n`;
|
|
475
|
+
frontmatter += '---\n';
|
|
476
|
+
|
|
477
|
+
content = frontmatter + content;
|
|
478
|
+
|
|
479
|
+
content = content.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, () => pluginInstallPath);
|
|
480
|
+
content = content.replace(/\$CLAUDE_PLUGIN_ROOT/g, () => pluginInstallPath);
|
|
481
|
+
content = content.replace(/\$\{PLUGIN_ROOT\}/g, () => pluginInstallPath);
|
|
482
|
+
content = content.replace(/\$PLUGIN_ROOT/g, () => pluginInstallPath);
|
|
483
|
+
|
|
484
|
+
content = content.replace(/(?:const|let|var)\s+\{?[^}=\n]+\}?\s*=\s*require\s*\([^)]+\);?/g, '');
|
|
485
|
+
content = content.replace(/require\s*\(['"][^'"]+['"]\)/g, '');
|
|
486
|
+
|
|
487
|
+
// Transform code blocks containing Promise.all + Task() (parallel reviewer spawns).
|
|
488
|
+
// The bare Task() regex below can't reach inside fenced code blocks.
|
|
489
|
+
// Fence boundaries must be at line start (^```) to avoid matching backtick
|
|
490
|
+
// template literals inside the code as false fence endings.
|
|
491
|
+
content = content.replace(/^```(?:javascript|js)?\n([\s\S]*?)^```$/gm, (fullBlock, codeContent) => {
|
|
492
|
+
if (!codeContent.includes('Promise.all') || !codeContent.includes('Task(')) return fullBlock;
|
|
493
|
+
const taskMatches = [...codeContent.matchAll(/Task\s*\(\s*\{[\s\S]*?subagent_type:\s*['"](?:[^"':]+:)?([^'"]+)['"][\s\S]*?prompt:\s*`((?:[^`]|\$\{[^}]*\})*)`/gs)];
|
|
494
|
+
if (taskMatches.length < 2) return fullBlock;
|
|
495
|
+
|
|
496
|
+
const delegations = taskMatches.map(m => {
|
|
497
|
+
const agent = m[1];
|
|
498
|
+
const promptFirstLine = m[2].split('\n').find(l => l.trim()) || '';
|
|
499
|
+
return `Delegate to the \`${agent}\` subagent:\n> ${promptFirstLine.trim()}`;
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
let result = delegations.join('\n\n');
|
|
503
|
+
|
|
504
|
+
const hasReviewKeyword = delegations.some(d =>
|
|
505
|
+
/review|quality|security|performance|test|coverage/i.test(d)
|
|
506
|
+
);
|
|
507
|
+
if (delegations.length >= 4 && hasReviewKeyword) {
|
|
508
|
+
result = `**Review phase (Kiro - max 4 agents, fallback to 2 sequential):**\n\nTry delegating to these subagents (experimental parallel spawning):\n\n${result}\n\nIf parallel spawning is unavailable, run 2 combined reviewers sequentially:\n1. Delegate to the \`reviewer-quality-security\` subagent (code quality + security)\n2. Then delegate to the \`reviewer-perf-test\` subagent (performance + test coverage)\n\nAggregate all findings from whichever execution path succeeded.`;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
return result;
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
// Transform bare Task() calls outside code blocks
|
|
515
|
+
content = content.replace(/await\s+Task\s*\(\s*\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\}\s*\);?/g, (match) => {
|
|
516
|
+
const agentMatch = match.match(/subagent_type:\s*["'](?:[^"':]+:)?([^"']+)["']/);
|
|
517
|
+
const promptMatch = match.match(/prompt:\s*[`"']([\s\S]*?)[`"']/);
|
|
518
|
+
if (agentMatch) {
|
|
519
|
+
const agentName = agentMatch[1];
|
|
520
|
+
const prompt = promptMatch ? promptMatch[1].replace(/\\n/g, '\n').trim() : '';
|
|
521
|
+
if (prompt) {
|
|
522
|
+
return `Delegate to the \`${agentName}\` subagent:\n> ${prompt.split('\n')[0]}`;
|
|
523
|
+
}
|
|
524
|
+
return `Delegate to the \`${agentName}\` subagent.`;
|
|
525
|
+
}
|
|
526
|
+
return '';
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
// Transform AskUserQuestion to markdown prompt for Kiro chat
|
|
530
|
+
content = content.replace(/(?:await\s+)?AskUserQuestion\s*\(\s*\{[\s\S]*?\}\s*\);?/g, (match) => {
|
|
531
|
+
const questionMatch = match.match(/question:\s*["'`]([\s\S]*?)["'`]/);
|
|
532
|
+
const question = questionMatch ? questionMatch[1] : 'Please choose:';
|
|
533
|
+
const optionMatches = [...match.matchAll(/label:\s*["'`]([^"'`]+)["'`][\s\S]*?description:\s*["'`]([^"'`]+)["'`]/g)];
|
|
534
|
+
if (optionMatches.length > 0) {
|
|
535
|
+
const options = optionMatches.map((m, i) => `${i + 1}. **${m[1]}** - ${m[2]}`).join('\n');
|
|
536
|
+
return `**${question}**\n\n${options}\n\nReply with the number or name of your choice.`;
|
|
537
|
+
}
|
|
538
|
+
return `**${question}**\n\nReply in chat with your choice.`;
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
content = content.replace(/(?:next-task|deslop|ship|sync-docs|audit-project|enhance|perf|repo-map|drift-detect|consult|debate|learn|web-ctl):([a-z][a-z0-9-]*)/g, '$1');
|
|
542
|
+
|
|
543
|
+
// Batch parallel reviewer delegations for Kiro's agent limit.
|
|
544
|
+
// Detects 4+ consecutive "Delegate to" lines with review-related names
|
|
545
|
+
// and rewrites as try-4-then-fallback-to-2 pattern.
|
|
546
|
+
const reviewerBatchPattern = /((?:Delegate to the `[^`]*` subagent[^\n]*\n){4,})/g;
|
|
547
|
+
content = content.replace(reviewerBatchPattern, (block) => {
|
|
548
|
+
const delegations = block.match(/Delegate to the `([^`]+)` subagent/g) || [];
|
|
549
|
+
if (delegations.length < 4) return block;
|
|
550
|
+
|
|
551
|
+
const hasReviewKeyword = delegations.some(d =>
|
|
552
|
+
/review|quality|security|performance|test|coverage/i.test(d)
|
|
553
|
+
);
|
|
554
|
+
if (!hasReviewKeyword) return block;
|
|
555
|
+
|
|
556
|
+
return `**Review phase (Kiro - max 4 agents, fallback to 2 sequential):**
|
|
557
|
+
|
|
558
|
+
Try delegating to these subagents (experimental parallel spawning):
|
|
559
|
+
${block}
|
|
560
|
+
If parallel spawning is unavailable, run 2 combined reviewers sequentially:
|
|
561
|
+
1. Delegate to the \`reviewer-quality-security\` subagent (code quality + security)
|
|
562
|
+
2. Then delegate to the \`reviewer-perf-test\` subagent (performance + test coverage)
|
|
563
|
+
|
|
564
|
+
Aggregate all findings from whichever execution path succeeded.\n`;
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
return content;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Transform agent markdown+frontmatter to Kiro JSON format.
|
|
572
|
+
*
|
|
573
|
+
* Parses frontmatter for name/description/model/tools, uses body as prompt.
|
|
574
|
+
* Returns a JSON string matching Kiro's agent schema.
|
|
575
|
+
*/
|
|
576
|
+
function transformAgentForKiro(content, options) {
|
|
577
|
+
const { pluginInstallPath } = options || {};
|
|
578
|
+
|
|
579
|
+
const frontmatter = discovery.parseFrontmatter(content);
|
|
580
|
+
let body = content;
|
|
581
|
+
if (content.startsWith('---')) {
|
|
582
|
+
const endIdx = content.indexOf('\n---', 3);
|
|
583
|
+
if (endIdx !== -1) {
|
|
584
|
+
body = content.substring(endIdx + 4).replace(/^\n/, '');
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
if (pluginInstallPath) {
|
|
589
|
+
body = body.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, () => pluginInstallPath);
|
|
590
|
+
body = body.replace(/\$CLAUDE_PLUGIN_ROOT/g, () => pluginInstallPath);
|
|
591
|
+
body = body.replace(/\$\{PLUGIN_ROOT\}/g, () => pluginInstallPath);
|
|
592
|
+
body = body.replace(/\$PLUGIN_ROOT/g, () => pluginInstallPath);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
body = body.replace(/(?:next-task|deslop|ship|sync-docs|audit-project|enhance|perf|repo-map|drift-detect|consult|debate|learn|web-ctl):([a-z][a-z0-9-]*)/g, '$1');
|
|
596
|
+
|
|
597
|
+
const agent = {
|
|
598
|
+
name: frontmatter.name || '',
|
|
599
|
+
description: frontmatter.description || '',
|
|
600
|
+
prompt: body.trim()
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
if (frontmatter.tools) {
|
|
604
|
+
// parseFrontmatter returns arrays for YAML list syntax, string for inline
|
|
605
|
+
const toolItems = Array.isArray(frontmatter.tools)
|
|
606
|
+
? frontmatter.tools.map(t => t.toLowerCase())
|
|
607
|
+
: [frontmatter.tools.toLowerCase()];
|
|
608
|
+
const toolStr = toolItems.join(' ');
|
|
609
|
+
const tools = [];
|
|
610
|
+
if (toolStr.includes('read')) tools.push('read');
|
|
611
|
+
if (toolStr.includes('edit') || toolStr.includes('write')) tools.push('write');
|
|
612
|
+
if (toolStr.includes('bash') || toolStr.includes('shell')) tools.push('shell');
|
|
613
|
+
if (toolStr.includes('glob')) tools.push('read');
|
|
614
|
+
if (toolStr.includes('grep')) tools.push('read');
|
|
615
|
+
const deduped = [...new Set(tools)];
|
|
616
|
+
agent.tools = deduped.length > 0 ? deduped : ['read'];
|
|
617
|
+
} else {
|
|
618
|
+
agent.tools = ['read'];
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
agent.resources = ['file://.kiro/steering/**/*.md'];
|
|
622
|
+
|
|
623
|
+
return JSON.stringify(agent, null, 2);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
/**
|
|
627
|
+
* Generate a combined reviewer agent JSON for Kiro's 4-agent limit.
|
|
628
|
+
* Merges multiple review responsibilities into a single agent.
|
|
629
|
+
*
|
|
630
|
+
* @param {Array<{name: string, focus: string}>} roles - Review passes to combine
|
|
631
|
+
* @param {string} name - Agent name
|
|
632
|
+
* @param {string} description - Agent description
|
|
633
|
+
* @returns {string} JSON string for .kiro/agents/*.json
|
|
634
|
+
*/
|
|
635
|
+
function generateCombinedReviewerAgent(roles, name, description) {
|
|
636
|
+
const sections = roles.map(r =>
|
|
637
|
+
`## ${r.name} Review\n\nFocus: ${r.focus}`
|
|
638
|
+
).join('\n\n---\n\n');
|
|
639
|
+
|
|
640
|
+
const agent = {
|
|
641
|
+
name,
|
|
642
|
+
description,
|
|
643
|
+
prompt: `You are a combined code reviewer covering multiple review passes in a single session.\n\n${sections}\n\nFor each file you review, check ALL of the above review dimensions. Return findings as a JSON array with objects containing: pass (which review), file, line, severity (critical/high/medium/low), description, suggestion.`,
|
|
644
|
+
tools: ['read'],
|
|
645
|
+
resources: ['file://.kiro/steering/**/*.md'],
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
return JSON.stringify(agent, null, 2);
|
|
649
|
+
}
|
|
650
|
+
|
|
432
651
|
module.exports = {
|
|
433
652
|
transformBodyForOpenCode,
|
|
434
653
|
transformCommandFrontmatterForOpenCode,
|
|
@@ -438,5 +657,9 @@ module.exports = {
|
|
|
438
657
|
transformRuleForCursor,
|
|
439
658
|
transformSkillForCursor,
|
|
440
659
|
transformCommandForCursor,
|
|
441
|
-
transformForCursor: transformRuleForCursor
|
|
660
|
+
transformForCursor: transformRuleForCursor,
|
|
661
|
+
transformSkillForKiro,
|
|
662
|
+
transformCommandForKiro,
|
|
663
|
+
transformAgentForKiro,
|
|
664
|
+
generateCombinedReviewerAgent
|
|
442
665
|
};
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* - Claude Code (Anthropic)
|
|
6
6
|
* - OpenCode (multi-model)
|
|
7
7
|
* - Codex CLI (OpenAI)
|
|
8
|
+
* - Cursor (AI-first editor)
|
|
9
|
+
* - Kiro (AWS agentic IDE)
|
|
8
10
|
*
|
|
9
11
|
* Based on research from official documentation:
|
|
10
12
|
* - Anthropic Claude 4 Best Practices
|
|
@@ -45,7 +47,8 @@ const PLATFORMS = {
|
|
|
45
47
|
CLAUDE_CODE: 'claude-code',
|
|
46
48
|
OPENCODE: 'opencode',
|
|
47
49
|
CODEX_CLI: 'codex-cli',
|
|
48
|
-
CURSOR: 'cursor'
|
|
50
|
+
CURSOR: 'cursor',
|
|
51
|
+
KIRO: 'kiro'
|
|
49
52
|
};
|
|
50
53
|
|
|
51
54
|
/**
|
|
@@ -56,7 +59,8 @@ const STATE_DIRS = {
|
|
|
56
59
|
[PLATFORMS.CLAUDE_CODE]: '.claude',
|
|
57
60
|
[PLATFORMS.OPENCODE]: '.opencode',
|
|
58
61
|
[PLATFORMS.CODEX_CLI]: '.codex',
|
|
59
|
-
[PLATFORMS.CURSOR]: '.cursor'
|
|
62
|
+
[PLATFORMS.CURSOR]: '.cursor',
|
|
63
|
+
[PLATFORMS.KIRO]: '.kiro'
|
|
60
64
|
};
|
|
61
65
|
|
|
62
66
|
/**
|
|
@@ -79,6 +83,7 @@ function detectPlatform() {
|
|
|
79
83
|
if (stateDir === '.opencode') return PLATFORMS.OPENCODE;
|
|
80
84
|
if (stateDir === '.codex') return PLATFORMS.CODEX_CLI;
|
|
81
85
|
if (stateDir === '.cursor') return PLATFORMS.CURSOR;
|
|
86
|
+
if (stateDir === '.kiro') return PLATFORMS.KIRO;
|
|
82
87
|
return PLATFORMS.CLAUDE_CODE;
|
|
83
88
|
}
|
|
84
89
|
|
|
@@ -487,7 +492,8 @@ const INSTRUCTION_FILES = {
|
|
|
487
492
|
[PLATFORMS.CLAUDE_CODE]: ['CLAUDE.md', '.claude/CLAUDE.md'],
|
|
488
493
|
[PLATFORMS.OPENCODE]: ['AGENTS.md', 'CLAUDE.md'],
|
|
489
494
|
[PLATFORMS.CODEX_CLI]: ['AGENTS.md', 'AGENTS.override.md'],
|
|
490
|
-
[PLATFORMS.CURSOR]: ['.cursor/rules/*.mdc']
|
|
495
|
+
[PLATFORMS.CURSOR]: ['.cursor/rules/*.mdc'],
|
|
496
|
+
[PLATFORMS.KIRO]: ['AGENTS.md', '.kiro/steering/*.md']
|
|
491
497
|
};
|
|
492
498
|
|
|
493
499
|
/**
|
package/lib/discovery/index.js
CHANGED
|
@@ -361,6 +361,27 @@ function getCursorRuleMappings(repoRoot) {
|
|
|
361
361
|
});
|
|
362
362
|
}
|
|
363
363
|
|
|
364
|
+
/**
|
|
365
|
+
* Build Kiro steering mappings from discovered commands.
|
|
366
|
+
* Returns [steeringName, pluginName, sourceFile, description] tuples.
|
|
367
|
+
* Uses kiro-description frontmatter field, falls back to cursor-description,
|
|
368
|
+
* codex-description, then description.
|
|
369
|
+
*
|
|
370
|
+
* @param {string} [repoRoot] - Repository root path
|
|
371
|
+
* @returns {Array<[string, string, string, string]>}
|
|
372
|
+
*/
|
|
373
|
+
function getKiroSteeringMappings(repoRoot) {
|
|
374
|
+
const commands = discoverCommands(repoRoot);
|
|
375
|
+
return commands.map(cmd => {
|
|
376
|
+
const description = cmd.frontmatter['kiro-description'] ||
|
|
377
|
+
cmd.frontmatter['cursor-description'] ||
|
|
378
|
+
cmd.frontmatter['codex-description'] ||
|
|
379
|
+
cmd.frontmatter.description ||
|
|
380
|
+
'';
|
|
381
|
+
return [cmd.name, cmd.plugin, cmd.file, description];
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
|
|
364
385
|
module.exports = {
|
|
365
386
|
parseFrontmatter,
|
|
366
387
|
isValidPluginName,
|
|
@@ -372,6 +393,7 @@ module.exports = {
|
|
|
372
393
|
getCommandMappings,
|
|
373
394
|
getCodexSkillMappings,
|
|
374
395
|
getCursorRuleMappings,
|
|
396
|
+
getKiroSteeringMappings,
|
|
375
397
|
getPluginPrefixRegex,
|
|
376
398
|
invalidateCache
|
|
377
399
|
};
|
|
@@ -32,10 +32,12 @@ function isDirectory(targetPath) {
|
|
|
32
32
|
* 1. AI_STATE_DIR env var (user override)
|
|
33
33
|
* 2. OpenCode detection (OPENCODE_CONFIG env or .opencode/ exists)
|
|
34
34
|
* 3. Codex detection (CODEX_HOME env or .codex/ exists)
|
|
35
|
-
* 4.
|
|
35
|
+
* 4. Kiro detection (.kiro/ exists)
|
|
36
|
+
* 5. Cursor detection (.cursor/ exists)
|
|
37
|
+
* 6. Default to .claude (Claude Code or unknown)
|
|
36
38
|
*
|
|
37
39
|
* @param {string} [basePath=process.cwd()] - Base path to check for project directories
|
|
38
|
-
* @returns {string} State directory name (e.g., '.claude', '.opencode', '.codex')
|
|
40
|
+
* @returns {string} State directory name (e.g., '.claude', '.opencode', '.codex', '.kiro')
|
|
39
41
|
*/
|
|
40
42
|
function getStateDir(basePath = process.cwd()) {
|
|
41
43
|
// Check user override first
|
|
@@ -83,6 +85,17 @@ function getStateDir(basePath = process.cwd()) {
|
|
|
83
85
|
// Ignore errors, continue detection
|
|
84
86
|
}
|
|
85
87
|
|
|
88
|
+
// Kiro detection
|
|
89
|
+
try {
|
|
90
|
+
const kiroPath = path.join(basePath, '.kiro');
|
|
91
|
+
if (isDirectory(kiroPath)) {
|
|
92
|
+
_cachedStateDirs.set(cacheKey, '.kiro');
|
|
93
|
+
return '.kiro';
|
|
94
|
+
}
|
|
95
|
+
} catch {
|
|
96
|
+
// Ignore errors, continue detection
|
|
97
|
+
}
|
|
98
|
+
|
|
86
99
|
// Default to Claude Code
|
|
87
100
|
_cachedStateDirs.set(cacheKey, '.claude');
|
|
88
101
|
return '.claude';
|
|
@@ -112,6 +125,7 @@ function getPlatformName(basePath = process.cwd()) {
|
|
|
112
125
|
switch (stateDir) {
|
|
113
126
|
case '.opencode': return 'opencode';
|
|
114
127
|
case '.codex': return 'codex';
|
|
128
|
+
case '.kiro': return 'kiro';
|
|
115
129
|
case '.claude': return 'claude';
|
|
116
130
|
default: return 'unknown';
|
|
117
131
|
}
|
package/package.json
CHANGED