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 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
- 4. **Create a feature**
26
- ```bash
27
- hone prd "Add user login with email and password"
28
- hone prd-to-tasks .plans/prd-user-login.md
29
- hone run .plans/tasks-user-login.yml -i 3
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
- That's it! hone will implement the feature, run tests, and commit changes automatically.
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
- ## Common Commands
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 5 # Implement tasks
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.10.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 { loadConfig, resolveModelForPhase, type HoneConfig, type AgentType } from './config'
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 loadConfig()
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: 'claude',
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 { loadConfig, ensurePlansDir, resolveAgent, initProject } from './config'
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' command
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 resolveAgent(program.opts().agent)
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