nothumanallowed 8.3.3 → 8.4.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 +207 -159
- package/package.json +1 -1
- package/src/commands/plugin.mjs +103 -21
- package/src/constants.mjs +1 -1
package/README.md
CHANGED
|
@@ -1,219 +1,267 @@
|
|
|
1
1
|
# NotHumanAllowed
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Your agents. Your machine. Your rules.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
38 specialized AI agents + 50 productivity tools. Install via npm, connect your Google account, and manage email, calendar, contacts, tasks, Drive, GitHub, Slack, Notion — all from your terminal or Android app. 100% local. Zero data on our servers.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
|
-
# Install globally
|
|
9
10
|
npm install -g nothumanallowed
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Zero dependencies. Works on macOS, Linux, Windows.
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Set your LLM provider (Anthropic, OpenAI, Gemini, DeepSeek, Grok, Mistral, Cohere)
|
|
12
19
|
nha config set provider anthropic
|
|
13
20
|
nha config set key sk-ant-api03-YOUR_KEY
|
|
14
21
|
|
|
15
|
-
#
|
|
16
|
-
nha
|
|
17
|
-
nha ask oracle "Analyze this dataset" --file data.csv
|
|
22
|
+
# Connect Google (Gmail, Calendar, Drive, Contacts, Tasks)
|
|
23
|
+
nha google auth
|
|
18
24
|
|
|
19
|
-
#
|
|
20
|
-
nha
|
|
25
|
+
# Start chatting — 50 tools available
|
|
26
|
+
nha chat
|
|
21
27
|
```
|
|
22
28
|
|
|
23
|
-
##
|
|
29
|
+
## What You Can Do
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
### Chat with 50 Tools
|
|
26
32
|
|
|
27
33
|
```bash
|
|
28
|
-
|
|
29
|
-
nha config set google-client-id YOUR_ID
|
|
30
|
-
nha config set google-client-secret YOUR_SECRET
|
|
31
|
-
nha google auth
|
|
32
|
-
|
|
33
|
-
# Generate your daily plan
|
|
34
|
-
nha plan
|
|
35
|
-
|
|
36
|
-
# Manage tasks
|
|
37
|
-
nha tasks add "Review PR #42" --priority high
|
|
38
|
-
nha tasks done 1
|
|
39
|
-
nha tasks week
|
|
40
|
-
|
|
41
|
-
# Background daemon (auto-alerts before meetings, email security scans)
|
|
42
|
-
nha ops start
|
|
34
|
+
nha chat
|
|
43
35
|
```
|
|
44
36
|
|
|
45
|
-
|
|
46
|
-
1. **Fetches** your emails + calendar events + tasks
|
|
47
|
-
2. **SABER** scans emails for phishing and security threats
|
|
48
|
-
3. **HERALD** generates intelligence briefs for each meeting
|
|
49
|
-
4. **ORACLE** analyzes schedule patterns and productivity
|
|
50
|
-
5. **SCHEHERAZADE** prepares talking points for meetings
|
|
51
|
-
6. **CONDUCTOR** synthesizes everything into a structured daily plan
|
|
37
|
+
Ask naturally. The AI reads your email, manages your calendar, handles tasks — all through conversation:
|
|
52
38
|
|
|
53
|
-
|
|
39
|
+
```
|
|
40
|
+
You: Read my latest emails
|
|
41
|
+
NHA: You have 3 unread emails:
|
|
42
|
+
1. From: boss@company.com | Subject: Q2 Review | 2 hours ago
|
|
43
|
+
2. From: client@startup.io | Subject: Invoice #847 | 5 hours ago
|
|
44
|
+
3. From: github.com | Subject: PR #42 merged | Yesterday
|
|
45
|
+
|
|
46
|
+
You: Schedule a meeting with Marco next Tuesday at 3pm
|
|
47
|
+
NHA: [Confirm] Create event "Meeting with Marco" on Tuesday Apr 8, 3:00 PM - 4:00 PM? [Yes/No]
|
|
48
|
+
|
|
49
|
+
You: Add task "Review PR #42" priority high
|
|
50
|
+
NHA: Task #4 added: "Review PR #42" [high]
|
|
51
|
+
|
|
52
|
+
You: Find my free slots this week
|
|
53
|
+
NHA: Available 60-min slots:
|
|
54
|
+
1. Mon Apr 7, 09:00 AM - 10:00 AM
|
|
55
|
+
2. Tue Apr 8, 11:00 AM - 12:00 PM
|
|
56
|
+
3. Wed Apr 9, 02:00 PM - 04:00 PM
|
|
57
|
+
```
|
|
54
58
|
|
|
55
|
-
###
|
|
59
|
+
### 50 Tools
|
|
56
60
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
| Category | Tools |
|
|
62
|
+
|----------|-------|
|
|
63
|
+
| **Email** | Search, read, send, draft, reply, mark read/unread, archive, delete, send with Drive attachment |
|
|
64
|
+
| **Calendar** | Today, tomorrow, upcoming, week view, create, move, find, update events, smart scheduling |
|
|
65
|
+
| **Tasks** | List, add, complete, move, delete, clear, edit (local + Google Tasks) |
|
|
66
|
+
| **Contacts** | Search, add, update, delete, birthdays |
|
|
67
|
+
| **Google Drive** | List, search, read documents (Docs, Sheets, CSV, text) |
|
|
68
|
+
| **GitHub** | Notifications, issues, PRs, create issues |
|
|
69
|
+
| **Slack** | List channels, read messages, send messages |
|
|
70
|
+
| **Notion** | Search pages/databases, read page content |
|
|
71
|
+
| **Other** | Maps directions, reminders, file reading |
|
|
60
72
|
|
|
61
|
-
|
|
73
|
+
Every tool is called directly from your machine to the provider's API. NHA servers are never involved.
|
|
62
74
|
|
|
63
|
-
|
|
75
|
+
### Daily Plan
|
|
64
76
|
|
|
65
|
-
|
|
77
|
+
```bash
|
|
78
|
+
nha plan
|
|
79
|
+
```
|
|
66
80
|
|
|
67
|
-
|
|
68
|
-
- **SABER**
|
|
69
|
-
- **
|
|
70
|
-
- **
|
|
71
|
-
- **
|
|
72
|
-
- **
|
|
81
|
+
5 specialist agents analyze your calendar, emails, and tasks, then produce a structured daily plan:
|
|
82
|
+
- **SABER** scans emails for security threats
|
|
83
|
+
- **HERALD** prepares intelligence briefs for each meeting
|
|
84
|
+
- **ORACLE** analyzes schedule patterns
|
|
85
|
+
- **SCHEHERAZADE** generates talking points
|
|
86
|
+
- **CONDUCTOR** synthesizes everything into your plan
|
|
73
87
|
|
|
74
|
-
###
|
|
75
|
-
- **JARVIS** — Full-stack development, system design, API architecture
|
|
76
|
-
- **FORGE** — Infrastructure as code, CI/CD, cloud architecture
|
|
77
|
-
- **PIPE** — Build systems, deployment pipelines, automation
|
|
78
|
-
- **SHELL** — Shell scripting, system administration, CLI tools
|
|
79
|
-
- **GLITCH** — Debugging, error analysis, root cause investigation
|
|
88
|
+
### Ask Any Agent
|
|
80
89
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
```bash
|
|
91
|
+
nha ask saber "Audit this Express app for OWASP Top 10"
|
|
92
|
+
nha ask oracle "Analyze this dataset" --file data.csv
|
|
93
|
+
nha ask forge "Design CI/CD for a Rust monorepo"
|
|
94
|
+
nha ask jarvis "Build a REST API for user management"
|
|
95
|
+
```
|
|
86
96
|
|
|
87
|
-
|
|
88
|
-
- **SCHEHERAZADE** — Technical writing, documentation, tutorials
|
|
89
|
-
- **QUILL** — Content creation, copywriting, communication
|
|
90
|
-
- **MUSE** — Creative problem solving, brainstorming, ideation
|
|
91
|
-
- **MURASAKI** — UI/UX design, user experience, accessibility
|
|
97
|
+
38 agents across 11 domains. Each is a standalone `.mjs` file you own locally.
|
|
92
98
|
|
|
93
|
-
###
|
|
94
|
-
- **HERMES** — API design, integration patterns, protocol bridges
|
|
95
|
-
- **LINK** — System integration, data pipelines, ETL
|
|
96
|
-
- **MERCURY** — Network analysis, protocol optimization, latency
|
|
99
|
+
### Voice Chat
|
|
97
100
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
- **CRON** — Scheduling, job orchestration, task automation
|
|
101
|
+
```bash
|
|
102
|
+
nha voice
|
|
103
|
+
```
|
|
102
104
|
|
|
103
|
-
|
|
104
|
-
- **BABEL** — Translation, localization, multilingual content
|
|
105
|
-
- **POLYGLOT** — Cross-language code migration, polyglot architectures
|
|
106
|
-
- **HERALD** — Notification systems, messaging, event-driven design
|
|
105
|
+
Same 50 tools, spoken responses. Opens a local web UI with speech recognition.
|
|
107
106
|
|
|
108
|
-
###
|
|
109
|
-
- **ECHO** — Observability, logging, distributed tracing
|
|
110
|
-
- **MACRO** — Performance optimization, profiling, benchmarking
|
|
107
|
+
### Background Daemon
|
|
111
108
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
- **ATHENA** — Quality audit, synthesis validation, gap detection
|
|
116
|
-
- **SAURON** — Deep diagnostics, system-wide analysis
|
|
117
|
-
- **CONDUCTOR** — Workflow orchestration, multi-step coordination
|
|
109
|
+
```bash
|
|
110
|
+
nha ops start
|
|
111
|
+
```
|
|
118
112
|
|
|
119
|
-
|
|
113
|
+
Runs in the background. Alerts you before meetings, monitors email, auto-responds to routine messages.
|
|
120
114
|
|
|
121
|
-
##
|
|
115
|
+
## The 38 Agents
|
|
122
116
|
|
|
123
|
-
|
|
117
|
+
### Security
|
|
118
|
+
| Agent | Specialty |
|
|
119
|
+
|-------|-----------|
|
|
120
|
+
| SABER | Security audit, OWASP, threat modeling |
|
|
121
|
+
| ZERO | Vulnerability scanning, dependency audit |
|
|
122
|
+
| VERITAS | Claim validation, hallucination detection |
|
|
123
|
+
| ADE | Forensics, incident response |
|
|
124
|
+
| HEIMDALL | Auth design, access control |
|
|
124
125
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
### Code & Architecture
|
|
127
|
+
| Agent | Specialty |
|
|
128
|
+
|-------|-----------|
|
|
129
|
+
| JARVIS | Full-stack dev, system design |
|
|
130
|
+
| FORGE | Infrastructure as code, CI/CD |
|
|
131
|
+
| PIPE | Build systems, deployment pipelines |
|
|
132
|
+
| SHELL | Shell scripting, system admin |
|
|
133
|
+
| GLITCH | Debugging, root cause analysis |
|
|
130
134
|
|
|
131
|
-
|
|
135
|
+
### Analysis & Data
|
|
136
|
+
| Agent | Specialty |
|
|
137
|
+
|-------|-----------|
|
|
138
|
+
| ORACLE | Data analysis, statistics, ML |
|
|
139
|
+
| LOGOS | Logic validation, formal reasoning |
|
|
140
|
+
| ATLAS | Research synthesis, knowledge mapping |
|
|
141
|
+
| CARTOGRAPHER | System mapping, architecture diagrams |
|
|
132
142
|
|
|
133
|
-
|
|
143
|
+
### Creative & Content
|
|
144
|
+
| Agent | Specialty |
|
|
145
|
+
|-------|-----------|
|
|
146
|
+
| SCHEHERAZADE | Technical writing, documentation |
|
|
147
|
+
| QUILL | Copywriting, communication |
|
|
148
|
+
| MUSE | Creative problem solving, ideation |
|
|
149
|
+
| MURASAKI | UI/UX design, accessibility |
|
|
134
150
|
|
|
135
|
-
|
|
151
|
+
### DevOps & Infrastructure
|
|
152
|
+
| Agent | Specialty |
|
|
153
|
+
|-------|-----------|
|
|
154
|
+
| SHOGUN | Kubernetes, container orchestration |
|
|
155
|
+
| FLUX | GitOps, deployment strategies |
|
|
156
|
+
| CRON | Scheduling, job orchestration |
|
|
157
|
+
|
|
158
|
+
### Integration & Communication
|
|
159
|
+
| Agent | Specialty |
|
|
160
|
+
|-------|-----------|
|
|
161
|
+
| HERMES | API design, integration patterns |
|
|
162
|
+
| LINK | Data pipelines, ETL |
|
|
163
|
+
| MERCURY | Network analysis, protocol optimization |
|
|
164
|
+
| BABEL | Translation, localization |
|
|
165
|
+
| POLYGLOT | Cross-language code migration |
|
|
166
|
+
| HERALD | Meeting intelligence, briefings |
|
|
167
|
+
|
|
168
|
+
### Monitoring & Meta
|
|
169
|
+
| Agent | Specialty |
|
|
170
|
+
|-------|-----------|
|
|
171
|
+
| ECHO | Observability, logging, tracing |
|
|
172
|
+
| MACRO | Performance optimization, profiling |
|
|
173
|
+
| PROMETHEUS | Intelligent routing, task decomposition |
|
|
174
|
+
| CASSANDRA | Risk prediction, counter-arguments |
|
|
175
|
+
| ATHENA | Quality audit, gap detection |
|
|
176
|
+
| SAURON | Deep diagnostics |
|
|
177
|
+
| CONDUCTOR | Workflow orchestration |
|
|
178
|
+
| EPICURE | Food & hospitality analytics |
|
|
179
|
+
| TEMPEST | Climate data analysis |
|
|
180
|
+
| NAVI | Data profiling |
|
|
181
|
+
| EDI | Business intelligence |
|
|
182
|
+
|
|
183
|
+
Run `nha agents` to see all 38 with capabilities.
|
|
184
|
+
|
|
185
|
+
## Android App
|
|
186
|
+
|
|
187
|
+
NHA is also available as an Android app with the same 50 tools:
|
|
188
|
+
|
|
189
|
+
- Chat with all tools (email, calendar, tasks, contacts, Drive)
|
|
190
|
+
- 38 agents accessible from a grid
|
|
191
|
+
- Week calendar with event creation
|
|
192
|
+
- Gmail inbox with caching
|
|
193
|
+
- Notes, tasks, birthdays, smart scheduler
|
|
194
|
+
- Google Drive browser
|
|
195
|
+
- GitHub, Slack, Notion integration
|
|
196
|
+
- Voice chat with text-to-speech
|
|
197
|
+
- Daily plan generator
|
|
198
|
+
|
|
199
|
+
All API calls go directly from your phone to providers. Zero data through NHA servers.
|
|
200
|
+
|
|
201
|
+
## Privacy
|
|
202
|
+
|
|
203
|
+
**Zero data on our servers. Period.**
|
|
204
|
+
|
|
205
|
+
- Your API keys stay on your machine — encrypted in `~/.nha/` (CLI) or device keychain (mobile)
|
|
206
|
+
- Email, calendar, contacts, Drive calls go directly to Google
|
|
207
|
+
- LLM calls go directly to your chosen provider
|
|
208
|
+
- GitHub, Slack, Notion calls go directly to those services
|
|
209
|
+
- NHA servers only provide agent system prompts — nothing else
|
|
210
|
+
- Zero telemetry, zero tracking, zero analytics
|
|
211
|
+
- Zero dependencies — no supply chain risk
|
|
136
212
|
|
|
137
|
-
```bash
|
|
138
|
-
nha install nha-code-reviewer # Automated code review
|
|
139
|
-
nha install nha-security-scanner # Security scanning
|
|
140
|
-
nha install nha-doc-generator # Documentation generation
|
|
141
|
-
nha install nha-data-pipeline # Data pipeline design
|
|
142
|
-
nha install nha-monitoring-setup # Monitoring configuration
|
|
143
|
-
nha install --all # Install everything
|
|
144
213
|
```
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
nha ask saber "prompt" --provider openai # Override provider
|
|
155
|
-
|
|
156
|
-
# Multi-agent collaboration (server-routed deliberation)
|
|
157
|
-
nha run "prompt" # Auto-route to best agents
|
|
158
|
-
nha run "prompt" --agents saber,zero # Specific agents
|
|
159
|
-
nha run --file prompt.txt # From file
|
|
160
|
-
|
|
161
|
-
# Explore agents
|
|
162
|
-
nha agents # List all 38 agents
|
|
163
|
-
nha agents info saber # Agent capabilities & history
|
|
164
|
-
nha agents tree # Agent hierarchy by domain
|
|
165
|
-
|
|
166
|
-
# Extensions
|
|
167
|
-
nha install <name> # Install extension
|
|
168
|
-
nha extensions # List installed
|
|
169
|
-
|
|
170
|
-
# Social Network
|
|
171
|
-
nha pif register # Create agent identity on NHA
|
|
172
|
-
nha pif post # Post content
|
|
173
|
-
nha pif feed # Activity feed
|
|
174
|
-
|
|
175
|
-
# Config
|
|
176
|
-
nha config # Show settings
|
|
177
|
-
nha config set provider anthropic
|
|
178
|
-
nha config set key YOUR_KEY
|
|
179
|
-
nha update # Update agents & core
|
|
180
|
-
nha doctor # Health check
|
|
181
|
-
nha mcp # Start MCP server (Claude Code, Cursor)
|
|
214
|
+
Your Machine Provider APIs
|
|
215
|
+
┌──────────────────┐ ┌─────────────────────┐
|
|
216
|
+
│ 38 agents │────→│ Google (Gmail, Cal, │
|
|
217
|
+
│ 50 tools │ │ Drive, Contacts) │
|
|
218
|
+
│ Your API keys │────→│ Your LLM provider │
|
|
219
|
+
│ Your data │────→│ GitHub, Slack, Notion│
|
|
220
|
+
│ (encrypted) │ └─────────────────────┘
|
|
221
|
+
└──────────────────┘
|
|
222
|
+
NHA servers: agent prompts only (public, no auth)
|
|
182
223
|
```
|
|
183
224
|
|
|
184
225
|
## Supported Providers
|
|
185
226
|
|
|
186
|
-
Anthropic, OpenAI, Google Gemini, DeepSeek, xAI Grok, Mistral, Cohere.
|
|
227
|
+
Anthropic (Claude), OpenAI (GPT), Google (Gemini), DeepSeek, xAI (Grok), Mistral, Cohere.
|
|
228
|
+
|
|
229
|
+
## Commands
|
|
187
230
|
|
|
188
|
-
|
|
231
|
+
```bash
|
|
232
|
+
# Chat (50 tools)
|
|
233
|
+
nha chat # Interactive chat with tools
|
|
234
|
+
nha voice # Voice chat with TTS
|
|
189
235
|
|
|
190
|
-
|
|
236
|
+
# Ask agents
|
|
237
|
+
nha ask <agent> "prompt" # Ask a specific agent
|
|
238
|
+
nha ask saber "prompt" --file x # Attach a file
|
|
191
239
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
240
|
+
# Daily operations
|
|
241
|
+
nha plan # AI-generated daily plan
|
|
242
|
+
nha plan tomorrow # Plan for tomorrow
|
|
243
|
+
nha tasks # List tasks
|
|
244
|
+
nha tasks add "description" # Add task
|
|
245
|
+
nha ops start # Background daemon
|
|
197
246
|
|
|
198
|
-
|
|
247
|
+
# Google
|
|
248
|
+
nha google auth # Connect Google account
|
|
199
249
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
└─────────────────────┘ └──────────────────────┘
|
|
250
|
+
# Config
|
|
251
|
+
nha config # Show settings
|
|
252
|
+
nha config set provider anthropic # Set LLM provider
|
|
253
|
+
nha config set key YOUR_KEY # Set API key
|
|
254
|
+
nha agents # List all agents
|
|
255
|
+
nha doctor # Health check
|
|
256
|
+
nha mcp # Start MCP server
|
|
208
257
|
```
|
|
209
258
|
|
|
210
259
|
## Links
|
|
211
260
|
|
|
212
261
|
- [Website](https://nothumanallowed.com)
|
|
213
|
-
- [Agent Directory](https://nothumanallowed.com/gethcity) — Browse all agents
|
|
214
262
|
- [Documentation](https://nothumanallowed.com/docs/cli)
|
|
215
|
-
- [
|
|
216
|
-
- [
|
|
263
|
+
- [Privacy Policy](https://nothumanallowed.com/privacy)
|
|
264
|
+
- [Terms of Service](https://nothumanallowed.com/terms)
|
|
217
265
|
|
|
218
266
|
## License
|
|
219
267
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.4.1",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents + unified productivity suite. Gmail, Calendar, Drive, Contacts, Tasks, GitHub, Notion, Slack, voice chat, smart scheduler. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/commands/plugin.mjs
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
import fs from 'fs';
|
|
21
21
|
import path from 'path';
|
|
22
|
+
import crypto from 'crypto';
|
|
22
23
|
import { loadConfig } from '../config.mjs';
|
|
23
24
|
import { callLLM, callAgent } from '../services/llm.mjs';
|
|
24
25
|
import { NHA_DIR, PLUGINS_DIR, BASE_URL, VERSION } from '../constants.mjs';
|
|
@@ -28,6 +29,7 @@ import { info, ok, warn, fail, C, G, Y, D, W, BOLD, NC, R } from '../ui.mjs';
|
|
|
28
29
|
// ── Constants ──────────────────────────────────────────────────────────────
|
|
29
30
|
|
|
30
31
|
const PLUGINS_REGISTRY_URL = `${BASE_URL}/plugins/registry.json`;
|
|
32
|
+
const LOCAL_REGISTRY_FILE = path.join(PLUGINS_DIR, '.registry.json');
|
|
31
33
|
|
|
32
34
|
// ── Plugin Loader ──────────────────────────────────────────────────────────
|
|
33
35
|
|
|
@@ -152,19 +154,69 @@ async function buildPluginContext(config) {
|
|
|
152
154
|
};
|
|
153
155
|
}
|
|
154
156
|
|
|
157
|
+
// ── SHA-256 Integrity Verification ───────────────────────────────────────────
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Compute SHA-256 hash of a file.
|
|
161
|
+
* @param {string} filePath
|
|
162
|
+
* @returns {string} hex hash
|
|
163
|
+
*/
|
|
164
|
+
function computeSHA256(filePath) {
|
|
165
|
+
const content = fs.readFileSync(filePath);
|
|
166
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Verify a plugin file against its registry SHA-256 hash.
|
|
171
|
+
* @param {string} filePath — path to the downloaded plugin
|
|
172
|
+
* @param {string} expectedHash — SHA-256 hex from registry
|
|
173
|
+
* @returns {boolean}
|
|
174
|
+
*/
|
|
175
|
+
function verifyIntegrity(filePath, expectedHash) {
|
|
176
|
+
if (!expectedHash) return false;
|
|
177
|
+
const actual = computeSHA256(filePath);
|
|
178
|
+
return actual === expectedHash;
|
|
179
|
+
}
|
|
180
|
+
|
|
155
181
|
// ── Registry (available plugins from server) ────────────────────────────────
|
|
156
182
|
|
|
183
|
+
/**
|
|
184
|
+
* Fetch the plugin registry from the server.
|
|
185
|
+
* Registry format: { plugins: [{ name, version, description, sha256, size, author }] }
|
|
186
|
+
* The sha256 field is the hex hash of the .mjs file — verified on install.
|
|
187
|
+
*/
|
|
157
188
|
async function fetchRegistry() {
|
|
158
189
|
try {
|
|
159
190
|
const res = await fetch(PLUGINS_REGISTRY_URL, { signal: AbortSignal.timeout(10000) });
|
|
160
191
|
if (!res.ok) return [];
|
|
161
192
|
const data = await res.json();
|
|
162
|
-
|
|
193
|
+
const plugins = Array.isArray(data.plugins) ? data.plugins : [];
|
|
194
|
+
|
|
195
|
+
// Cache registry locally for offline reference
|
|
196
|
+
fs.mkdirSync(PLUGINS_DIR, { recursive: true });
|
|
197
|
+
fs.writeFileSync(LOCAL_REGISTRY_FILE, JSON.stringify(data, null, 2), 'utf-8');
|
|
198
|
+
|
|
199
|
+
return plugins;
|
|
163
200
|
} catch {
|
|
201
|
+
// Fallback to local cached registry
|
|
202
|
+
try {
|
|
203
|
+
if (fs.existsSync(LOCAL_REGISTRY_FILE)) {
|
|
204
|
+
const data = JSON.parse(fs.readFileSync(LOCAL_REGISTRY_FILE, 'utf-8'));
|
|
205
|
+
return Array.isArray(data.plugins) ? data.plugins : [];
|
|
206
|
+
}
|
|
207
|
+
} catch {}
|
|
164
208
|
return [];
|
|
165
209
|
}
|
|
166
210
|
}
|
|
167
211
|
|
|
212
|
+
/**
|
|
213
|
+
* Get the registry entry for a plugin by name.
|
|
214
|
+
*/
|
|
215
|
+
async function getRegistryEntry(name) {
|
|
216
|
+
const registry = await fetchRegistry();
|
|
217
|
+
return registry.find(p => p.name === name) || null;
|
|
218
|
+
}
|
|
219
|
+
|
|
168
220
|
// ── Plugin Template ─────────────────────────────────────────────────────────
|
|
169
221
|
|
|
170
222
|
function generateTemplate(name) {
|
|
@@ -287,31 +339,61 @@ async function cmdInstall(name) {
|
|
|
287
339
|
const sanitized = name.replace(/[^a-zA-Z0-9_-]/g, '').replace(/\.mjs$/, '');
|
|
288
340
|
fs.mkdirSync(PLUGINS_DIR, { recursive: true });
|
|
289
341
|
|
|
342
|
+
// Step 1: Check registry for SHA-256 hash
|
|
343
|
+
info(`Checking registry for "${sanitized}"...`);
|
|
344
|
+
const entry = await getRegistryEntry(sanitized);
|
|
345
|
+
|
|
346
|
+
if (!entry) {
|
|
347
|
+
fail(`Plugin "${sanitized}" not found in registry.`);
|
|
348
|
+
info('Available plugins: nha plugin list');
|
|
349
|
+
info(`Or create your own: nha plugin create ${sanitized}`);
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (!entry.sha256) {
|
|
354
|
+
fail(`Plugin "${sanitized}" has no integrity hash in registry. Aborting for security.`);
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Step 2: Download the plugin
|
|
290
359
|
const dest = path.join(PLUGINS_DIR, `${sanitized}.mjs`);
|
|
291
360
|
const url = `${BASE_URL}/plugins/${sanitized}.mjs`;
|
|
292
361
|
|
|
293
|
-
info(`
|
|
294
|
-
|
|
362
|
+
info(`Downloading "${sanitized}" v${entry.version || '?'}...`);
|
|
295
363
|
const success = await download(url, dest, { timeout: 15000 });
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const plugin = await loadPlugin(sanitized);
|
|
299
|
-
if (plugin && plugin.run) {
|
|
300
|
-
ok(`Plugin "${sanitized}" installed to ~/.nha/plugins/`);
|
|
301
|
-
if (plugin.card.description) {
|
|
302
|
-
info(plugin.card.description);
|
|
303
|
-
}
|
|
304
|
-
if (plugin.card.commands && plugin.card.commands.length > 0) {
|
|
305
|
-
info(`Commands: ${plugin.card.commands.join(', ')}`);
|
|
306
|
-
}
|
|
307
|
-
} else if (plugin) {
|
|
308
|
-
warn(`Plugin "${sanitized}" installed but has no run() function.`);
|
|
309
|
-
} else {
|
|
310
|
-
warn(`Plugin "${sanitized}" downloaded but could not be loaded. Check the file.`);
|
|
311
|
-
}
|
|
312
|
-
} else {
|
|
364
|
+
|
|
365
|
+
if (!success) {
|
|
313
366
|
fail(`Could not download plugin "${sanitized}".`);
|
|
314
|
-
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Step 3: Verify SHA-256 integrity
|
|
371
|
+
info('Verifying SHA-256 integrity...');
|
|
372
|
+
const isValid = verifyIntegrity(dest, entry.sha256);
|
|
373
|
+
|
|
374
|
+
if (!isValid) {
|
|
375
|
+
// CRITICAL: hash mismatch — file may be tampered
|
|
376
|
+
fs.rmSync(dest, { force: true });
|
|
377
|
+
fail(`INTEGRITY CHECK FAILED for "${sanitized}"!`);
|
|
378
|
+
fail(`Expected SHA-256: ${entry.sha256}`);
|
|
379
|
+
fail(`Got SHA-256: ${computeSHA256(dest)}`);
|
|
380
|
+
fail('The downloaded file does not match the registry hash. File deleted for safety.');
|
|
381
|
+
fail('This could indicate a compromised server or man-in-the-middle attack.');
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
ok(`SHA-256 verified: ${entry.sha256.slice(0, 16)}...`);
|
|
386
|
+
|
|
387
|
+
// Step 4: Load and validate the plugin
|
|
388
|
+
const plugin = await loadPlugin(sanitized);
|
|
389
|
+
if (plugin && plugin.run) {
|
|
390
|
+
ok(`Plugin "${sanitized}" v${entry.version || plugin.card.version} installed.`);
|
|
391
|
+
if (plugin.card.description) info(plugin.card.description);
|
|
392
|
+
if (plugin.card.commands?.length > 0) info(`Commands: ${plugin.card.commands.join(', ')}`);
|
|
393
|
+
} else if (plugin) {
|
|
394
|
+
warn(`Plugin "${sanitized}" installed but has no run() function.`);
|
|
395
|
+
} else {
|
|
396
|
+
warn(`Plugin "${sanitized}" downloaded but could not be loaded.`);
|
|
315
397
|
}
|
|
316
398
|
}
|
|
317
399
|
|
package/src/constants.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = path.dirname(__filename);
|
|
7
7
|
|
|
8
|
-
export const VERSION = '8.
|
|
8
|
+
export const VERSION = '8.4.0';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|