@harnspec/cli 0.0.1
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 +225 -0
- package/bin/harnspec-rust.js +201 -0
- package/bin/harnspec.js +10 -0
- package/binaries/darwin-arm64/harnspec +0 -0
- package/binaries/darwin-arm64/harnspec-http +0 -0
- package/binaries/darwin-arm64/package.json +24 -0
- package/binaries/darwin-arm64/postinstall.js +17 -0
- package/binaries/darwin-x64/harnspec +0 -0
- package/binaries/darwin-x64/harnspec-http +0 -0
- package/binaries/darwin-x64/package.json +24 -0
- package/binaries/darwin-x64/postinstall.js +17 -0
- package/binaries/linux-x64/harnspec +0 -0
- package/binaries/linux-x64/harnspec-http +0 -0
- package/binaries/linux-x64/package.json +24 -0
- package/binaries/linux-x64/postinstall.js +17 -0
- package/binaries/windows-x64/harnspec-http.exe +0 -0
- package/binaries/windows-x64/harnspec.exe +0 -0
- package/binaries/windows-x64/package.json +24 -0
- package/binaries/windows-x64/postinstall.js +6 -0
- package/package.json +51 -0
- package/templates/detailed/AGENTS-minimal.md +9 -0
- package/templates/detailed/AGENTS.md +118 -0
- package/templates/detailed/README.md +28 -0
- package/templates/detailed/config.json +20 -0
- package/templates/detailed/files/DESIGN.md +43 -0
- package/templates/detailed/files/PLAN.md +59 -0
- package/templates/detailed/files/README.md +30 -0
- package/templates/detailed/files/TEST.md +71 -0
- package/templates/examples/api-refactor/README.md +86 -0
- package/templates/examples/api-refactor/package.json +16 -0
- package/templates/examples/api-refactor/src/app.js +40 -0
- package/templates/examples/api-refactor/src/services/currencyService.js +43 -0
- package/templates/examples/api-refactor/src/services/timezoneService.js +41 -0
- package/templates/examples/api-refactor/src/services/weatherService.js +42 -0
- package/templates/examples/dark-theme/README.md +69 -0
- package/templates/examples/dark-theme/package.json +16 -0
- package/templates/examples/dark-theme/src/public/app.js +277 -0
- package/templates/examples/dark-theme/src/public/index.html +225 -0
- package/templates/examples/dark-theme/src/public/style.css +625 -0
- package/templates/examples/dark-theme/src/server.js +18 -0
- package/templates/examples/dashboard-widgets/README.md +74 -0
- package/templates/examples/dashboard-widgets/index.html +12 -0
- package/templates/examples/dashboard-widgets/package.json +22 -0
- package/templates/examples/dashboard-widgets/src/App.css +20 -0
- package/templates/examples/dashboard-widgets/src/App.jsx +16 -0
- package/templates/examples/dashboard-widgets/src/components/Dashboard.css +17 -0
- package/templates/examples/dashboard-widgets/src/components/Dashboard.jsx +15 -0
- package/templates/examples/dashboard-widgets/src/components/WidgetWrapper.css +23 -0
- package/templates/examples/dashboard-widgets/src/components/WidgetWrapper.jsx +16 -0
- package/templates/examples/dashboard-widgets/src/components/widgets/ChartWidget.css +33 -0
- package/templates/examples/dashboard-widgets/src/components/widgets/ChartWidget.jsx +28 -0
- package/templates/examples/dashboard-widgets/src/components/widgets/StatsWidget.css +24 -0
- package/templates/examples/dashboard-widgets/src/components/widgets/StatsWidget.jsx +22 -0
- package/templates/examples/dashboard-widgets/src/index.css +13 -0
- package/templates/examples/dashboard-widgets/src/main.jsx +10 -0
- package/templates/examples/dashboard-widgets/src/utils/mockData.js +30 -0
- package/templates/examples/dashboard-widgets/vite.config.js +6 -0
- package/templates/standard/AGENTS-minimal.md +10 -0
- package/templates/standard/AGENTS.md +118 -0
- package/templates/standard/README.md +25 -0
- package/templates/standard/config.json +18 -0
- package/templates/standard/files/README.md +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# HarnSpec
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://github.com/harnspec/harnspec-docs/blob/main/static/img/logo-with-bg.svg" alt="HarnSpec Logo" width="120" height="120">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://github.com/harnspec/harnspec/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/harnspec/harnspec/ci.yml?branch=main" alt="CI Status"></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/@harnspec/cli"><img src="https://img.shields.io/npm/v/@harnspec/cli.svg?label=npm%20%40harnspec%2Fcli" alt="npm version"></a>
|
|
10
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT%20with%20Commons%20Clause-red.svg" alt="License"></a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
<a href="https://harnspec.github.io"><strong>Documentation</strong></a>
|
|
15
|
+
•
|
|
16
|
+
<a href="https://harnspec.github.io/zh-Hans/docs/guide/"><strong>中文文档</strong></a>
|
|
17
|
+
•
|
|
18
|
+
<a href="https://harnspec.github.io"><strong>Live Examples</strong></a>
|
|
19
|
+
•
|
|
20
|
+
<a href="https://harnspec.github.io/docs/tutorials/first-spec-with-ai"><strong>Tutorials</strong></a>
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
> [!IMPORTANT]
|
|
24
|
+
> This project is a fork of [codervisor/lean-spec](https://github.com/codervisor/lean-spec). Following the fork, the [Commons Clause](LICENSE) license condition was added to the original MIT license to ensure the project's sustainability while remaining open for community use.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
**Ship faster with higher quality. Lean specs that both humans and AI understand.**
|
|
29
|
+
|
|
30
|
+
HarnSpec brings agile principles to SDD (Spec-Driven Development)—small, focused documents (<2,000 tokens) that keep you and your AI aligned.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Try with a tutorial project
|
|
38
|
+
npx harnspec init --example dark-theme
|
|
39
|
+
cd dark-theme && npm install && npm start
|
|
40
|
+
|
|
41
|
+
# Or add to your existing project
|
|
42
|
+
# Install with the @harnspec scope
|
|
43
|
+
npm install -g @harnspec/cli && harnspec init
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Visualize your project:**
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
harnspec board # Kanban view
|
|
50
|
+
harnspec stats # Project metrics
|
|
51
|
+
harnspec ui # Web UI at localhost:3000
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Next:** [Your First Spec with AI](https://harnspec.github.io/docs/tutorials/first-spec-with-ai) (10 min tutorial)
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Why HarnSpec?
|
|
59
|
+
|
|
60
|
+
**High velocity + High quality.** Other SDD frameworks add process overhead (multi-step workflows, rigid templates). Vibe coding is fast but chaotic (no shared understanding). HarnSpec hits the sweet spot:
|
|
61
|
+
|
|
62
|
+
- **Fast iteration** - Living documents that grow with your code
|
|
63
|
+
- **AI performance** - Small specs = better AI output (context rot is real)
|
|
64
|
+
- **Always current** - Lightweight enough that you actually update them
|
|
65
|
+
|
|
66
|
+
📖 [Compare with Spec Kit, OpenSpec, Kiro →](https://harnspec.github.io/docs/guide/why-harnspec)
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## AI Integration
|
|
71
|
+
|
|
72
|
+
HarnSpec is designed to be used with any AI coding assistant (Claude Code, Cursor, Windsurf, GitHub Copilot, Aider, etc.) via the **CLI + Agent Skills** approach.
|
|
73
|
+
|
|
74
|
+
Teach your AI assistant the methodology using:
|
|
75
|
+
```bash
|
|
76
|
+
harnspec skill install
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
AI agents can then use `harnspec` CLI tools directly to manage your project board and specs.
|
|
80
|
+
|
|
81
|
+
📖 [Full AI integration guide →](https://harnspec.github.io/docs/guide/usage/ai-coding-workflow)
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Agent Skills
|
|
86
|
+
|
|
87
|
+
Teach your AI assistant the Spec-Driven Development methodology:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Recommended (uses skills.sh)
|
|
91
|
+
harnspec skill install
|
|
92
|
+
|
|
93
|
+
# Or directly via skills.sh
|
|
94
|
+
npx skills add harnspec/skills@harnspec -y
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
This installs the **harnspec** skill which teaches AI agents:
|
|
98
|
+
|
|
99
|
+
- When to create specs vs. implement directly
|
|
100
|
+
- How to discover existing specs before creating new ones
|
|
101
|
+
- Best practices for context economy and progressive disclosure
|
|
102
|
+
- Complete SDD workflow (Discover → Design → Implement → Validate)
|
|
103
|
+
|
|
104
|
+
**Compatible with:** Claude Code, Cursor, Windsurf, GitHub Copilot, and other [Agent Skills](https://skills.sh/) compatible tools.
|
|
105
|
+
|
|
106
|
+
📖 [View skill documentation →](.agents/skills/harnspec/SKILL.md)
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Features
|
|
111
|
+
|
|
112
|
+
| Feature | Description |
|
|
113
|
+
| ------------------- | ------------------------------------------------------------------------------------------------- |
|
|
114
|
+
| **📊 Kanban Board** | `harnspec board` - visual project tracking |
|
|
115
|
+
| **🔍 Smart Search** | `harnspec search` - find specs by content or metadata |
|
|
116
|
+
| **🔗 Dependencies** | Track spec relationships with `depends_on` and `related` |
|
|
117
|
+
| **🎨 Web UI** | `harnspec ui` - browser-based dashboard |
|
|
118
|
+
| **📈 Project Stats** | `harnspec stats` - health metrics and bottleneck detection |
|
|
119
|
+
| **🤖 AI-Native** | CLI-first with Agent Skills |
|
|
120
|
+
| **🖥️ Desktop App** | Desktop app repo: [harnspec/harnspec-desktop](https://github.com/harnspec/harnspec-desktop) |
|
|
121
|
+
|
|
122
|
+
<p align="center">
|
|
123
|
+
<img src="https://github.com/harnspec/harnspec-docs/blob/main/static/img/ui/ui-board-view.png" alt="Kanban Board View" width="800">
|
|
124
|
+
</p>
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Requirements
|
|
129
|
+
|
|
130
|
+
### Runtime
|
|
131
|
+
|
|
132
|
+
- **Node.js**: `>= 20.0.0`
|
|
133
|
+
- **pnpm**: `>= 10.0.0` (preferred package manager)
|
|
134
|
+
|
|
135
|
+
### Development
|
|
136
|
+
|
|
137
|
+
- **Node.js**: `>= 20.0.0`
|
|
138
|
+
- **Rust**: `>= 1.70` (for building CLI/HTTP binaries)
|
|
139
|
+
- **pnpm**: `>= 10.0.0`
|
|
140
|
+
|
|
141
|
+
**Quick Check:**
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
node --version # Should be v20.0.0 or higher
|
|
145
|
+
pnpm --version # Should be 10.0.0 or higher
|
|
146
|
+
rustc --version # Should be 1.70 or higher (dev only)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Desktop App
|
|
152
|
+
|
|
153
|
+
The desktop application has moved to a dedicated repository:
|
|
154
|
+
|
|
155
|
+
- <https://github.com/harnspec/harnspec-desktop>
|
|
156
|
+
|
|
157
|
+
Use that repository for desktop development, CI, and release workflows.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Developer Workflow
|
|
162
|
+
|
|
163
|
+
Common development tasks using `pnpm`:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# Development
|
|
167
|
+
pnpm install # Install dependencies
|
|
168
|
+
pnpm build # Build all packages
|
|
169
|
+
pnpm dev # Start dev mode (UI + Core)
|
|
170
|
+
pnpm dev:web # UI only
|
|
171
|
+
pnpm dev:cli # CLI only
|
|
172
|
+
|
|
173
|
+
# Testing
|
|
174
|
+
pnpm test # Run all tests
|
|
175
|
+
pnpm test:ui # Tests with UI
|
|
176
|
+
pnpm test:coverage # Coverage report
|
|
177
|
+
pnpm typecheck # Type check all packages
|
|
178
|
+
|
|
179
|
+
# Rust
|
|
180
|
+
pnpm rust:build # Build Rust packages (release)
|
|
181
|
+
pnpm rust:build:dev # Build Rust (dev, faster)
|
|
182
|
+
pnpm rust:test # Run Rust tests
|
|
183
|
+
pnpm rust:check # Quick Rust check
|
|
184
|
+
pnpm rust:clippy # Rust linting
|
|
185
|
+
pnpm rust:fmt # Format Rust code
|
|
186
|
+
|
|
187
|
+
# CLI (run locally)
|
|
188
|
+
pnpm cli board # Show spec board
|
|
189
|
+
pnpm cli list # List specs
|
|
190
|
+
pnpm cli create my-feat # Create new spec
|
|
191
|
+
pnpm cli validate # Validate specs
|
|
192
|
+
|
|
193
|
+
# Documentation
|
|
194
|
+
pnpm docs:dev # Start docs site
|
|
195
|
+
pnpm docs:build # Build docs
|
|
196
|
+
|
|
197
|
+
# Release
|
|
198
|
+
pnpm pre-release # Run all pre-release checks
|
|
199
|
+
pnpm prepare-publish # Prepare for npm publish
|
|
200
|
+
pnpm restore-packages # Restore after publish
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
See [package.json](package.json) for all available scripts.
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Documentation
|
|
208
|
+
|
|
209
|
+
📖 [Full Documentation](https://harnspec.github.io) · [CLI Reference](https://harnspec.github.io/docs/reference/cli) · [First Principles](https://harnspec.github.io/docs/advanced/first-principles) · [FAQ](https://harnspec.github.io/docs/faq) · [中文文档](https://harnspec.github.io/zh-Hans/)
|
|
210
|
+
|
|
211
|
+
## Community
|
|
212
|
+
|
|
213
|
+
💬 [Discussions](https://github.com/harnspec/harnspec/discussions) · 🐛 [Issues](https://github.com/harnspec/harnspec/issues) · 🤝 [Contributing](CONTRIBUTING.md) · 📋 [Changelog](CHANGELOG.md) · 📄 [LICENSE](LICENSE)
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
### Contact Me | 联系我
|
|
218
|
+
|
|
219
|
+
If you find HarnSpec helpful, feel free to add me on WeChat (note "HarnSpec") to join the discussion group.
|
|
220
|
+
|
|
221
|
+
如果您觉得 HarnSpec 对您有帮助,欢迎添加微信(备注 "HarnSpec")加入交流群。
|
|
222
|
+
|
|
223
|
+
<p align="center">
|
|
224
|
+
<img src="https://github.com/harnspec/harnspec-docs/blob/main/static/img/qr-code.png" alt="WeChat Contact | 微信联系" height="280">
|
|
225
|
+
</p>
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* HarnSpec CLI Binary Wrapper
|
|
4
|
+
*
|
|
5
|
+
* This script detects the current platform and architecture,
|
|
6
|
+
* then spawns the appropriate Rust binary with the provided arguments.
|
|
7
|
+
*
|
|
8
|
+
* The wrapper looks for binaries in the following locations:
|
|
9
|
+
* 1. Rust target/debug binary (for local development)
|
|
10
|
+
* 2. Rust target/release binary (for local development)
|
|
11
|
+
* 3. Platform-specific npm package (harnspec-darwin-x64, etc.)
|
|
12
|
+
* 4. Local binaries directory (fallback)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { spawn } from 'child_process';
|
|
16
|
+
import { createRequire } from 'module';
|
|
17
|
+
import { fileURLToPath } from 'url';
|
|
18
|
+
import { dirname, join } from 'path';
|
|
19
|
+
import { accessSync, openSync, readSync, closeSync } from 'fs';
|
|
20
|
+
|
|
21
|
+
const require = createRequire(import.meta.url);
|
|
22
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
23
|
+
const __dirname = dirname(__filename);
|
|
24
|
+
|
|
25
|
+
// Debug mode - enable with HARNSPEC_DEBUG=1
|
|
26
|
+
const DEBUG = process.env.HARNSPEC_DEBUG === '1';
|
|
27
|
+
const debug = (...args) => DEBUG && console.error('[harnspec debug]', ...args);
|
|
28
|
+
|
|
29
|
+
// Platform detection mapping
|
|
30
|
+
const PLATFORM_MAP = {
|
|
31
|
+
darwin: { x64: 'darwin-x64', arm64: 'darwin-arm64' },
|
|
32
|
+
linux: { x64: 'linux-x64' },
|
|
33
|
+
win32: { x64: 'windows-x64' }
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const MACHO_MAGICS = new Set([
|
|
37
|
+
0xfeedface,
|
|
38
|
+
0xfeedfacf,
|
|
39
|
+
0xcefaedfe,
|
|
40
|
+
0xcffaedfe,
|
|
41
|
+
0xcafebabe,
|
|
42
|
+
0xbebafeca,
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
function readHeaderBytes(filePath) {
|
|
46
|
+
const fd = openSync(filePath, 'r');
|
|
47
|
+
try {
|
|
48
|
+
const buffer = Buffer.alloc(4);
|
|
49
|
+
const bytesRead = readSync(fd, buffer, 0, 4, 0);
|
|
50
|
+
return bytesRead === 4 ? buffer : null;
|
|
51
|
+
} finally {
|
|
52
|
+
closeSync(fd);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function isValidBinaryHeader(filePath, platform) {
|
|
57
|
+
try {
|
|
58
|
+
const header = readHeaderBytes(filePath);
|
|
59
|
+
if (!header) return false;
|
|
60
|
+
|
|
61
|
+
if (platform === 'linux') {
|
|
62
|
+
return header[0] === 0x7f && header[1] === 0x45 && header[2] === 0x4c && header[3] === 0x46;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (platform === 'win32') {
|
|
66
|
+
return header[0] === 0x4d && header[1] === 0x5a;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (platform === 'darwin') {
|
|
70
|
+
const magicBE = header.readUInt32BE(0);
|
|
71
|
+
const magicLE = header.readUInt32LE(0);
|
|
72
|
+
return MACHO_MAGICS.has(magicBE) || MACHO_MAGICS.has(magicLE);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return false;
|
|
76
|
+
} catch (error) {
|
|
77
|
+
debug('Failed to read binary header:', error.message);
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function isExecutableBinary(filePath, platform) {
|
|
83
|
+
if (!isValidBinaryHeader(filePath, platform)) {
|
|
84
|
+
debug('Invalid binary header:', filePath);
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function getBinaryPath() {
|
|
91
|
+
const platform = process.platform;
|
|
92
|
+
const arch = process.arch;
|
|
93
|
+
|
|
94
|
+
debug('Platform detection:', { platform, arch });
|
|
95
|
+
|
|
96
|
+
const platformKey = PLATFORM_MAP[platform]?.[arch];
|
|
97
|
+
if (!platformKey) {
|
|
98
|
+
console.error(`Unsupported platform: ${platform}-${arch}`);
|
|
99
|
+
console.error('Supported: macOS (x64/arm64), Linux (x64), Windows (x64)');
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const isWindows = platform === 'win32';
|
|
104
|
+
const binaryName = isWindows ? 'harnspec.exe' : 'harnspec';
|
|
105
|
+
const packageName = `@harnspec/cli-${platformKey}`;
|
|
106
|
+
|
|
107
|
+
debug('Binary info:', { platformKey, binaryName, packageName });
|
|
108
|
+
|
|
109
|
+
// Try rust/target/debug directory first (for local development with `pnpm build:rust`)
|
|
110
|
+
try {
|
|
111
|
+
const rustDebugPath = join(__dirname, '..', '..', '..', 'rust', 'target', 'debug', binaryName);
|
|
112
|
+
debug('Trying rust debug binary:', rustDebugPath);
|
|
113
|
+
accessSync(rustDebugPath);
|
|
114
|
+
if (isExecutableBinary(rustDebugPath, platform)) {
|
|
115
|
+
debug('Found rust debug binary:', rustDebugPath);
|
|
116
|
+
return rustDebugPath;
|
|
117
|
+
}
|
|
118
|
+
debug('Rust debug binary is invalid:', rustDebugPath);
|
|
119
|
+
} catch (e) {
|
|
120
|
+
debug('Rust debug binary not found:', e.message);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Try rust/target/release directory (for local development with `pnpm build:rust:release`)
|
|
124
|
+
try {
|
|
125
|
+
const rustTargetPath = join(__dirname, '..', '..', '..', 'rust', 'target', 'release', binaryName);
|
|
126
|
+
debug('Trying rust release binary:', rustTargetPath);
|
|
127
|
+
accessSync(rustTargetPath);
|
|
128
|
+
if (isExecutableBinary(rustTargetPath, platform)) {
|
|
129
|
+
debug('Found rust release binary:', rustTargetPath);
|
|
130
|
+
return rustTargetPath;
|
|
131
|
+
}
|
|
132
|
+
debug('Rust release binary is invalid:', rustTargetPath);
|
|
133
|
+
} catch (e) {
|
|
134
|
+
debug('Rust release binary not found:', e.message);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Try to resolve platform package
|
|
138
|
+
try {
|
|
139
|
+
const resolvedPath = require.resolve(`${packageName}/${binaryName}`);
|
|
140
|
+
if (isExecutableBinary(resolvedPath, platform)) {
|
|
141
|
+
debug('Found platform package binary:', resolvedPath);
|
|
142
|
+
return resolvedPath;
|
|
143
|
+
}
|
|
144
|
+
debug('Platform package binary is invalid:', resolvedPath);
|
|
145
|
+
} catch (e) {
|
|
146
|
+
debug('Platform package not found:', packageName, '-', e.message);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Try local binaries directory (fallback)
|
|
150
|
+
try {
|
|
151
|
+
const localPath = join(__dirname, '..', 'binaries', platformKey, binaryName);
|
|
152
|
+
debug('Trying local binary:', localPath);
|
|
153
|
+
accessSync(localPath);
|
|
154
|
+
if (isExecutableBinary(localPath, platform)) {
|
|
155
|
+
debug('Found local binary:', localPath);
|
|
156
|
+
return localPath;
|
|
157
|
+
}
|
|
158
|
+
debug('Local binary is invalid:', localPath);
|
|
159
|
+
} catch (e) {
|
|
160
|
+
debug('Local binary not found:', e.message);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
console.error(`Binary not found for ${platform}-${arch}`);
|
|
164
|
+
console.error(`Expected package: ${packageName}`);
|
|
165
|
+
console.error('');
|
|
166
|
+
console.error('Detected missing or corrupted binary.');
|
|
167
|
+
console.error('If you installed globally, reinstall to restore the binary:');
|
|
168
|
+
console.error(' npm uninstall -g harnspec && npm install -g harnspec');
|
|
169
|
+
console.error('');
|
|
170
|
+
console.error('If your npm config omits optional dependencies, enable them and reinstall.');
|
|
171
|
+
console.error('');
|
|
172
|
+
console.error('To install:');
|
|
173
|
+
console.error(' npm install -g harnspec');
|
|
174
|
+
console.error('');
|
|
175
|
+
console.error('If you installed globally, try:');
|
|
176
|
+
console.error(' npm uninstall -g harnspec && npm install -g harnspec');
|
|
177
|
+
process.exit(1);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Execute binary
|
|
181
|
+
const binaryPath = getBinaryPath();
|
|
182
|
+
const args = process.argv.slice(2);
|
|
183
|
+
|
|
184
|
+
debug('Spawning binary:', binaryPath);
|
|
185
|
+
debug('Arguments:', args);
|
|
186
|
+
|
|
187
|
+
const child = spawn(binaryPath, args, {
|
|
188
|
+
stdio: 'inherit',
|
|
189
|
+
windowsHide: true,
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
child.on('exit', (code) => {
|
|
193
|
+
debug('Binary exited with code:', code);
|
|
194
|
+
process.exit(code ?? 1);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
child.on('error', (err) => {
|
|
198
|
+
console.error('Failed to start harnspec:', err.message);
|
|
199
|
+
debug('Spawn error:', err);
|
|
200
|
+
process.exit(1);
|
|
201
|
+
});
|
package/bin/harnspec.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* HarnSpec CLI Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Thin wrapper that delegates to the Rust binary.
|
|
6
|
+
* The TypeScript implementation has been deprecated in favor of Rust.
|
|
7
|
+
*
|
|
8
|
+
* @see spec 181-typescript-deprecation-rust-migration
|
|
9
|
+
*/
|
|
10
|
+
import './harnspec-rust.js';
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@harnspec/cli-darwin-arm64",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "HarnSpec CLI binary for macOS ARM64",
|
|
5
|
+
"os": [
|
|
6
|
+
"darwin"
|
|
7
|
+
],
|
|
8
|
+
"cpu": [
|
|
9
|
+
"arm64"
|
|
10
|
+
],
|
|
11
|
+
"main": "harnspec",
|
|
12
|
+
"files": [
|
|
13
|
+
"harnspec",
|
|
14
|
+
"postinstall.js"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"postinstall": "node postinstall.js"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/codervisor/harnspec.git"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT"
|
|
24
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Postinstall script to set execute permissions on the binary.
|
|
4
|
+
* npm doesn't preserve file permissions, so we need to set them after install.
|
|
5
|
+
*/
|
|
6
|
+
const { chmodSync } = require('fs');
|
|
7
|
+
const { join } = require('path');
|
|
8
|
+
|
|
9
|
+
const binaryPath = join(__dirname, 'harnspec');
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
chmodSync(binaryPath, 0o755);
|
|
13
|
+
console.log('✓ Set execute permissions on harnspec binary');
|
|
14
|
+
} catch (err) {
|
|
15
|
+
console.error('Warning: Could not set execute permissions:', err.message);
|
|
16
|
+
// Don't fail the install
|
|
17
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@harnspec/cli-darwin-x64",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "HarnSpec CLI binary for macOS x64",
|
|
5
|
+
"os": [
|
|
6
|
+
"darwin"
|
|
7
|
+
],
|
|
8
|
+
"cpu": [
|
|
9
|
+
"x64"
|
|
10
|
+
],
|
|
11
|
+
"main": "harnspec",
|
|
12
|
+
"files": [
|
|
13
|
+
"harnspec",
|
|
14
|
+
"postinstall.js"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"postinstall": "node postinstall.js"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/codervisor/harnspec.git"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT"
|
|
24
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Postinstall script to set execute permissions on the binary.
|
|
4
|
+
* npm doesn't preserve file permissions, so we need to set them after install.
|
|
5
|
+
*/
|
|
6
|
+
const { chmodSync } = require('fs');
|
|
7
|
+
const { join } = require('path');
|
|
8
|
+
|
|
9
|
+
const binaryPath = join(__dirname, 'harnspec');
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
chmodSync(binaryPath, 0o755);
|
|
13
|
+
console.log('✓ Set execute permissions on harnspec binary');
|
|
14
|
+
} catch (err) {
|
|
15
|
+
console.error('Warning: Could not set execute permissions:', err.message);
|
|
16
|
+
// Don't fail the install
|
|
17
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@harnspec/cli-linux-x64",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "HarnSpec CLI binary for Linux x64",
|
|
5
|
+
"os": [
|
|
6
|
+
"linux"
|
|
7
|
+
],
|
|
8
|
+
"cpu": [
|
|
9
|
+
"x64"
|
|
10
|
+
],
|
|
11
|
+
"main": "harnspec",
|
|
12
|
+
"files": [
|
|
13
|
+
"harnspec",
|
|
14
|
+
"postinstall.js"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"postinstall": "node postinstall.js"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/codervisor/harnspec.git"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT"
|
|
24
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Postinstall script to set execute permissions on the binary.
|
|
4
|
+
* npm doesn't preserve file permissions, so we need to set them after install.
|
|
5
|
+
*/
|
|
6
|
+
const { chmodSync } = require('fs');
|
|
7
|
+
const { join } = require('path');
|
|
8
|
+
|
|
9
|
+
const binaryPath = join(__dirname, 'harnspec');
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
chmodSync(binaryPath, 0o755);
|
|
13
|
+
console.log('✓ Set execute permissions on harnspec binary');
|
|
14
|
+
} catch (err) {
|
|
15
|
+
console.error('Warning: Could not set execute permissions:', err.message);
|
|
16
|
+
// Don't fail the install
|
|
17
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@harnspec/cli-windows-x64",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "HarnSpec CLI binary for Windows x64",
|
|
5
|
+
"os": [
|
|
6
|
+
"win32"
|
|
7
|
+
],
|
|
8
|
+
"cpu": [
|
|
9
|
+
"x64"
|
|
10
|
+
],
|
|
11
|
+
"main": "harnspec.exe",
|
|
12
|
+
"files": [
|
|
13
|
+
"harnspec.exe",
|
|
14
|
+
"postinstall.js"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"postinstall": "node postinstall.js"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/codervisor/harnspec.git"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT"
|
|
24
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@harnspec/cli",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Specification-driven development made simple",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"harnspec": "./bin/harnspec.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"typecheck": "echo 'No TypeScript source to check'"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@harnspec/http-server": "0.0.1",
|
|
14
|
+
"@harnspec/ui": "0.0.1"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"spec",
|
|
18
|
+
"specification",
|
|
19
|
+
"documentation",
|
|
20
|
+
"ai",
|
|
21
|
+
"agent",
|
|
22
|
+
"sdd"
|
|
23
|
+
],
|
|
24
|
+
"author": "Marvin Zhang",
|
|
25
|
+
"license": "MIT AND Commons-Clause-1.0",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/harnspec/harnspec.git"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://harnspec.github.io",
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/harnspec/harnspec/issues"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"bin/",
|
|
36
|
+
"binaries/",
|
|
37
|
+
"templates/",
|
|
38
|
+
"README.md",
|
|
39
|
+
"LICENSE",
|
|
40
|
+
"CHANGELOG.md"
|
|
41
|
+
],
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=20"
|
|
44
|
+
},
|
|
45
|
+
"optionalDependencies": {
|
|
46
|
+
"@harnspec/cli-darwin-x64": "0.0.1",
|
|
47
|
+
"@harnspec/cli-darwin-arm64": "0.0.1",
|
|
48
|
+
"@harnspec/cli-linux-x64": "0.0.1",
|
|
49
|
+
"@harnspec/cli-windows-x64": "0.0.1"
|
|
50
|
+
}
|
|
51
|
+
}
|