@harnspec/http-server 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 ADDED
@@ -0,0 +1,127 @@
1
+ # @harnspec/http-server
2
+
3
+ High-performance Rust HTTP server for HarnSpec UI.
4
+
5
+ ## Features
6
+
7
+ - **Fast**: Built with Rust and Axum web framework
8
+ - **Lightweight**: <30MB bundle size
9
+ - **Multi-project**: Support for multiple project workspaces
10
+ - **RESTful API**: JSON API for all spec operations
11
+ - **Unified UI + API**: Serves the Vite UI and `/api/*` from one server
12
+ - **CORS-enabled**: Configurable cross-origin resource sharing
13
+ - **Detailed Logging**: Request tracing with error context for development
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @harnspec/http-server
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ### As a standalone server
24
+
25
+ ```bash
26
+ npx harnspec-http
27
+ ```
28
+
29
+ Options:
30
+
31
+ - `--host <host>` - Server host (default: 127.0.0.1)
32
+ - `--port <port>` - Server port (default: 3000)
33
+ - `-v, --verbose` - Enable verbose (debug) logging
34
+ - `--log-level <level>` - Log level: trace, debug, info, warn, error (default: info)
35
+ - `--help` - Show help message
36
+
37
+ ### Development Mode
38
+
39
+ For improved developer experience, set environment variables to enable detailed logging:
40
+
41
+ ```bash
42
+ # Enable debug mode with verbose logging
43
+ HARNSPEC_DEBUG=1 HARNSPEC_DEV_MODE=1 npx harnspec-http -v
44
+
45
+ # Or use RUST_LOG for fine-grained control
46
+ RUST_LOG=harnspec_http=debug,tower_http=debug npx harnspec-http
47
+ ```
48
+
49
+ In dev mode, the server provides:
50
+
51
+ - **Request tracing**: Each request gets a unique ID for correlation
52
+ - **Error context**: Full error details with status codes and stack context
53
+ - **Latency tracking**: Response timing in milliseconds
54
+ - **File/line info**: Source location for debugging
55
+
56
+ ### Log Levels
57
+
58
+ | Level | When to use | What you see |
59
+ | ------- | ----------- | ----------------------------------- |
60
+ | `error` | Production | Only errors/failures |
61
+ | `warn` | Production | Warnings + errors |
62
+ | `info` | Default | Requests + responses + errors |
63
+ | `debug` | Development | Detailed request/response info |
64
+ | `trace` | Debugging | Everything including internal calls |
65
+
66
+ ### As a library
67
+
68
+ ```javascript
69
+ import { spawn } from 'child_process';
70
+
71
+ const server = spawn('harnspec-http', ['--port', '3000']);
72
+ ```
73
+
74
+ ## Configuration
75
+
76
+ The server reads configuration from `~/.harnspec/config.json`:
77
+
78
+ ```json
79
+ {
80
+ "server": {
81
+ "host": "127.0.0.1",
82
+ "port": 3000,
83
+ "cors": {
84
+ "enabled": false,
85
+ "origins": [
86
+ "http://localhost:5173",
87
+ "http://localhost:3000"
88
+ ]
89
+ }
90
+ }
91
+ }
92
+ ```
93
+
94
+ ## API Endpoints
95
+
96
+ ### Projects
97
+
98
+ - `GET /api/projects` - List all projects
99
+ - `POST /api/projects` - Add new project
100
+ - `GET /api/projects/:id` - Get project details
101
+ - `PATCH /api/projects/:id` - Update project
102
+ - `DELETE /api/projects/:id` - Remove project
103
+ - `POST /api/projects/:id/switch` - Switch to project
104
+
105
+ ### Specs
106
+
107
+ - `GET /api/specs` - List specs (with filters)
108
+ - `GET /api/specs/:spec` - Get spec detail
109
+ - `PATCH /api/specs/:spec/metadata` - Update spec metadata
110
+ - `POST /api/search` - Search specs
111
+ - `GET /api/stats` - Project statistics
112
+ - `GET /api/deps/:spec` - Dependency graph
113
+ - `GET /api/validate` - Validate all specs
114
+
115
+ ### Health
116
+
117
+ - `GET /health` - Health check
118
+
119
+ ## Platform Support
120
+
121
+ - macOS (x64, arm64)
122
+ - Linux (x64, arm64)
123
+ - Windows (x64)
124
+
125
+ ## License
126
+
127
+ MIT
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * HarnSpec HTTP Server Binary Wrapper
4
+ *
5
+ * This script detects the current platform and architecture,
6
+ * then spawns the appropriate Rust HTTP server binary.
7
+ *
8
+ * The wrapper looks for binaries in the following locations:
9
+ * 1. Platform-specific npm package (@harnspec/http-darwin-x64, etc.)
10
+ * 2. Local binaries directory (for development)
11
+ * 3. Rust target directory (for local development)
12
+ */
13
+
14
+ import { spawn } from 'child_process';
15
+ import { createRequire } from 'module';
16
+ import { fileURLToPath } from 'url';
17
+ import { dirname, join } from 'path';
18
+ import { accessSync } from 'fs';
19
+
20
+ const require = createRequire(import.meta.url);
21
+ const __filename = fileURLToPath(import.meta.url);
22
+ const __dirname = dirname(__filename);
23
+
24
+ // Debug mode - enable with HARNSPEC_DEBUG=1
25
+ const DEBUG = process.env.HARNSPEC_DEBUG === '1';
26
+ const DEV_MODE = process.env.HARNSPEC_DEV_MODE === '1';
27
+ const debug = (...args) => DEBUG && console.error('[harnspec-http 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
+ function getBinaryPath() {
37
+ const platform = process.platform;
38
+ const arch = process.arch;
39
+
40
+ debug('Platform detection:', { platform, arch });
41
+
42
+ const platformKey = PLATFORM_MAP[platform]?.[arch];
43
+ if (!platformKey) {
44
+ console.error(`Unsupported platform: ${platform}-${arch}`);
45
+ console.error('Supported: macOS (x64/arm64), Linux (x64), Windows (x64)');
46
+ process.exit(1);
47
+ }
48
+
49
+ const isWindows = platform === 'win32';
50
+ const binaryName = isWindows ? 'harnspec-http.exe' : 'harnspec-http';
51
+ const packageName = `@harnspec/http-${platformKey}`;
52
+
53
+ debug('Binary info:', { platformKey, binaryName, packageName });
54
+
55
+ // In dev mode, prefer rust target directory first for faster iteration
56
+ if (DEV_MODE) {
57
+ // Try rust/target/debug directory first (faster builds)
58
+ try {
59
+ const rustDebugPath = join(__dirname, '..', '..', '..', 'rust', 'target', 'debug', binaryName);
60
+ debug('Trying rust debug binary:', rustDebugPath);
61
+ accessSync(rustDebugPath);
62
+ debug('Found rust debug binary:', rustDebugPath);
63
+ return rustDebugPath;
64
+ } catch (e) {
65
+ debug('Rust debug binary not found:', e.message);
66
+ }
67
+
68
+ // Try rust/target/release directory
69
+ try {
70
+ const rustReleasePath = join(__dirname, '..', '..', '..', 'rust', 'target', 'release', binaryName);
71
+ debug('Trying rust release binary:', rustReleasePath);
72
+ accessSync(rustReleasePath);
73
+ debug('Found rust release binary:', rustReleasePath);
74
+ return rustReleasePath;
75
+ } catch (e) {
76
+ debug('Rust release binary not found:', e.message);
77
+ }
78
+ }
79
+
80
+ // Try to resolve platform package
81
+ try {
82
+ const resolvedPath = require.resolve(`${packageName}/${binaryName}`);
83
+ debug('Found platform package binary:', resolvedPath);
84
+ return resolvedPath;
85
+ } catch (e) {
86
+ debug('Platform package not found:', packageName, '-', e.message);
87
+ }
88
+
89
+ // Try local binaries directory (for development/testing)
90
+ try {
91
+ const localPath = join(__dirname, '..', 'binaries', platformKey, binaryName);
92
+ debug('Trying local binary:', localPath);
93
+ accessSync(localPath);
94
+ debug('Found local binary:', localPath);
95
+ return localPath;
96
+ } catch (e) {
97
+ debug('Local binary not found:', e.message);
98
+ }
99
+
100
+ // Try rust/target/release directory (fallback for local development)
101
+ try {
102
+ const rustTargetPath = join(__dirname, '..', '..', '..', 'rust', 'target', 'release', binaryName);
103
+ debug('Trying rust target binary:', rustTargetPath);
104
+ accessSync(rustTargetPath);
105
+ debug('Found rust target binary:', rustTargetPath);
106
+ return rustTargetPath;
107
+ } catch (e) {
108
+ debug('Rust target binary not found:', e.message);
109
+ }
110
+
111
+ console.error(`Binary not found for ${platform}-${arch}`);
112
+ console.error(`Expected package: ${packageName}`);
113
+ console.error('');
114
+ console.error('To install:');
115
+ console.error(' npm install @harnspec/http-server');
116
+ console.error('');
117
+ process.exit(1);
118
+ }
119
+
120
+ // Execute binary
121
+ const binaryPath = getBinaryPath();
122
+ const args = process.argv.slice(2);
123
+
124
+ debug('Spawning binary:', binaryPath);
125
+ debug('Arguments:', args);
126
+
127
+ const child = spawn(binaryPath, args, {
128
+ stdio: 'inherit',
129
+ windowsHide: true,
130
+ });
131
+
132
+ child.on('exit', (code) => {
133
+ debug('Binary exited with code:', code);
134
+ process.exit(code ?? 1);
135
+ });
136
+
137
+ child.on('error', (err) => {
138
+ console.error('Failed to start harnspec-http:', err.message);
139
+ debug('Spawn error:', err);
140
+ process.exit(1);
141
+ });
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@harnspec/http-darwin-arm64",
3
+ "version": "0.0.1",
4
+ "description": "HarnSpec HTTP Server binary for macOS ARM64",
5
+ "os": [
6
+ "darwin"
7
+ ],
8
+ "cpu": [
9
+ "arm64"
10
+ ],
11
+ "main": "harnspec-http",
12
+ "files": [
13
+ "harnspec-http",
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-http');
10
+
11
+ try {
12
+ chmodSync(binaryPath, 0o755);
13
+ console.log('✓ Set execute permissions on harnspec-http binary');
14
+ } catch (err) {
15
+ console.error('Warning: Could not set execute permissions:', err.message);
16
+ // Don't fail the install
17
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@harnspec/http-darwin-x64",
3
+ "version": "0.0.1",
4
+ "description": "HarnSpec HTTP Server binary for macOS x64",
5
+ "os": [
6
+ "darwin"
7
+ ],
8
+ "cpu": [
9
+ "x64"
10
+ ],
11
+ "main": "harnspec-http",
12
+ "files": [
13
+ "harnspec-http",
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-http');
10
+
11
+ try {
12
+ chmodSync(binaryPath, 0o755);
13
+ console.log('✓ Set execute permissions on harnspec-http binary');
14
+ } catch (err) {
15
+ console.error('Warning: Could not set execute permissions:', err.message);
16
+ // Don't fail the install
17
+ }
Binary file
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@harnspec/http-linux-x64",
3
+ "version": "0.0.1",
4
+ "description": "HarnSpec HTTP Server binary for Linux x64",
5
+ "os": [
6
+ "linux"
7
+ ],
8
+ "cpu": [
9
+ "x64"
10
+ ],
11
+ "main": "harnspec-http",
12
+ "files": [
13
+ "harnspec-http",
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-http');
10
+
11
+ try {
12
+ chmodSync(binaryPath, 0o755);
13
+ console.log('✓ Set execute permissions on harnspec-http binary');
14
+ } catch (err) {
15
+ console.error('Warning: Could not set execute permissions:', err.message);
16
+ // Don't fail the install
17
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@harnspec/http-windows-x64",
3
+ "version": "0.0.1",
4
+ "description": "HarnSpec HTTP Server binary for Windows x64",
5
+ "os": [
6
+ "win32"
7
+ ],
8
+ "cpu": [
9
+ "x64"
10
+ ],
11
+ "main": "harnspec-http.exe",
12
+ "files": [
13
+ "harnspec-http.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
+ }
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Postinstall script - no-op on Windows (permissions not needed).
4
+ * This file exists for consistency across all platform packages.
5
+ */
6
+ console.log('✓ harnspec-http.exe ready');
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@harnspec/http-server",
3
+ "version": "0.0.1",
4
+ "description": "Rust HTTP server for HarnSpec UI",
5
+ "type": "module",
6
+ "bin": {
7
+ "harnspec-http": "./bin/harnspec-http.js"
8
+ },
9
+ "scripts": {
10
+ "dev": "RUST_BACKTRACE=1 HARNSPEC_DEBUG=1 HARNSPEC_DEV_MODE=1 nodemon --watch ./binaries --ignore '*.js' --ignore '*.json' --delay 1 --exec 'node ./bin/harnspec-http.js -v --no-open'",
11
+ "typecheck": "echo 'No TypeScript source to check'"
12
+ },
13
+ "keywords": [
14
+ "harnspec",
15
+ "http",
16
+ "server",
17
+ "api",
18
+ "rust"
19
+ ],
20
+ "author": "Marvin Zhang",
21
+ "license": "MIT AND Commons-Clause-1.0",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/harnspec/harnspec.git"
25
+ },
26
+ "homepage": "https://harnspec.github.io",
27
+ "bugs": {
28
+ "url": "https://github.com/harnspec/harnspec/issues"
29
+ },
30
+ "files": [
31
+ "bin/",
32
+ "binaries/",
33
+ "README.md",
34
+ "LICENSE"
35
+ ],
36
+ "engines": {
37
+ "node": ">=20"
38
+ },
39
+ "devDependencies": {
40
+ "nodemon": "^3.1.11"
41
+ },
42
+ "optionalDependencies": {
43
+ "@harnspec/http-darwin-x64": "0.0.1",
44
+ "@harnspec/http-darwin-arm64": "0.0.1",
45
+ "@harnspec/http-linux-x64": "0.0.1",
46
+ "@harnspec/http-windows-x64": "0.0.1"
47
+ }
48
+ }