worktrust 0.9.5 → 0.9.6

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/README.md CHANGED
@@ -180,6 +180,7 @@ nothing it does not:
180
180
  | `adaptation` | evidence and adaptation: what the stretch read by kind (docs, tests, logs, config, source, the web), a plan written again after a failure, a model changed right after a failure, two or more agents whose work a check met, and outages (overloaded, rate-limited, timed out) and how many the work went on past; counts only, never a path or a message (0.9.3) |
181
181
  | `reach` | the work's reach and its plan: commands on infrastructure (terraform, kubectl, helm, docker), data (psql, sqlite, bq, dbt) and cloud (aws, gcloud, az, supabase, vercel); plan or roadmap documents written and whether one came before the first code change; reviews approved, sent back or commented and issues opened or closed from the terminal; counts and one flag, never a command, a file name or a path (0.9.4) |
182
182
  | `hygiene.secrets` | counts a secret touched only when a file that holds one (a .env, a private key, credentials.json, .aws/credentials) is shown or copied (cat, head, tail, base64, cp); a search for a word (grep, sed, awk) is no read (0.9.5) |
183
+ | `hygiene.secrets` | counts a secret shown only when a reader (cat, head, tail, base64, cp) takes the file as its own argument; a command that uses a .env and reads its output, and a template (.env.example), are no secret shown (0.9.6) |
183
184
  | `collector_version` | the CLI version that measured it |
184
185
  | `seq`, `prev`, `hash` | the line's place, the hash of the line before it, and its own hash |
185
186
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "worktrust",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "description": "Couple this computer to WorkTrust: approve a code in your browser, and every AI app here reports what you built. Metadata only, no dependencies.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -63,9 +63,13 @@ const MARKS = [
63
63
  const PLAN_DOC = /(^|[\\/])(PLAN|ROADMAP|DESIGN|SPEC|RFC|ADR)[\w.-]*\.(md|mdx|txt)$|(^|[\\/])(plans?|roadmaps?|rfcs?|adrs?|specs?)[\\/][^\\/]+\.(md|mdx)$|\.plan\.md$/i;
64
64
  const WRITE_TOOLS = new Set(["Write", "Edit", "MultiEdit", "write_file", "edit_file", "create_file"]);
65
65
  // 0.9.5: a file that holds a secret by its name, as a path token; "credentials" only as a file (a search for the word is no read).
66
- const SECRET_FILE = /(^|[\/\s'"])(\.env(\.[\w-]+)?|id_(rsa|ed25519|ecdsa)|[\w.-]+\.(pem|p12|pfx|key)|credentials\.json|\.aws[\/]credentials|\.npmrc|\.netrc|\.pgpass)(['"\s]|$)/;
66
+ // 0.9.6: a file that holds a secret by its name, as a path token; a template (.env.example, .sample, .template, .dist) holds none.
67
+ const SECRET_FILE = /(^|[\/\s'"])(\.env(\.(?!example\b|sample\b|template\b|dist\b)[\w-]+)?|id_(rsa|ed25519|ecdsa)|[\w.-]+\.(pem|p12|pfx)|credentials\.json|\.aws[\/]credentials|\.npmrc|\.netrc|\.pgpass)(['"\s]|$)/;
67
68
  // 0.9.5: a command that shows or copies a file's content; a search (grep, sed, awk) names a word and is no read.
68
- const PRINTS = /(^|[\s;&|(])(cat|less|more|head|tail|bat|type|Get-Content|base64|xxd|strings|cp|scp)\s/;
69
+ // 0.9.6: a piece of the pipeline whose command IS a reader (cat, head, tail, cp ...) and whose own arguments name the file;
70
+ // `node --env-file .env.local x | tail` uses the file and reads the output, and is no secret shown (2,000 such counted before).
71
+ const READER = /^\s*(sudo\s+)?(cat|less|more|head|tail|bat|base64|xxd|strings|cp|scp|Get-Content)\b/;
72
+ const readsSecret = (command) => command.split(/\|\|?|&&|;|\n/).some((segment) => READER.test(segment) && SECRET_FILE.test(segment.replace(READER, " ")));
69
73
  const READ_TOOLS = new Set(["Read", "read_file", "view", "open_file"]);
70
74
  export const marksOf = (block) => {
71
75
  const name = String(block?.name ?? "");
@@ -74,7 +78,7 @@ export const marksOf = (block) => {
74
78
  const marks = typeof command === "string" ? MARKS.filter(([, pattern]) => pattern.test(command)).map(([mark]) => mark) : [];
75
79
  const written = WRITE_TOOLS.has(name) ? block.input?.file_path ?? block.input?.path ?? null : null;
76
80
  if (typeof written === "string" && PLAN_DOC.test(written)) marks.push("plan_doc");
77
- if ((typeof path === "string" && SECRET_FILE.test(path)) || (typeof command === "string" && PRINTS.test(command) && SECRET_FILE.test(command))) marks.push("secret");
81
+ if ((typeof path === "string" && SECRET_FILE.test(path)) || (typeof command === "string" && readsSecret(command))) marks.push("secret");
78
82
  return marks;
79
83
  };
80
84
 
package/worktrust.mjs CHANGED
@@ -73,7 +73,7 @@ const command = args.find((arg, at) => !arg.startsWith("--") && !(at > 0 && VALU
73
73
  const flag = (name) => { const at = args.indexOf(`--${name}`); return at >= 0 ? args[at + 1] : undefined; };
74
74
  const has = (name) => args.includes(`--${name}`);
75
75
  /** This CLI's version, said to the door so the app can tell which computer runs an old one (check-cli-package holds it equal to package.json). */
76
- const CLI_VERSION = "0.9.5";
76
+ const CLI_VERSION = "0.9.6";
77
77
  const ORIGIN = (flag("origin") ?? process.env.WORKTRUST_ORIGIN ?? "https://app.worktrust.io").replace(/\/$/, "");
78
78
  const MCP = flag("url") ?? process.env.WORKTRUST_MCP_URL ?? `${ORIGIN}/api/mcp`;
79
79
  const HOME_DIR = join(homedir(), ".worktrust");