hone-ai 0.10.0 → 0.12.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 +27 -9
- package/package.json +2 -1
- package/src/agents-md-generator.ts +8 -2
- package/src/config.ts +53 -1
- package/src/index.ts +19 -5
package/README.md
CHANGED
|
@@ -22,14 +22,28 @@ Transform feature ideas into working code through autonomous development with hu
|
|
|
22
22
|
hone init
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
That's it! You're ready to use hone.
|
|
26
|
+
|
|
27
|
+
## Common Workflow
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# 1. Generate project documentation (if no AGENTS.md exists)
|
|
31
|
+
hone agents-md
|
|
32
|
+
|
|
33
|
+
# 2. Create a PRD from your feature description
|
|
34
|
+
hone prd "Add user login with email and password"
|
|
31
35
|
|
|
32
|
-
|
|
36
|
+
# 3. Manually review the generated PRD
|
|
37
|
+
# Edit .plans/prd-user-login.md as needed
|
|
38
|
+
|
|
39
|
+
# 4. Generate tasks from the PRD
|
|
40
|
+
hone prd-to-tasks .plans/prd-user-login.md
|
|
41
|
+
|
|
42
|
+
# 5. Implement the feature
|
|
43
|
+
hone run .plans/tasks-user-login.yml -i 10
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
hone will implement the feature, run tests, and commit changes automatically.
|
|
33
47
|
|
|
34
48
|
## Prerequisites
|
|
35
49
|
|
|
@@ -77,14 +91,16 @@ cp hone-macos /usr/local/bin/hone # macOS
|
|
|
77
91
|
cp hone-linux /usr/local/bin/hone # Linux
|
|
78
92
|
```
|
|
79
93
|
|
|
80
|
-
##
|
|
94
|
+
## Commands
|
|
81
95
|
|
|
82
96
|
### Create and implement a feature
|
|
83
97
|
|
|
84
98
|
```bash
|
|
99
|
+
hone agents-md # Generate AGENTS.md (first time only)
|
|
85
100
|
hone prd "Feature description" # Generate requirements
|
|
101
|
+
# Review .plans/prd-<feature>.md manually
|
|
86
102
|
hone prd-to-tasks .plans/prd-feature.md # Generate tasks
|
|
87
|
-
hone run .plans/tasks-feature.yml -i
|
|
103
|
+
hone run .plans/tasks-feature.yml -i 10 # Implement tasks
|
|
88
104
|
```
|
|
89
105
|
|
|
90
106
|
### Reference files and URLs in PRDs
|
|
@@ -148,11 +164,13 @@ Each `hone run` executes multiple iterations of this cycle automatically.
|
|
|
148
164
|
When creating PRDs, you can reference files and URLs directly in your feature description:
|
|
149
165
|
|
|
150
166
|
**Local files:**
|
|
167
|
+
|
|
151
168
|
- `./docs/api-spec.md` - Read project documentation
|
|
152
169
|
- `src/components/Button.tsx` - Analyze existing components
|
|
153
170
|
- `./database/schema.sql` - Review database structure
|
|
154
171
|
|
|
155
172
|
**URLs:**
|
|
173
|
+
|
|
156
174
|
- `https://docs.stripe.com/api` - External API documentation
|
|
157
175
|
- `https://www.figma.com/design/123/App` - Design specifications
|
|
158
176
|
- `http://localhost:3000/dashboard` - Reference existing pages
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hone-ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "AI coding agent orchestrator - orchestrate AI agents to implement features based on PRDs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"hone": "src/index.ts"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
|
+
"test": "bun test",
|
|
36
37
|
"build": "bun run build:linux && bun run build:macos",
|
|
37
38
|
"format": "prettier --write \"**/*.ts\"",
|
|
38
39
|
"build:linux": "bun build --compile --minify --sourcemap --target=bun-linux-x64 ./src/index.ts --outfile hone-linux",
|
|
@@ -3,7 +3,13 @@
|
|
|
3
3
|
* Core module for generating project documentation for AI agents
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
loadConfig,
|
|
8
|
+
loadConfigWithoutCreation,
|
|
9
|
+
resolveModelForPhase,
|
|
10
|
+
type HoneConfig,
|
|
11
|
+
type AgentType,
|
|
12
|
+
} from './config'
|
|
7
13
|
import { readFile, writeFile, mkdir } from 'fs/promises'
|
|
8
14
|
import { join } from 'path'
|
|
9
15
|
import { existsSync } from 'fs'
|
|
@@ -729,7 +735,7 @@ export async function generateAgentsMd(
|
|
|
729
735
|
process.stdout.write('✓\n')
|
|
730
736
|
|
|
731
737
|
process.stdout.write('Loading configuration... ')
|
|
732
|
-
const config = await
|
|
738
|
+
const config = await loadConfigWithoutCreation()
|
|
733
739
|
process.stdout.write('✓\n')
|
|
734
740
|
|
|
735
741
|
logVerbose(
|
package/src/config.ts
CHANGED
|
@@ -21,8 +21,10 @@ export interface HoneConfig {
|
|
|
21
21
|
lintCommand?: string
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
export const DEFAULT_AGENT: AgentType = 'claude'
|
|
25
|
+
|
|
24
26
|
const DEFAULT_CONFIG: HoneConfig = {
|
|
25
|
-
defaultAgent:
|
|
27
|
+
defaultAgent: DEFAULT_AGENT,
|
|
26
28
|
models: {
|
|
27
29
|
opencode: 'claude-sonnet-4-20250514',
|
|
28
30
|
claude: 'claude-sonnet-4-20250514',
|
|
@@ -99,6 +101,56 @@ export async function resolveAgent(flagAgent?: string): Promise<AgentType> {
|
|
|
99
101
|
return config.defaultAgent
|
|
100
102
|
}
|
|
101
103
|
|
|
104
|
+
export async function resolveAgentWithoutConfigCreation(flagAgent?: string): Promise<AgentType> {
|
|
105
|
+
// Priority: flag > config (if exists) > default
|
|
106
|
+
if (flagAgent) {
|
|
107
|
+
if (!isValidAgent(flagAgent)) {
|
|
108
|
+
exitWithError(
|
|
109
|
+
'Error: Invalid agent',
|
|
110
|
+
`Agent "${flagAgent}" is not valid. Must be "opencode" or "claude".`
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
return flagAgent
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const configPath = getConfigPath()
|
|
117
|
+
if (existsSync(configPath)) {
|
|
118
|
+
try {
|
|
119
|
+
const content = await readFile(configPath, 'utf-8')
|
|
120
|
+
const config = yaml.load(content) as Partial<HoneConfig>
|
|
121
|
+
return config.defaultAgent || DEFAULT_AGENT
|
|
122
|
+
} catch (error) {
|
|
123
|
+
console.error('Error reading config, using default agent:', error)
|
|
124
|
+
return DEFAULT_AGENT
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return DEFAULT_AGENT
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export async function loadConfigWithoutCreation(): Promise<HoneConfig> {
|
|
132
|
+
const configPath = getConfigPath()
|
|
133
|
+
|
|
134
|
+
if (!existsSync(configPath)) {
|
|
135
|
+
// Return default config without creating the file
|
|
136
|
+
return DEFAULT_CONFIG
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
const content = await readFile(configPath, 'utf-8')
|
|
141
|
+
const config = yaml.load(content) as Partial<HoneConfig>
|
|
142
|
+
// Deep merge models to preserve defaults
|
|
143
|
+
return {
|
|
144
|
+
...DEFAULT_CONFIG,
|
|
145
|
+
...config,
|
|
146
|
+
models: { ...DEFAULT_CONFIG.models, ...config.models },
|
|
147
|
+
}
|
|
148
|
+
} catch (error) {
|
|
149
|
+
console.error('Error reading config, using defaults:', error)
|
|
150
|
+
return DEFAULT_CONFIG
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
102
154
|
export interface InitResult {
|
|
103
155
|
plansCreated: boolean
|
|
104
156
|
configCreated: boolean
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import { Command } from 'commander'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
loadConfig,
|
|
5
|
+
ensurePlansDir,
|
|
6
|
+
resolveAgent,
|
|
7
|
+
resolveAgentWithoutConfigCreation,
|
|
8
|
+
initProject,
|
|
9
|
+
} from './config'
|
|
4
10
|
import type { AgentType } from './config'
|
|
5
11
|
import { listPrds } from './prds'
|
|
6
12
|
import { listIncompleteTaskFiles } from './status'
|
|
@@ -11,11 +17,12 @@ import packageJson from '../package.json'
|
|
|
11
17
|
|
|
12
18
|
const program = new Command()
|
|
13
19
|
|
|
14
|
-
// Get command name to avoid auto-init on 'init'
|
|
20
|
+
// Get command name to avoid auto-init on 'init' and 'agents-md' commands
|
|
15
21
|
const isInitCommand = process.argv[2] === 'init'
|
|
22
|
+
const isAgentsMdCommand = process.argv[2] === 'agents-md'
|
|
16
23
|
|
|
17
|
-
// Auto-initialize for all commands except 'init'
|
|
18
|
-
if (!isInitCommand) {
|
|
24
|
+
// Auto-initialize for all commands except 'init' and 'agents-md'
|
|
25
|
+
if (!isInitCommand && !isAgentsMdCommand) {
|
|
19
26
|
ensurePlansDir()
|
|
20
27
|
loadConfig().catch(console.error)
|
|
21
28
|
}
|
|
@@ -29,6 +36,13 @@ program
|
|
|
29
36
|
.addHelpText(
|
|
30
37
|
'after',
|
|
31
38
|
`
|
|
39
|
+
Common Workflow:
|
|
40
|
+
hone agents-md # Generate AGENTS.md (if none exists)
|
|
41
|
+
hone prd "your feature description" # Create a PRD
|
|
42
|
+
# Manually review .plans/prd-<feature>.md
|
|
43
|
+
hone prd-to-tasks .plans/prd-<feature>.md # Generate tasks from PRD
|
|
44
|
+
hone run .plans/tasks-<feature>.yml -i 10 # Implement the feature
|
|
45
|
+
|
|
32
46
|
Model Configuration:
|
|
33
47
|
Configure models in .plans/hone.config.yml:
|
|
34
48
|
|
|
@@ -212,7 +226,7 @@ program
|
|
|
212
226
|
.action(async (options: { overwrite?: boolean }) => {
|
|
213
227
|
try {
|
|
214
228
|
setVerbose(program.opts().verbose || false)
|
|
215
|
-
const agent = await
|
|
229
|
+
const agent = await resolveAgentWithoutConfigCreation(program.opts().agent)
|
|
216
230
|
const { generateAgentsMd } = await import('./agents-md-generator')
|
|
217
231
|
const result = await generateAgentsMd({ overwrite: options.overwrite, agent })
|
|
218
232
|
|