clawborrator-cli 0.2.7 → 0.2.8

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.
@@ -63999,13 +63999,14 @@ var {
63999
63999
 
64000
64000
  // src/commands/login.ts
64001
64001
  var import_node_http = require("node:http");
64002
- var import_node_crypto = require("node:crypto");
64002
+ var import_node_crypto2 = require("node:crypto");
64003
64003
  var import_node_child_process = require("node:child_process");
64004
64004
 
64005
64005
  // src/config.ts
64006
64006
  var import_node_os = require("node:os");
64007
64007
  var import_node_path = require("node:path");
64008
64008
  var import_node_fs = require("node:fs");
64009
+ var import_node_crypto = require("node:crypto");
64009
64010
  var CONFIG_DIR = (0, import_node_path.resolve)((0, import_node_os.homedir)(), ".clawborrator");
64010
64011
  var CONFIG_PATH = (0, import_node_path.resolve)(CONFIG_DIR, "cli_v1.json");
64011
64012
  var DEFAULTS = {
@@ -64013,24 +64014,37 @@ var DEFAULTS = {
64013
64014
  // CLAWBORRATOR_HUB=http://localhost:8787 or `claw login --hub <url>`,
64014
64015
  // which persists into ~/.clawborrator/cli_v1.json.
64015
64016
  hubUrl: process.env.CLAWBORRATOR_HUB ?? "https://next.clawborrator.com",
64016
- sessionToken: null
64017
+ sessionToken: null,
64018
+ machineId: ""
64019
+ // populated on first loadConfig()
64017
64020
  };
64018
64021
  function loadConfig() {
64019
- if (!(0, import_node_fs.existsSync)(CONFIG_PATH)) return { ...DEFAULTS };
64020
- try {
64021
- const raw = (0, import_node_fs.readFileSync)(CONFIG_PATH, "utf8");
64022
- const parsed = JSON.parse(raw);
64023
- return {
64022
+ let parsed = {};
64023
+ if ((0, import_node_fs.existsSync)(CONFIG_PATH)) {
64024
+ try {
64025
+ const raw = (0, import_node_fs.readFileSync)(CONFIG_PATH, "utf8");
64026
+ parsed = JSON.parse(raw);
64027
+ } catch {
64028
+ }
64029
+ }
64030
+ let machineId = parsed.machineId?.trim() || "";
64031
+ if (!machineId) {
64032
+ machineId = (0, import_node_crypto.randomUUID)();
64033
+ saveConfig({
64024
64034
  hubUrl: parsed.hubUrl?.trim() || DEFAULTS.hubUrl,
64025
- // Forward-migrate a legacy `pat` field. The token itself is now
64026
- // dead on the server side, but carrying it forward avoids loud
64027
- // "config corrupt" errors — the next API call will 401 cleanly
64028
- // and prompt re-login.
64029
- sessionToken: parsed.sessionToken ?? parsed.pat ?? null
64030
- };
64031
- } catch {
64032
- return { ...DEFAULTS };
64035
+ sessionToken: parsed.sessionToken ?? parsed.pat ?? null,
64036
+ machineId
64037
+ });
64033
64038
  }
64039
+ return {
64040
+ hubUrl: parsed.hubUrl?.trim() || DEFAULTS.hubUrl,
64041
+ // Forward-migrate a legacy `pat` field. The token itself is now
64042
+ // dead on the server side, but carrying it forward avoids loud
64043
+ // "config corrupt" errors — the next API call will 401 cleanly
64044
+ // and prompt re-login.
64045
+ sessionToken: parsed.sessionToken ?? parsed.pat ?? null,
64046
+ machineId
64047
+ };
64034
64048
  }
64035
64049
  function saveConfig(cfg) {
64036
64050
  if (!(0, import_node_fs.existsSync)(CONFIG_DIR)) {
@@ -64149,10 +64163,10 @@ function awaitCallback(server) {
64149
64163
  server.on("error", reject);
64150
64164
  });
64151
64165
  }
64152
- async function browserOAuthFlow(hubUrl) {
64153
- const verifier = base64url((0, import_node_crypto.randomBytes)(32));
64154
- const challenge = base64url((0, import_node_crypto.createHash)("sha256").update(verifier).digest());
64155
- const state = base64url((0, import_node_crypto.randomBytes)(16));
64166
+ async function browserOAuthFlow(hubUrl, machineId) {
64167
+ const verifier = base64url((0, import_node_crypto2.randomBytes)(32));
64168
+ const challenge = base64url((0, import_node_crypto2.createHash)("sha256").update(verifier).digest());
64169
+ const state = base64url((0, import_node_crypto2.randomBytes)(16));
64156
64170
  const server = (0, import_node_http.createServer)();
64157
64171
  await new Promise((resolve3, reject) => {
64158
64172
  server.once("error", reject);
@@ -64165,6 +64179,7 @@ async function browserOAuthFlow(hubUrl) {
64165
64179
  startUrl.searchParams.set("state", state);
64166
64180
  startUrl.searchParams.set("code_challenge", challenge);
64167
64181
  startUrl.searchParams.set("code_challenge_method", "S256");
64182
+ startUrl.searchParams.set("machine_id", machineId);
64168
64183
  console.log("opening browser to authenticate with GitHub\u2026");
64169
64184
  console.log(` if it doesn't open automatically, paste this URL into a browser:`);
64170
64185
  console.log(` ${startUrl}`);
@@ -64209,8 +64224,8 @@ var loginCmd = new Command("login").description("authenticate against a hub_v1 i
64209
64224
  const hubUrl = (opts.hub ?? cfg.hubUrl).replace(/\/+$/, "");
64210
64225
  console.log(`hub: ${hubUrl}`);
64211
64226
  try {
64212
- const { user, session } = await browserOAuthFlow(hubUrl);
64213
- saveConfig({ hubUrl, sessionToken: session.token });
64227
+ const { user, session } = await browserOAuthFlow(hubUrl, cfg.machineId);
64228
+ saveConfig({ hubUrl, sessionToken: session.token, machineId: cfg.machineId });
64214
64229
  console.log(`logged in as @${user.githubLogin}`);
64215
64230
  console.log(`hub: ${hubUrl}`);
64216
64231
  console.log(`session: ${session.token.slice(0, 16)}\u2026 (stored in ~/.clawborrator/cli_v1.json)`);
@@ -69125,7 +69140,7 @@ var agentsCmd = new Command("agents").description("public expert agents \u2014 l
69125
69140
  // src/commands/apps.ts
69126
69141
  var import_promises = require("node:readline/promises");
69127
69142
  var import_node_http2 = require("node:http");
69128
- var import_node_crypto2 = require("node:crypto");
69143
+ var import_node_crypto3 = require("node:crypto");
69129
69144
  var import_node_child_process2 = require("node:child_process");
69130
69145
  function fmtAgo3(iso) {
69131
69146
  if (!iso) return "never";
@@ -69252,9 +69267,9 @@ function awaitSpaCallback(server) {
69252
69267
  });
69253
69268
  }
69254
69269
  async function spaTestOauthFlow(args) {
69255
- const verifier = base64url2((0, import_node_crypto2.randomBytes)(32));
69256
- const challenge = base64url2((0, import_node_crypto2.createHash)("sha256").update(verifier).digest());
69257
- const stateNonce = base64url2((0, import_node_crypto2.randomBytes)(16));
69270
+ const verifier = base64url2((0, import_node_crypto3.randomBytes)(32));
69271
+ const challenge = base64url2((0, import_node_crypto3.createHash)("sha256").update(verifier).digest());
69272
+ const stateNonce = base64url2((0, import_node_crypto3.randomBytes)(16));
69258
69273
  const appName = "claw-cli-test-oauth";
69259
69274
  const server = (0, import_node_http2.createServer)();
69260
69275
  await new Promise((resolve3, reject) => {
@@ -69389,7 +69404,7 @@ function fmtAgo4(iso) {
69389
69404
 
69390
69405
  // src/index.ts
69391
69406
  var program2 = new Command();
69392
- program2.name("claw").description("clawborrator CLI \u2014 control your Claude Code sessions from the terminal").version("0.2.7");
69407
+ program2.name("claw").description("clawborrator CLI \u2014 control your Claude Code sessions from the terminal").version("0.2.8");
69393
69408
  program2.addCommand(loginCmd);
69394
69409
  program2.addCommand(logoutCmd);
69395
69410
  program2.addCommand(whoamiCmd);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawborrator-cli",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "type": "module",
5
5
  "description": "claw — command-line client for clawborrator. Attach to remote Claude Code sessions, send prompts, resolve permission gates, route across sessions, manage public agents and webhooks. Auth via GitHub OAuth + PKCE.",
6
6
  "license": "MIT",