@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.
Files changed (62) hide show
  1. package/README.md +225 -0
  2. package/bin/harnspec-rust.js +201 -0
  3. package/bin/harnspec.js +10 -0
  4. package/binaries/darwin-arm64/harnspec +0 -0
  5. package/binaries/darwin-arm64/harnspec-http +0 -0
  6. package/binaries/darwin-arm64/package.json +24 -0
  7. package/binaries/darwin-arm64/postinstall.js +17 -0
  8. package/binaries/darwin-x64/harnspec +0 -0
  9. package/binaries/darwin-x64/harnspec-http +0 -0
  10. package/binaries/darwin-x64/package.json +24 -0
  11. package/binaries/darwin-x64/postinstall.js +17 -0
  12. package/binaries/linux-x64/harnspec +0 -0
  13. package/binaries/linux-x64/harnspec-http +0 -0
  14. package/binaries/linux-x64/package.json +24 -0
  15. package/binaries/linux-x64/postinstall.js +17 -0
  16. package/binaries/windows-x64/harnspec-http.exe +0 -0
  17. package/binaries/windows-x64/harnspec.exe +0 -0
  18. package/binaries/windows-x64/package.json +24 -0
  19. package/binaries/windows-x64/postinstall.js +6 -0
  20. package/package.json +51 -0
  21. package/templates/detailed/AGENTS-minimal.md +9 -0
  22. package/templates/detailed/AGENTS.md +118 -0
  23. package/templates/detailed/README.md +28 -0
  24. package/templates/detailed/config.json +20 -0
  25. package/templates/detailed/files/DESIGN.md +43 -0
  26. package/templates/detailed/files/PLAN.md +59 -0
  27. package/templates/detailed/files/README.md +30 -0
  28. package/templates/detailed/files/TEST.md +71 -0
  29. package/templates/examples/api-refactor/README.md +86 -0
  30. package/templates/examples/api-refactor/package.json +16 -0
  31. package/templates/examples/api-refactor/src/app.js +40 -0
  32. package/templates/examples/api-refactor/src/services/currencyService.js +43 -0
  33. package/templates/examples/api-refactor/src/services/timezoneService.js +41 -0
  34. package/templates/examples/api-refactor/src/services/weatherService.js +42 -0
  35. package/templates/examples/dark-theme/README.md +69 -0
  36. package/templates/examples/dark-theme/package.json +16 -0
  37. package/templates/examples/dark-theme/src/public/app.js +277 -0
  38. package/templates/examples/dark-theme/src/public/index.html +225 -0
  39. package/templates/examples/dark-theme/src/public/style.css +625 -0
  40. package/templates/examples/dark-theme/src/server.js +18 -0
  41. package/templates/examples/dashboard-widgets/README.md +74 -0
  42. package/templates/examples/dashboard-widgets/index.html +12 -0
  43. package/templates/examples/dashboard-widgets/package.json +22 -0
  44. package/templates/examples/dashboard-widgets/src/App.css +20 -0
  45. package/templates/examples/dashboard-widgets/src/App.jsx +16 -0
  46. package/templates/examples/dashboard-widgets/src/components/Dashboard.css +17 -0
  47. package/templates/examples/dashboard-widgets/src/components/Dashboard.jsx +15 -0
  48. package/templates/examples/dashboard-widgets/src/components/WidgetWrapper.css +23 -0
  49. package/templates/examples/dashboard-widgets/src/components/WidgetWrapper.jsx +16 -0
  50. package/templates/examples/dashboard-widgets/src/components/widgets/ChartWidget.css +33 -0
  51. package/templates/examples/dashboard-widgets/src/components/widgets/ChartWidget.jsx +28 -0
  52. package/templates/examples/dashboard-widgets/src/components/widgets/StatsWidget.css +24 -0
  53. package/templates/examples/dashboard-widgets/src/components/widgets/StatsWidget.jsx +22 -0
  54. package/templates/examples/dashboard-widgets/src/index.css +13 -0
  55. package/templates/examples/dashboard-widgets/src/main.jsx +10 -0
  56. package/templates/examples/dashboard-widgets/src/utils/mockData.js +30 -0
  57. package/templates/examples/dashboard-widgets/vite.config.js +6 -0
  58. package/templates/standard/AGENTS-minimal.md +10 -0
  59. package/templates/standard/AGENTS.md +118 -0
  60. package/templates/standard/README.md +25 -0
  61. package/templates/standard/config.json +18 -0
  62. package/templates/standard/files/README.md +42 -0
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "dashboard-widgets-demo",
3
+ "version": "1.0.0",
4
+ "description": "React Dashboard for HarnSpec Tutorial 2",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "keywords": ["harnspec", "tutorial", "demo"],
12
+ "author": "",
13
+ "license": "MIT",
14
+ "dependencies": {
15
+ "react": "^18.2.0",
16
+ "react-dom": "^18.2.0"
17
+ },
18
+ "devDependencies": {
19
+ "@vitejs/plugin-react": "^4.2.1",
20
+ "vite": "^5.0.0"
21
+ }
22
+ }
@@ -0,0 +1,20 @@
1
+ .app {
2
+ padding: 20px;
3
+ max-width: 1400px;
4
+ margin: 0 auto;
5
+ }
6
+
7
+ header {
8
+ margin-bottom: 30px;
9
+ }
10
+
11
+ header h1 {
12
+ margin: 0 0 5px 0;
13
+ color: #333;
14
+ }
15
+
16
+ header p {
17
+ margin: 0;
18
+ color: #666;
19
+ font-size: 14px;
20
+ }
@@ -0,0 +1,16 @@
1
+ import Dashboard from './components/Dashboard';
2
+ import './App.css';
3
+
4
+ function App() {
5
+ return (
6
+ <div className="app">
7
+ <header>
8
+ <h1>Analytics Dashboard</h1>
9
+ <p>Demo for harnspec Tutorial 2</p>
10
+ </header>
11
+ <Dashboard />
12
+ </div>
13
+ );
14
+ }
15
+
16
+ export default App;
@@ -0,0 +1,17 @@
1
+ .dashboard-grid {
2
+ display: grid;
3
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
4
+ gap: 20px;
5
+ }
6
+
7
+ @media (min-width: 768px) {
8
+ .dashboard-grid {
9
+ grid-template-columns: repeat(2, 1fr);
10
+ }
11
+ }
12
+
13
+ @media (min-width: 1200px) {
14
+ .dashboard-grid {
15
+ grid-template-columns: repeat(3, 1fr);
16
+ }
17
+ }
@@ -0,0 +1,15 @@
1
+ import StatsWidget from './widgets/StatsWidget';
2
+ import ChartWidget from './widgets/ChartWidget';
3
+ import './Dashboard.css';
4
+
5
+ function Dashboard() {
6
+ return (
7
+ <div className="dashboard-grid">
8
+ <StatsWidget />
9
+ <ChartWidget />
10
+ {/* TODO: Add new widgets here */}
11
+ </div>
12
+ );
13
+ }
14
+
15
+ export default Dashboard;
@@ -0,0 +1,23 @@
1
+ .widget {
2
+ background: white;
3
+ border-radius: 8px;
4
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
5
+ overflow: hidden;
6
+ }
7
+
8
+ .widget-header {
9
+ padding: 15px 20px;
10
+ border-bottom: 1px solid #eee;
11
+ background: #fafafa;
12
+ }
13
+
14
+ .widget-header h3 {
15
+ margin: 0;
16
+ font-size: 16px;
17
+ font-weight: 600;
18
+ color: #333;
19
+ }
20
+
21
+ .widget-body {
22
+ padding: 20px;
23
+ }
@@ -0,0 +1,16 @@
1
+ import './WidgetWrapper.css';
2
+
3
+ function WidgetWrapper({ title, children }) {
4
+ return (
5
+ <div className="widget">
6
+ <div className="widget-header">
7
+ <h3>{title}</h3>
8
+ </div>
9
+ <div className="widget-body">
10
+ {children}
11
+ </div>
12
+ </div>
13
+ );
14
+ }
15
+
16
+ export default WidgetWrapper;
@@ -0,0 +1,33 @@
1
+ .chart {
2
+ height: 200px;
3
+ }
4
+
5
+ .chart-bars {
6
+ display: flex;
7
+ align-items: flex-end;
8
+ justify-content: space-around;
9
+ height: 100%;
10
+ gap: 8px;
11
+ }
12
+
13
+ .chart-bar-container {
14
+ flex: 1;
15
+ display: flex;
16
+ flex-direction: column;
17
+ align-items: center;
18
+ height: 100%;
19
+ }
20
+
21
+ .chart-bar {
22
+ width: 100%;
23
+ background: linear-gradient(to top, #2563eb, #60a5fa);
24
+ border-radius: 4px 4px 0 0;
25
+ transition: height 0.3s ease;
26
+ min-height: 4px;
27
+ }
28
+
29
+ .chart-label {
30
+ margin-top: 8px;
31
+ font-size: 11px;
32
+ color: #666;
33
+ }
@@ -0,0 +1,28 @@
1
+ import WidgetWrapper from '../WidgetWrapper';
2
+ import { getChartData } from '../../utils/mockData';
3
+ import './ChartWidget.css';
4
+
5
+ function ChartWidget() {
6
+ const data = getChartData();
7
+ const maxValue = Math.max(...data.map(d => d.value));
8
+
9
+ return (
10
+ <WidgetWrapper title="Activity Trend">
11
+ <div className="chart">
12
+ <div className="chart-bars">
13
+ {data.map((item, index) => (
14
+ <div key={index} className="chart-bar-container">
15
+ <div
16
+ className="chart-bar"
17
+ style={{ height: `${(item.value / maxValue) * 100}%` }}
18
+ />
19
+ <div className="chart-label">{item.label}</div>
20
+ </div>
21
+ ))}
22
+ </div>
23
+ </div>
24
+ </WidgetWrapper>
25
+ );
26
+ }
27
+
28
+ export default ChartWidget;
@@ -0,0 +1,24 @@
1
+ .stats-grid {
2
+ display: grid;
3
+ grid-template-columns: repeat(2, 1fr);
4
+ gap: 15px;
5
+ }
6
+
7
+ .stat-item {
8
+ text-align: center;
9
+ padding: 10px;
10
+ }
11
+
12
+ .stat-value {
13
+ font-size: 28px;
14
+ font-weight: bold;
15
+ color: #2563eb;
16
+ margin-bottom: 5px;
17
+ }
18
+
19
+ .stat-label {
20
+ font-size: 12px;
21
+ color: #666;
22
+ text-transform: uppercase;
23
+ letter-spacing: 0.5px;
24
+ }
@@ -0,0 +1,22 @@
1
+ import WidgetWrapper from '../WidgetWrapper';
2
+ import { getStats } from '../../utils/mockData';
3
+ import './StatsWidget.css';
4
+
5
+ function StatsWidget() {
6
+ const stats = getStats();
7
+
8
+ return (
9
+ <WidgetWrapper title="Quick Stats">
10
+ <div className="stats-grid">
11
+ {stats.map((stat, index) => (
12
+ <div key={index} className="stat-item">
13
+ <div className="stat-value">{stat.value}</div>
14
+ <div className="stat-label">{stat.label}</div>
15
+ </div>
16
+ ))}
17
+ </div>
18
+ </WidgetWrapper>
19
+ );
20
+ }
21
+
22
+ export default StatsWidget;
@@ -0,0 +1,13 @@
1
+ body {
2
+ margin: 0;
3
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5
+ sans-serif;
6
+ -webkit-font-smoothing: antialiased;
7
+ -moz-osx-font-smoothing: grayscale;
8
+ background: #f5f5f5;
9
+ }
10
+
11
+ * {
12
+ box-sizing: border-box;
13
+ }
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import App from './App';
4
+ import './index.css';
5
+
6
+ ReactDOM.createRoot(document.getElementById('root')).render(
7
+ <React.StrictMode>
8
+ <App />
9
+ </React.StrictMode>
10
+ );
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Mock data generators for dashboard widgets
3
+ */
4
+
5
+ export function getStats() {
6
+ return [
7
+ { label: 'Users', value: '2,453' },
8
+ { label: 'Revenue', value: '$12.5K' },
9
+ { label: 'Orders', value: '186' },
10
+ { label: 'Growth', value: '+23%' },
11
+ ];
12
+ }
13
+
14
+ export function getChartData() {
15
+ return [
16
+ { label: 'Mon', value: 45 },
17
+ { label: 'Tue', value: 62 },
18
+ { label: 'Wed', value: 38 },
19
+ { label: 'Thu', value: 71 },
20
+ { label: 'Fri', value: 55 },
21
+ { label: 'Sat', value: 28 },
22
+ { label: 'Sun', value: 34 },
23
+ ];
24
+ }
25
+
26
+ // TODO: Add more mock data generators for new widgets
27
+ // Example:
28
+ // export function getActivityFeed() { ... }
29
+ // export function getPerformanceMetrics() { ... }
30
+ // export function getQuickActions() { ... }
@@ -0,0 +1,6 @@
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ });
@@ -0,0 +1,10 @@
1
+
2
+ # {project_name}
3
+
4
+ ## Project-Specific Rules
5
+
6
+ Add your project-specific conventions here. For example:
7
+ - Code style preferences
8
+ - Naming conventions
9
+ - Team workflows
10
+ - Custom tooling
@@ -0,0 +1,118 @@
1
+ # AI Agent Instructions
2
+
3
+ ## Project: {project_name}
4
+
5
+ ## 🚨 CRITICAL: Before ANY Task
6
+
7
+ **STOP and check these first:**
8
+
9
+ 1. **Discover context** → Use `board` tool to see project state
10
+ 2. **Search for related work** → Use `search` tool before creating new specs
11
+ 3. **Never create files manually** → Always use `create` tool for new specs
12
+
13
+ > **Why?** Skipping discovery creates duplicate work. Manual file creation breaks HarnSpec tooling.
14
+
15
+ ## 🔧 Managing Specs
16
+
17
+ ### CLI Commands with Agent Skills
18
+
19
+ | Action | Command |
20
+ |--------|---------|
21
+ | Project status | `harnspec board` |
22
+ | List specs | `harnspec list` |
23
+ | Search specs | `harnspec search "query"` |
24
+ | View spec | `harnspec view <spec>` |
25
+ | Create spec | `harnspec create <name>` |
26
+ | Update spec | `harnspec update <spec> --status <status>` |
27
+ | Link specs | `harnspec rel add <spec> --depends-on <other>` |
28
+ | Unlink specs | `harnspec rel rm <spec> --depends-on <other>` |
29
+ | Dependencies | `harnspec deps <spec>` |
30
+ | Token count | `harnspec tokens <spec>` |
31
+ | Validate specs | `harnspec validate` |
32
+
33
+ ## ⚠️ Core Rules
34
+
35
+ | Rule | Details |
36
+ |------|---------|
37
+ | **NEVER edit frontmatter manually** | Use `update`, `link`, `unlink` for: `status`, `priority`, `tags`, `assignee`, `transitions`, timestamps, `depends_on` |
38
+ | **ALWAYS link spec references** | Content mentions another spec → `harnspec link <spec> --depends-on <other>` |
39
+ | **Track status transitions** | `draft` → `planned` → `in-progress` (before coding) → `complete` (after done) |
40
+ | **Keep specs current** | Document progress, decisions, and learnings as work happens. Obsolete specs mislead both humans and AI |
41
+ | **No nested code blocks** | Use indentation instead |
42
+
43
+ ### 🚫 Common Mistakes
44
+
45
+ | ❌ Don't | ✅ Do Instead |
46
+ |----------|---------------|
47
+ | Create spec files manually | Use `create` tool |
48
+ | Skip discovery | Run `board` and `search` first |
49
+ | Leave status as "draft" or "planned" | Update to `in-progress` before coding |
50
+ | Edit frontmatter manually | Use `update` tool |
51
+ | Complete spec without documentation | Document progress, prompts, learnings first |
52
+
53
+ ## 📋 SDD Workflow
54
+
55
+ ```
56
+ BEFORE: board → search → check existing specs
57
+ DURING: update status to in-progress → code → document decisions → link dependencies
58
+ AFTER: document completion → update status to complete
59
+ ```
60
+
61
+ **Status tracks implementation, NOT spec writing.**
62
+
63
+ ## Spec Dependencies
64
+
65
+ Use `depends_on` to express blocking relationships between specs:
66
+
67
+ - **`depends_on`** = True blocker, work order matters, directional (A depends on B)
68
+
69
+ Link dependencies when one spec builds on another:
70
+
71
+ ```bash
72
+ harnspec link <spec> --depends-on <other-spec>
73
+ ```
74
+
75
+ ## When to Use Specs
76
+
77
+ | ✅ Write spec | ❌ Skip spec |
78
+ |---------------|--------------|
79
+ | Multi-part features | Bug fixes |
80
+ | Breaking changes | Trivial changes |
81
+ | Design decisions | Self-explanatory refactors |
82
+
83
+ ## Token Thresholds
84
+
85
+ | Tokens | Status |
86
+ |--------|--------|
87
+ | <2,000 | ✅ Optimal |
88
+ | 2,000-3,500 | ✅ Good |
89
+ | 3,500-5,000 | ⚠️ Consider splitting |
90
+ | >5,000 | 🔴 Must split |
91
+
92
+ ## Quality Validation
93
+
94
+ Before completing work, validate spec quality:
95
+
96
+ ```bash
97
+ harnspec validate # Check structure and quality
98
+ harnspec validate --check-deps # Verify dependency alignment
99
+ ```
100
+
101
+ Validation checks:
102
+
103
+ - Missing required sections
104
+ - Excessive length (>400 lines)
105
+ - Content/frontmatter dependency misalignment
106
+ - Invalid frontmatter fields
107
+
108
+ ## First Principles (Priority Order)
109
+
110
+ 1. **Context Economy** - <2,000 tokens optimal, >3,500 needs splitting
111
+ 2. **Signal-to-Noise** - Every word must inform a decision
112
+ 3. **Intent Over Implementation** - Capture why, let how emerge
113
+ 4. **Bridge the Gap** - Both human and AI must understand
114
+ 5. **Progressive Disclosure** - Add complexity only when pain is felt
115
+
116
+ ---
117
+
118
+ **Remember:** HarnSpec tracks what you're building. Keep specs in sync with your work!
@@ -0,0 +1,25 @@
1
+ # Standard Template
2
+
3
+ Recommended for most projects. Single-file specs with AI agent instructions.
4
+
5
+ ## What's Included
6
+
7
+ - **AGENTS.md** - Instructions for AI coding assistants
8
+ - **Single-file spec template** - All sections in one README.md
9
+ - Opinionated defaults for fast iteration
10
+
11
+ ## When to Use
12
+
13
+ - Solo developers or small teams
14
+ - Simple to moderate complexity specs
15
+ - Want AI agent integration
16
+ - Need clear but not heavy-weight process
17
+
18
+ ## Philosophy
19
+
20
+ Keep it lean. Write specs for features that need clarity. Skip them for obvious changes.
21
+
22
+ ## Next Steps
23
+
24
+ You're ready to go! Ask your AI to create a spec for your next feature.
25
+
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "Standard",
3
+ "description": "Recommended for most projects - solo devs and small teams",
4
+ "config": {
5
+ "template": "standard",
6
+ "specsDir": "specs",
7
+ "structure": {
8
+ "pattern": "flat",
9
+ "prefix": "",
10
+ "dateFormat": "YYYYMMDD",
11
+ "sequenceDigits": 3,
12
+ "defaultFile": "README.md"
13
+ },
14
+ "features": {
15
+ "aiAgents": true
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,42 @@
1
+ ---
2
+ status: planned
3
+ created: '{date}'
4
+ tags: []
5
+ priority: medium
6
+ ---
7
+
8
+ # {name}
9
+
10
+ > **Status**: {status} · **Priority**: {priority} · **Created**: {date}
11
+
12
+ ## Overview
13
+
14
+ <!-- What are we solving? Why now? -->
15
+
16
+ ## Design
17
+
18
+ <!-- Technical approach, architecture decisions -->
19
+
20
+ ## Plan
21
+
22
+ <!-- Break down implementation into steps -->
23
+
24
+ <!-- 💡 TIP: If your plan has >6 phases or this spec approaches
25
+ 400 lines, consider using sub-spec files:
26
+ - IMPLEMENTATION.md for detailed implementation
27
+ - See spec 012-sub-spec-files for guidance on splitting -->
28
+
29
+ - [ ] Task 1
30
+ - [ ] Task 2
31
+ - [ ] Task 3
32
+
33
+ ## Test
34
+
35
+ <!-- How will we verify this works? -->
36
+
37
+ - [ ] Test criteria 1
38
+ - [ ] Test criteria 2
39
+
40
+ ## Notes
41
+
42
+ <!-- Optional: Research findings, alternatives considered, open questions -->