hone-ai 0.14.0 → 0.15.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/README.md +12 -2
- package/package.json +1 -1
- package/src/agents-md-generator.ts +115 -7
- package/src/prompt.ts +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
# hone
|
|
1
|
+
# hone-ai
|
|
2
2
|
|
|
3
3
|
**AI Coding Agent Orchestrator** — Automatically implement features from requirements using AI agents.
|
|
4
4
|
|
|
5
5
|
Transform feature ideas into working code through autonomous development with human oversight.
|
|
6
6
|
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
When working on long running tasks with agents, their context window fills up and the performance degrades. To mitigate this, hone-ai provides a solution starting each new iteration with a fresh context window just passing in a summary of the progress made so far on the specific PRD, repository architecture and gotchas, and any other relevant information.
|
|
10
|
+
|
|
11
|
+
Everything else is stripped away, leaving only the essential information needed for the next iteration. This approach helps maintain optimal performance and reduces the likelihood of context drift.
|
|
12
|
+
|
|
13
|
+
It's a surprisingly powerful process.
|
|
14
|
+
|
|
7
15
|
## Quick Start
|
|
8
16
|
|
|
9
17
|
1. **Install hone**
|
|
@@ -12,6 +20,8 @@ Transform feature ideas into working code through autonomous development with hu
|
|
|
12
20
|
npm install -g hone-ai
|
|
13
21
|
# or
|
|
14
22
|
bun add -g hone-ai
|
|
23
|
+
# or
|
|
24
|
+
# download binary or build from source, instructions below
|
|
15
25
|
```
|
|
16
26
|
|
|
17
27
|
2. **Install an AI agent** ([OpenCode](https://opencode.ai) or [Claude Code](https://docs.anthropic.com/claude/docs/claude-code))
|
|
@@ -27,7 +37,7 @@ That's it! You're ready to use hone.
|
|
|
27
37
|
## Common Workflow
|
|
28
38
|
|
|
29
39
|
```bash
|
|
30
|
-
# 1. Generate project documentation (if no AGENTS.md exists)
|
|
40
|
+
# 1. Generate project documentation (if no AGENTS.md exists). A one time thing.
|
|
31
41
|
hone agents-md
|
|
32
42
|
|
|
33
43
|
# 2. Create a PRD from your feature description
|
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from './config'
|
|
13
13
|
import { readFile, writeFile, mkdir } from 'fs/promises'
|
|
14
14
|
import { join } from 'path'
|
|
15
|
-
import { existsSync } from 'fs'
|
|
15
|
+
import { existsSync, readFileSync } from 'fs'
|
|
16
16
|
import { AgentClient } from './agent-client'
|
|
17
17
|
import { log, logError, logVerbose, logVerboseError } from './logger'
|
|
18
18
|
|
|
@@ -424,12 +424,103 @@ async function executeParallelScanning(
|
|
|
424
424
|
return scanResults
|
|
425
425
|
}
|
|
426
426
|
|
|
427
|
+
/**
|
|
428
|
+
* Generate project-specific feedback commands based on package.json and project files
|
|
429
|
+
*/
|
|
430
|
+
function generateFeedbackContent(projectPath: string, analysis: ProjectAnalysis): string {
|
|
431
|
+
const feedbackCommands: string[] = []
|
|
432
|
+
|
|
433
|
+
// Read package.json to get actual project scripts
|
|
434
|
+
let packageJsonScripts: Record<string, string> = {}
|
|
435
|
+
try {
|
|
436
|
+
const packageJsonPath = join(projectPath, 'package.json')
|
|
437
|
+
if (existsSync(packageJsonPath)) {
|
|
438
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'))
|
|
439
|
+
packageJsonScripts = packageJson.scripts || {}
|
|
440
|
+
}
|
|
441
|
+
} catch (error) {
|
|
442
|
+
logVerbose('[AgentsMd] Could not read package.json scripts')
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Unit tests - use actual package.json scripts or detected framework
|
|
446
|
+
if (packageJsonScripts.test) {
|
|
447
|
+
feedbackCommands.push(`**Unit Tests:** \`npm run test\` or \`${packageJsonScripts.test}\``)
|
|
448
|
+
} else if (analysis.testingFrameworks.some(fw => fw.toLowerCase().includes('jest'))) {
|
|
449
|
+
feedbackCommands.push('**Unit Tests:** `npm test` or `jest`')
|
|
450
|
+
} else if (analysis.testingFrameworks.some(fw => fw.toLowerCase().includes('pytest'))) {
|
|
451
|
+
feedbackCommands.push('**Unit Tests:** `pytest`')
|
|
452
|
+
} else if (analysis.testingFrameworks.some(fw => fw.toLowerCase().includes('bun'))) {
|
|
453
|
+
feedbackCommands.push('**Unit Tests:** `bun test`')
|
|
454
|
+
} else {
|
|
455
|
+
feedbackCommands.push('**Unit Tests:** `bun test`')
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// Code formatting - use actual package.json scripts if available
|
|
459
|
+
if (packageJsonScripts.format) {
|
|
460
|
+
feedbackCommands.push(
|
|
461
|
+
`**Code Formatting:** \`npm run format\` or \`${packageJsonScripts.format}\``
|
|
462
|
+
)
|
|
463
|
+
} else if (
|
|
464
|
+
analysis.languages.some(
|
|
465
|
+
lang => lang.toLowerCase().includes('typescript') || lang.toLowerCase().includes('javascript')
|
|
466
|
+
)
|
|
467
|
+
) {
|
|
468
|
+
feedbackCommands.push('**Code Formatting:** `prettier --write "**/*.{ts,tsx,js,jsx}"`')
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// Code linting - check for lint script or eslint
|
|
472
|
+
if (packageJsonScripts.lint) {
|
|
473
|
+
feedbackCommands.push(`**Code Linting:** \`npm run lint\` or \`${packageJsonScripts.lint}\``)
|
|
474
|
+
} else if (
|
|
475
|
+
analysis.languages.some(
|
|
476
|
+
lang => lang.toLowerCase().includes('typescript') || lang.toLowerCase().includes('javascript')
|
|
477
|
+
)
|
|
478
|
+
) {
|
|
479
|
+
feedbackCommands.push('**Code Linting:** `eslint . --fix`')
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// YAML formatting and linting from package.json scripts
|
|
483
|
+
if (packageJsonScripts['format:yaml']) {
|
|
484
|
+
feedbackCommands.push(
|
|
485
|
+
`**YAML Formatting:** \`npm run format:yaml\` or \`${packageJsonScripts['format:yaml']}\``
|
|
486
|
+
)
|
|
487
|
+
}
|
|
488
|
+
if (packageJsonScripts['lint:yaml']) {
|
|
489
|
+
feedbackCommands.push(
|
|
490
|
+
`**YAML Linting:** \`npm run lint:yaml\` or \`${packageJsonScripts['lint:yaml']}\``
|
|
491
|
+
)
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// Build command - use actual package.json scripts or detected build systems
|
|
495
|
+
if (packageJsonScripts.build) {
|
|
496
|
+
feedbackCommands.push(`**Build:** \`npm run build\` or \`${packageJsonScripts.build}\``)
|
|
497
|
+
} else if (analysis.buildSystems.length > 0) {
|
|
498
|
+
const buildSystems = analysis.buildSystems.map(sys => sys.toLowerCase())
|
|
499
|
+
if (buildSystems.some(sys => sys.includes('bun'))) {
|
|
500
|
+
feedbackCommands.push('**Build:** `bun run build`')
|
|
501
|
+
} else if (buildSystems.some(sys => sys.includes('npm') || sys.includes('yarn'))) {
|
|
502
|
+
feedbackCommands.push('**Build:** `npm run build` or `yarn build`')
|
|
503
|
+
} else if (buildSystems.some(sys => sys.includes('maven'))) {
|
|
504
|
+
feedbackCommands.push('**Build:** `mvn clean compile`')
|
|
505
|
+
} else if (buildSystems.some(sys => sys.includes('gradle'))) {
|
|
506
|
+
feedbackCommands.push('**Build:** `./gradlew build`')
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
return `Run these commands to validate your changes before committing:
|
|
511
|
+
|
|
512
|
+
${feedbackCommands.join('\n\n')}
|
|
513
|
+
|
|
514
|
+
These commands are project-specific based on the configured scripts and tooling.`
|
|
515
|
+
}
|
|
516
|
+
|
|
427
517
|
/**
|
|
428
518
|
* Create adaptive template sections based on discovered tech stack
|
|
429
519
|
*/
|
|
430
520
|
function createTemplateSections(
|
|
431
521
|
scanResults: Record<keyof typeof DISCOVERY_PROMPTS, string>,
|
|
432
|
-
analysis: ProjectAnalysis
|
|
522
|
+
analysis: ProjectAnalysis,
|
|
523
|
+
projectPath: string
|
|
433
524
|
): TemplateSection[] {
|
|
434
525
|
const sections: TemplateSection[] = []
|
|
435
526
|
|
|
@@ -500,6 +591,14 @@ function createTemplateSections(
|
|
|
500
591
|
})
|
|
501
592
|
}
|
|
502
593
|
|
|
594
|
+
// Add feedback section inline at the top with project-specific commands
|
|
595
|
+
sections.push({
|
|
596
|
+
title: 'Feedback Instructions',
|
|
597
|
+
content: generateFeedbackContent(projectPath, analysis),
|
|
598
|
+
priority: 0, // Highest priority to appear at top
|
|
599
|
+
detailFile: undefined, // Force inline, never create separate file
|
|
600
|
+
})
|
|
601
|
+
|
|
503
602
|
// Sort by priority
|
|
504
603
|
return sections.sort((a, b) => a.priority - b.priority)
|
|
505
604
|
}
|
|
@@ -543,16 +642,25 @@ ${section.content}
|
|
|
543
642
|
)
|
|
544
643
|
}
|
|
545
644
|
|
|
546
|
-
// Compact version with references to ${AGENTS_DOCS_DIR}/ files
|
|
645
|
+
// Compact version with references to ${AGENTS_DOCS_DIR}/ files, but keep inline sections inline
|
|
547
646
|
const compactSections = sections
|
|
548
|
-
.map(
|
|
549
|
-
section
|
|
647
|
+
.map(section => {
|
|
648
|
+
// If section has no detailFile, render it inline (like Feedback Instructions)
|
|
649
|
+
if (!section.detailFile) {
|
|
650
|
+
return `## ${section.title}
|
|
651
|
+
|
|
652
|
+
${section.content}
|
|
653
|
+
`
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// Otherwise, use compact format with reference to detail file
|
|
657
|
+
return `## ${section.title}
|
|
550
658
|
|
|
551
659
|
${getFirstSentence(section.content)}
|
|
552
660
|
|
|
553
661
|
See [@${AGENTS_DOCS_DIR}/${section.detailFile}](${AGENTS_DOCS_DIR}/${section.detailFile}) for detailed information.
|
|
554
662
|
`
|
|
555
|
-
)
|
|
663
|
+
})
|
|
556
664
|
.join('\n')
|
|
557
665
|
|
|
558
666
|
return (
|
|
@@ -680,7 +788,7 @@ async function generateContent(
|
|
|
680
788
|
log('-'.repeat(80))
|
|
681
789
|
|
|
682
790
|
// Create adaptive template sections based on discovered tech stack
|
|
683
|
-
const sections = createTemplateSections(scanResults, analysis)
|
|
791
|
+
const sections = createTemplateSections(scanResults, analysis, projectPath)
|
|
684
792
|
|
|
685
793
|
// Generate initial content to check line count
|
|
686
794
|
const fullContent = generateCompactContent(sections, false)
|
package/src/prompt.ts
CHANGED
|
@@ -262,7 +262,7 @@ ${reviewFeedback || 'No review feedback provided (review was skipped or approved
|
|
|
262
262
|
Next Task: <next-task-id> or "All tasks complete"
|
|
263
263
|
\`\`\`
|
|
264
264
|
|
|
265
|
-
5. **Update AGENTS.md**
|
|
265
|
+
5. **Update AGENTS.md file**
|
|
266
266
|
- Add useful learnings and gotchas under appropriate heading
|
|
267
267
|
- Be terse - only add truly useful info that future agents need
|
|
268
268
|
- Don't duplicate existing info
|