imhcode 1.0.2 → 1.0.3
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/bin/imhcode.js +41 -42
- package/package.json +1 -1
package/bin/imhcode.js
CHANGED
|
@@ -1662,28 +1662,40 @@ async function generateSprintPlans(cwd, userPrompt, brainstormContent, config) {
|
|
|
1662
1662
|
const testingModeRaw = extractAnswer(brainstormContent, 'Q31', 'A').trim().toUpperCase().charAt(0);
|
|
1663
1663
|
const detectedTesting = testingModeRaw === 'B' ? 'balanced' : testingModeRaw === 'C' ? 'strict' : 'fast';
|
|
1664
1664
|
|
|
1665
|
-
|
|
1666
|
-
const
|
|
1667
|
-
const
|
|
1668
|
-
const
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
const
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
const
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1665
|
+
const ansQ8 = extractAnswer(brainstormContent, 'Q8', 'Dark Premium').trim();
|
|
1666
|
+
const ansQ9 = extractAnswer(brainstormContent, 'Q9', 'Modern SaaS').trim();
|
|
1667
|
+
const ansQ12 = extractAnswer(brainstormContent, 'Q12', 'system toggle').toLowerCase();
|
|
1668
|
+
const ansQ14 = extractAnswer(brainstormContent, 'Q14', 'no').toLowerCase();
|
|
1669
|
+
const ansQ16 = extractAnswer(brainstormContent, 'Q16', 'no').toLowerCase();
|
|
1670
|
+
const ansQ21 = extractAnswer(brainstormContent, 'Q21', 'no').toLowerCase();
|
|
1671
|
+
const ansQ22 = extractAnswer(brainstormContent, 'Q22', 'no').toLowerCase();
|
|
1672
|
+
const ansQ25 = extractAnswer(brainstormContent, 'Q25', 'no').toLowerCase();
|
|
1673
|
+
|
|
1674
|
+
const hasFrontend = true; // Always assume frontend
|
|
1675
|
+
|
|
1676
|
+
// Robust scope detection: only true if user answer is not "no", "none", or standard default fallback placeholder
|
|
1677
|
+
const hasBackend = (() => {
|
|
1678
|
+
if (ansQ16.includes('no') || ansQ16.includes('none') || ansQ16.includes('edit if needed') || ansQ16.trim() === '') {
|
|
1679
|
+
return false;
|
|
1680
|
+
}
|
|
1681
|
+
return true;
|
|
1681
1682
|
})();
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1683
|
+
|
|
1684
|
+
const hasMobile = (() => {
|
|
1685
|
+
if (ansQ25.includes('no') || ansQ25.includes('none') || ansQ25.includes('edit if needed') || ansQ25.trim() === '') {
|
|
1686
|
+
return false;
|
|
1687
|
+
}
|
|
1688
|
+
return true;
|
|
1685
1689
|
})();
|
|
1686
1690
|
|
|
1691
|
+
const needsWorktrees = ansQ14.includes('yes') || ansQ14.includes('true');
|
|
1692
|
+
const hasPayments = !ansQ22.includes('no') && !ansQ22.includes('none') && !ansQ22.includes('edit if needed') && ansQ22.trim().length > 0;
|
|
1693
|
+
const hasRealtime = !ansQ21.includes('no') && !ansQ21.includes('none') && !ansQ21.includes('edit if needed') && ansQ21.trim().length > 0;
|
|
1694
|
+
|
|
1695
|
+
const designStyle = ansQ9.replace(/\*\(.*?\)\*/g, '').trim() || 'Modern SaaS';
|
|
1696
|
+
const colorStyle = ansQ8.replace(/\*\(.*?\)\*/g, '').trim() || 'Dark Premium';
|
|
1697
|
+
const darkmode = ansQ12.replace(/\*\(.*?\)\*/g, '').trim() || 'system toggle';
|
|
1698
|
+
|
|
1687
1699
|
// Save testing mode to config
|
|
1688
1700
|
if (config) {
|
|
1689
1701
|
config.testing_mode = detectedTesting;
|
|
@@ -1691,21 +1703,7 @@ async function generateSprintPlans(cwd, userPrompt, brainstormContent, config) {
|
|
|
1691
1703
|
try { fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8'); } catch {}
|
|
1692
1704
|
}
|
|
1693
1705
|
|
|
1694
|
-
//
|
|
1695
|
-
if (hasFrontend) {
|
|
1696
|
-
const frontendDir = path.join(cwd, 'frontend');
|
|
1697
|
-
if (!fs.existsSync(frontendDir)) {
|
|
1698
|
-
fs.mkdirSync(frontendDir, { recursive: true });
|
|
1699
|
-
console.log(` 📁 Created frontend/ (scope confirmed in brainstorming)`);
|
|
1700
|
-
}
|
|
1701
|
-
}
|
|
1702
|
-
if (hasBackend) {
|
|
1703
|
-
const backendDir = path.join(cwd, 'backend');
|
|
1704
|
-
if (!fs.existsSync(backendDir)) {
|
|
1705
|
-
fs.mkdirSync(backendDir, { recursive: true });
|
|
1706
|
-
console.log(` 📁 Created backend/ (scope confirmed in brainstorming)`);
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1706
|
+
// Create workspace directories lazily (only worktrees since it's a layout helper, NOT frontend/backend which must remain empty for official CLI scaffolding)
|
|
1709
1707
|
if (needsWorktrees) {
|
|
1710
1708
|
const wtDir = path.join(cwd, '.worktrees');
|
|
1711
1709
|
if (!fs.existsSync(wtDir)) {
|
|
@@ -1716,7 +1714,7 @@ async function generateSprintPlans(cwd, userPrompt, brainstormContent, config) {
|
|
|
1716
1714
|
|
|
1717
1715
|
// Generate PROJECT_BRIEF.md
|
|
1718
1716
|
const briefContent = generateProjectBrief(userPrompt, brainstormContent, {
|
|
1719
|
-
hasFrontend, hasBackend, hasMobile, designStyle, colorStyle, detectedTesting
|
|
1717
|
+
hasFrontend, hasBackend, hasMobile, designStyle, colorStyle, darkmode, detectedTesting
|
|
1720
1718
|
});
|
|
1721
1719
|
fs.writeFileSync(path.join(cwd, BRIEF_MD), briefContent, 'utf8');
|
|
1722
1720
|
console.log(` ✅ Created PROJECT_BRIEF.md`);
|
|
@@ -1724,7 +1722,7 @@ async function generateSprintPlans(cwd, userPrompt, brainstormContent, config) {
|
|
|
1724
1722
|
// Try LLM-powered sprint generation first (Fix 0)
|
|
1725
1723
|
const llmSprintResult = await tryLLMSprintGeneration(
|
|
1726
1724
|
cwd, userPrompt, brainstormContent, config,
|
|
1727
|
-
{ hasFrontend, hasBackend, hasMobile, hasPayments, hasRealtime, designStyle, colorStyle, detectedTesting, needsWorktrees }
|
|
1725
|
+
{ hasFrontend, hasBackend, hasMobile, hasPayments, hasRealtime, designStyle, colorStyle, darkmode, detectedTesting, needsWorktrees }
|
|
1728
1726
|
);
|
|
1729
1727
|
|
|
1730
1728
|
let lastSprintNum;
|
|
@@ -1736,7 +1734,7 @@ async function generateSprintPlans(cwd, userPrompt, brainstormContent, config) {
|
|
|
1736
1734
|
// Fix 5: Fallback to smart static generation
|
|
1737
1735
|
lastSprintNum = await generateStaticSprintPlans(
|
|
1738
1736
|
cwd,
|
|
1739
|
-
{ hasFrontend, hasBackend, hasMobile, hasPayments, hasRealtime, designStyle, colorStyle, detectedTesting },
|
|
1737
|
+
{ hasFrontend, hasBackend, hasMobile, hasPayments, hasRealtime, designStyle, colorStyle, darkmode, detectedTesting },
|
|
1740
1738
|
config
|
|
1741
1739
|
);
|
|
1742
1740
|
}
|
|
@@ -1750,7 +1748,7 @@ async function generateSprintPlans(cwd, userPrompt, brainstormContent, config) {
|
|
|
1750
1748
|
|
|
1751
1749
|
// Update compact context
|
|
1752
1750
|
const contextContent = buildContextContent(userPrompt, {
|
|
1753
|
-
hasFrontend, hasBackend, hasMobile, detectedTesting, lastSprintNum, designStyle, colorStyle
|
|
1751
|
+
hasFrontend, hasBackend, hasMobile, detectedTesting, lastSprintNum, designStyle, colorStyle, darkmode
|
|
1754
1752
|
});
|
|
1755
1753
|
fs.mkdirSync(path.join(cwd, LOCAL_DIR_NAME), { recursive: true });
|
|
1756
1754
|
fs.writeFileSync(path.join(cwd, CONTEXT_MD), contextContent, 'utf8');
|
|
@@ -1761,7 +1759,7 @@ async function generateSprintPlans(cwd, userPrompt, brainstormContent, config) {
|
|
|
1761
1759
|
* Attempt LLM-generated sprint plans. Returns { sprintCount } on success, null on failure.
|
|
1762
1760
|
*/
|
|
1763
1761
|
async function tryLLMSprintGeneration(cwd, userPrompt, brainstormContent, config, scope) {
|
|
1764
|
-
const { hasFrontend, hasBackend, hasMobile, hasPayments, hasRealtime, designStyle, colorStyle, detectedTesting } = scope;
|
|
1762
|
+
const { hasFrontend, hasBackend, hasMobile, hasPayments, hasRealtime, designStyle, colorStyle, darkmode, detectedTesting } = scope;
|
|
1765
1763
|
|
|
1766
1764
|
const agentList = [
|
|
1767
1765
|
'planner (planning)', 'designer (frontend)', 'nextjs-executor (frontend)', 'react-executor (frontend)',
|
|
@@ -1788,7 +1786,7 @@ ${userPrompt}
|
|
|
1788
1786
|
${brainstormContent}
|
|
1789
1787
|
|
|
1790
1788
|
## Scope
|
|
1791
|
-
- Frontend: ${hasFrontend ? 'YES' : 'NO'} (Design style: ${designStyle}, Colors: ${colorStyle})
|
|
1789
|
+
- Frontend: ${hasFrontend ? 'YES' : 'NO'} (Design style: ${designStyle}, Colors: ${colorStyle}, Dark Mode Strategy: ${darkmode})
|
|
1792
1790
|
- Backend: ${hasBackend ? 'YES' : 'NO'}
|
|
1793
1791
|
- Mobile: ${hasMobile ? 'YES' : 'NO'}
|
|
1794
1792
|
- Payments: ${hasPayments ? 'YES' : 'NO'}
|
|
@@ -1838,7 +1836,8 @@ Return ONLY this JSON structure (no markdown, no explanation):
|
|
|
1838
1836
|
8. Max 6 tasks per sprint for clean execution
|
|
1839
1837
|
9. If design style is Glassmorphism/Neumorphism — include a designer task for design tokens in Sprint 1
|
|
1840
1838
|
10. If payments needed — include payment integration task in a sprint
|
|
1841
|
-
11. If realtime needed — include WebSocket/SSE task in a sprint
|
|
1839
|
+
11. If realtime needed — include WebSocket/SSE task in a sprint
|
|
1840
|
+
12. Under Frontend, STRICTLY respect the Dark Mode Strategy: if strategy is "light only", do NOT generate any dark mode setups, variables, toggles or dark styles. If strategy is "always dark", design the UI strictly for dark backgrounds.`;
|
|
1842
1841
|
|
|
1843
1842
|
const llmOutput = await invokePlanningLLM(llmPrompt, config, cwd);
|
|
1844
1843
|
if (!llmOutput) return null;
|
|
@@ -2021,7 +2020,7 @@ ${tasks.map((t, i) => `- [ ] Task ${i+1}: ${t.task} [\`${t.agent}\`]`).join('\n'
|
|
|
2021
2020
|
# Model: ${routedModel || 'default'} via ${routedEngine || 'default'}
|
|
2022
2021
|
# Tier: ${t.tier}
|
|
2023
2022
|
CWD="$(cd "$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
|
|
2024
|
-
cd "$CWD
|
|
2023
|
+
cd "$CWD/../../.."
|
|
2025
2024
|
|
|
2026
2025
|
TASK="${taskDesc.replace(/"/g, '\\"')}"
|
|
2027
2026
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "imhcode",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "IMH-Code — Imam Hussain Coding Harness Platform. A fast-first multi-agent AI coding framework with intelligent model routing. 19 generic role-based agents (planner, nextjs-executor, laravel-executor, etc.), configurable testing strategy, and 7 token-saving optimizations for rapid MVP development.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|