Skip to content

Commit 265f67c

Browse files
authored
Merge pull request #2 from link-foundation/issue-1-025320ceee9d
feat: Implement setProcessName function with cross-platform, multi-runtime support
2 parents 82dc099 + 4adad09 commit 265f67c

File tree

16 files changed

+1140
-216
lines changed

16 files changed

+1140
-216
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
'set-process-name': minor
3+
---
4+
5+
Implement setProcessName function with cross-platform and multi-runtime support
6+
7+
- Add setProcessName() async function to set process name visible in system monitoring tools
8+
- Add setProcessNameSync() synchronous version for simpler use cases
9+
- Add getProcessName() to retrieve current process name
10+
- Add getCapabilities() to check platform/runtime capabilities
11+
- Add detectRuntime() and detectPlatform() utility functions
12+
- Support Node.js with native process.title (uses libuv prctl internally on Linux)
13+
- Support Bun with FFI-based prctl for Linux
14+
- Support Deno with FFI-based prctl for Linux
15+
- Cross-platform: Linux (prctl), macOS (process.title), Windows (process.title)
16+
- Include comprehensive test suite (31 tests)
17+
- Include TypeScript type definitions
18+
- Include case study documentation

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,6 @@ vite.config.ts.timestamp-*
140140

141141
# jscpd reports
142142
reports/
143+
144+
# Deno lock file (generated by Deno runtime - not needed for library distribution)
145+
deno.lock

README.md

Lines changed: 169 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -1,196 +1,231 @@
1-
# js-ai-driven-development-pipeline-template
1+
# set-process-name
22

3-
A comprehensive template for AI-driven JavaScript/TypeScript development with full CI/CD pipeline support.
3+
Cross-platform, multi-runtime library to set the process name visible in system monitoring tools (top, ps, htop, Activity Monitor, Task Manager, etc.).
44

55
## Features
66

