@earntori/cli 0.2.0 → 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/README.md +13 -4
- package/dist/index.js +12 -2
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
# @earntori/cli
|
|
2
2
|
|
|
3
|
+
The Tori command line. Sign in, wire Tori into a repo, run checks, mint AI keys.
|
|
4
|
+
|
|
3
5
|
```
|
|
4
|
-
npx @earntori/cli login
|
|
5
|
-
npx @earntori/cli
|
|
6
|
-
npx @earntori/cli
|
|
6
|
+
npx @earntori/cli login sign in with GitHub (device flow)
|
|
7
|
+
npx @earntori/cli init wire Tori into this repo (MCP server + Claude Code hooks)
|
|
8
|
+
npx @earntori/cli check [paths…] run Tori's checks on changed files
|
|
9
|
+
npx @earntori/cli status balance + your AI keys
|
|
10
|
+
npx @earntori/cli key --limit 5 mint a spend-capped AI key from your credits (--write env to save it)
|
|
11
|
+
npx @earntori/cli stats your integration + developer program numbers
|
|
12
|
+
npx @earntori/cli logout
|
|
7
13
|
```
|
|
8
|
-
|
|
14
|
+
|
|
15
|
+
**Earn AI credits by building securely in Claude Code and Cursor.** Tori checks the code your coding agent writes before you ship it, tells the agent how to fix what it finds, and rewards you in AI credits for building with it. Full guide: https://www.earntori.com/docs/mcp · issues: https://github.com/GAishZOEish/Tori-MCP/issues
|
|
16
|
+
|
|
17
|
+
Sending rewards to your own users? That's the Partner API: https://github.com/GAishZOEish/tori-examples
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { readFileSync, writeFileSync, mkdirSync, existsSync, appendFileSync, unl
|
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { join, resolve, relative, isAbsolute, dirname } from "node:path";
|
|
6
6
|
import { execSync } from "node:child_process";
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
7
8
|
const CONFIG_DIR = join(homedir(), ".tori");
|
|
8
9
|
const CONFIG = join(CONFIG_DIR, "config.json");
|
|
9
10
|
const args = process.argv.slice(2);
|
|
@@ -22,7 +23,7 @@ function out(o, human) { console.log(json ? JSON.stringify(o, null, 2) : human);
|
|
|
22
23
|
function die(msg) { console.error(json ? JSON.stringify({ error: msg }) : `\u2717 ${msg}`); process.exit(1); }
|
|
23
24
|
const usd = (c) => `$${(c / 100).toFixed(2)}`;
|
|
24
25
|
async function api(cfg, method, path, body) {
|
|
25
|
-
const r = await fetch(`${cfg.base}${path}`, { method, headers: { Authorization: `Bearer ${cfg.token}`, "Content-Type": "application/json", "User-Agent": "@earntori/cli/0.2.
|
|
26
|
+
const r = await fetch(`${cfg.base}${path}`, { method, headers: { Authorization: `Bearer ${cfg.token}`, "Content-Type": "application/json", "User-Agent": "@earntori/cli/0.2.2" }, body: body ? JSON.stringify(body) : undefined });
|
|
26
27
|
const t = await r.text();
|
|
27
28
|
let j = null;
|
|
28
29
|
try {
|
|
@@ -154,6 +155,15 @@ function init() {
|
|
|
154
155
|
`\n\nClaude Code: restart the session (hooks and .mcp.json load at start). Cursor: reload the window.\nTori's checks now run when the agent finishes a turn; findings are shown to the agent before it stops.`);
|
|
155
156
|
}
|
|
156
157
|
const CODE_EXT = /\.(ts|tsx|js|jsx|mjs|cjs|py|go|rb|php|java|kt|cs)$/i;
|
|
158
|
+
function projectId() {
|
|
159
|
+
try {
|
|
160
|
+
const url = execSync("git config --get remote.origin.url", { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
161
|
+
if (url)
|
|
162
|
+
return url.replace(/^https?:\/\/[^@]*@/, "https://").replace(/\.git$/, "").toLowerCase();
|
|
163
|
+
}
|
|
164
|
+
catch { }
|
|
165
|
+
return "local:" + createHash("sha256").update(process.cwd()).digest("hex").slice(0, 12);
|
|
166
|
+
}
|
|
157
167
|
function gitChanged() {
|
|
158
168
|
try {
|
|
159
169
|
const o = execSync("git status --porcelain --untracked-files=all", { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
@@ -220,7 +230,7 @@ async function check() {
|
|
|
220
230
|
}
|
|
221
231
|
let r;
|
|
222
232
|
try {
|
|
223
|
-
const res = await fetch(`${cfg.base}/api/v1/checks/run`, { method: "POST", headers: { Authorization: `Bearer ${cfg.token}`, "Content-Type": "application/json", "User-Agent": "@earntori/cli/check" }, body: JSON.stringify({ files }) });
|
|
233
|
+
const res = await fetch(`${cfg.base}/api/v1/checks/run`, { method: "POST", headers: { Authorization: `Bearer ${cfg.token}`, "Content-Type": "application/json", "User-Agent": "@earntori/cli/check" }, body: JSON.stringify({ files, project: projectId() }) });
|
|
224
234
|
const t = await res.text();
|
|
225
235
|
if (!res.ok)
|
|
226
236
|
throw new Error(`Tori API ${res.status}${t ? ": " + t.slice(0, 200) : ""}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@earntori/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Tori CLI \u2014 sign in with GitHub, check your credits, mint a capped AI key into your tools.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -25,5 +25,13 @@
|
|
|
25
25
|
},
|
|
26
26
|
"publishConfig": {
|
|
27
27
|
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://www.earntori.com/docs/mcp",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/GAishZOEish/Tori-MCP.git"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/GAishZOEish/Tori-MCP/issues"
|
|
28
36
|
}
|
|
29
37
|
}
|