@bluenotelogic/harness 0.1.0 → 0.2.0

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/writers.js CHANGED
@@ -13,8 +13,9 @@
13
13
  * `--dry-run` shows precisely what would happen and the merge logic is unit-testable
14
14
  * without touching a filesystem.
15
15
  */
16
- import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
17
- import { dirname } from "node:path";
16
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync, statSync, unlinkSync } from "node:fs";
17
+ import { dirname, join } from "node:path";
18
+ import { execFileSync } from "node:child_process";
18
19
  /** True when the change would actually alter the file. */
19
20
  export function isNoop(c) {
20
21
  return c.after === null || c.after === c.before;
@@ -54,88 +55,136 @@ export function planMcpJson(path, existing, servers) {
54
55
  doc["mcpServers"] = { ...current, ...servers };
55
56
  return { path, before: existing, after: JSON.stringify(doc, null, 2) + "\n" };
56
57
  }
57
- /**
58
- * `.claude/settings.local.json` — an `env` block Claude Code applies to every session.
59
- *
60
- * WHY THIS EXISTS AT ALL: the VS Code extension launches `claude` without sourcing a shell
61
- * env file, so a `${VAR}` reference in `.mcp.json` would not expand there. This file is how
62
- * the harness works from the VS Code button rather than only from `source .env && claude`.
63
- * Only written when a token was minted — the OAuth path needs no env at all.
64
- */
65
- export function planSettingsLocal(path, existing, env) {
66
- let doc = {};
67
- if (existing !== null && existing.trim() !== "") {
68
- try {
69
- const parsed = JSON.parse(existing);
70
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
71
- throw new Error("not a JSON object");
72
- }
73
- doc = parsed;
74
- }
75
- catch (e) {
76
- return {
77
- path,
78
- before: existing,
79
- after: null,
80
- skipped: `existing settings.local.json is not valid JSON (${e.message}) — left untouched.`,
81
- };
82
- }
83
- }
84
- const currentEnv = typeof doc["env"] === "object" && doc["env"] !== null && !Array.isArray(doc["env"])
85
- ? doc["env"]
86
- : {};
87
- doc["env"] = { ...currentEnv, ...env };
88
- return {
89
- path,
90
- before: existing,
91
- after: JSON.stringify(doc, null, 2) + "\n",
92
- note: "holds a plaintext token — make sure .claude/settings.local.json is gitignored",
93
- };
94
- }
95
58
  /**
96
59
  * Codex `config.toml`.
97
60
  *
98
- * We do NOT parse TOML (that would mean a dependency, and this package has none). Instead:
99
- * if a `[mcp_servers.<name>]` table already exists we leave the file completely alone and
100
- * hand the user the snippet; otherwise we APPEND the table. Appending is safe because TOML
101
- * tables are order-independent, and appending can never corrupt what is already there.
61
+ * We do NOT parse TOML (that would mean a dependency, and this package has none). The active
62
+ * writer below owns one explicit marked block, replaces only that block, and refuses ambiguous
63
+ * unowned conflicts while preserving all unrelated TOML.
102
64
  *
103
65
  * The token itself never goes in here — it goes to `~/.codex/.env`, referenced by
104
66
  * `bearer_token_env_var`, so the config file stays safe to read over someone's shoulder.
105
67
  */