7-
- **Multi-runtime support**: Works with Bun, Node.js, and Deno
8-
- **Universal testing**: Uses [test-anywhere](https://github.com/link-foundation/test-anywhere) for cross-runtime tests
9-
- **Automated releases**: Changesets-based versioning with GitHub Actions
10-
- **Code quality**: ESLint + Prettier with pre-commit hooks via Husky
11-
- **Package manager agnostic**: Works with bun, npm, yarn, pnpm, and deno
7+
- **Multi-runtime support**: Works with Node.js, Bun, and Deno
8+
- **Cross-platform**: Supports Linux, macOS, and Windows
9+
- **Zero dependencies**: Pure JavaScript with optional FFI for enhanced Linux support
10+
- **TypeScript support**: Full type definitions included
11+
- **Comprehensive API**: Async and sync versions, getters, and capability detection
12+
13+
## Installation
14+
15+
```bash
16+
# npm
17+
npm install set-process-name
18+
19+
# bun
20+
bun add set-process-name
21+
22+
# deno
23+
deno add jsr:@link-foundation/set-process-name
24+
```
1225

1326
## Quick Start
1427

15-
### Using This Template
28+
```javascript
29+
import { setProcessName } from 'set-process-name';
1630

17-
1. Click "Use this template" on GitHub to create a new repository
18-
2. Clone your new repository
19-
3. Update `package.json` with your package name and description
20-
4. Update the `PACKAGE_NAME` constant in these scripts:
21-
- `scripts/validate-changeset.mjs`
22-
- `scripts/merge-changesets.mjs`
23-
- `scripts/publish-to-npm.mjs`
24-
- `scripts/format-release-notes.mjs`
25-
- `scripts/create-manual-changeset.mjs`
26-
5. Install dependencies: `bun install`
27-
6. Start developing!
31+
// Set the process name
32+
await setProcessName('my-app');
2833

29-
### Development
34+
// Now 'my-app' appears in top, ps, htop instead of 'node' or 'bun'
35+
```
3036

31-
```bash
32-
# Install dependencies
33-
bun install
37+
## API Reference
3438

35-
# Run tests
36-
bun test
39+
### `setProcessName(name: string): Promise<SetProcessNameResult>`
3740

38-
# Or with other runtimes:
39-
npm test
40-
deno test --allow-read
41+
Sets the process name visible in system monitoring tools.
4142

42-
# Lint code
43-
bun run lint
43+
```javascript
44+
import { setProcessName } from 'set-process-name';
4445

45-
# Format code
46-
bun run format
46+
const result = await setProcessName('my-service');
4747

48-
# Check all (lint + format + file size)
49-
bun run check
48+
console.log(result);
49+
// {
50+
// success: true,
51+
// processTitle: true, // process.title was set successfully
52+
// prctl: true, // prctl was called successfully (Linux only)
53+
// runtime: 'node', // detected runtime
54+
// platform: 'linux' // detected platform
55+
// }
5056
```
5157

52-
## Project Structure
58+
### `setProcessNameSync(name: string): SetProcessNameResult`
59+
60+
Synchronous version. Note: On Bun runtime, prctl changes may not be applied (use async version for full functionality).
5361

62+
```javascript
63+
import { setProcessNameSync } from 'set-process-name';
64+
65+
const result = setProcessNameSync('my-service');
5466
```
55-
.
56-
├── .changeset/ # Changeset configuration
57-
├── .github/workflows/ # GitHub Actions CI/CD
58-
├── .husky/ # Git hooks (pre-commit)
59-
├── examples/ # Usage examples
60-
├── scripts/ # Build and release scripts
61-
├── src/ # Source code
62-
│ ├── index.js # Main entry point
63-
│ └── index.d.ts # TypeScript definitions
64-
├── tests/ # Test files
65-
├── .eslintrc.js # ESLint configuration
66-
├── .prettierrc # Prettier configuration
67-
├── bunfig.toml # Bun configuration
68-
├── deno.json # Deno configuration
69-
└── package.json # Node.js package manifest
67+
68+
### `getProcessName(): string | null`
69+
70+
Gets the current process name from `process.title`.
71+
72+
```javascript
73+
import { getProcessName, setProcessName } from 'set-process-name';
74+
75+
await setProcessName('my-app');
76+
console.log(getProcessName()); // 'my-app'
7077
```
7178

72-
## Design Choices
79+
### `getCapabilities(): Capabilities`
80+
81+
Returns information about what features are available on the current platform/runtime.
7382

74-
### Multi-Runtime Support
83+
```javascript
84+
import { getCapabilities } from 'set-process-name';
85+
86+
const caps = getCapabilities();
87+
console.log(caps);
88+
// {
89+
// canSetTitle: true, // process.title can be set
90+
// canSetPrctl: true, // prctl is available (Linux only)
91+
// runtime: 'node',
92+
// platform: 'linux'
93+
// }
94+
```
7595

76-
This template is designed to work seamlessly with all major JavaScript runtimes:
96+
### `detectRuntime(): 'node' | 'bun' | 'deno' | 'unknown'`
7797

78-
- **Bun**: Primary runtime with highest performance, uses native test support (`bun test`)
79-
- **Node.js**: Alternative runtime, uses built-in test runner (`node --test`)
80-
- **Deno**: Secure runtime with built-in TypeScript support (`deno test`)
98+
Detects the current JavaScript runtime.
8199

82-
The [test-anywhere](https://github.com/link-foundation/test-anywhere) framework provides a unified testing API that works identically across all runtimes.
100+
### `detectPlatform(): 'linux' | 'darwin' | 'win32' | 'unknown'`
83101

84-
### Package Manager Agnostic
102+
Detects the current operating system.
85103

86-
While `package.json` is the source of truth for dependencies, the template supports:
104+
## Platform-Specific Behavior
87105

88-
- **bun**: Primary choice, uses `bun.lockb`
89-
- **npm**: Uses `package-lock.json`
90-
- **yarn**: Uses `yarn.lock`
91-
- **pnpm**: Uses `pnpm-lock.yaml`
92-
- **deno**: Uses `deno.json` for configuration
106+
### Linux
93107

94-
Note: `package-lock.json` is not committed by default to allow any package manager.
108+
- Uses `process.title` (which internally uses `prctl` via libuv in Node.js)
109+
- On Bun/Deno: Uses FFI to call `prctl(PR_SET_NAME, name)` directly
110+
- Name is truncated to 15 characters (Linux kernel limitation for `/proc/<pid>/comm`)
111+
- Process name visible in `top`, `ps`, `htop`, and `/proc/<pid>/comm`
95112

96-
### Code Quality
113+
### macOS
97114

98-
- **ESLint**: Configured with recommended rules + Prettier integration
99-
- **Prettier**: Consistent code formatting
100-
- **Husky + lint-staged**: Pre-commit hooks ensure code quality
101-
- **File size limit**: Scripts must stay under 1000 lines for maintainability
115+
- Uses `process.title` which works via libuv in Node.js
116+
- Process name visible in Activity Monitor and `ps`
102117

103-
### Release Workflow
118+
### Windows
104119

105-
The release workflow uses [Changesets](https://github.com/changesets/changesets) for version management:
120+
- Uses `process.title` for console title
121+
- Task Manager always shows executable name (cosmetic only)
106122

107-
1. **Creating a changeset**: Run `bun run changeset` to document changes
108-
2. **PR validation**: CI checks for valid changeset in each PR
109-
3. **Automated versioning**: Merging to `main` triggers version bump
110-
4. **npm publishing**: Automated via OIDC trusted publishing (no tokens needed)
111-
5. **GitHub releases**: Auto-created with formatted release notes
123+
## Runtime Support
112124

113-
#### Manual Releases
125+
| Runtime | process.title | prctl (Linux) |
126+
| ------- | ------------- | -------------- |
127+
| Node.js || ✅ (via libuv) |
128+
| Bun || ✅ (via FFI) |
129+
| Deno || ✅ (via FFI) |
114130

115-
Two manual release modes are available via GitHub Actions:
131+
## Examples
116132

117-
- **Instant release**: Immediately bump version and publish
118-
- **Changeset PR**: Create a PR with changeset for review
133+
### Basic Usage
119134

120-
### CI/CD Pipeline
135+
```javascript
136+
import { setProcessName, getProcessName } from 'set-process-name';
121137

122-
The GitHub Actions workflow (`.github/workflows/release.yml`) provides:
138+
async function main() {
139+
console.log('Before:', getProcessName()); // 'node'
123140

124-
1. **Changeset check**: Validates PR has exactly one changeset (added by that PR)
125-
2. **Lint & format**: Ensures code quality standards
126-
3. **Test matrix**: 3 runtimes × 3 OS = 9 test combinations
127-
4. **Changeset merge**: Combines multiple pending changesets at release time
128-
5. **Release**: Automated versioning and npm publishing
141+
await setProcessName('my-daemon');
129142

130-
#### Robust Changeset Handling
143+
console.log('After:', getProcessName()); // 'my-daemon'
144+
}
131145

132-
The CI/CD pipeline is designed to handle concurrent PRs gracefully:
146+
main();
147+
```
133148

134-
- **PR Validation**: Only validates changesets **added by the current PR**, not pre-existing ones from other merged PRs. This prevents false failures when multiple PRs merge before a release cycle completes.
149+
### With Capability Check
135150

136-
- **Release-time Merging**: If multiple changesets exist when releasing, they are automatically merged into a single changeset with:
137-
- The highest version bump type (major > minor > patch)
138-
- All descriptions preserved in chronological order
151+
```javascript
152+
import { setProcessName, getCapabilities } from 'set-process-name';
139153

140-
This design decouples PR validation from the need to pull changes from the default branch, reducing conflicts and ensuring that even if CI/CD fails, all unpublished changesets will still get published when the error is resolved.
154+
const caps = getCapabilities();
141155

142-
## Configuration
156+
if (caps.canSetPrctl) {
157+
console.log('Full Linux prctl support available');
158+
}
143159

144-
### Updating Package Name
160+
const result = await setProcessName('worker-1');
145161

146-
After creating a repository from this template, update the package name in:
162+
if (result.success) {
163+
console.log('Process name set successfully');
164+
} else {
165+
console.log('Could not set process name (non-critical)');
166+
}
167+
```
147168

148-
1. `package.json`: `"name": "your-package-name"`
149-
2. `.changeset/config.json`: Package references
150-
3. Scripts that reference the package name (see Quick Start)
169+
### CLI Application
151170

152-
### ESLint Rules
171+
```javascript
172+
#!/usr/bin/env node
173+
import { setProcessName } from 'set-process-name';
153174

154-
Customize ESLint in `eslint.config.js`. Current configuration:
175+
// Set process name at startup
176+
await setProcessName('my-cli');
155177

156-
- ES Modules support
157-
- Prettier integration
158-
- No console restrictions (common in CLI tools)
159-
- Strict equality enforcement
160-
- Async/await best practices
161-
- **Strict unused variables rule**: No exceptions - all unused variables, arguments, and caught errors must be removed (no `_` prefix exceptions)
178+
// Your CLI code here...
179+
```
162180

163-
### Prettier Options
181+
## TypeScript
164182

165-
Configured in `.prettierrc`:
183+
Full TypeScript support with type definitions:
166184

167-
- Single quotes
168-
- Semicolons
169-
- 2-space indentation
170-
- 80-character line width
171-
- ES5 trailing commas
172-
- LF line endings
185+
```typescript
186+
import {
187+
setProcessName,
188+
SetProcessNameResult,
189+
Capabilities,
190+
Runtime,
191+
Platform,
192+
} from 'set-process-name';
173193

174-
## Scripts Reference
194+
const result: SetProcessNameResult = await setProcessName('typed-app');
195+
```
175196

176-
| Script | Description |
177-
| ---------------------- | --------------------------------------- |
178-
| `bun test` | Run tests with Bun |
179-
| `bun run lint` | Check code with ESLint |
180-
| `bun run lint:fix` | Fix ESLint issues automatically |
181-
| `bun run format` | Format code with Prettier |
182-
| `bun run format:check` | Check formatting without changing files |
183-
| `bun run check` | Run all checks (lint + format) |
184-
| `bun run changeset` | Create a new changeset |
197+
## Testing
185198

186-
## Contributing
199+
```bash
200+
# Node.js
201+
npm test
202+
203+
# Bun
204+
bun test
205+
206+
# Deno
207+
deno test --allow-read
208+
```
187209

188-
1. Fork the repository
189-
2. Create a feature branch: `git checkout -b feature/my-feature`
190-
3. Make your changes
191-
4. Create a changeset: `bun run changeset`
192-
5. Commit your changes (pre-commit hooks will run automatically)
193-
6. Push and create a Pull Request
210+
## How It Works
211+
212+
1. **JavaScript Level**: Sets `process.title` and `process.argv0`
213+
2. **Node.js**: `process.title` setter uses libuv which internally calls `prctl` on Linux
214+
3. **Bun/Deno on Linux**: Uses FFI to call `prctl(PR_SET_NAME, name)` directly
215+
4. **macOS/Windows**: Relies on `process.title` for best-effort support
216+
217+
## Comparison with Alternatives
218+
219+
| Feature | set-process-name | process-title | process-name |
220+
| ------------------ | ---------------- | ------------- | ------------ |
221+
| Set process name ||||
222+
| Linux prctl ||||
223+
| Node.js ||||
224+
| Bun ||||
225+
| Deno ||||
226+
| Zero dependencies ||||
227+
| TypeScript support ||||
228+
| Active maintenance ||||
194229

195230
## License
196231

deno.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
"test": {
44
"include": ["tests/"],
55
"exclude": ["examples/", "node_modules/"]
6-
}
6+
},
7+
"unstable": ["ffi"]
78
}

0 commit comments

Comments
 (0)