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.
Files changed (149) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.cursor/commands/audit-project-agents.md +454 -0
  4. package/.cursor/commands/audit-project-github.md +141 -0
  5. package/.cursor/commands/audit-project.md +330 -0
  6. package/.cursor/commands/consult.md +417 -0
  7. package/.cursor/commands/debate.md +381 -0
  8. package/.cursor/commands/delivery-approval.md +334 -0
  9. package/.cursor/commands/deslop.md +142 -0
  10. package/.cursor/commands/drift-detect.md +259 -0
  11. package/.cursor/commands/enhance.md +172 -0
  12. package/.cursor/commands/learn.md +165 -0
  13. package/.cursor/commands/next-task.md +519 -0
  14. package/.cursor/commands/perf.md +464 -0
  15. package/.cursor/commands/repo-map.md +124 -0
  16. package/.cursor/commands/ship-ci-review-loop.md +468 -0
  17. package/.cursor/commands/ship-deployment.md +348 -0
  18. package/.cursor/commands/ship-error-handling.md +265 -0
  19. package/.cursor/commands/ship.md +517 -0
  20. package/.cursor/commands/sync-docs.md +171 -0
  21. package/.cursor/commands/web-ctl.md +101 -0
  22. package/.cursor/skills/consult/SKILL.md +425 -0
  23. package/.cursor/skills/debate/SKILL.md +316 -0
  24. package/.cursor/skills/deslop/SKILL.md +204 -0
  25. package/.cursor/skills/discover-tasks/SKILL.md +297 -0
  26. package/.cursor/skills/drift-analysis/SKILL.md +324 -0
  27. package/.cursor/skills/enhance-agent-prompts/SKILL.md +277 -0
  28. package/.cursor/skills/enhance-claude-memory/SKILL.md +387 -0
  29. package/.cursor/skills/enhance-cross-file/SKILL.md +110 -0
  30. package/.cursor/skills/enhance-docs/SKILL.md +298 -0
  31. package/.cursor/skills/enhance-hooks/SKILL.md +554 -0
  32. package/.cursor/skills/enhance-orchestrator/SKILL.md +255 -0
  33. package/.cursor/skills/enhance-plugins/SKILL.md +319 -0
  34. package/.cursor/skills/enhance-prompts/SKILL.md +340 -0
  35. package/.cursor/skills/enhance-skills/SKILL.md +436 -0
  36. package/.cursor/skills/learn/SKILL.md +349 -0
  37. package/.cursor/skills/orchestrate-review/SKILL.md +260 -0
  38. package/.cursor/skills/perf-analyzer/SKILL.md +37 -0
  39. package/.cursor/skills/perf-baseline-manager/SKILL.md +30 -0
  40. package/.cursor/skills/perf-benchmarker/SKILL.md +52 -0
  41. package/.cursor/skills/perf-code-paths/SKILL.md +32 -0
  42. package/.cursor/skills/perf-investigation-logger/SKILL.md +41 -0
  43. package/.cursor/skills/perf-profiler/SKILL.md +42 -0
  44. package/.cursor/skills/perf-theory-gatherer/SKILL.md +35 -0
  45. package/.cursor/skills/perf-theory-tester/SKILL.md +36 -0
  46. package/.cursor/skills/repo-mapping/SKILL.md +83 -0
  47. package/.cursor/skills/sync-docs/SKILL.md +351 -0
  48. package/.cursor/skills/validate-delivery/SKILL.md +186 -0
  49. package/.cursor/skills/web-auth/SKILL.md +177 -0
  50. package/.cursor/skills/web-browse/SKILL.md +516 -0
  51. package/.kiro/agents/agent-enhancer.json +12 -0
  52. package/.kiro/agents/ci-fixer.json +13 -0
  53. package/.kiro/agents/ci-monitor.json +12 -0
  54. package/.kiro/agents/claudemd-enhancer.json +12 -0
  55. package/.kiro/agents/consult-agent.json +13 -0
  56. package/.kiro/agents/cross-file-enhancer.json +12 -0
  57. package/.kiro/agents/debate-orchestrator.json +13 -0
  58. package/.kiro/agents/delivery-validator.json +12 -0
  59. package/.kiro/agents/deslop-agent.json +12 -0
  60. package/.kiro/agents/docs-enhancer.json +12 -0
  61. package/.kiro/agents/exploration-agent.json +12 -0
  62. package/.kiro/agents/hooks-enhancer.json +11 -0
  63. package/.kiro/agents/implementation-agent.json +13 -0
  64. package/.kiro/agents/learn-agent.json +12 -0
  65. package/.kiro/agents/map-validator.json +11 -0
  66. package/.kiro/agents/perf-analyzer.json +12 -0
  67. package/.kiro/agents/perf-code-paths.json +11 -0
  68. package/.kiro/agents/perf-investigation-logger.json +12 -0
  69. package/.kiro/agents/perf-orchestrator.json +13 -0
  70. package/.kiro/agents/perf-theory-gatherer.json +12 -0
  71. package/.kiro/agents/perf-theory-tester.json +13 -0
  72. package/.kiro/agents/plan-synthesizer.json +12 -0
  73. package/.kiro/agents/planning-agent.json +12 -0
  74. package/.kiro/agents/plugin-enhancer.json +12 -0
  75. package/.kiro/agents/prompt-enhancer.json +12 -0
  76. package/.kiro/agents/reviewer-perf-test.json +11 -0
  77. package/.kiro/agents/reviewer-quality-security.json +11 -0
  78. package/.kiro/agents/simple-fixer.json +13 -0
  79. package/.kiro/agents/skills-enhancer.json +11 -0
  80. package/.kiro/agents/sync-docs-agent.json +13 -0
  81. package/.kiro/agents/task-discoverer.json +12 -0
  82. package/.kiro/agents/test-coverage-checker.json +12 -0
  83. package/.kiro/agents/web-session.json +12 -0
  84. package/.kiro/agents/worktree-manager.json +13 -0
  85. package/.kiro/skills/consult/SKILL.md +425 -0
  86. package/.kiro/skills/debate/SKILL.md +316 -0
  87. package/.kiro/skills/deslop/SKILL.md +204 -0
  88. package/.kiro/skills/discover-tasks/SKILL.md +297 -0
  89. package/.kiro/skills/drift-analysis/SKILL.md +324 -0
  90. package/.kiro/skills/enhance-agent-prompts/SKILL.md +277 -0
  91. package/.kiro/skills/enhance-claude-memory/SKILL.md +387 -0
  92. package/.kiro/skills/enhance-cross-file/SKILL.md +110 -0
  93. package/.kiro/skills/enhance-docs/SKILL.md +298 -0
  94. package/.kiro/skills/enhance-hooks/SKILL.md +554 -0
  95. package/.kiro/skills/enhance-orchestrator/SKILL.md +255 -0
  96. package/.kiro/skills/enhance-plugins/SKILL.md +319 -0
  97. package/.kiro/skills/enhance-prompts/SKILL.md +340 -0
  98. package/.kiro/skills/enhance-skills/SKILL.md +436 -0
  99. package/.kiro/skills/learn/SKILL.md +349 -0
  100. package/.kiro/skills/orchestrate-review/SKILL.md +260 -0
  101. package/.kiro/skills/perf-analyzer/SKILL.md +37 -0
  102. package/.kiro/skills/perf-baseline-manager/SKILL.md +30 -0
  103. package/.kiro/skills/perf-benchmarker/SKILL.md +52 -0
  104. package/.kiro/skills/perf-code-paths/SKILL.md +32 -0
  105. package/.kiro/skills/perf-investigation-logger/SKILL.md +41 -0
  106. package/.kiro/skills/perf-profiler/SKILL.md +42 -0
  107. package/.kiro/skills/perf-theory-gatherer/SKILL.md +35 -0
  108. package/.kiro/skills/perf-theory-tester/SKILL.md +36 -0
  109. package/.kiro/skills/repo-mapping/SKILL.md +83 -0
  110. package/.kiro/skills/sync-docs/SKILL.md +351 -0
  111. package/.kiro/skills/validate-delivery/SKILL.md +186 -0
  112. package/.kiro/skills/web-auth/SKILL.md +177 -0
  113. package/.kiro/skills/web-browse/SKILL.md +516 -0
  114. package/.kiro/steering/audit-project-agents.md +459 -0
  115. package/.kiro/steering/audit-project-github.md +146 -0
  116. package/.kiro/steering/audit-project.md +330 -0
  117. package/.kiro/steering/consult.md +422 -0
  118. package/.kiro/steering/debate.md +386 -0
  119. package/.kiro/steering/delivery-approval.md +339 -0
  120. package/.kiro/steering/deslop.md +149 -0
  121. package/.kiro/steering/drift-detect.md +264 -0
  122. package/.kiro/steering/enhance.md +177 -0
  123. package/.kiro/steering/learn.md +166 -0
  124. package/.kiro/steering/next-task.md +481 -0
  125. package/.kiro/steering/perf.md +469 -0
  126. package/.kiro/steering/repo-map.md +126 -0
  127. package/.kiro/steering/ship-ci-review-loop.md +473 -0
  128. package/.kiro/steering/ship-deployment.md +353 -0
  129. package/.kiro/steering/ship-error-handling.md +270 -0
  130. package/.kiro/steering/ship.md +522 -0
  131. package/.kiro/steering/sync-docs.md +178 -0
  132. package/.kiro/steering/web-ctl.md +106 -0
  133. package/AGENTS.md +5 -3
  134. package/CHANGELOG.md +25 -1
  135. package/README.md +6 -5
  136. package/agent-knowledge/AGENTS.md +32 -2
  137. package/agent-knowledge/acp-with-codex-gemini-copilot-claude.md +504 -0
  138. package/agent-knowledge/kiro-supervised-autopilot.md +400 -0
  139. package/agent-knowledge/resources/acp-with-codex-gemini-copilot-claude-sources.json +408 -0
  140. package/agent-knowledge/resources/kiro-supervised-autopilot-sources.json +135 -0
  141. package/bin/cli.js +176 -9
  142. package/lib/adapter-transforms.js +224 -1
  143. package/lib/cross-platform/index.js +9 -3
  144. package/lib/discovery/index.js +22 -0
  145. package/lib/platform/state-dir.js +16 -2
  146. package/package.json +1 -1
  147. package/scripts/dev-install.js +137 -1
  148. package/scripts/gen-adapters.js +66 -4
  149. 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 .mdc rules)
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
  /**
@@ -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. Default to .claude (Claude Code or unknown)
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentsys",
3
- "version": "5.2.1",
3
+ "version": "5.3.1",
4
4
  "description": "A modular runtime and orchestration system for AI agents - works with Claude Code, OpenCode, and Codex CLI",
5
5
  "main": "lib/platform/detect-platform.js",
6
6
  "type": "commonjs",