pudu-ai 0.2.2
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/LICENSE +21 -0
- package/README.md +158 -0
- package/bin/pudu-ai.mjs +30 -0
- package/dist/cli/index.js +3068 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 devjaime
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# Pudu-AI
|
|
2
|
+
|
|
3
|
+
**Local AI Hardware & Benchmark Lab** for the terminal.
|
|
4
|
+
|
|
5
|
+
Discover, inspect, benchmark, and compare models that run on your machine. Measurements stay local. Estimates are never mixed with real `llama-bench` results.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx pudu-ai
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
English is the default UI language. Use `--lang es` for Spanish.
|
|
12
|
+
|
|
13
|
+
The npm name `pudu` is taken by an empty stub. This CLI is **`pudu-ai`**.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
From this repo (not yet on npm):
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
git clone https://github.com/devjaime/pudu-ai.git
|
|
21
|
+
cd pudu-ai
|
|
22
|
+
npm install
|
|
23
|
+
npx . --lang es
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm run pudu-ai -- --lang es
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
After publish:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx pudu-ai
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Commands
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npx pudu-ai
|
|
42
|
+
npx pudu-ai hardware
|
|
43
|
+
npx pudu-ai models
|
|
44
|
+
npx pudu-ai models add-path ~/Models
|
|
45
|
+
npx pudu-ai recommend
|
|
46
|
+
npx pudu-ai tasks
|
|
47
|
+
npx pudu-ai tasks --for code,image,transcription --lang es
|
|
48
|
+
npx pudu-ai benchmark
|
|
49
|
+
npx pudu-ai benchmark qwen3:8b
|
|
50
|
+
npx pudu-ai benchmark qwen3:8b --json --preset quick
|
|
51
|
+
npx pudu-ai compare
|
|
52
|
+
npx pudu-ai history
|
|
53
|
+
npx pudu-ai history --csv
|
|
54
|
+
npx pudu-ai doctor
|
|
55
|
+
npx pudu-ai report --markdown
|
|
56
|
+
npx pudu-ai launch
|
|
57
|
+
npx pudu-ai launch opencode
|
|
58
|
+
npx pudu-ai launch opencode --yes
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Flags: `--json` `--csv` `--no-network` `--no-color` `--verbose` `--preset quick|standard|stress` `--lang en|es` `--for` `--scope` `--priority`
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx pudu-ai --lang es
|
|
65
|
+
npx pudu-ai doctor --lang es
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`PUDU_AI_LANG=es` or a Spanish `LANG` (e.g. `es_CL.UTF-8`) also selects Spanish. Unrecognized locales fall back to English.
|
|
69
|
+
|
|
70
|
+
## Supported platforms (MVP)
|
|
71
|
+
|
|
72
|
+
| Phase | Platform |
|
|
73
|
+
| --- | --- |
|
|
74
|
+
| 1 (this release) | macOS Apple Silicon |
|
|
75
|
+
| 2 | LM Studio / MLX adapters, richer energy metrics |
|
|
76
|
+
| 3 | Linux NVIDIA, Linux AMD, Windows |
|
|
77
|
+
|
|
78
|
+
## Supported runtimes
|
|
79
|
+
|
|
80
|
+
| Runtime | Detect | List models | Benchmark |
|
|
81
|
+
| --- | --- | --- | --- |
|
|
82
|
+
| Ollama | yes | yes | via resolved GGUF blob + llama-bench |
|
|
83
|
+
| llama.cpp / llama-bench | yes | GGUF dirs | yes |
|
|
84
|
+
| LM Studio | yes | GGUF in known dirs | via llama-bench |
|
|
85
|
+
| MLX | detect only | later | later |
|
|
86
|
+
|
|
87
|
+
## Benchmark methodology
|
|
88
|
+
|
|
89
|
+
Default mini benchmark:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
llama-bench -m MODEL -p 512 -n 128 -r 3 -o json
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
| Preset | prompt | gen | repeats |
|
|
96
|
+
| --- | --- | --- | --- |
|
|
97
|
+
| Quick | 512 | 128 | 3 |
|
|
98
|
+
| Standard | 2048 | 256 | 5 |
|
|
99
|
+
| Stress | 4096 | 512 | 10 |
|
|
100
|
+
|
|
101
|
+
**Measured** values come from `llama-bench` and OS telemetry. **Estimated** values come from [CanIRun.ai](https://canirun.ai) by [midudev](https://midu.dev) ([GitHub](https://github.com/midudev/canirun.ai)) or a local fallback, and are labelled as such.
|
|
102
|
+
|
|
103
|
+
If a metric cannot be measured (GPU %, package power, temperature without extra permissions), Pudu-AI prints `N/A`. It does not invent numbers.
|
|
104
|
+
|
|
105
|
+
On Apple Silicon the memory figure is **Unified Memory**, never VRAM.
|
|
106
|
+
|
|
107
|
+
## Interpreting metrics
|
|
108
|
+
|
|
109
|
+
- **Prompt t/s** — prompt processing throughput (measured).
|
|
110
|
+
- **Generation t/s** — token generation throughput (measured).
|
|
111
|
+
- **Peak memory** — system-wide peak during the run (not claimed as model-only).
|
|
112
|
+
- **Average GPU** — system-wide when available.
|
|
113
|
+
- **t/s/W** — generation tokens per second per watt when power is measured.
|
|
114
|
+
- **Pudu-AI Score** — hardware performance only (speed, memory, energy, thermals, swap). It does **not** include model quality/intelligence.
|
|
115
|
+
|
|
116
|
+
See `docs/spec/03-scoring.md`.
|
|
117
|
+
|
|
118
|
+
## Ollama integrations
|
|
119
|
+
|
|
120
|
+
Pudu-AI can explain and, **only if a recommended model fits this hardware**, pull and launch:
|
|
121
|
+
|
|
122
|
+
| Tool | Docs | Command |
|
|
123
|
+
| --- | --- | --- |
|
|
124
|
+
| OpenCode | [docs.ollama.com/integrations/opencode](https://docs.ollama.com/integrations/opencode) | `npx pudu-ai launch opencode` |
|
|
125
|
+
| OpenClaw | [docs.ollama.com/integrations/openclaw](https://docs.ollama.com/integrations/openclaw) | `npx pudu-ai launch openclaw` |
|
|
126
|
+
| Hermes | [docs.ollama.com/integrations/hermes](https://docs.ollama.com/integrations/hermes) | `npx pudu-ai launch hermes` |
|
|
127
|
+
| Claude Code | [docs.ollama.com/integrations/claude-code](https://docs.ollama.com/integrations/claude-code) | `npx pudu-ai launch claude` |
|
|
128
|
+
|
|
129
|
+
Without `--yes` the command only explains eligibility (grade S–B, coding/chat use case, measured t/s floor when a benchmark exists). It will **not** `ollama pull`, install, or `ollama launch` unless `--yes` is set **and** the gate passes. Pudu-AI never curl-pipes installers.
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npx pudu-ai launch
|
|
133
|
+
npx pudu-ai launch opencode --yes
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Privacy
|
|
137
|
+
|
|
138
|
+
Local-first. Benchmarks, model paths, and machine identifiers stay in `~/.pudu-ai/`. Nothing is uploaded. Network is optional and used only for the CanIRun catalog (`--no-network` disables it).
|
|
139
|
+
|
|
140
|
+
## Architecture
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
Hardware → discovery → compatibility → benchmark + telemetry → storage → TUI / JSON / CSV
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Business logic does not depend on Ink. Specs live in `docs/spec/`. UI strings live in `src/i18n/en.ts` and `src/i18n/es.ts`.
|
|
147
|
+
|
|
148
|
+
## Credits
|
|
149
|
+
|
|
150
|
+
**Measured** performance is produced by Pudu-AI using `llama-bench` and native OS telemetry.
|
|
151
|
+
|
|
152
|
+
**Estimated** compatibility, catalog metadata, and recommended models come from **[CanIRun.ai](https://canirun.ai)** by **[midudev](https://midu.dev)** — also see the source repo [midudev/canirun.ai](https://github.com/midudev/canirun.ai). Those estimates are always labelled *Estimated* and are never mixed with measured results.
|
|
153
|
+
|
|
154
|
+
Pudu-AI does not copy CanIRun.ai source. Telemetry is inspired by tools such as basitop but implemented with native OS APIs (`sysctl`, `vm_stat`, `memory_pressure`, Node `os`) — the TUI of other tools is never scraped.
|
|
155
|
+
|
|
156
|
+
## Contributing
|
|
157
|
+
|
|
158
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). MIT licensed.
|
package/bin/pudu-ai.mjs
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { access } from "node:fs/promises";
|
|
6
|
+
|
|
7
|
+
const root = path.join(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
8
|
+
const distEntry = path.join(root, "dist", "cli", "index.js");
|
|
9
|
+
const srcEntry = path.join(root, "src", "cli", "index.ts");
|
|
10
|
+
const tsxCli = path.join(root, "node_modules", "tsx", "dist", "cli.mjs");
|
|
11
|
+
|
|
12
|
+
async function main() {
|
|
13
|
+
let argv = [distEntry, ...process.argv.slice(2)];
|
|
14
|
+
try {
|
|
15
|
+
await access(distEntry);
|
|
16
|
+
} catch {
|
|
17
|
+
argv = [tsxCli, srcEntry, ...process.argv.slice(2)];
|
|
18
|
+
}
|
|
19
|
+
const child = spawn(process.execPath, argv, {
|
|
20
|
+
stdio: "inherit",
|
|
21
|
+
cwd: root,
|
|
22
|
+
env: process.env,
|
|
23
|
+
});
|
|
24
|
+
child.on("exit", (code, signal) => {
|
|
25
|
+
if (signal) process.kill(process.pid, signal);
|
|
26
|
+
process.exit(code ?? 1);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
void main();
|