68
+ /** Stable Codex approval surface. Token grants still enforce the daily/maintainer boundary. */
69
+ export const CODEX_MAINTAINER_APPROVED_TOOLS = [
70
+ "memory_bootstrap", "memory_context", "memory_recall", "memory_recall_repo",
71
+ "memory_propose", "memory_feedback",
72
+ "memory_scratch_set", "memory_scratch_get", "memory_scratch_delete",
73
+ "memory_episodic_log", "memory_episodic_recall",
74
+ "harness_run_start", "harness_run_step", "harness_run_complete", "harness_run_list",
75
+ "memory_review", "memory_v3_status", "harness_run_release",
76
+ ];
77
+ /** Codex config writer for the one block owned by this installer. */
106
78
  export function planCodexConfig(path, existing, serverName, mcpUrl, tokenEnvVar) {
79
+ const start = "# BEGIN @bluenotelogic/harness managed MCP";
80
+ const end = "# END @bluenotelogic/harness managed MCP";
107
81
  const table = `[mcp_servers.${serverName}]`;
108
- const block = `\n# Added by @bluenotelogic/harness. Codex cannot do OAuth yet, so it reads a token\n` +
109
- `# from the environment; the value lives in ~/.codex/.env, never in this file.\n` +
82
+ const approvals = CODEX_MAINTAINER_APPROVED_TOOLS.map((tool) => `\n[mcp_servers.${serverName}.tools.${tool}]\napproval_mode = "approve"\n`).join("");
83
+ const block = `${start}\n` +
84
+ `# Credentials are environment-only; the owner-restricted value lives in ~/.codex/.env.\n` +
110
85
  `${table}\n` +
111
86
  `url = "${mcpUrl}"\n` +
112
- `bearer_token_env_var = "${tokenEnvVar}"\n`;
113
- if (existing !== null && existing.includes(table)) {
87
+ `bearer_token_env_var = "${tokenEnvVar}"\n` +
88
+ `default_tools_approval_mode = "prompt"\n` +
89
+ approvals +
90
+ `${end}\n`;
91
+ const base = existing ?? "";
92
+ const startCount = base.split(start).length - 1;
93
+ const endCount = base.split(end).length - 1;
94
+ if (startCount !== endCount || startCount > 1) {
95
+ return { path, before: existing, after: null, skipped: "ambiguous @bluenotelogic/harness managed-block markers; left untouched" };
96
+ }
97
+ if (startCount === 1) {
98
+ const from = base.indexOf(start);
99
+ const through = base.indexOf(end, from) + end.length;
100
+ const after = `${base.slice(0, from)}${block}${base.slice(through).replace(/^\r?\n/, "")}`;
101
+ return { path, before: existing, after };
102
+ }
103
+ const legacy = /\n?# Added by @bluenotelogic\/harness\. Codex cannot do OAuth yet, so it reads a token\r?\n# from the environment; the value lives in ~\/\.codex\/\.env, never in this file\.\r?\n\[mcp_servers\.([^\]\r\n]+)\]\r?\nurl = "[^"\r\n]+"\r?\nbearer_token_env_var = "[A-Za-z_][A-Za-z0-9_]*"\r?\n?/g;
104
+ const matches = [...base.matchAll(legacy)];
105
+ if (matches.length > 1) {
106
+ return { path, before: existing, after: null, skipped: "multiple legacy harness blocks are ambiguous; left untouched" };
107
+ }
108
+ if (matches.length === 1) {
109
+ const match = matches[0];
110
+ const index = match.index;
111
+ const without = `${base.slice(0, index)}${base.slice(index + match[0].length)}`.trimEnd();
112
+ return { path, before: existing, after: `${without}${without ? "\n\n" : ""}${block}` };
113
+ }
114
+ // `codex mcp add` writes this exact, tokenless three-line table. It is safe to adopt only
115
+ // when its URL and env reference already match the requested installation and the table has
116
+ // no child settings; any different or extended table remains an ambiguous unowned conflict.
117
+ const childTablePrefix = `[mcp_servers.${serverName}.`;
118
+ if (base.includes(childTablePrefix)) {
114
119
  return {
115
120
  path,
116
121
  before: existing,
117
122
  after: null,
118
- skipped: `${table} already present — left untouched. If the URL changed, update it by hand:\n` +
119
- block.trim(),
123
+ skipped: `${table} has unowned child settings; ownership is ambiguous, so it was left untouched.`,
120
124
  };
121
125
  }
122
- const base = existing ?? "";
123
- const sep = base === "" || base.endsWith("\n") ? "" : "\n";
124
- return { path, before: existing, after: base + sep + block };
126
+ const exactCliTable = new RegExp(`(?:^|\\r?\\n)${escapeRe(table)}\\r?\\n` +
127
+ `url = "${escapeRe(mcpUrl)}"\\r?\\n` +
128
+ `bearer_token_env_var = "${escapeRe(tokenEnvVar)}"\\r?\\n?` +
129
+ `(?=\\r?\\n\\[|$)`);
130
+ const cliMatch = base.match(exactCliTable);
131
+ if (cliMatch?.index !== undefined) {
132
+ const without = `${base.slice(0, cliMatch.index)}${base.slice(cliMatch.index + cliMatch[0].length)}`.trimEnd();
133
+ return { path, before: existing, after: `${without}${without ? "\n\n" : ""}${block}` };
134
+ }
135
+ if (base.includes(table)) {
136
+ return {
137
+ path,
138
+ before: existing,
139
+ after: null,
140
+ skipped: `${table} exists outside the @bluenotelogic/harness managed block; ownership is ambiguous, so it was left untouched.`,
141
+ };
142
+ }
143
+ const withoutTrailing = base.trimEnd();
144
+ return { path, before: existing, after: `${withoutTrailing}${withoutTrailing ? "\n\n" : ""}${block}` };
125
145
  }
126
- /** `~/.codex/.env` — one KEY=value line, replaced in place if already present. */
127
- export function planEnvVar(path, existing, key, value) {
146
+ /** The names (never the values) of `names` that a dotenv file defines, in the order given. */
147
+ export function legacyEnvVarsPresent(existing, names) {
148
+ if (existing === null)
149
+ return [];
150
+ return names.filter((name) => new RegExp(`^${escapeRe(name)}=`, "m").test(existing));
151
+ }
152
+ /**
153
+ * Set `key` in a dotenv file, leaving every other line as it was.
154
+ *
155
+ * `legacyAliases` are earlier names for the same credential. They are NOT removed: this used to
156
+ * delete them, but BNL staff machines still run tools that read BNL_MEMORY_MCP_TOKEN /
157
+ * CAVEAU_MCP_TOKEN, so a re-install would have broken those tools. The ones present are named
158
+ * in a notice instead, so the user can remove them once nothing uses them.
159
+ */
160
+ export function planEnvVar(path, existing, key, value, legacyAliases = []) {
128
161
  const line = `${key}=${value}`;
129
162
  const base = existing ?? "";
130
163
  const re = new RegExp(`^${escapeRe(key)}=.*$`, "m");
131
164
  const after = re.test(base)
132
165
  ? base.replace(re, line)
133
166
  : base + (base === "" || base.endsWith("\n") ? "" : "\n") + line + "\n";
167
+ const legacy = legacyEnvVarsPresent(existing, legacyAliases.filter((alias) => alias !== key));
168
+ const them = legacy.length > 1 ? "them" : "it";
134
169
  return {
135
170
  path,
136
171
  before: existing,
137
172
  after,
138
173
  note: "holds a plaintext token — never commit it",
174
+ ...(legacy.length
175
+ ? { notice: `legacy ${legacy.join(", ")} left in place; ${key} is now used, so remove ${them} once nothing uses ${them}` }
176
+ : {}),
177
+ sensitive: true,
178
+ };
179
+ }
180
+ /** Plan one owner-only credential file whose entire contents are the supplied value. */
181
+ export function planCredentialFile(path, existing, value, note = "holds a plaintext token — never commit or share it") {
182
+ return {
183
+ path,
184
+ before: existing,
185
+ after: `${value.replace(/[\r\n]+$/g, "")}\n`,
186
+ note,
187
+ sensitive: true,
139
188
  };
140
189
  }
141
190
  function escapeRe(s) {
@@ -163,8 +212,8 @@ export function assertNoSecret(c) {
163
212
  const found = c.after.match(/\b(cmem|mcp)_[A-Za-z0-9_-]{16,}/);
164
213
  if (found) {
165
214
  throw new Error(`refusing to write what looks like a live token into ${c.path} ` +
166
- `(matched ${found[0].slice(0, 8)}…). Tokens belong in ~/.codex/.env or ` +
167
- `.claude/settings.local.json, never in a committed config.`);
215
+ `(matched ${found[0].slice(0, 8)}…). Tokens belong only in ~/.codex/.env, never in a ` +
216
+ `repository file.`);
168
217
  }
169
218
  }
170
219
  export function readIfExists(path) {
@@ -175,6 +224,137 @@ export function readIfExists(path) {
175
224
  return null;
176
225
  }
177
226
  }
227
+ const UNSAFE_WINDOWS_PRINCIPALS = ["Everyone", "BUILTIN\\Users", "Authenticated Users", "Users"];
228
+ /**
229
+ * Confirms `icacls <path>` output grants access to nobody broader than the given owner.
230
+ * Exported (rather than folded into secureCredentialFileWindows) so this has real unit
231
+ * coverage without shelling out to icacls in a test -- icacls output is the only part of
232
+ * Windows ACL handling that is pure and deterministic; the actual system calls are not.
233
+ *
234
+ * Match a complete principal immediately before `:(`. A plain substring check is unsafe here:
235
+ * the sandbox-local `CodexSandboxUsers` principal ends in `Users`, so searching for `Users:(`
236
+ * incorrectly treats that narrow execution group as the broad built-in Users group. The left
237
+ * boundary deliberately excludes every character valid inside the account names we encounter,
238
+ * including backslash and hyphen; this also keeps `DAVE-NEW\david` intact.
239
+ */
240
+ export function assertWindowsAclIsOwnerOnly(icaclsOutput, owner, path) {
241
+ const hasPrincipal = (principal) => {
242
+ const escaped = escapeRe(principal);
243
+ return new RegExp(`(?:^|[^A-Za-z0-9_.\\\\-])${escaped}:\\(`, "im").test(icaclsOutput);
244
+ };
245
+ const unsafe = UNSAFE_WINDOWS_PRINCIPALS.filter(hasPrincipal);
246
+ if (unsafe.length > 0) {
247
+ throw new Error(`${path} still grants access to ${unsafe.join(", ")} after tightening its ACL`);
248
+ }
249
+ // An ACL that granted nothing to anyone would pass the check above while leaving the file
250
+ // unreadable by its own owner -- a different bug this must not let through silently.
251
+ if (!hasPrincipal(owner)) {
252
+ throw new Error(`${path}'s ACL does not grant the current user (${owner}) after tightening it`);
253
+ }
254
+ }
255
+ /**
256
+ * Proves a DACL (SDDL form, from Get-Acl) is OWNER-ONLY: protected from inheritance, and every
257
+ * allow ACE names the current user's SID. This is the authoritative check; the icacls one above
258
+ * is a denylist of English group names, so it waved through a German `VORDEFINIERT\Benutzer`,
259
+ * a stray explicit grant to another account, and sandbox groups. SIDs read the same in every
260
+ * language.
261
+ */
262
+ export function assertWindowsSddlIsOwnerOnly(sddl, userSid, path) {
263
+ const dacl = /D:([A-Z]*)((?:\([^)]*\))*)/.exec(sddl);
264
+ if (!dacl)
265
+ throw new Error(`could not read the access control list of ${path}`);
266
+ if (!(dacl[1] ?? "").includes("P")) {
267
+ throw new Error(`${path} still inherits permissions from its folder after tightening its ACL`);
268
+ }
269
+ const allows = [...(dacl[2] ?? "").matchAll(/\(([^)]*)\)/g)]
270
+ .map((m) => (m[1] ?? "").split(";"))
271
+ .filter((fields) => fields[0] === "A" || fields[0] === "OA");
272
+ const others = allows
273
+ .map((fields) => fields[5] ?? "")
274
+ .filter((sid) => sid.toUpperCase() !== userSid.toUpperCase());
275
+ if (others.length > 0) {
276
+ throw new Error(`${path} still grants access to ${others.join(", ")} besides the current user after tightening ` +
277
+ `its ACL (if this runs inside a sandbox, run the installer from a normal terminal)`);
278
+ }
279
+ if (allows.length === 0) {
280
+ throw new Error(`${path}'s ACL does not grant the current user after tightening it`);
281
+ }
282
+ }
283
+ function currentWindowsUserSid() {
284
+ // By absolute path: from Git Bash, a bare `whoami` resolves to MSYS coreutils, which has no /user.
285
+ const whoami = join(process.env["SystemRoot"] || "C:\\Windows", "System32", "whoami.exe");
286
+ const out = execFileSync(whoami, ["/user", "/fo", "csv", "/nh"], { encoding: "utf8", windowsHide: true });
287
+ const sid = /S-1-\d+(?:-\d+)+/.exec(out)?.[0];
288
+ if (!sid)
289
+ throw new Error("cannot determine the current Windows user's SID (whoami /user)");
290
+ return sid;
291
+ }
292
+ function powershell(command, extraEnv) {
293
+ // Values travel in the environment, never interpolated into the command text.
294
+ return execFileSync(join(process.env["SystemRoot"] || "C:\\Windows", "System32", "WindowsPowerShell", "v1.0", "powershell.exe"), ["-NoProfile", "-NonInteractive", "-Command", command], { encoding: "utf8", env: { ...process.env, ...extraEnv }, windowsHide: true }).trim();
295
+ }
296
+ function windowsSddl(path) {
297
+ return powershell("(Get-Acl -LiteralPath $env:BNL_HARNESS_ACL_PATH).Sddl", { BNL_HARNESS_ACL_PATH: path });
298
+ }
299
+ /**
300
+ * Replace the DACL with exactly one entry, the current user. `icacls /grant:r` cannot do this: it
301
+ * replaces only the NAMED user's entry. Measured on a machine with Codex's Windows sandbox: every
302
+ * new file there arrives with an explicit `CodexSandboxUsers:(RX)` entry, which survived
303
+ * `/inheritance:r /grant:r` and left the credential readable by the sandbox group that runs
304
+ * agent commands.
305
+ */
306
+ function setOwnerOnlyDacl(path, userSid) {
307
+ // GetAccessControl/SetAccessControl on the Access section only. Set-Acl rewrites the audit
308
+ // section too and fails without SeSecurityPrivilege.
309
+ powershell("$s = [System.Security.AccessControl.AccessControlSections]::Access; " +
310
+ "$i = Get-Item -LiteralPath $env:BNL_HARNESS_ACL_PATH; $a = $i.GetAccessControl($s); " +
311
+ "$a.SetSecurityDescriptorSddlForm('D:PAI(A;;FA;;;' + $env:BNL_HARNESS_ACL_SID + ')', $s); " +
312
+ "$i.SetAccessControl($a)", { BNL_HARNESS_ACL_PATH: path, BNL_HARNESS_ACL_SID: userSid });
313
+ }
314
+ function currentWindowsUser() {
315
+ const user = process.env["USERNAME"];
316
+ if (!user)
317
+ throw new Error("cannot determine the current Windows user (USERNAME is unset)");
318
+ const domain = process.env["USERDOMAIN"];
319
+ return domain ? `${domain}\\${user}` : user;
320
+ }
321
+ function secureCredentialFileWindows(path) {
322
+ const owner = currentWindowsUser();
323
+ // /inheritance:r drops whatever ACEs the file inherited from its parent directory;
324
+ // /grant:r REPLACES any existing explicit grants with exactly this one, rather than adding
325
+ // to them -- so re-running this on an already-tightened file converges instead of piling up.
326
+ execFileSync("icacls", [path, "/inheritance:r", "/grant:r", `${owner}:F`], { stdio: "ignore" });
327
+ const userSid = currentWindowsUserSid();
328
+ setOwnerOnlyDacl(path, userSid);
329
+ const verify = execFileSync("icacls", [path], { encoding: "utf8" });
330
+ assertWindowsAclIsOwnerOnly(verify, owner, path);
331
+ assertWindowsSddlIsOwnerOnly(windowsSddl(path), userSid, path);
332
+ }
333
+ /**
334
+ * Restrict a just-written credential file to the current user only, and PROVE it before
335
+ * returning -- a credential file whose protection could not be verified is worse than none,
336
+ * and the caller (apply()) deletes what it just wrote when this throws.
337
+ */
338
+ export function secureCredentialFile(path) {
339
+ if (process.platform === "win32") {
340
+ secureCredentialFileWindows(path);
341
+ return;
342
+ }
343
+ chmodSync(path, 0o600);
344
+ const mode = statSync(path).mode & 0o777;
345
+ if (mode !== 0o600) {
346
+ throw new Error(`chmod 0600 did not take effect on ${path} (mode is 0${mode.toString(8)})`);
347
+ }
348
+ // Best-effort: the file's own 0600 is the load-bearing protection. A parent directory this
349
+ // process does not own (so chmod fails) is still reported by the outer try/catch in apply(),
350
+ // just not treated as fatal on its own -- only the file's own mode is asserted above.
351
+ try {
352
+ chmodSync(dirname(path), 0o700);
353
+ }
354
+ catch {
355
+ /* best-effort */
356
+ }
357
+ }
178
358
  export function apply(changes, dryRun) {
179
359
  for (const c of changes) {
180
360
  if (c.after === null || isNoop(c))
@@ -184,7 +364,27 @@ export function apply(changes, dryRun) {
184
364
  const dir = dirname(c.path);
185
365
  if (!existsSync(dir))
186
366
  mkdirSync(dir, { recursive: true });
187
- writeFileSync(c.path, c.after, "utf8");
367
+ // A credential file is recreated, not rewritten in place: overwriting keeps the old file's
368
+ // ACL, and `icacls /grant:r` replaces only the named user's entry, so an explicit grant some
369
+ // earlier tool left on it would survive the tightening.
370
+ if (c.sensitive && existsSync(c.path))
371
+ unlinkSync(c.path);
372
+ writeFileSync(c.path, c.after, c.sensitive ? { encoding: "utf8", mode: 0o600 } : "utf8");
373
+ if (c.sensitive) {
374
+ try {
375
+ secureCredentialFile(c.path);
376
+ }
377
+ catch (e) {
378
+ try {
379
+ unlinkSync(c.path);
380
+ }
381
+ catch {
382
+ /* best-effort -- the thrown error below is what the user sees regardless */
383
+ }
384
+ throw new Error(`wrote ${c.path} but could not verify it is protected, so it was removed: ` +
385
+ `${e.message}`);
386
+ }
387
+ }
188
388
  }
189
389
  }
190
390
  //# sourceMappingURL=writers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"writers.js","sourceRoot":"","sources":["../src/writers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,0DAA0D;AAC1D,MAAM,UAAU,MAAM,CAAC,CAAa;IAClC,OAAO,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,MAAM,CAAC;AAClD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,IAAY,EACZ,QAAuB,EACvB,OAAgC;IAEhC,IAAI,GAAG,GAA4B,EAAE,CAAC;IAEtC,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAChD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACpC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3E,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC;YACD,GAAG,GAAG,MAAiC,CAAC;QAC1C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO;gBACL,IAAI;gBACJ,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,IAAI;gBACX,OAAO,EACL,yCAA0C,CAAW,CAAC,OAAO,MAAM;oBACnE,wDAAwD;aAC3D,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GACX,OAAO,GAAG,CAAC,YAAY,CAAC,KAAK,QAAQ,IAAI,GAAG,CAAC,YAAY,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACtG,CAAC,CAAE,GAAG,CAAC,YAAY,CAA6B;QAChD,CAAC,CAAC,EAAE,CAAC;IAET,wFAAwF;IACxF,8EAA8E;IAC9E,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;IAE/C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;AAChF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAY,EACZ,QAAuB,EACvB,GAA2B;IAE3B,IAAI,GAAG,GAA4B,EAAE,CAAC;IACtC,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAChD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACpC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3E,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC;YACD,GAAG,GAAG,MAAiC,CAAC;QAC1C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO;gBACL,IAAI;gBACJ,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,IAAI;gBACX,OAAO,EAAE,mDAAoD,CAAW,CAAC,OAAO,qBAAqB;aACtG,CAAC;QACJ,CAAC;IACH,CAAC;IACD,MAAM,UAAU,GACd,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACjF,CAAC,CAAE,GAAG,CAAC,KAAK,CAA6B;QACzC,CAAC,CAAC,EAAE,CAAC;IACT,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,UAAU,EAAE,GAAG,GAAG,EAAE,CAAC;IACvC,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,QAAQ;QAChB,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI;QAC1C,IAAI,EAAE,+EAA+E;KACtF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAY,EACZ,QAAuB,EACvB,UAAkB,EAClB,MAAc,EACd,WAAmB;IAEnB,MAAM,KAAK,GAAG,gBAAgB,UAAU,GAAG,CAAC;IAC5C,MAAM,KAAK,GACT,uFAAuF;QACvF,iFAAiF;QACjF,GAAG,KAAK,IAAI;QACZ,UAAU,MAAM,KAAK;QACrB,2BAA2B,WAAW,KAAK,CAAC;IAE9C,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,QAAQ;YAChB,KAAK,EAAE,IAAI;YACX,OAAO,EACL,GAAG,KAAK,6EAA6E;gBACrF,KAAK,CAAC,IAAI,EAAE;SACf,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,IAAI,EAAE,CAAC;IAC5B,MAAM,GAAG,GAAG,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,GAAG,GAAG,GAAG,KAAK,EAAE,CAAC;AAC/D,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,QAAuB,EACvB,GAAW,EACX,KAAa;IAEb,MAAM,IAAI,GAAG,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,QAAQ,IAAI,EAAE,CAAC;IAC5B,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;QACzB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC;QACxB,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1E,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,QAAQ;QAChB,KAAK;QACL,IAAI,EAAE,2CAA2C;KAClD,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS;IACzB,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,QAAuB,EAAE,IAAY;IACjF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC;AACrF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,CAAa;IAC1C,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI;QAAE,OAAO;IAC7B,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAC/D,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,uDAAuD,CAAC,CAAC,IAAI,GAAG;YAC9D,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,wCAAwC;YACxE,2DAA2D,CAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,OAAqB,EAAE,MAAe;IAC1D,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC;YAAE,SAAS;QAC5C,IAAI,MAAM;YAAE,SAAS;QACrB,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"writers.js","sourceRoot":"","sources":["../src/writers.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bluenotelogic/harness",
3
- "version": "0.1.0",
4
- "description": "One command to point a machine at Blue Note Memory (mem.bnlgit.com). Writes a TOKENLESS MCP config — OAuth-capable hosts hold their own credentials, so nothing secret lands in a repo file.",
3
+ "version": "0.2.0",
4
+ "description": "One command to connect Claude Code, Codex, VS Code, and Google Antigravity to ProofMEM with tokenless native OAuth MCP configuration.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "bnl-harness": "dist/index.js"
@@ -9,8 +9,11 @@
9
9
  "main": "./dist/index.js",
10
10
  "files": [
11
11
  "dist",
12
+ "assets",
12
13
  "README.md",
13
- "LICENSE"
14
+ "CHANGELOG.md",
15
+ "LICENSE",
16
+ "NOTICE"
14
17
  ],
15
18
  "scripts": {
16
19
  "build": "tsc",
@@ -31,7 +34,8 @@
31
34
  },
32
35
  "repository": {
33
36
  "type": "git",
34
- "url": "https://git.bluenotelogic.com/bnl/bnlgit-harness"
37
+ "url": "https://git.bluenotelogic.com/bnl/bnlgit-harness",
38
+ "directory": "packages/cli"
35
39
  },
36
40
  "keywords": [
37
41
  "mcp",
@@ -39,6 +43,8 @@
39
43
  "oauth",
40
44
  "claude-code",
41
45
  "codex",
46
+ "antigravity",
47
+ "proofmem",
42
48
  "bnlgit"
43
49
  ],
44
50
  "license": "Apache-2.0",