@cluesmith/codev-core 3.3.0 → 3.3.2

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/auth.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
- * Read the local auth key from disk. Returns null if file doesn't exist.
3
- * Read-only — does not create directories or generate keys.
4
- * Safe for use in the VS Code extension.
2
+ * Read the local auth key. Honors the `CODEV_TOWER_KEY` env override; otherwise
3
+ * reads it from disk, returning null if the file doesn't exist. Read-only — does
4
+ * not create directories or generate keys. Safe for use in the VS Code extension.
5
5
  */
6
6
  export declare function readLocalKey(): string | null;
7
7
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAM5C;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAYvC"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAyBA;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAQ5C;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAwBvC"}
package/dist/auth.js CHANGED
@@ -1,14 +1,35 @@
1
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
1
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, chmodSync } from 'node:fs';
2
2
  import { resolve } from 'node:path';
3
3
  import { randomBytes } from 'node:crypto';
4
4
  import { AGENT_FARM_DIR } from './constants.js';
5
5
  const LOCAL_KEY_PATH = resolve(AGENT_FARM_DIR, 'local-key');
6
6
  /**
7
- * Read the local auth key from disk. Returns null if file doesn't exist.
8
- * Read-only — does not create directories or generate keys.
9
- * Safe for use in the VS Code extension.
7
+ * Optional environment override for the shared Tower key. When `CODEV_TOWER_KEY`
8
+ * is set it IS the key on both sides: Tower treats it as the expected key and
9
+ * clients present it. This is the supported way to authenticate across a boundary
10
+ * where the client does not share Tower's `local-key` file — a host CLI/SDK
11
+ * reaching a Tower inside a container, or a Tower on a non-loopback bind
12
+ * (`BRIDGE_MODE`). Set the SAME value on Tower and every client. It must be the
13
+ * Tower's 64-hex key (the browser dashboard shell only injects a well-formed
14
+ * key). Unset for same-host loopback use, where the `local-key` file is the
15
+ * source of truth.
16
+ */
17
+ function keyOverride() {
18
+ const v = process.env.CODEV_TOWER_KEY;
19
+ if (!v)
20
+ return null;
21
+ const trimmed = v.trim();
22
+ return trimmed.length > 0 ? trimmed : null;
23
+ }
24
+ /**
25
+ * Read the local auth key. Honors the `CODEV_TOWER_KEY` env override; otherwise
26
+ * reads it from disk, returning null if the file doesn't exist. Read-only — does
27
+ * not create directories or generate keys. Safe for use in the VS Code extension.
10
28
  */
11
29
  export function readLocalKey() {
30
+ const override = keyOverride();
31
+ if (override)
32
+ return override;
12
33
  try {
13
34
  return readFileSync(LOCAL_KEY_PATH, 'utf-8').trim() || null;
14
35
  }
@@ -21,6 +42,9 @@ export function readLocalKey() {
21
42
  * a random key if missing. CLI-only — the extension should use readLocalKey().
22
43
  */
23
44
  export function ensureLocalKey() {
45
+ const override = keyOverride();
46
+ if (override)
47
+ return override;
24
48
  if (!existsSync(AGENT_FARM_DIR)) {
25
49
  mkdirSync(AGENT_FARM_DIR, { recursive: true, mode: 0o700 });
26
50
  }
@@ -29,6 +53,16 @@ export function ensureLocalKey() {
29
53
  writeFileSync(LOCAL_KEY_PATH, key, { mode: 0o600 });
30
54
  return key;
31
55
  }
56
+ // Repair permissions on an existing key file: `mode` on writeFileSync only
57
+ // applies at creation, so a key written before this hardening (or by another
58
+ // tool) may be world-readable. Tighten it to 0600 on read (best effort;
59
+ // chmod is a no-op on platforms that don't support POSIX modes).
60
+ try {
61
+ chmodSync(LOCAL_KEY_PATH, 0o600);
62
+ }
63
+ catch {
64
+ /* best effort — platform may not support chmod */
65
+ }
32
66
  return readFileSync(LOCAL_KEY_PATH, 'utf-8').trim();
33
67
  }
34
68
  //# sourceMappingURL=auth.js.map
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;AAE5D;;;;GAIG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAChC,SAAS,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5C,aAAa,CAAC,cAAc,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACpD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,OAAO,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;AACtD,CAAC"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;AAE5D;;;;;;;;;;GAUG;AACH,SAAS,WAAW;IAClB,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACtC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACzB,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAChC,SAAS,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5C,aAAa,CAAC,cAAc,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACpD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,2EAA2E;IAC3E,6EAA6E;IAC7E,wEAAwE;IACxE,iEAAiE;IACjE,IAAI,CAAC;QACH,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,kDAAkD;IACpD,CAAC;IACD,OAAO,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;AACtD,CAAC"}
@@ -1,2 +1,14 @@
1
+ /**
2
+ * Root of the user-global Agent Farm state directory: cloud credentials, the
3
+ * shared local key, `global.db`, `tower.log`, session logs.
4
+ *
5
+ * `CODEV_AGENT_FARM_DIR` overrides the default (#1515). Nothing in production
6
+ * sets it — it exists so a spawned *test* Tower can be pointed at a throwaway
7
+ * directory. Without an override there was no way to isolate one: every test
8
+ * Tower read the developer's real cloud credentials and real local key, wrote
9
+ * its test DB into `~/.agent-farm`, and watched the real config file. A test
10
+ * that then exercised tunnel disconnect acted as the user's registered Tower —
11
+ * deregistering it server-side and deleting the real credentials.
12
+ */
1
13
  export declare const AGENT_FARM_DIR: string;
2
14
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc,QAAoC,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,QAEU,CAAC"}
package/dist/constants.js CHANGED
@@ -1,4 +1,18 @@
1
1
  import { resolve } from 'node:path';
2
2
  import { homedir } from 'node:os';
3
- export const AGENT_FARM_DIR = resolve(homedir(), '.agent-farm');
3
+ /**
4
+ * Root of the user-global Agent Farm state directory: cloud credentials, the
5
+ * shared local key, `global.db`, `tower.log`, session logs.
6
+ *
7
+ * `CODEV_AGENT_FARM_DIR` overrides the default (#1515). Nothing in production
8
+ * sets it — it exists so a spawned *test* Tower can be pointed at a throwaway
9
+ * directory. Without an override there was no way to isolate one: every test
10
+ * Tower read the developer's real cloud credentials and real local key, wrote
11
+ * its test DB into `~/.agent-farm`, and watched the real config file. A test
12
+ * that then exercised tunnel disconnect acted as the user's registered Tower —
13
+ * deregistering it server-side and deleting the real credentials.
14
+ */
15
+ export const AGENT_FARM_DIR = process.env.CODEV_AGENT_FARM_DIR
16
+ ? resolve(process.env.CODEV_AGENT_FARM_DIR)
17
+ : resolve(homedir(), '.agent-farm');
4
18
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB;IAC5D,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IAC3C,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cluesmith/codev-core",
3
- "version": "3.3.0",
3
+ "version": "3.3.2",
4
4
  "description": "Server-side runtime for Codev — local-key issuance and homedir-derived paths. Client-side Tower access lives in @cluesmith/codev-sdk; the two packages never import each other.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -20,7 +20,7 @@
20
20
  "@types/node": "22.x",
21
21
  "typescript": "^6.0.3",
22
22
  "vitest": "^4.0.15",
23
- "@cluesmith/codev-types": "3.3.0"
23
+ "@cluesmith/codev-types": "3.3.2"
24
24
  },
25
25
  "license": "Apache-2.0",
26
26
  "scripts": {