ima-claude 2.9.0

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 (182) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +463 -0
  3. package/dist/cli.js +1064 -0
  4. package/package.json +49 -0
  5. package/platforms/claude/adapter.ts +115 -0
  6. package/platforms/junie/adapter.ts +254 -0
  7. package/platforms/junie/agents-template.md +113 -0
  8. package/platforms/junie/hook-translations.md +84 -0
  9. package/platforms/shared/detector.ts +27 -0
  10. package/platforms/shared/installer.ts +202 -0
  11. package/platforms/shared/types.ts +78 -0
  12. package/plugins/ima-claude/.claude-plugin/plugin.json +25 -0
  13. package/plugins/ima-claude/agents/explorer.md +30 -0
  14. package/plugins/ima-claude/agents/implementer.md +30 -0
  15. package/plugins/ima-claude/agents/memory.md +42 -0
  16. package/plugins/ima-claude/agents/reviewer.md +53 -0
  17. package/plugins/ima-claude/agents/tester.md +33 -0
  18. package/plugins/ima-claude/agents/wp-developer.md +46 -0
  19. package/plugins/ima-claude/hooks/README.md +145 -0
  20. package/plugins/ima-claude/hooks/atlassian_prereqs.py +112 -0
  21. package/plugins/ima-claude/hooks/block_sed_edits.py +59 -0
  22. package/plugins/ima-claude/hooks/bootstrap.sh +90 -0
  23. package/plugins/ima-claude/hooks/bootstrap_utility_check.py +94 -0
  24. package/plugins/ima-claude/hooks/composer_autoload_check.py +70 -0
  25. package/plugins/ima-claude/hooks/docs_organization.py +104 -0
  26. package/plugins/ima-claude/hooks/enforce_rg_over_grep.py +56 -0
  27. package/plugins/ima-claude/hooks/fp_utility_check.py +90 -0
  28. package/plugins/ima-claude/hooks/hook_logger.py +69 -0
  29. package/plugins/ima-claude/hooks/hooks.json +239 -0
  30. package/plugins/ima-claude/hooks/jira_issue_fetch.py +79 -0
  31. package/plugins/ima-claude/hooks/jquery_in_wordpress.py +92 -0
  32. package/plugins/ima-claude/hooks/memory_bootstrap.py +79 -0
  33. package/plugins/ima-claude/hooks/memory_store_reminder.py +75 -0
  34. package/plugins/ima-claude/hooks/prompt_coach.py +125 -0
  35. package/plugins/ima-claude/hooks/prompt_coach_digest.md +48 -0
  36. package/plugins/ima-claude/hooks/prompt_coach_system.md +30 -0
  37. package/plugins/ima-claude/hooks/sequential_thinking_check.py +81 -0
  38. package/plugins/ima-claude/hooks/serena_over_grep.py +96 -0
  39. package/plugins/ima-claude/hooks/serena_over_read.py +66 -0
  40. package/plugins/ima-claude/hooks/serena_project_check.py +133 -0
  41. package/plugins/ima-claude/hooks/sql_injection_check.py +73 -0
  42. package/plugins/ima-claude/hooks/task_master_after_plan.py +31 -0
  43. package/plugins/ima-claude/hooks/task_master_before_impl.py +93 -0
  44. package/plugins/ima-claude/hooks/tavily_extract_advanced.py +48 -0
  45. package/plugins/ima-claude/hooks/vestige_before_external.py +86 -0
  46. package/plugins/ima-claude/hooks/webfetch_to_tavily.py +42 -0
  47. package/plugins/ima-claude/hooks/websearch_to_tavily.py +41 -0
  48. package/plugins/ima-claude/hooks/wp_security_check.py +150 -0
  49. package/plugins/ima-claude/personalities/README.md +45 -0
  50. package/plugins/ima-claude/personalities/enable-40k.md +69 -0
  51. package/plugins/ima-claude/personalities/enable-templars.md +69 -0
  52. package/plugins/ima-claude/skills/.research-summary.md +340 -0
  53. package/plugins/ima-claude/skills/architect/SKILL.md +304 -0
  54. package/plugins/ima-claude/skills/compound-bridge/SKILL.md +200 -0
  55. package/plugins/ima-claude/skills/discourse/SKILL.md +440 -0
  56. package/plugins/ima-claude/skills/discourse-admin/SKILL.md +192 -0
  57. package/plugins/ima-claude/skills/discourse-admin/references/api-endpoints.md +441 -0
  58. package/plugins/ima-claude/skills/discourse-admin/references/gotchas.md +107 -0
  59. package/plugins/ima-claude/skills/discourse-admin/references/staging-defaults.md +98 -0
  60. package/plugins/ima-claude/skills/discourse-admin/scripts/discourse-admin.py +319 -0
  61. package/plugins/ima-claude/skills/docs-organize/SKILL.md +254 -0
  62. package/plugins/ima-claude/skills/docs-organize/templates/active-README.md +50 -0
  63. package/plugins/ima-claude/skills/docs-organize/templates/archive-README.md +57 -0
  64. package/plugins/ima-claude/skills/docs-organize/templates/docs-README.md +43 -0
  65. package/plugins/ima-claude/skills/docs-organize/templates/phase-archive-README.md +83 -0
  66. package/plugins/ima-claude/skills/docs-organize/templates/section-README.md +48 -0
  67. package/plugins/ima-claude/skills/docs-organize/templates/transient-README.md +79 -0
  68. package/plugins/ima-claude/skills/docs-organize/templates/transient-gitignore +9 -0
  69. package/plugins/ima-claude/skills/ember-discourse/SKILL.md +496 -0
  70. package/plugins/ima-claude/skills/functional-programmer/SKILL.md +258 -0
  71. package/plugins/ima-claude/skills/ima-bootstrap/SKILL.md +278 -0
  72. package/plugins/ima-claude/skills/ima-bootstrap/references/bootstrap-patterns.md +356 -0
  73. package/plugins/ima-claude/skills/ima-bootstrap/references/ima-brand.md +273 -0
  74. package/plugins/ima-claude/skills/ima-bootstrap/references/theme-integration.md +212 -0
  75. package/plugins/ima-claude/skills/ima-brand/SKILL.md +108 -0
  76. package/plugins/ima-claude/skills/ima-brand/references/brand-identity.md +140 -0
  77. package/plugins/ima-claude/skills/ima-brand/references/digital-standards.md +180 -0
  78. package/plugins/ima-claude/skills/ima-brand/references/visual-system.md +173 -0
  79. package/plugins/ima-claude/skills/ima-forms-expert/SKILL.md +175 -0
  80. package/plugins/ima-claude/skills/ima-forms-expert/references/container-components.md +154 -0
  81. package/plugins/ima-claude/skills/ima-forms-expert/references/examples.md +328 -0
  82. package/plugins/ima-claude/skills/ima-forms-expert/references/field-components.md +298 -0
  83. package/plugins/ima-claude/skills/ima-forms-expert/references/form-factory.md +193 -0
  84. package/plugins/ima-claude/skills/ima-forms-expert/references/quick-reference.md +153 -0
  85. package/plugins/ima-claude/skills/ima-forms-expert/references/validation-engine.md +336 -0
  86. package/plugins/ima-claude/skills/jira-checkpoint/SKILL.md +178 -0
  87. package/plugins/ima-claude/skills/jquery/SKILL.md +413 -0
  88. package/plugins/ima-claude/skills/js-fp/SKILL.md +463 -0
  89. package/plugins/ima-claude/skills/js-fp/core-principles.md +487 -0
  90. package/plugins/ima-claude/skills/js-fp/examples/pure-functions.js +260 -0
  91. package/plugins/ima-claude/skills/js-fp/examples/tests/pure-functions.test.js +262 -0
  92. package/plugins/ima-claude/skills/js-fp/references/anti-patterns.md +120 -0
  93. package/plugins/ima-claude/skills/js-fp/references/performance-patterns.md +116 -0
  94. package/plugins/ima-claude/skills/js-fp/references/testing-patterns.md +134 -0
  95. package/plugins/ima-claude/skills/js-fp-api/SKILL.md +280 -0
  96. package/plugins/ima-claude/skills/js-fp-api/examples/crud-endpoint.js +258 -0
  97. package/plugins/ima-claude/skills/js-fp-api/references/middleware-patterns.md +134 -0
  98. package/plugins/ima-claude/skills/js-fp-api/references/security-sql.md +110 -0
  99. package/plugins/ima-claude/skills/js-fp-api/references/validation-patterns.md +165 -0
  100. package/plugins/ima-claude/skills/js-fp-react/SKILL.md +447 -0
  101. package/plugins/ima-claude/skills/js-fp-react/examples/ProductCard.tsx +65 -0
  102. package/plugins/ima-claude/skills/js-fp-react/references/hooks-advanced.md +136 -0
  103. package/plugins/ima-claude/skills/js-fp-react/references/performance-patterns.md +175 -0
  104. package/plugins/ima-claude/skills/js-fp-vue/SKILL.md +322 -0
  105. package/plugins/ima-claude/skills/js-fp-vue/references/complete-examples.md +397 -0
  106. package/plugins/ima-claude/skills/js-fp-vue/references/composables-advanced.md +282 -0
  107. package/plugins/ima-claude/skills/js-fp-vue/references/reactivity-patterns.md +348 -0
  108. package/plugins/ima-claude/skills/js-fp-vue/references/testing.md +314 -0
  109. package/plugins/ima-claude/skills/js-fp-wordpress/SKILL.md +301 -0
  110. package/plugins/ima-claude/skills/js-fp-wordpress/references/ajax-patterns.md +192 -0
  111. package/plugins/ima-claude/skills/js-fp-wordpress/references/event-patterns.md +136 -0
  112. package/plugins/ima-claude/skills/js-fp-wordpress/references/wp-integration.md +248 -0
  113. package/plugins/ima-claude/skills/livecanvas/SKILL.md +209 -0
  114. package/plugins/ima-claude/skills/livecanvas/references/livecanvas-features.md +311 -0
  115. package/plugins/ima-claude/skills/livecanvas/references/loops-and-logic.md +730 -0
  116. package/plugins/ima-claude/skills/livecanvas/references/picostrap.md +227 -0
  117. package/plugins/ima-claude/skills/mcp-atlassian/SKILL.md +339 -0
  118. package/plugins/ima-claude/skills/mcp-context7/SKILL.md +109 -0
  119. package/plugins/ima-claude/skills/mcp-memory/SKILL.md +182 -0
  120. package/plugins/ima-claude/skills/mcp-qdrant/SKILL.md +233 -0
  121. package/plugins/ima-claude/skills/mcp-sequential/SKILL.md +149 -0
  122. package/plugins/ima-claude/skills/mcp-serena/SKILL.md +174 -0
  123. package/plugins/ima-claude/skills/mcp-tavily/SKILL.md +118 -0
  124. package/plugins/ima-claude/skills/mcp-vestige/SKILL.md +259 -0
  125. package/plugins/ima-claude/skills/php-authnet/SKILL.md +275 -0
  126. package/plugins/ima-claude/skills/php-authnet/references/api-reference.md +624 -0
  127. package/plugins/ima-claude/skills/php-authnet/references/sandbox-testing.md +424 -0
  128. package/plugins/ima-claude/skills/php-fp/SKILL.md +333 -0
  129. package/plugins/ima-claude/skills/php-fp/examples/pure-functions.php +403 -0
  130. package/plugins/ima-claude/skills/php-fp/examples/tests/PureFunctionsTest.php +515 -0
  131. package/plugins/ima-claude/skills/php-fp/references/core-principles.md +277 -0
  132. package/plugins/ima-claude/skills/php-fp/references/testing-patterns.md +374 -0
  133. package/plugins/ima-claude/skills/php-fp-wordpress/SKILL.md +216 -0
  134. package/plugins/ima-claude/skills/php-fp-wordpress/references/fp-patterns.md +275 -0
  135. package/plugins/ima-claude/skills/php-fp-wordpress/references/plugin-architecture.md +295 -0
  136. package/plugins/ima-claude/skills/php-fp-wordpress/references/security-examples.md +203 -0
  137. package/plugins/ima-claude/skills/php-fp-wordpress/references/testing-strategy.md +259 -0
  138. package/plugins/ima-claude/skills/phpunit-wp/SKILL.md +716 -0
  139. package/plugins/ima-claude/skills/playwright/SKILL.md +434 -0
  140. package/plugins/ima-claude/skills/playwright/references/accessibility-testing.md +153 -0
  141. package/plugins/ima-claude/skills/playwright/references/ci-cd.md +268 -0
  142. package/plugins/ima-claude/skills/playwright/references/network-mocking.md +270 -0
  143. package/plugins/ima-claude/skills/playwright/references/visual-regression.md +215 -0
  144. package/plugins/ima-claude/skills/py-fp/SKILL.md +663 -0
  145. package/plugins/ima-claude/skills/py-fp/examples/pure-functions.py +185 -0
  146. package/plugins/ima-claude/skills/py-fp/examples/tests/test_pure_functions.py +244 -0
  147. package/plugins/ima-claude/skills/py-fp/references/core-principles.md +381 -0
  148. package/plugins/ima-claude/skills/py-fp/references/testing-patterns.md +283 -0
  149. package/plugins/ima-claude/skills/quasar-fp/SKILL.md +327 -0
  150. package/plugins/ima-claude/skills/quasar-fp/metadata.json +85 -0
  151. package/plugins/ima-claude/skills/quasar-fp/references/component-patterns.md +257 -0
  152. package/plugins/ima-claude/skills/quasar-fp/references/theme-integration.md +233 -0
  153. package/plugins/ima-claude/skills/quasar-fp/references/utility-classes.md +237 -0
  154. package/plugins/ima-claude/skills/quickstart/SKILL.md +129 -0
  155. package/plugins/ima-claude/skills/rails/SKILL.md +359 -0
  156. package/plugins/ima-claude/skills/resume-session/SKILL.md +68 -0
  157. package/plugins/ima-claude/skills/rg/SKILL.md +205 -0
  158. package/plugins/ima-claude/skills/ruby-fp/SKILL.md +336 -0
  159. package/plugins/ima-claude/skills/save-session/SKILL.md +81 -0
  160. package/plugins/ima-claude/skills/scorecard/SKILL.md +96 -0
  161. package/plugins/ima-claude/skills/skill-analyzer/SKILL.md +127 -0
  162. package/plugins/ima-claude/skills/skill-analyzer/references/advanced-checklist.md +44 -0
  163. package/plugins/ima-claude/skills/skill-analyzer/references/core-checklist.md +60 -0
  164. package/plugins/ima-claude/skills/skill-analyzer/scripts/analyze_skill.py +418 -0
  165. package/plugins/ima-claude/skills/skill-creator/LICENSE.txt +202 -0
  166. package/plugins/ima-claude/skills/skill-creator/SKILL.md +343 -0
  167. package/plugins/ima-claude/skills/skill-creator/references/output-patterns.md +82 -0
  168. package/plugins/ima-claude/skills/skill-creator/references/workflows.md +28 -0
  169. package/plugins/ima-claude/skills/skill-creator/scripts/init_skill.py +303 -0
  170. package/plugins/ima-claude/skills/skill-creator/scripts/package_skill.py +110 -0
  171. package/plugins/ima-claude/skills/skill-creator/scripts/quick_validate.py +103 -0
  172. package/plugins/ima-claude/skills/task-master/SKILL.md +51 -0
  173. package/plugins/ima-claude/skills/task-planner/SKILL.md +228 -0
  174. package/plugins/ima-claude/skills/task-runner/SKILL.md +192 -0
  175. package/plugins/ima-claude/skills/unit-testing/SKILL.md +198 -0
  176. package/plugins/ima-claude/skills/unit-testing/references/mock-patterns.md +181 -0
  177. package/plugins/ima-claude/skills/unit-testing/references/tdd-workflow.md +177 -0
  178. package/plugins/ima-claude/skills/unit-testing/references/test-strategy.md +126 -0
  179. package/plugins/ima-claude/skills/wp-local/SKILL.md +246 -0
  180. package/plugins/ima-claude/skills/wp-local/references/configuration.md +198 -0
  181. package/plugins/ima-claude/skills/wp-local/references/wp-cli-reference.md +406 -0
  182. package/plugins/ima-claude/skills/wp-local/scripts/wp-local.sh +61 -0
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "ima-claude",
3
+ "version": "2.9.0",
4
+ "description": "IMA's AI coding agent skills - FP patterns, architecture guidance, and team standards. Supports Claude Code, Junie CLI, and more.",
5
+ "type": "module",
6
+ "scripts": {
7
+ "build": "tsup",
8
+ "dev": "bun run scripts/cli.ts",
9
+ "migrate": "bun run scripts/migrate-to-plugin.ts"
10
+ },
11
+ "bin": {
12
+ "ima-claude": "./dist/cli.js"
13
+ },
14
+ "files": [
15
+ "dist/",
16
+ "plugins/",
17
+ "platforms/",
18
+ "!**/ima-cancer-care-guides/**",
19
+ "!**/__pycache__/**",
20
+ "!**/*.pyc",
21
+ "!**/*.skill"
22
+ ],
23
+ "devDependencies": {
24
+ "@types/bun": "latest",
25
+ "@types/node": "^25.4.0",
26
+ "tsup": "^8.5.1",
27
+ "typescript": "^5.9.3"
28
+ },
29
+ "author": {
30
+ "name": "Eric Jensen",
31
+ "email": "ejensen@imahealth.org",
32
+ "url": "https://imahealth.org"
33
+ },
34
+ "homepage": "https://github.com/Soabirw/ima-claude#readme",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/Soabirw/ima-claude.git"
38
+ },
39
+ "bugs": "https://github.com/Soabirw/ima-claude/issues",
40
+ "keywords": [
41
+ "claude-code",
42
+ "claude-code-skills",
43
+ "functional-programming",
44
+ "ai-tools",
45
+ "developer-tools",
46
+ "mcp"
47
+ ],
48
+ "license": "MIT"
49
+ }
@@ -0,0 +1,115 @@
1
+ import { join } from "path";
2
+ import { existsSync, copyFileSync, readdirSync, statSync } from "fs";
3
+
4
+ import type { PlatformAdapter, InstallItem, InstallPreview } from "../shared/types";
5
+ import {
6
+ CLAUDE_DIR,
7
+ ensureDir,
8
+ copyDirRecursive,
9
+ mergeHooksIntoSettings,
10
+ SKILLS_TO_INSTALL,
11
+ HOOKS_TO_INSTALL,
12
+ SKILLS_DIR,
13
+ HOOKS_DIR,
14
+ log,
15
+ } from "../../scripts/utils";
16
+
17
+ const AGENTS_DIR = join(CLAUDE_DIR, "agents");
18
+
19
+ export class ClaudeAdapter implements PlatformAdapter {
20
+ readonly name = "claude";
21
+ readonly displayName = "Claude Code";
22
+ readonly configDir = CLAUDE_DIR;
23
+
24
+ detect(): boolean {
25
+ return existsSync(CLAUDE_DIR);
26
+ }
27
+
28
+ preview(sourceDir: string): InstallPreview {
29
+ const skillItems: InstallItem[] = SKILLS_TO_INSTALL.map((skill) => ({
30
+ name: skill,
31
+ category: "skill",
32
+ destPath: join(SKILLS_DIR, skill),
33
+ exists: existsSync(join(SKILLS_DIR, skill)),
34
+ }));
35
+
36
+ const agentsSourceDir = join(sourceDir, "agents");
37
+ const agentItems: InstallItem[] = existsSync(agentsSourceDir)
38
+ ? readdirSync(agentsSourceDir)
39
+ .filter((f) => f.endsWith(".md"))
40
+ .map((file) => ({
41
+ name: file.replace(/\.md$/, ""),
42
+ category: "agent",
43
+ destPath: join(AGENTS_DIR, file),
44
+ exists: existsSync(join(AGENTS_DIR, file)),
45
+ }))
46
+ : [];
47
+
48
+ const hooksSourceDir = join(sourceDir, "hooks");
49
+ const hookItems: InstallItem[] = HOOKS_TO_INSTALL.map((file) => ({
50
+ name: file,
51
+ category: "hook",
52
+ destPath: join(HOOKS_DIR, file),
53
+ exists: existsSync(join(HOOKS_DIR, file)),
54
+ }));
55
+
56
+ return {
57
+ platform: this.name,
58
+ targetDir: CLAUDE_DIR,
59
+ items: [...skillItems, ...agentItems, ...hookItems],
60
+ };
61
+ }
62
+
63
+ installSkills(sourceDir: string, exclude?: string[]): void {
64
+ ensureDir(SKILLS_DIR);
65
+ const skills = exclude?.length
66
+ ? SKILLS_TO_INSTALL.filter((s) => !exclude.includes(s))
67
+ : SKILLS_TO_INSTALL;
68
+ for (const skill of skills) {
69
+ const src = join(sourceDir, skill);
70
+ if (existsSync(src) && statSync(src).isDirectory()) {
71
+ copyDirRecursive(src, join(SKILLS_DIR, skill));
72
+ log.step(`skill: ${skill}`);
73
+ }
74
+ }
75
+ }
76
+
77
+ installAgents(sourceDir: string, exclude?: string[]): void {
78
+ ensureDir(AGENTS_DIR);
79
+ const entries = readdirSync(sourceDir).filter((f) => f.endsWith(".md"));
80
+ const filtered = exclude?.length
81
+ ? entries.filter((f) => !exclude.includes(f.replace(/\.md$/, "")))
82
+ : entries;
83
+ for (const file of filtered) {
84
+ copyFileSync(join(sourceDir, file), join(AGENTS_DIR, file));
85
+ log.step(`agent: ${file}`);
86
+ }
87
+ }
88
+
89
+ installGuidelines(_pluginRoot: string): void {
90
+ // No-op — guidelines come from the plugin system via CLAUDE.md injection
91
+ }
92
+
93
+ installHooks(sourceDir: string, exclude?: string[]): void {
94
+ ensureDir(HOOKS_DIR);
95
+ const hooks = exclude?.length
96
+ ? HOOKS_TO_INSTALL.filter((f) => !exclude.includes(f))
97
+ : HOOKS_TO_INSTALL;
98
+ for (const file of hooks) {
99
+ const src = join(sourceDir, file);
100
+ if (existsSync(src)) {
101
+ copyFileSync(src, join(HOOKS_DIR, file));
102
+ log.step(`hook: ${file}`);
103
+ }
104
+ }
105
+ const { created } = mergeHooksIntoSettings();
106
+ log.info(created ? "Created ~/.claude/settings.json with hooks" : "Merged hooks into ~/.claude/settings.json");
107
+ }
108
+
109
+ postInstall(): void {
110
+ log.warn("Note: Direct install is not the recommended approach for Claude Code.");
111
+ log.info("Prefer the plugin system instead:");
112
+ log.info(" /plugin marketplace add Soabirw/ima-claude");
113
+ log.info(" /plugin install ima-claude");
114
+ }
115
+ }
@@ -0,0 +1,254 @@
1
+ import { join } from "path";
2
+ import { homedir } from "os";
3
+ import { existsSync, readdirSync, statSync, readFileSync, writeFileSync } from "fs";
4
+
5
+ import type { PlatformAdapter, InstallItem, InstallPreview } from "../shared/types";
6
+ import { ensureDir, copyDirRecursive, log, SKILLS_TO_INSTALL, VERSION } from "../../scripts/utils";
7
+
8
+ const JUNIE_DIR = join(homedir(), ".junie");
9
+ const JUNIE_SKILLS_DIR = join(JUNIE_DIR, "skills");
10
+ const JUNIE_AGENTS_DIR = join(JUNIE_DIR, "agents");
11
+ const JUNIE_GUIDELINES_FILE = join(JUNIE_DIR, "AGENTS.md");
12
+
13
+ // Simple single-line YAML parser. Handles `key: value` pairs only.
14
+ // Does NOT support multi-line values, block scalars, or indented lists.
15
+ // Sufficient for our agent definitions which use simple key-value frontmatter.
16
+ function parseFrontmatter(content: string): { frontmatter: Record<string, string>; body: string } {
17
+ const match = content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
18
+ if (!match) return { frontmatter: {}, body: content };
19
+
20
+ const frontmatter: Record<string, string> = {};
21
+ for (const line of match[1].split("\n")) {
22
+ const colonIdx = line.indexOf(":");
23
+ if (colonIdx === -1) continue;
24
+ const key = line.slice(0, colonIdx).trim();
25
+ const value = line.slice(colonIdx + 1).trim();
26
+ if (key) frontmatter[key] = value;
27
+ }
28
+
29
+ return { frontmatter, body: match[2] };
30
+ }
31
+
32
+ function serializeFrontmatter(frontmatter: Record<string, string>, body: string): string {
33
+ const lines = Object.entries(frontmatter).map(([k, v]) => `${k}: ${v}`);
34
+ return `---\n${lines.join("\n")}\n---\n${body}`;
35
+ }
36
+
37
+ function transformAgentForJunie(content: string): string {
38
+ const { frontmatter, body } = parseFrontmatter(content);
39
+ const { permissionMode: _dropped, ...junieFrontmatter } = frontmatter;
40
+ return serializeFrontmatter(junieFrontmatter, body);
41
+ }
42
+
43
+ function generateAgentsMd(): string {
44
+ return `# ima-claude: AI Coding Agent Guidelines
45
+
46
+ > Generated by ima-claude v${VERSION} for Junie CLI.
47
+ > Source: https://github.com/Soabirw/ima-claude
48
+
49
+ ## Default Persona: The Practitioner
50
+
51
+ A 25-year software development veteran. FP-first, composition-minded, anti-over-engineering.
52
+ Uses "we" not "I" — collaborative, humble, light-hearted. "Slow is smooth, smooth is fast."
53
+
54
+ **Philosophy**: Simple > Complex | Evidence > Assumptions | Native > Utilities | MVP > Enterprise
55
+
56
+ ---
57
+
58
+ ## Memory Routing
59
+
60
+ | Store what | Where | Why |
61
+ |---|---|---|
62
+ | Decisions, preferences, patterns, bugs | Vestige \`smart_ingest\` | Fades naturally if not referenced |
63
+ | Reference material (docs, standards, PRDs) | Qdrant \`qdrant-store\` | Permanent library |
64
+ | Session state, task progress | Serena \`write_memory\` | Project-scoped workbench |
65
+ | Future reminders | Vestige \`intention\` | Surfaces at next session |
66
+
67
+ At session start, check memory before asking questions:
68
+ - Vestige: search for user preferences and project context
69
+ - Vestige: check for pending reminders/intentions
70
+ - Serena: list memories if in a Serena-activated project
71
+
72
+ Auto-store: "I prefer..." → Vestige preference. "Let's go with X because..." → Vestige decision. "The reason this failed..." → Vestige bug.
73
+
74
+ After completing work: store outcome in Vestige, reference material in Qdrant, session state in Serena.
75
+
76
+ ---
77
+
78
+ ## Orchestrator Protocol
79
+
80
+ You are the Orchestrator. Plan and delegate. Do NOT implement directly.
81
+ - Non-trivial work → task-planner (decompose) → task-runner (delegate)
82
+ - Trivial = single file, < 5 lines, no judgment calls
83
+ - Model selection: opus for orchestration, sonnet for implementation (default), haiku for lookups
84
+
85
+ ---
86
+
87
+ ## Available Agents
88
+
89
+ Delegate to named agents — they enforce model, tools, and permissions automatically.
90
+
91
+ | Agent | Model | Use For |
92
+ |---|---|---|
93
+ | \`explorer\` | haiku | File discovery, codebase exploration |
94
+ | \`implementer\` | sonnet | Feature dev, bug fixes, refactoring |
95
+ | \`reviewer\` | sonnet | Code review, security audit, FP checks |
96
+ | \`wp-developer\` | sonnet | WordPress plugins, themes, WP-CLI, forms |
97
+ | \`memory\` | sonnet | Memory search, storage, consolidation |
98
+
99
+ ---
100
+
101
+ ## Code Navigation (Serena)
102
+
103
+ When Serena MCP is available, **prefer Serena over Read/Grep for code investigation.** 40-70% token savings.
104
+
105
+ | Instead of | Use |
106
+ |---|---|
107
+ | Read file to understand structure | Serena get_symbols_overview |
108
+ | Grep for class/function definition | Serena find_symbol |
109
+ | Grep for callers/references | Serena find_referencing_symbols |
110
+
111
+ Use Read only when you need the actual implementation body of a known, specific symbol.
112
+
113
+ ---
114
+
115
+ ## Complex Reasoning
116
+
117
+ Use sequential thinking before acting on:
118
+ - Debugging / root cause analysis / "why is this failing"
119
+ - Trade-off evaluation / "which approach"
120
+ - Architectural decisions / design choices
121
+ - Multi-step investigations where approach may change
122
+
123
+ ---
124
+
125
+ ## MCP Tool Routing
126
+
127
+ | Signal | Preferred Tool |
128
+ |---|---|
129
+ | "latest", "2025/2026", "what's new" | Tavily search |
130
+ | Library/framework API question | Context7 |
131
+ | URL content extraction | Tavily extract (use advanced for complex pages) |
132
+
133
+ Before web tools: check internal knowledge → Context7 → then Tavily.
134
+ Before external lookups: check Vestige memory first.
135
+
136
+ ---
137
+
138
+ ## Search Preference
139
+
140
+ Always prefer \`rg\` (ripgrep) over grep/find. Faster, respects .gitignore, recursive by default.
141
+
142
+ ---
143
+
144
+ ## Security
145
+
146
+ - Verify nonce usage and input sanitization in WordPress PHP code
147
+ - Never concatenate user input directly into SQL — use parameterized queries
148
+ - Check for XSS, CSRF, and OWASP top 10 vulnerabilities in written code
149
+
150
+ ---
151
+
152
+ ## Code Style
153
+
154
+ - Don't create custom FP utility functions (pipe, compose, curry) — use language-native patterns or established libraries
155
+ - In WordPress JavaScript context, use jQuery patterns when jQuery is already loaded
156
+ - Prefer Bootstrap utility classes over custom CSS overrides
157
+ - Run \`composer dump-autoload\` after creating new PHP files
158
+ - Use proper Edit tools for code changes, not sed/awk
159
+
160
+ ---
161
+
162
+ ## Documentation
163
+
164
+ Follow the three-tier documentation system:
165
+ - **Active** — Living docs, kept current (README, API docs, architecture)
166
+ - **Archive** — Historical reference, rarely updated (decisions, post-mortems)
167
+ - **Transient** — Ephemeral, git-ignored (session notes, scratch)
168
+ `;
169
+ }
170
+
171
+ export class JunieAdapter implements PlatformAdapter {
172
+ readonly name = "junie";
173
+ readonly displayName = "Junie CLI";
174
+ readonly configDir = JUNIE_DIR;
175
+
176
+ detect(): boolean {
177
+ return existsSync(JUNIE_DIR);
178
+ }
179
+
180
+ preview(sourceDir: string): InstallPreview {
181
+ const skillItems: InstallItem[] = SKILLS_TO_INSTALL.map((skill) => ({
182
+ name: skill,
183
+ category: "skill" as const,
184
+ destPath: join(JUNIE_SKILLS_DIR, skill),
185
+ exists: existsSync(join(JUNIE_SKILLS_DIR, skill)),
186
+ })).filter((item) => existsSync(join(sourceDir, "skills", item.name)));
187
+
188
+ const agentsDir = join(sourceDir, "agents");
189
+ const agentItems: InstallItem[] = existsSync(agentsDir)
190
+ ? readdirSync(agentsDir)
191
+ .filter((f) => f.endsWith(".md"))
192
+ .map((file) => ({
193
+ name: file.replace(/\.md$/, ""),
194
+ category: "agent" as const,
195
+ destPath: join(JUNIE_AGENTS_DIR, file),
196
+ exists: existsSync(join(JUNIE_AGENTS_DIR, file)),
197
+ }))
198
+ : [];
199
+
200
+ const guidelineItem: InstallItem = {
201
+ name: "AGENTS.md",
202
+ category: "guideline",
203
+ destPath: JUNIE_GUIDELINES_FILE,
204
+ exists: existsSync(JUNIE_GUIDELINES_FILE),
205
+ };
206
+
207
+ return {
208
+ platform: this.name,
209
+ targetDir: JUNIE_DIR,
210
+ items: [...skillItems, ...agentItems, guidelineItem],
211
+ };
212
+ }
213
+
214
+ installSkills(sourceDir: string, exclude?: string[]): void {
215
+ ensureDir(JUNIE_SKILLS_DIR);
216
+ const skills = exclude?.length
217
+ ? SKILLS_TO_INSTALL.filter((s) => !exclude.includes(s))
218
+ : SKILLS_TO_INSTALL;
219
+ for (const skill of skills) {
220
+ const src = join(sourceDir, skill);
221
+ if (existsSync(src) && statSync(src).isDirectory()) {
222
+ copyDirRecursive(src, join(JUNIE_SKILLS_DIR, skill));
223
+ log.step(`skill: ${skill}`);
224
+ }
225
+ }
226
+ }
227
+
228
+ installAgents(sourceDir: string, exclude?: string[]): void {
229
+ ensureDir(JUNIE_AGENTS_DIR);
230
+ const entries = readdirSync(sourceDir)
231
+ .filter((f) => f.endsWith(".md"))
232
+ .filter((f) => !exclude?.includes(f.replace(/\.md$/, "")));
233
+ for (const file of entries) {
234
+ const content = readFileSync(join(sourceDir, file), "utf8");
235
+ const transformed = transformAgentForJunie(content);
236
+ writeFileSync(join(JUNIE_AGENTS_DIR, file), transformed);
237
+ log.step(`agent: ${file}`);
238
+ }
239
+ }
240
+
241
+ installGuidelines(_pluginRoot: string): void {
242
+ ensureDir(JUNIE_DIR);
243
+ writeFileSync(JUNIE_GUIDELINES_FILE, generateAgentsMd());
244
+ log.step(`guidelines: ${JUNIE_GUIDELINES_FILE}`);
245
+ }
246
+
247
+ postInstall(): void {
248
+ log.info("Junie install complete. Verify:");
249
+ log.info(` Skills: ${JUNIE_SKILLS_DIR}`);
250
+ log.info(` Agents: ${JUNIE_AGENTS_DIR}`);
251
+ log.info(` Guidelines: ${JUNIE_GUIDELINES_FILE}`);
252
+ log.warn("Note: Junie does not support hooks — behavioral guidelines are in AGENTS.md instead.");
253
+ }
254
+ }
@@ -0,0 +1,113 @@
1
+ # ima-claude: AI Coding Agent Guidelines
2
+
3
+ > Generated by ima-claude v{{VERSION}} for Junie CLI.
4
+ > Source: https://github.com/Soabirw/ima-claude
5
+
6
+ ## Default Persona: The Practitioner
7
+
8
+ A 25-year software development veteran. FP-first, composition-minded, anti-over-engineering.
9
+ Uses "we" not "I" — collaborative, humble, light-hearted. "Slow is smooth, smooth is fast."
10
+
11
+ ## Core Philosophy
12
+
13
+ **"Simple > Complex | Evidence > Assumptions"**
14
+
15
+ 1. **Anti-over-engineering** — Start simple, add complexity only with evidence
16
+ 2. **Native patterns** — Use language idioms, don't create custom FP utilities (pipe/compose/curry). Using established libraries is fine.
17
+ 3. **Testability** — Pure functions enable comprehensive testing
18
+ 4. **Context-appropriate** — CLI script ≠ production service
19
+
20
+ ## Memory Bootstrap
21
+
22
+ At session start, check memory before asking questions:
23
+ - Vestige: search for user preferences and project context
24
+ - Vestige: check for pending reminders/intentions
25
+ - Serena: list memories if in a Serena-activated project
26
+
27
+ ## Memory Routing
28
+
29
+ | Store what | Where | Why |
30
+ |---|---|---|
31
+ | Decisions, preferences, patterns, bugs | Vestige `smart_ingest` | Fades naturally if not referenced |
32
+ | Reference material (docs, standards, PRDs) | Qdrant `qdrant-store` | Permanent library |
33
+ | Session state, task progress | Serena `write_memory` | Project-scoped workbench |
34
+ | Future reminders | Vestige `intention` | Surfaces at next session |
35
+
36
+ Auto-store: "I prefer..." → Vestige preference. "Let's go with X because..." → Vestige decision. "The reason this failed..." → Vestige bug.
37
+
38
+ After completing work: store outcome in Vestige, reference material in Qdrant, session state in Serena.
39
+
40
+ ## Orchestrator Protocol
41
+
42
+ You are the Orchestrator. Plan and delegate. Do NOT implement directly.
43
+ - Non-trivial work → task-planner (decompose) → task-runner (delegate)
44
+ - Trivial = single file, < 5 lines, no judgment calls
45
+ - Model selection: opus for orchestration, sonnet for implementation (default), haiku for lookups
46
+
47
+ ## Available Agents
48
+
49
+ Delegate to named agents — they enforce model, tools, and permissions automatically.
50
+
51
+ | Agent | Model | Mode | Use For |
52
+ |---|---|---|---|
53
+ | `explorer` | haiku | read-only | File discovery, codebase exploration |
54
+ | `implementer` | sonnet | full | Feature dev, bug fixes, refactoring |
55
+ | `reviewer` | sonnet | read-only | Code review, security audit, FP checks |
56
+ | `wp-developer` | sonnet | full | WordPress plugins, themes, WP-CLI, forms |
57
+ | `memory` | sonnet | full | Memory search, storage, consolidation |
58
+
59
+ ## Code Navigation
60
+
61
+ When Serena MCP is available, **prefer Serena over Read/Grep for code investigation.** 40-70% token savings.
62
+
63
+ | Instead of | Use |
64
+ |---|---|
65
+ | Read file to understand structure | Serena get_symbols_overview |
66
+ | Grep for class/function definition | Serena find_symbol |
67
+ | Grep for callers/references | Serena find_referencing_symbols |
68
+
69
+ Use Read only when you need the actual implementation body of a known, specific symbol.
70
+
71
+ ## Complex Reasoning
72
+
73
+ Use sequential thinking before acting on:
74
+ - Debugging / root cause analysis / "why is this failing"
75
+ - Trade-off evaluation / "which approach"
76
+ - Architectural decisions / design choices
77
+ - Multi-step investigations where approach may change
78
+
79
+ ## Search Preference
80
+
81
+ Always prefer `rg` (ripgrep) over grep/find. Faster, respects .gitignore, recursive by default.
82
+
83
+ ## MCP Tool Routing
84
+
85
+ | Signal | Preferred Tool |
86
+ |---|---|
87
+ | "latest", "2025/2026", "what's new" | Tavily search |
88
+ | Library/framework API question | Context7 |
89
+ | URL content extraction | Tavily extract (use advanced for complex pages) |
90
+
91
+ Before web tools: check internal knowledge → Context7 → then Tavily.
92
+ Before external lookups: check Vestige memory first.
93
+
94
+ ## Security
95
+
96
+ - Verify nonce usage and input sanitization in WordPress PHP code
97
+ - Never concatenate user input directly into SQL — use parameterized queries
98
+ - Check for XSS, CSRF, and OWASP top 10 vulnerabilities in written code
99
+
100
+ ## Code Style
101
+
102
+ - Don't create custom FP utility functions (pipe, compose, curry) — use language-native patterns or established libraries
103
+ - In WordPress JavaScript context, use jQuery patterns when jQuery is already loaded
104
+ - Prefer Bootstrap utility classes over custom CSS overrides
105
+ - Run `composer dump-autoload` after creating new PHP files
106
+ - Use proper Edit tools for code changes, not sed/awk
107
+
108
+ ## Documentation
109
+
110
+ Follow the three-tier documentation system:
111
+ - **Active** — Living docs, kept current (README, API docs, architecture)
112
+ - **Archive** — Historical reference, rarely updated (decisions, post-mortems)
113
+ - **Transient** — Ephemeral, git-ignored (session notes, scratch)
@@ -0,0 +1,84 @@
1
+ # Hook-to-Guideline Translation Map
2
+
3
+ This document tracks the relationship between Claude Code hooks and their
4
+ Junie AGENTS.md guideline equivalents. When a hook is updated, the corresponding
5
+ guideline text in `agents-template.md` should be reviewed.
6
+
7
+ ## Translation Strategy
8
+
9
+ Junie has no hook system. Hook behaviors are translated into:
10
+ 1. **AGENTS.md guidelines** — persistent instructions loaded every session
11
+ 2. **Skill content** — where the behavior is skill-specific (no change needed)
12
+ 3. **Dropped** — where the behavior is Claude-specific with no Junie equivalent
13
+
14
+ ## Hook → Guideline Mapping
15
+
16
+ ### Tool Redirection Hooks → Search & Tool Preferences
17
+
18
+ | Hook | Guideline Section | Notes |
19
+ |------|-------------------|-------|
20
+ | `enforce_rg_over_grep.py` | Search Preference | "Prefer rg (ripgrep) over grep/find" |
21
+ | `webfetch_to_tavily.py` | MCP Tool Routing | "Prefer Tavily extract over WebFetch" |
22
+ | `websearch_to_tavily.py` | MCP Tool Routing | "Prefer Tavily search over WebSearch" |
23
+ | `tavily_extract_advanced.py` | MCP Tool Routing | "Use advanced extraction for complex pages" |
24
+
25
+ ### Memory Hooks → Memory Routing Guidelines
26
+
27
+ | Hook | Guideline Section | Notes |
28
+ |------|-------------------|-------|
29
+ | `memory_bootstrap.py` | Memory Bootstrap | "Check Vestige/Qdrant at session start" |
30
+ | `memory_store_reminder.py` | Memory Routing | "After completing work, store outcomes" |
31
+ | `vestige_before_external.py` | Memory Routing | "Check Vestige before external tools" |
32
+
33
+ ### Serena Hooks → Code Navigation Guidelines
34
+
35
+ | Hook | Guideline Section | Notes |
36
+ |------|-------------------|-------|
37
+ | `serena_over_read.py` | Code Navigation | "Prefer Serena symbol overview over Read" |
38
+ | `serena_over_grep.py` | Code Navigation | "Prefer Serena find_symbol over Grep" |
39
+ | `serena_project_check.py` | Code Navigation | "Verify Serena project path before ops" |
40
+
41
+ ### Workflow Hooks → Orchestrator Protocol
42
+
43
+ | Hook | Guideline Section | Notes |
44
+ |------|-------------------|-------|
45
+ | `prompt_coach.py` | Dropped | Claude-specific prompt evaluation hook |
46
+ | `task_master_before_impl.py` | Orchestrator Protocol | "Non-trivial work → task decomposition" |
47
+ | `task_master_after_plan.py` | Orchestrator Protocol | "After planning, delegate to agents" |
48
+ | `jira_issue_fetch.py` | Dropped | Requires Claude-specific hook stdin |
49
+
50
+ ### Security Hooks → Code Quality Guidelines
51
+
52
+ | Hook | Guideline Section | Notes |
53
+ |------|-------------------|-------|
54
+ | `wp_security_check.py` | Security | "Verify nonce/sanitization in WordPress PHP" |
55
+ | `sql_injection_check.py` | Security | "Never concatenate user input into SQL" |
56
+
57
+ ### Code Quality Hooks → Code Style Guidelines
58
+
59
+ | Hook | Guideline Section | Notes |
60
+ |------|-------------------|-------|
61
+ | `fp_utility_check.py` | FP Principles | "Don't create custom pipe/compose/curry utilities" |
62
+ | `jquery_in_wordpress.py` | WordPress JS | "Use jQuery patterns when in WP context" |
63
+ | `bootstrap_utility_check.py` | CSS Patterns | "Use Bootstrap utility classes, avoid custom CSS" |
64
+ | `composer_autoload_check.py` | PHP Patterns | "Run composer dump-autoload after new PHP files" |
65
+ | `docs_organization.py` | Documentation | "Follow Active/Archive/Transient doc tiers" |
66
+ | `block_sed_edits.py` | Tool Usage | "Use Edit tool, not sed, for code changes" |
67
+
68
+ ### Session Hooks → Session Management
69
+
70
+ | Hook | Guideline Section | Notes |
71
+ |------|-------------------|-------|
72
+ | `bootstrap.sh` | Full AGENTS.md | Entire bootstrap content becomes AGENTS.md |
73
+
74
+ ### Atlassian Hooks → Dropped
75
+
76
+ | Hook | Guideline Section | Notes |
77
+ |------|-------------------|-------|
78
+ | `atlassian_prereqs.py` | Dropped | Requires Claude-specific hook mechanism |
79
+
80
+ ### Sequential Thinking → Complex Reasoning
81
+
82
+ | Hook | Guideline Section | Notes |
83
+ |------|-------------------|-------|
84
+ | `sequential_thinking_check.py` | Complex Reasoning | "Use sequential thinking for debugging/analysis" |
@@ -0,0 +1,27 @@
1
+ import type { DetectedPlatform, PlatformAdapter } from "./types";
2
+ import { ClaudeAdapter } from "../claude/adapter";
3
+ import { JunieAdapter } from "../junie/adapter";
4
+
5
+ const ADAPTERS: PlatformAdapter[] = [
6
+ new ClaudeAdapter(),
7
+ new JunieAdapter(),
8
+ ];
9
+
10
+ export function detectPlatforms(): DetectedPlatform[] {
11
+ return ADAPTERS.map((adapter) => {
12
+ const detected = adapter.detect();
13
+ const note = adapter.name === "claude" && detected
14
+ ? "Recommended: install via plugin marketplace instead"
15
+ : undefined;
16
+
17
+ return { adapter, detected, note };
18
+ });
19
+ }
20
+
21
+ export function getAdapter(name: string): PlatformAdapter | undefined {
22
+ return ADAPTERS.find((a) => a.name === name);
23
+ }
24
+
25
+ export function getAllAdapters(): PlatformAdapter[] {
26
+ return [...ADAPTERS];
27
+ }