@heyanon-arp/cli 0.0.30 → 0.0.31

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/dist/cli.js CHANGED
@@ -741,7 +741,7 @@ var import_commander = require("commander");
741
741
  // package.json
742
742
  var package_default = {
743
743
  name: "@heyanon-arp/cli",
744
- version: "0.0.30",
744
+ version: "0.0.31",
745
745
  description: "Command-line client for the Agent Relationship Protocol \u2014 register agents, sign envelopes, run escrowed work cycles on Solana.",
746
746
  license: "MIT",
747
747
  keywords: ["arp", "agent-relationship-protocol", "did", "solana", "escrow", "ed25519", "agents", "a2a", "cli"],
@@ -1022,7 +1022,7 @@ function requireCredential(commandName, serverUrl) {
1022
1022
 
1023
1023
  // src/state.ts
1024
1024
  init_paths();
1025
- var STATE_WARNING = "DO NOT COMMIT \u2014 contains private keys (Ed25519 + derived scrypt).";
1025
+ var STATE_WARNING = "DO NOT COMMIT \u2014 contains private keys (Ed25519 identity + settlement).";
1026
1026
  function stateFilePath() {
1027
1027
  return (0, import_node_path4.join)(arpHomeDir(), "agents.json");
1028
1028
  }
@@ -1135,9 +1135,6 @@ function toKeyBundle(agent, exportedAt) {
1135
1135
  identitySecretKeyB64: agent.identitySecretKeyB64,
1136
1136
  settlementPublicKeyB58: agent.settlementPublicKeyB58,
1137
1137
  settlementSecretKeyB64: agent.settlementSecretKeyB64,
1138
- scryptKeyB64: agent.scryptKeyB64,
1139
- scryptSaltB64: agent.scryptSaltB64,
1140
- scryptSaltId: agent.scryptSaltId,
1141
1138
  ownerWallet: agent.ownerWallet,
1142
1139
  exportedAt
1143
1140
  };
@@ -1147,16 +1144,7 @@ function validateKeyBundle(raw) {
1147
1144
  throw new Error("recover: key file is not a JSON object");
1148
1145
  }
1149
1146
  const o = raw;
1150
- const required = [
1151
- "did",
1152
- "identityPublicKeyB58",
1153
- "identitySecretKeyB64",
1154
- "settlementPublicKeyB58",
1155
- "settlementSecretKeyB64",
1156
- "scryptKeyB64",
1157
- "scryptSaltB64",
1158
- "scryptSaltId"
1159
- ];
1147
+ const required = ["did", "identityPublicKeyB58", "identitySecretKeyB64", "settlementPublicKeyB58", "settlementSecretKeyB64"];
1160
1148
  for (const f of required) {
1161
1149
  if (typeof o[f] !== "string" || o[f].length === 0) {
1162
1150
  throw new Error(`recover: key file is missing or has an invalid '${f}' (expected a non-empty string) \u2014 is this a 'heyarp keys export' file?`);
@@ -1171,9 +1159,6 @@ function validateKeyBundle(raw) {
1171
1159
  identitySecretKeyB64: o.identitySecretKeyB64,
1172
1160
  settlementPublicKeyB58: o.settlementPublicKeyB58,
1173
1161
  settlementSecretKeyB64: o.settlementSecretKeyB64,
1174
- scryptKeyB64: o.scryptKeyB64,
1175
- scryptSaltB64: o.scryptSaltB64,
1176
- scryptSaltId: o.scryptSaltId,
1177
1162
  ownerWallet: o.ownerWallet,
1178
1163
  exportedAt: typeof o.exportedAt === "string" ? o.exportedAt : ""
1179
1164
  };
@@ -6939,9 +6924,6 @@ async function runRecover(opts) {
6939
6924
  identitySecretKeyB64: bundle.identitySecretKeyB64,
6940
6925
  settlementPublicKeyB58: bundle.settlementPublicKeyB58,
6941
6926
  settlementSecretKeyB64: bundle.settlementSecretKeyB64,
6942
- scryptKeyB64: bundle.scryptKeyB64,
6943
- scryptSaltB64: bundle.scryptSaltB64,
6944
- scryptSaltId: bundle.scryptSaltId,
6945
6927
  currentAttestationId: row.currentAttestationId,
6946
6928
  name: row.name ?? void 0,
6947
6929
  description: row.description ?? void 0,
@@ -6959,7 +6941,6 @@ async function runRecover(opts) {
6959
6941
  }
6960
6942
 
6961
6943
  // src/commands/register.ts
6962
- var import_node_crypto4 = require("crypto");
6963
6944
  var import_node_fs9 = require("fs");
6964
6945
  var import_sdk25 = require("@heyanon-arp/sdk");
6965
6946
  var import_chalk28 = __toESM(require("chalk"));
@@ -6971,28 +6952,10 @@ function registerRegisterCommand(root) {
6971
6952
  [
6972
6953
  "Register a new ARP agent. Interactive by default; pass any of the profile flags below to skip the matching prompt.",
6973
6954
  "",
6974
- "`--password` is REQUIRED \u2014 must be at least 8 characters. In interactive mode (--yes omitted) the CLI prompts for it; with --yes it must be passed explicitly.",
6955
+ "No password \u2014 the agent identity key self-signs the owner key-link; ownership is your `heyarp login` wallet.",
6975
6956
  "`--yes` is the non-interactive switch \u2014 every required field must arrive via flags (no prompts). Use this for scripted setups."
6976
6957
  ].join("\n")
6977
- ).option("--server <url>", "Override ARP server base URL").option("--from-keys <file>", "Load identity + settlement keys from a JSON file instead of generating").option("--name <s>", "Unique handle \u2014 lowercase a-z0-9_, 3-32 chars, immutable (skips the name prompt)").option("--description <s>", "Description (skips the description prompt)").option("--tag <s>", "Capability tag \u2014 repeatable, e.g. --tag translation --tag fr", accumulate3, []).option(
6978
- "--password <s>",
6979
- // `--password` puts the secret in `argv` — visible via
6980
- // `ps aux` / kernel process table on shared hosts,
6981
- // recorded by `/proc/<pid>/cmdline`, and almost always
6982
- // logged by CI runners (e.g. GitHub Actions echoes the
6983
- // full command). Safer alternatives:
6984
- // • interactive prompt (default) — never written anywhere
6985
- // • `HEYARP_PASSWORD` env var (tracked) reads from env so
6986
- // the secret stays out of argv even in scripts
6987
- // Treat `--password <s>` as a one-off local-dev affordance;
6988
- // do NOT use it in CI pipelines without a secret-redacting
6989
- // runner.
6990
- "Owner password \u2014 MUST be at least 8 characters. REQUIRED when --yes is set; otherwise the CLI prompts for it. WARNING: --password puts the secret in process argv (visible in `ps`, /proc/<pid>/cmdline, and CI logs that echo commands). Prefer the interactive prompt unless your CI runner redacts secrets in command echoes. HEYARP_PASSWORD env var support is tracked."
6991
- ).option(
6992
- "--yes",
6993
- "Strict non-interactive: fail if any required field is still missing after merging flags. With --yes, --password must be supplied explicitly (>= 8 chars).",
6994
- false
6995
- ).option(
6958
+ ).option("--server <url>", "Override ARP server base URL").option("--from-keys <file>", "Load identity + settlement keys from a JSON file instead of generating").option("--name <s>", "Unique handle \u2014 lowercase a-z0-9_, 3-32 chars, immutable (skips the name prompt)").option("--description <s>", "Description (skips the description prompt)").option("--tag <s>", "Capability tag \u2014 repeatable, e.g. --tag translation --tag fr", accumulate3, []).option("--yes", "Strict non-interactive: fail if any required field (--name) is still missing after merging flags.", false).option(
6996
6959
  "--json",
6997
6960
  // Emit a single JSON object instead of human-friendly
6998
6961
  // success prints. Output shape:
@@ -7029,9 +6992,6 @@ async function runRegister(opts, deps = defaultRegisterDeps) {
7029
6992
  const did = (0, import_sdk25.formatDid)(keys.identityPublicKey);
7030
6993
  if (!opts.json) console.log(import_chalk28.default.dim(`DID will be: ${did}`));
7031
6994
  const answers = await mergeAnswers(opts);
7032
- const scryptSalt = (0, import_node_crypto4.randomBytes)(16);
7033
- if (!opts.json) console.log(import_chalk28.default.dim("Deriving scrypt key, this may take a moment..."));
7034
- const scryptKey = (0, import_sdk25.deriveScryptKey)(answers.password, new Uint8Array(scryptSalt));
7035
6995
  const challenge = await api.issueChallenge("register");
7036
6996
  const challengeBytes = base64UrlNoPadDecode(challenge.challengeB64);
7037
6997
  if (challengeBytes.length !== 32) {
@@ -7045,7 +7005,6 @@ async function runRegister(opts, deps = defaultRegisterDeps) {
7045
7005
  signature: Buffer.from(challengeSig).toString("base64")
7046
7006
  });
7047
7007
  const settlementPublicKeyB58 = (0, import_sdk25.base58btcEncode)(keys.settlementPublicKey);
7048
- const scryptSaltId = (0, import_sdk25.uuidV4)();
7049
7008
  const payload = {
7050
7009
  purpose: import_sdk25.Purpose.KEY_LINK,
7051
7010
  agent_did: did,
@@ -7056,18 +7015,15 @@ async function runRegister(opts, deps = defaultRegisterDeps) {
7056
7015
  created_at: (0, import_sdk25.rfc3339)(),
7057
7016
  nonce: (0, import_sdk25.senderNonce)()
7058
7017
  };
7059
- const attestation = (0, import_sdk25.signKeyLinkAttestation)({ payload, scryptKey, scryptSaltId });
7018
+ const attestation = (0, import_sdk25.signKeyLinkAttestation)({ payload, identitySecretKey: keys.identitySecretKey });
7060
7019
  const body = {
7061
7020
  challengeId: challenge.challengeId,
7062
7021
  identityPublicKey: identityPublicKeyB58,
7063
7022
  settlementPublicKey: settlementPublicKeyB58,
7064
7023
  ownerAttestation: {
7065
7024
  payload: attestation.payload,
7066
- sig: attestation.sig,
7067
- scrypt_salt_id: attestation.scrypt_salt_id
7025
+ sig: attestation.sig
7068
7026
  },
7069
- scryptKeyB64: Buffer.from(scryptKey).toString("base64"),
7070
- scryptSaltB64: Buffer.from(scryptSalt).toString("base64"),
7071
7027
  name: answers.name,
7072
7028
  description: answers.description ? answers.description : void 0,
7073
7029
  tags: answers.tags.length > 0 ? answers.tags : void 0
@@ -7078,9 +7034,6 @@ async function runRegister(opts, deps = defaultRegisterDeps) {
7078
7034
  identitySecretKeyB64: Buffer.from(keys.identitySecretKey).toString("base64"),
7079
7035
  settlementPublicKeyB58,
7080
7036
  settlementSecretKeyB64: Buffer.from(keys.settlementSecretKey).toString("base64"),
7081
- scryptKeyB64: Buffer.from(scryptKey).toString("base64"),
7082
- scryptSaltB64: Buffer.from(scryptSalt).toString("base64"),
7083
- scryptSaltId,
7084
7037
  // Placeholder until the server confirms registration and returns
7085
7038
  // the canonical attestation id (finalized in Step 8 below).
7086
7039
  currentAttestationId: "",
@@ -7159,32 +7112,15 @@ Local state saved to ${arpHomeDir()}/agents.json (mode 0600).`));
7159
7112
  }
7160
7113
  }
7161
7114
  async function mergeAnswers(opts) {
7162
- const need = opts.yes ? { password: false, name: false, description: false, tagsCsv: false } : {
7163
- password: opts.password === void 0,
7115
+ const need = opts.yes ? { name: false, description: false, tagsCsv: false } : {
7164
7116
  name: opts.name === void 0,
7165
7117
  description: opts.description === void 0,
7166
7118
  tagsCsv: opts.tag === void 0 || opts.tag.length === 0
7167
7119
  };
7168
- if (opts.yes) {
7169
- const missing = [];
7170
- if (opts.password === void 0) missing.push("--password");
7171
- if (opts.name === void 0) missing.push("--name");
7172
- if (missing.length > 0) {
7173
- throw new Error(`register --yes: missing required flag${missing.length > 1 ? "s" : ""}: ${missing.join(", ")}`);
7174
- }
7175
- }
7176
- if (opts.password !== void 0 && opts.password.length < 8) {
7177
- throw new Error("register --password: password must be at least 8 characters");
7120
+ if (opts.yes && opts.name === void 0) {
7121
+ throw new Error("register --yes: missing required flag: --name");
7178
7122
  }
7179
7123
  const promptDefs = [];
7180
- if (need.password) {
7181
- promptDefs.push({
7182
- type: "password",
7183
- name: "password",
7184
- message: "Owner password (used to derive the scrypt key)",
7185
- validate: (v) => v.length >= 8 ? true : "must be at least 8 characters"
7186
- });
7187
- }
7188
7124
  if (need.name) {
7189
7125
  promptDefs.push({
7190
7126
  type: "text",
@@ -7218,7 +7154,6 @@ async function mergeAnswers(opts) {
7218
7154
  const tags = (opts.tag && opts.tag.length > 0 ? opts.tag : parseTagsCsv(typeof prompted.tagsCsv === "string" ? prompted.tagsCsv : "")).map((t) => t.trim().toLowerCase()).filter((t) => t.length > 0);
7219
7155
  const name = normalizeAndValidateName(opts.name ?? prompted.name);
7220
7156
  return {
7221
- password: opts.password ?? prompted.password,
7222
7157
  name,
7223
7158
  description: opts.description ?? prompted.description ?? "",
7224
7159
  tags