@ouro.bot/cli 0.1.0-alpha.406 → 0.1.0-alpha.407

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/changelog.json CHANGED
@@ -1,6 +1,15 @@
1
1
  {
2
2
  "_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
3
3
  "versions": [
4
+ {
5
+ "version": "0.1.0-alpha.407",
6
+ "changes": [
7
+ "`credential_store` now uses the same Bitwarden-derived error scrubber as provider auth, so agent-saved secret flows redact raw `bw ...` command lines, encoded payload blobs, and hidden prompt echoes instead of free-styling their own failure cleanup.",
8
+ "The shared sanitizer now collapses fully scrubbed failures back to `command failed`, so redaction does not leave behind useless `[redacted]` noise when the only surviving text was secret-shaped.",
9
+ "Added regression coverage for the shared sanitizer itself plus the `credential_store` path that agents hit after signups and manual secret saves.",
10
+ "`@ouro.bot/cli` and the `ouro.bot` wrapper are version-synced for the shared credential error sanitization release."
11
+ ]
12
+ },
4
13
  {
5
14
  "version": "0.1.0-alpha.406",
6
15
  "changes": [
@@ -42,10 +42,39 @@ var __importStar = (this && this.__importStar) || (function () {
42
42
  })();
43
43
  Object.defineProperty(exports, "__esModule", { value: true });
44
44
  exports.BitwardenCredentialStore = void 0;
45
+ exports.sanitizeCredentialErrorDetail = sanitizeCredentialErrorDetail;
45
46
  const node_child_process_1 = require("node:child_process");
46
47
  const fs = __importStar(require("node:fs"));
47
48
  const runtime_1 = require("../nerves/runtime");
48
49
  const bw_installer_1 = require("./bw-installer");
50
+ const MAX_ERROR_DETAIL_LENGTH = 500;
51
+ const LONG_ENCODED_TOKEN_PATTERN = /[A-Za-z0-9+/=]{32,}/g;
52
+ function uniqueSecrets(secrets) {
53
+ return [...new Set(secrets.filter((value) => typeof value === "string" && value.length >= 4))].sort((left, right) => right.length - left.length);
54
+ }
55
+ function sanitizeCredentialErrorDetail(message, options = {}) {
56
+ const filtered = message
57
+ .split(/\r?\n/)
58
+ .filter((line) => {
59
+ const trimmed = line.trim();
60
+ if (trimmed.startsWith("Command failed:"))
61
+ return false;
62
+ if (trimmed.includes("[input is hidden]"))
63
+ return false;
64
+ return true;
65
+ })
66
+ .join("\n")
67
+ .trim();
68
+ let sanitized = filtered || "command failed";
69
+ for (const secret of uniqueSecrets(options.secrets ?? [])) {
70
+ sanitized = sanitized.split(secret).join("[redacted]");
71
+ }
72
+ sanitized = sanitized.replace(LONG_ENCODED_TOKEN_PATTERN, "[redacted]");
73
+ if (sanitized.replace(/\[redacted\]/g, "").trim().length === 0) {
74
+ return "command failed";
75
+ }
76
+ return sanitized.slice(0, MAX_ERROR_DETAIL_LENGTH);
77
+ }
49
78
  // ---------------------------------------------------------------------------
50
79
  // bw CLI wrapper
51
80
  // ---------------------------------------------------------------------------
@@ -81,14 +110,7 @@ function sanitizeBwErrorDetail(message) {
81
110
  if (isBwSessionUnavailableMessage(message)) {
82
111
  return "bw CLI could not use the local Bitwarden session because it is locked, missing, or expired";
83
112
  }
84
- const withoutCommandLine = message
85
- .split(/\r?\n/)
86
- .filter((line) => !line.trim().startsWith("Command failed:"))
87
- .join("\n")
88
- .trim();
89
- return (withoutCommandLine || "command failed")
90
- .replace(/[A-Za-z0-9+/=]{80,}/g, "[redacted]")
91
- .slice(0, 500);
113
+ return sanitizeCredentialErrorDetail(message);
92
114
  }
93
115
  function formatBwCliError(err, stderr = "", args = []) {
94
116
  const operation = formatBwOperation(args);
@@ -36,11 +36,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.credentialToolDefinitions = void 0;
37
37
  const crypto = __importStar(require("node:crypto"));
38
38
  const credential_access_1 = require("./credential-access");
39
+ const bitwarden_store_1 = require("./bitwarden-store");
39
40
  const runtime_1 = require("../nerves/runtime");
40
41
  const DEFAULT_PASSWORD_LENGTH = 24;
41
42
  const MIN_PASSWORD_LENGTH = 12;
42
43
  const MAX_PASSWORD_LENGTH = 128;
43
- const MAX_ERROR_DETAIL_LENGTH = 500;
44
44
  const PASSWORD_CHARSETS = {
45
45
  lower: "abcdefghijkmnopqrstuvwxyz",
46
46
  upper: "ABCDEFGHJKLMNPQRSTUVWXYZ",
@@ -49,20 +49,7 @@ const PASSWORD_CHARSETS = {
49
49
  };
50
50
  function sanitizeCredentialToolError(err, secrets = []) {
51
51
  const raw = err instanceof Error ? err.message : String(err);
52
- const scrubbed = raw
53
- .split(/\r?\n/)
54
- .filter((line) => !line.trim().startsWith("Command failed:"))
55
- .join("\n")
56
- .trim();
57
- let sanitized = scrubbed || "command failed";
58
- const uniqueSecrets = [...new Set(secrets.filter((value) => typeof value === "string" && value.length >= 4))]
59
- .sort((left, right) => right.length - left.length);
60
- for (const secret of uniqueSecrets) {
61
- sanitized = sanitized.split(secret).join("[redacted]");
62
- }
63
- return sanitized
64
- .replace(/[A-Za-z0-9+/=]{80,}/g, "[redacted]")
65
- .slice(0, MAX_ERROR_DETAIL_LENGTH);
52
+ return (0, bitwarden_store_1.sanitizeCredentialErrorDetail)(raw, { secrets });
66
53
  }
67
54
  function requireTrimmedText(value, fieldName) {
68
55
  if (typeof value !== "string" || value.trim().length === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.406",
3
+ "version": "0.1.0-alpha.407",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",