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.
- package/LICENSE +21 -0
- package/README.md +463 -0
- package/dist/cli.js +1064 -0
- package/package.json +49 -0
- package/platforms/claude/adapter.ts +115 -0
- package/platforms/junie/adapter.ts +254 -0
- package/platforms/junie/agents-template.md +113 -0
- package/platforms/junie/hook-translations.md +84 -0
- package/platforms/shared/detector.ts +27 -0
- package/platforms/shared/installer.ts +202 -0
- package/platforms/shared/types.ts +78 -0
- package/plugins/ima-claude/.claude-plugin/plugin.json +25 -0
- package/plugins/ima-claude/agents/explorer.md +30 -0
- package/plugins/ima-claude/agents/implementer.md +30 -0
- package/plugins/ima-claude/agents/memory.md +42 -0
- package/plugins/ima-claude/agents/reviewer.md +53 -0
- package/plugins/ima-claude/agents/tester.md +33 -0
- package/plugins/ima-claude/agents/wp-developer.md +46 -0
- package/plugins/ima-claude/hooks/README.md +145 -0
- package/plugins/ima-claude/hooks/atlassian_prereqs.py +112 -0
- package/plugins/ima-claude/hooks/block_sed_edits.py +59 -0
- package/plugins/ima-claude/hooks/bootstrap.sh +90 -0
- package/plugins/ima-claude/hooks/bootstrap_utility_check.py +94 -0
- package/plugins/ima-claude/hooks/composer_autoload_check.py +70 -0
- package/plugins/ima-claude/hooks/docs_organization.py +104 -0
- package/plugins/ima-claude/hooks/enforce_rg_over_grep.py +56 -0
- package/plugins/ima-claude/hooks/fp_utility_check.py +90 -0
- package/plugins/ima-claude/hooks/hook_logger.py +69 -0
- package/plugins/ima-claude/hooks/hooks.json +239 -0
- package/plugins/ima-claude/hooks/jira_issue_fetch.py +79 -0
- package/plugins/ima-claude/hooks/jquery_in_wordpress.py +92 -0
- package/plugins/ima-claude/hooks/memory_bootstrap.py +79 -0
- package/plugins/ima-claude/hooks/memory_store_reminder.py +75 -0
- package/plugins/ima-claude/hooks/prompt_coach.py +125 -0
- package/plugins/ima-claude/hooks/prompt_coach_digest.md +48 -0
- package/plugins/ima-claude/hooks/prompt_coach_system.md +30 -0
- package/plugins/ima-claude/hooks/sequential_thinking_check.py +81 -0
- package/plugins/ima-claude/hooks/serena_over_grep.py +96 -0
- package/plugins/ima-claude/hooks/serena_over_read.py +66 -0
- package/plugins/ima-claude/hooks/serena_project_check.py +133 -0
- package/plugins/ima-claude/hooks/sql_injection_check.py +73 -0
- package/plugins/ima-claude/hooks/task_master_after_plan.py +31 -0
- package/plugins/ima-claude/hooks/task_master_before_impl.py +93 -0
- package/plugins/ima-claude/hooks/tavily_extract_advanced.py +48 -0
- package/plugins/ima-claude/hooks/vestige_before_external.py +86 -0
- package/plugins/ima-claude/hooks/webfetch_to_tavily.py +42 -0
- package/plugins/ima-claude/hooks/websearch_to_tavily.py +41 -0
- package/plugins/ima-claude/hooks/wp_security_check.py +150 -0
- package/plugins/ima-claude/personalities/README.md +45 -0
- package/plugins/ima-claude/personalities/enable-40k.md +69 -0
- package/plugins/ima-claude/personalities/enable-templars.md +69 -0
- package/plugins/ima-claude/skills/.research-summary.md +340 -0
- package/plugins/ima-claude/skills/architect/SKILL.md +304 -0
- package/plugins/ima-claude/skills/compound-bridge/SKILL.md +200 -0
- package/plugins/ima-claude/skills/discourse/SKILL.md +440 -0
- package/plugins/ima-claude/skills/discourse-admin/SKILL.md +192 -0
- package/plugins/ima-claude/skills/discourse-admin/references/api-endpoints.md +441 -0
- package/plugins/ima-claude/skills/discourse-admin/references/gotchas.md +107 -0
- package/plugins/ima-claude/skills/discourse-admin/references/staging-defaults.md +98 -0
- package/plugins/ima-claude/skills/discourse-admin/scripts/discourse-admin.py +319 -0
- package/plugins/ima-claude/skills/docs-organize/SKILL.md +254 -0
- package/plugins/ima-claude/skills/docs-organize/templates/active-README.md +50 -0
- package/plugins/ima-claude/skills/docs-organize/templates/archive-README.md +57 -0
- package/plugins/ima-claude/skills/docs-organize/templates/docs-README.md +43 -0
- package/plugins/ima-claude/skills/docs-organize/templates/phase-archive-README.md +83 -0
- package/plugins/ima-claude/skills/docs-organize/templates/section-README.md +48 -0
- package/plugins/ima-claude/skills/docs-organize/templates/transient-README.md +79 -0
- package/plugins/ima-claude/skills/docs-organize/templates/transient-gitignore +9 -0
- package/plugins/ima-claude/skills/ember-discourse/SKILL.md +496 -0
- package/plugins/ima-claude/skills/functional-programmer/SKILL.md +258 -0
- package/plugins/ima-claude/skills/ima-bootstrap/SKILL.md +278 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/bootstrap-patterns.md +356 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/ima-brand.md +273 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/theme-integration.md +212 -0
- package/plugins/ima-claude/skills/ima-brand/SKILL.md +108 -0
- package/plugins/ima-claude/skills/ima-brand/references/brand-identity.md +140 -0
- package/plugins/ima-claude/skills/ima-brand/references/digital-standards.md +180 -0
- package/plugins/ima-claude/skills/ima-brand/references/visual-system.md +173 -0
- package/plugins/ima-claude/skills/ima-forms-expert/SKILL.md +175 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/container-components.md +154 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/examples.md +328 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/field-components.md +298 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/form-factory.md +193 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/quick-reference.md +153 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/validation-engine.md +336 -0
- package/plugins/ima-claude/skills/jira-checkpoint/SKILL.md +178 -0
- package/plugins/ima-claude/skills/jquery/SKILL.md +413 -0
- package/plugins/ima-claude/skills/js-fp/SKILL.md +463 -0
- package/plugins/ima-claude/skills/js-fp/core-principles.md +487 -0
- package/plugins/ima-claude/skills/js-fp/examples/pure-functions.js +260 -0
- package/plugins/ima-claude/skills/js-fp/examples/tests/pure-functions.test.js +262 -0
- package/plugins/ima-claude/skills/js-fp/references/anti-patterns.md +120 -0
- package/plugins/ima-claude/skills/js-fp/references/performance-patterns.md +116 -0
- package/plugins/ima-claude/skills/js-fp/references/testing-patterns.md +134 -0
- package/plugins/ima-claude/skills/js-fp-api/SKILL.md +280 -0
- package/plugins/ima-claude/skills/js-fp-api/examples/crud-endpoint.js +258 -0
- package/plugins/ima-claude/skills/js-fp-api/references/middleware-patterns.md +134 -0
- package/plugins/ima-claude/skills/js-fp-api/references/security-sql.md +110 -0
- package/plugins/ima-claude/skills/js-fp-api/references/validation-patterns.md +165 -0
- package/plugins/ima-claude/skills/js-fp-react/SKILL.md +447 -0
- package/plugins/ima-claude/skills/js-fp-react/examples/ProductCard.tsx +65 -0
- package/plugins/ima-claude/skills/js-fp-react/references/hooks-advanced.md +136 -0
- package/plugins/ima-claude/skills/js-fp-react/references/performance-patterns.md +175 -0
- package/plugins/ima-claude/skills/js-fp-vue/SKILL.md +322 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/complete-examples.md +397 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/composables-advanced.md +282 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/reactivity-patterns.md +348 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/testing.md +314 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/SKILL.md +301 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/ajax-patterns.md +192 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/event-patterns.md +136 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/wp-integration.md +248 -0
- package/plugins/ima-claude/skills/livecanvas/SKILL.md +209 -0
- package/plugins/ima-claude/skills/livecanvas/references/livecanvas-features.md +311 -0
- package/plugins/ima-claude/skills/livecanvas/references/loops-and-logic.md +730 -0
- package/plugins/ima-claude/skills/livecanvas/references/picostrap.md +227 -0
- package/plugins/ima-claude/skills/mcp-atlassian/SKILL.md +339 -0
- package/plugins/ima-claude/skills/mcp-context7/SKILL.md +109 -0
- package/plugins/ima-claude/skills/mcp-memory/SKILL.md +182 -0
- package/plugins/ima-claude/skills/mcp-qdrant/SKILL.md +233 -0
- package/plugins/ima-claude/skills/mcp-sequential/SKILL.md +149 -0
- package/plugins/ima-claude/skills/mcp-serena/SKILL.md +174 -0
- package/plugins/ima-claude/skills/mcp-tavily/SKILL.md +118 -0
- package/plugins/ima-claude/skills/mcp-vestige/SKILL.md +259 -0
- package/plugins/ima-claude/skills/php-authnet/SKILL.md +275 -0
- package/plugins/ima-claude/skills/php-authnet/references/api-reference.md +624 -0
- package/plugins/ima-claude/skills/php-authnet/references/sandbox-testing.md +424 -0
- package/plugins/ima-claude/skills/php-fp/SKILL.md +333 -0
- package/plugins/ima-claude/skills/php-fp/examples/pure-functions.php +403 -0
- package/plugins/ima-claude/skills/php-fp/examples/tests/PureFunctionsTest.php +515 -0
- package/plugins/ima-claude/skills/php-fp/references/core-principles.md +277 -0
- package/plugins/ima-claude/skills/php-fp/references/testing-patterns.md +374 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/SKILL.md +216 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/fp-patterns.md +275 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/plugin-architecture.md +295 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/security-examples.md +203 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/testing-strategy.md +259 -0
- package/plugins/ima-claude/skills/phpunit-wp/SKILL.md +716 -0
- package/plugins/ima-claude/skills/playwright/SKILL.md +434 -0
- package/plugins/ima-claude/skills/playwright/references/accessibility-testing.md +153 -0
- package/plugins/ima-claude/skills/playwright/references/ci-cd.md +268 -0
- package/plugins/ima-claude/skills/playwright/references/network-mocking.md +270 -0
- package/plugins/ima-claude/skills/playwright/references/visual-regression.md +215 -0
- package/plugins/ima-claude/skills/py-fp/SKILL.md +663 -0
- package/plugins/ima-claude/skills/py-fp/examples/pure-functions.py +185 -0
- package/plugins/ima-claude/skills/py-fp/examples/tests/test_pure_functions.py +244 -0
- package/plugins/ima-claude/skills/py-fp/references/core-principles.md +381 -0
- package/plugins/ima-claude/skills/py-fp/references/testing-patterns.md +283 -0
- package/plugins/ima-claude/skills/quasar-fp/SKILL.md +327 -0
- package/plugins/ima-claude/skills/quasar-fp/metadata.json +85 -0
- package/plugins/ima-claude/skills/quasar-fp/references/component-patterns.md +257 -0
- package/plugins/ima-claude/skills/quasar-fp/references/theme-integration.md +233 -0
- package/plugins/ima-claude/skills/quasar-fp/references/utility-classes.md +237 -0
- package/plugins/ima-claude/skills/quickstart/SKILL.md +129 -0
- package/plugins/ima-claude/skills/rails/SKILL.md +359 -0
- package/plugins/ima-claude/skills/resume-session/SKILL.md +68 -0
- package/plugins/ima-claude/skills/rg/SKILL.md +205 -0
- package/plugins/ima-claude/skills/ruby-fp/SKILL.md +336 -0
- package/plugins/ima-claude/skills/save-session/SKILL.md +81 -0
- package/plugins/ima-claude/skills/scorecard/SKILL.md +96 -0
- package/plugins/ima-claude/skills/skill-analyzer/SKILL.md +127 -0
- package/plugins/ima-claude/skills/skill-analyzer/references/advanced-checklist.md +44 -0
- package/plugins/ima-claude/skills/skill-analyzer/references/core-checklist.md +60 -0
- package/plugins/ima-claude/skills/skill-analyzer/scripts/analyze_skill.py +418 -0
- package/plugins/ima-claude/skills/skill-creator/LICENSE.txt +202 -0
- package/plugins/ima-claude/skills/skill-creator/SKILL.md +343 -0
- package/plugins/ima-claude/skills/skill-creator/references/output-patterns.md +82 -0
- package/plugins/ima-claude/skills/skill-creator/references/workflows.md +28 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/init_skill.py +303 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/package_skill.py +110 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/plugins/ima-claude/skills/task-master/SKILL.md +51 -0
- package/plugins/ima-claude/skills/task-planner/SKILL.md +228 -0
- package/plugins/ima-claude/skills/task-runner/SKILL.md +192 -0
- package/plugins/ima-claude/skills/unit-testing/SKILL.md +198 -0
- package/plugins/ima-claude/skills/unit-testing/references/mock-patterns.md +181 -0
- package/plugins/ima-claude/skills/unit-testing/references/tdd-workflow.md +177 -0
- package/plugins/ima-claude/skills/unit-testing/references/test-strategy.md +126 -0
- package/plugins/ima-claude/skills/wp-local/SKILL.md +246 -0
- package/plugins/ima-claude/skills/wp-local/references/configuration.md +198 -0
- package/plugins/ima-claude/skills/wp-local/references/wp-cli-reference.md +406 -0
- 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
|
+
}
|