From b1c51026dda204e37d87ad702d22813ff4ba2d7c Mon Sep 17 00:00:00 2001 From: Helios531 <57456290+Helios531@users.noreply.github.com> Date: Wed, 1 Jul 2026 16:18:37 +0200 Subject: [PATCH 1/2] feat(miner): scaffold gittensory-miner package --- package-lock.json | 31 +++++++++++++ packages/gittensory-engine/lib/index.js | 1 + packages/gittensory-engine/package.json | 35 +++++++++++++++ packages/gittensory-miner/README.md | 33 ++++++++++++++ .../gittensory-miner/bin/gittensory-miner.js | 19 ++++++++ packages/gittensory-miner/lib/cli.d.ts | 12 ++++++ packages/gittensory-miner/lib/cli.js | 25 +++++++++++ packages/gittensory-miner/package.json | 43 +++++++++++++++++++ test/unit/miner-cli.test.ts | 28 ++++++++++++ 9 files changed, 227 insertions(+) create mode 100644 packages/gittensory-engine/lib/index.js create mode 100644 packages/gittensory-engine/package.json create mode 100644 packages/gittensory-miner/README.md create mode 100755 packages/gittensory-miner/bin/gittensory-miner.js create mode 100644 packages/gittensory-miner/lib/cli.d.ts create mode 100644 packages/gittensory-miner/lib/cli.js create mode 100644 packages/gittensory-miner/package.json create mode 100644 test/unit/miner-cli.test.ts diff --git a/package-lock.json b/package-lock.json index a8e4c44f7a..ba1d4ccde8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2691,10 +2691,18 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@jsonbored/gittensory-engine": { + "resolved": "packages/gittensory-engine", + "link": true + }, "node_modules/@jsonbored/gittensory-mcp": { "resolved": "packages/gittensory-mcp", "link": true }, + "node_modules/@jsonbored/gittensory-miner": { + "resolved": "packages/gittensory-miner", + "link": true + }, "node_modules/@jsonbored/gittensory-ui": { "resolved": "apps/gittensory-ui", "link": true @@ -15474,6 +15482,14 @@ "zod": "^3.25.28 || ^4" } }, + "packages/gittensory-engine": { + "name": "@jsonbored/gittensory-engine", + "version": "0.1.0", + "license": "AGPL-3.0-only", + "engines": { + "node": ">=22.0.0" + } + }, "packages/gittensory-mcp": { "name": "@jsonbored/gittensory-mcp", "version": "0.6.0", @@ -15488,6 +15504,21 @@ "engines": { "node": ">=22.0.0" } + }, + "packages/gittensory-miner": { + "name": "@jsonbored/gittensory-miner", + "version": "0.1.0", + "license": "AGPL-3.0-only", + "dependencies": { + "@jsonbored/gittensory-engine": "0.1.0", + "zod": "^4.4.3" + }, + "bin": { + "gittensory-miner": "bin/gittensory-miner.js" + }, + "engines": { + "node": ">=22.0.0" + } } } } diff --git a/packages/gittensory-engine/lib/index.js b/packages/gittensory-engine/lib/index.js new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/packages/gittensory-engine/lib/index.js @@ -0,0 +1 @@ +export {}; diff --git a/packages/gittensory-engine/package.json b/packages/gittensory-engine/package.json new file mode 100644 index 0000000000..6f12a32ab2 --- /dev/null +++ b/packages/gittensory-engine/package.json @@ -0,0 +1,35 @@ +{ + "name": "@jsonbored/gittensory-engine", + "version": "0.1.0", + "license": "AGPL-3.0-only", + "type": "module", + "description": "Shared pure engine helpers for Gittensory miner and gate logic.", + "repository": { + "type": "git", + "url": "git+https://github.com/JSONbored/gittensory.git", + "directory": "packages/gittensory-engine" + }, + "homepage": "https://github.com/JSONbored/gittensory#readme", + "bugs": { + "url": "https://github.com/JSONbored/gittensory/issues" + }, + "keywords": [ + "gittensor", + "gittensory", + "engine", + "shared", + "miner" + ], + "publishConfig": { + "access": "public" + }, + "files": [ + "lib" + ], + "scripts": { + "build": "node --check lib/index.js" + }, + "engines": { + "node": ">=22.0.0" + } +} diff --git a/packages/gittensory-miner/README.md b/packages/gittensory-miner/README.md new file mode 100644 index 0000000000..fac922663d --- /dev/null +++ b/packages/gittensory-miner/README.md @@ -0,0 +1,33 @@ +# @jsonbored/gittensory-miner + +Foundation CLI for the local Gittensory miner runtime. + +This package is the future home of the autonomous discover → analyze → plan → prepare → create → manage miner workflow. In this foundation phase it only provides the package scaffold and a minimal CLI surface for `--help` and `--version`. + +## Status + +Current scope is intentionally small: + +- workspace package wiring +- CLI entry point +- `--help` and `version` commands + +Real miner commands land in follow-up issues. + +## Install + +From a local checkout: + +```sh +npm install +npm --workspace @jsonbored/gittensory-miner run build +``` + +## Commands + +```sh +gittensory-miner --help +gittensory-miner help +gittensory-miner --version +gittensory-miner version +``` diff --git a/packages/gittensory-miner/bin/gittensory-miner.js b/packages/gittensory-miner/bin/gittensory-miner.js new file mode 100755 index 0000000000..e5ac73f156 --- /dev/null +++ b/packages/gittensory-miner/bin/gittensory-miner.js @@ -0,0 +1,19 @@ +#!/usr/bin/env node +import { printHelp, printVersion, runCli } from "../lib/cli.js"; + +const cliArgs = process.argv.slice(2); +const packageName = "@jsonbored/gittensory-miner"; +const packageVersion = "0.1.0"; + +if (cliArgs.length === 0 || cliArgs.includes("--help") || cliArgs.includes("-h") || cliArgs[0] === "help") { + printHelp({ packageName }); + process.exit(0); +} + +if (cliArgs.includes("--version") || cliArgs.includes("-v") || cliArgs[0] === "version") { + printVersion({ packageName, packageVersion }); + process.exit(0); +} + +const exitCode = runCli(cliArgs, { packageName }); +process.exit(exitCode); diff --git a/packages/gittensory-miner/lib/cli.d.ts b/packages/gittensory-miner/lib/cli.d.ts new file mode 100644 index 0000000000..d2e718b111 --- /dev/null +++ b/packages/gittensory-miner/lib/cli.d.ts @@ -0,0 +1,12 @@ +export type VersionPrintInput = { + packageName: string; + packageVersion: string; +}; + +export type HelpPrintInput = { + packageName: string; +}; + +export declare function printVersion(input: VersionPrintInput): void; +export declare function printHelp(input: HelpPrintInput): void; +export declare function runCli(cliArgs: string[], input: HelpPrintInput): number; diff --git a/packages/gittensory-miner/lib/cli.js b/packages/gittensory-miner/lib/cli.js new file mode 100644 index 0000000000..426e019275 --- /dev/null +++ b/packages/gittensory-miner/lib/cli.js @@ -0,0 +1,25 @@ +export function printVersion(input) { + console.log(`${input.packageName}/${input.packageVersion} (node ${process.version})`); +} + +export function printHelp(input) { + console.log( + [ + input.packageName, + "", + "Foundation CLI for the local Gittensory miner runtime.", + "", + "Usage:", + " gittensory-miner --help", + " gittensory-miner --version", + " gittensory-miner help", + " gittensory-miner version", + ].join("\n"), + ); +} + +export function runCli(cliArgs, input) { + const command = cliArgs[0] ?? ""; + console.error(`Unknown command: ${command}. Run ${input.packageName} --help.`); + return 1; +} diff --git a/packages/gittensory-miner/package.json b/packages/gittensory-miner/package.json new file mode 100644 index 0000000000..6de6290950 --- /dev/null +++ b/packages/gittensory-miner/package.json @@ -0,0 +1,43 @@ +{ + "name": "@jsonbored/gittensory-miner", + "version": "0.1.0", + "license": "AGPL-3.0-only", + "type": "module", + "description": "Foundation CLI for the local Gittensory miner runtime.", + "repository": { + "type": "git", + "url": "git+https://github.com/JSONbored/gittensory.git", + "directory": "packages/gittensory-miner" + }, + "homepage": "https://github.com/JSONbored/gittensory#readme", + "bugs": { + "url": "https://github.com/JSONbored/gittensory/issues" + }, + "keywords": [ + "gittensor", + "gittensory", + "miner", + "cli", + "agent" + ], + "publishConfig": { + "access": "public" + }, + "bin": { + "gittensory-miner": "bin/gittensory-miner.js" + }, + "files": [ + "bin", + "lib" + ], + "scripts": { + "build": "node --check bin/gittensory-miner.js && node --check lib/cli.js" + }, + "dependencies": { + "@jsonbored/gittensory-engine": "0.1.0", + "zod": "^4.4.3" + }, + "engines": { + "node": ">=22.0.0" + } +} diff --git a/test/unit/miner-cli.test.ts b/test/unit/miner-cli.test.ts new file mode 100644 index 0000000000..f7aafc1d44 --- /dev/null +++ b/test/unit/miner-cli.test.ts @@ -0,0 +1,28 @@ +import { describe, expect, it, vi } from "vitest"; +import { printHelp, printVersion, runCli } from "../../packages/gittensory-miner/lib/cli.js"; + +describe("gittensory-miner CLI helpers", () => { + it("prints the package version with the node runtime", () => { + const log = vi.spyOn(console, "log").mockImplementation(() => undefined); + printVersion({ packageName: "@jsonbored/gittensory-miner", packageVersion: "0.1.0" }); + expect(log).toHaveBeenCalledWith(expect.stringContaining("@jsonbored/gittensory-miner/0.1.0")); + expect(log).toHaveBeenCalledWith(expect.stringContaining(process.version)); + log.mockRestore(); + }); + + it("prints help text with the supported commands", () => { + const log = vi.spyOn(console, "log").mockImplementation(() => undefined); + printHelp({ packageName: "@jsonbored/gittensory-miner" }); + const text = log.mock.calls[0]?.[0]; + expect(text).toContain("gittensory-miner --help"); + expect(text).toContain("gittensory-miner version"); + log.mockRestore(); + }); + + it("returns exit code 1 for unknown commands", () => { + const error = vi.spyOn(console, "error").mockImplementation(() => undefined); + expect(runCli(["mystery"], { packageName: "@jsonbored/gittensory-miner" })).toBe(1); + expect(error).toHaveBeenCalledWith("Unknown command: mystery. Run @jsonbored/gittensory-miner --help."); + error.mockRestore(); + }); +}); From fb8d120f0f6bf23c604e3646f6d5c2993214f1a0 Mon Sep 17 00:00:00 2001 From: Helios531 <57456290+Helios531@users.noreply.github.com> Date: Wed, 1 Jul 2026 17:38:57 +0200 Subject: [PATCH 2/2] fix(packages): publish engine entrypoint contract --- package-lock.json | 3 +-- packages/gittensory-engine/lib/index.d.ts | 1 + packages/gittensory-engine/package.json | 2 ++ packages/gittensory-miner/bin/gittensory-miner.js | 4 +++- packages/gittensory-miner/package.json | 3 +-- test/unit/miner-cli.test.ts | 14 ++++++++++---- test/unit/miner-package-contract.test.ts | 8 ++++++++ 7 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 packages/gittensory-engine/lib/index.d.ts create mode 100644 test/unit/miner-package-contract.test.ts diff --git a/package-lock.json b/package-lock.json index ba1d4ccde8..c77919714c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15510,8 +15510,7 @@ "version": "0.1.0", "license": "AGPL-3.0-only", "dependencies": { - "@jsonbored/gittensory-engine": "0.1.0", - "zod": "^4.4.3" + "@jsonbored/gittensory-engine": "0.1.0" }, "bin": { "gittensory-miner": "bin/gittensory-miner.js" diff --git a/packages/gittensory-engine/lib/index.d.ts b/packages/gittensory-engine/lib/index.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/packages/gittensory-engine/lib/index.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/gittensory-engine/package.json b/packages/gittensory-engine/package.json index 6f12a32ab2..972c7a8bcd 100644 --- a/packages/gittensory-engine/package.json +++ b/packages/gittensory-engine/package.json @@ -23,6 +23,8 @@ "publishConfig": { "access": "public" }, + "main": "./lib/index.js", + "exports": "./lib/index.js", "files": [ "lib" ], diff --git a/packages/gittensory-miner/bin/gittensory-miner.js b/packages/gittensory-miner/bin/gittensory-miner.js index e5ac73f156..f04e105069 100755 --- a/packages/gittensory-miner/bin/gittensory-miner.js +++ b/packages/gittensory-miner/bin/gittensory-miner.js @@ -1,9 +1,11 @@ #!/usr/bin/env node +import { createRequire } from "node:module"; import { printHelp, printVersion, runCli } from "../lib/cli.js"; const cliArgs = process.argv.slice(2); +const require = createRequire(import.meta.url); const packageName = "@jsonbored/gittensory-miner"; -const packageVersion = "0.1.0"; +const packageVersion = require("../package.json").version; if (cliArgs.length === 0 || cliArgs.includes("--help") || cliArgs.includes("-h") || cliArgs[0] === "help") { printHelp({ packageName }); diff --git a/packages/gittensory-miner/package.json b/packages/gittensory-miner/package.json index 6de6290950..74b8075d8b 100644 --- a/packages/gittensory-miner/package.json +++ b/packages/gittensory-miner/package.json @@ -34,8 +34,7 @@ "build": "node --check bin/gittensory-miner.js && node --check lib/cli.js" }, "dependencies": { - "@jsonbored/gittensory-engine": "0.1.0", - "zod": "^4.4.3" + "@jsonbored/gittensory-engine": "0.1.0" }, "engines": { "node": ">=22.0.0" diff --git a/test/unit/miner-cli.test.ts b/test/unit/miner-cli.test.ts index f7aafc1d44..b800eb21f0 100644 --- a/test/unit/miner-cli.test.ts +++ b/test/unit/miner-cli.test.ts @@ -1,13 +1,16 @@ -import { describe, expect, it, vi } from "vitest"; +import { afterEach, describe, expect, it, vi } from "vitest"; import { printHelp, printVersion, runCli } from "../../packages/gittensory-miner/lib/cli.js"; +afterEach(() => { + vi.restoreAllMocks(); +}); + describe("gittensory-miner CLI helpers", () => { it("prints the package version with the node runtime", () => { const log = vi.spyOn(console, "log").mockImplementation(() => undefined); printVersion({ packageName: "@jsonbored/gittensory-miner", packageVersion: "0.1.0" }); expect(log).toHaveBeenCalledWith(expect.stringContaining("@jsonbored/gittensory-miner/0.1.0")); expect(log).toHaveBeenCalledWith(expect.stringContaining(process.version)); - log.mockRestore(); }); it("prints help text with the supported commands", () => { @@ -16,13 +19,16 @@ describe("gittensory-miner CLI helpers", () => { const text = log.mock.calls[0]?.[0]; expect(text).toContain("gittensory-miner --help"); expect(text).toContain("gittensory-miner version"); - log.mockRestore(); }); it("returns exit code 1 for unknown commands", () => { const error = vi.spyOn(console, "error").mockImplementation(() => undefined); expect(runCli(["mystery"], { packageName: "@jsonbored/gittensory-miner" })).toBe(1); expect(error).toHaveBeenCalledWith("Unknown command: mystery. Run @jsonbored/gittensory-miner --help."); - error.mockRestore(); + }); + + it("keeps the CLI version source aligned with package metadata", async () => { + const packageJson = await import("../../packages/gittensory-miner/package.json", { with: { type: "json" } }); + expect(packageJson.default.version).toBe("0.1.0"); }); }); diff --git a/test/unit/miner-package-contract.test.ts b/test/unit/miner-package-contract.test.ts new file mode 100644 index 0000000000..14e1b8b34e --- /dev/null +++ b/test/unit/miner-package-contract.test.ts @@ -0,0 +1,8 @@ +import { describe, expect, it } from "vitest"; + +describe("miner package workspace contracts", () => { + it("allows importing @jsonbored/gittensory-engine by package name", async () => { + const mod = await import("@jsonbored/gittensory-engine"); + expect(Object.keys(mod)).toEqual([]); + }); +});