@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.
Files changed (3) hide show
  1. package/README.md +13 -4
  2. package/dist/index.js +12 -2
  3. 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 # sign in with GitHub (device flow)
5
- npx @earntori/cli status # balance + keys
6
- npx @earntori/cli key --limit 5 --write env # mint a $5 capped AI key into .env
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
- Your credits, in your tools, in one command. Docs: https://www.earntori.com/developers
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.0" }, body: body ? JSON.stringify(body) : undefined });
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.0",
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
  }