brainjar 0.3.721 → 0.3.725

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.
Files changed (2) hide show
  1. package/brainjar.js +49 -12
  2. package/package.json +1 -1
package/brainjar.js CHANGED
@@ -107,7 +107,7 @@ var CLI_VERSION, CACHE, DAY;
107
107
  var init_version_check = __esm({
108
108
  "packages/cli/src/version-check.ts"() {
109
109
  "use strict";
110
- CLI_VERSION = "0.3.721";
110
+ CLI_VERSION = "0.3.725";
111
111
  CACHE = path.join(os.homedir(), ".brainjar", "version-check.json");
112
112
  DAY = 864e5;
113
113
  }
@@ -6018,12 +6018,28 @@ var init_vector = __esm({
6018
6018
  }
6019
6019
  });
6020
6020
 
6021
+ // packages/db/src/audit-origin.ts
6022
+ import { AsyncLocalStorage } from "node:async_hooks";
6023
+ function withAuditOrigin(name, fn) {
6024
+ return store.run(name, fn);
6025
+ }
6026
+ function currentAuditOrigin() {
6027
+ return store.getStore() ?? null;
6028
+ }
6029
+ var store;
6030
+ var init_audit_origin = __esm({
6031
+ "packages/db/src/audit-origin.ts"() {
6032
+ "use strict";
6033
+ store = new AsyncLocalStorage();
6034
+ }
6035
+ });
6036
+
6021
6037
  // packages/db/src/repository.ts
6022
6038
  async function getBrain(id, pool2 = getPool()) {
6023
6039
  return (await pool2.query("SELECT * FROM brain WHERE id = $1", [id])).rows[0] ?? null;
6024
6040
  }
6025
- function brainRepo(brainId, pool2 = getPool(), actor = null) {
6026
- return new BrainRepository(brainId, pool2, actor);
6041
+ function brainRepo(brainId, pool2 = getPool(), actor = null, origin = null) {
6042
+ return new BrainRepository(brainId, pool2, actor, origin);
6027
6043
  }
6028
6044
  var MO_COLUMNS, MO_COLUMNS_MO, evAgg, EV_AGG, EV_AGG_MO, ConflictError, BrainRepository;
6029
6045
  var init_repository = __esm({
@@ -6031,6 +6047,7 @@ var init_repository = __esm({
6031
6047
  "use strict";
6032
6048
  init_src();
6033
6049
  init_pool();
6050
+ init_audit_origin();
6034
6051
  init_vector();
6035
6052
  MO_COLUMNS = "id, brain_id, type, title, body, why, status, confidence, version, created_by, verified_by, created_at, occurred_at, updated_at, last_verified_at";
6036
6053
  MO_COLUMNS_MO = MO_COLUMNS.split(", ").map((c) => `mo.${c}`).join(", ");
@@ -6050,29 +6067,47 @@ var init_repository = __esm({
6050
6067
  actual;
6051
6068
  };
6052
6069
  BrainRepository = class {
6053
- constructor(brainId, pool2 = getPool(), actor = null) {
6070
+ constructor(brainId, pool2 = getPool(), actor = null, origin = null) {
6054
6071
  this.brainId = brainId;
6055
6072
  this.pool = pool2;
6056
6073
  this.actor = actor;
6074
+ this.origin = origin;
6057
6075
  }
6058
6076
  brainId;
6059
6077
  pool;
6060
6078
  actor;
6079
+ origin;
6061
6080
  /** Append an audit-log entry (append-only). Uses the given client when inside a transaction. */
6062
6081
  async recordAudit(action, objectId, detail, client = this.pool) {
6082
+ const origin = this.origin ?? currentAuditOrigin();
6063
6083
  await client.query(
6064
6084
  `INSERT INTO audit_log (brain_id, actor_user_id, action, object_id, detail)
6065
6085
  VALUES ($1, $2, $3, $4, $5)`,
6066
- [this.brainId, this.actor, action, objectId, JSON.stringify(detail)]
6086
+ [
6087
+ this.brainId,
6088
+ this.actor,
6089
+ action,
6090
+ objectId,
6091
+ JSON.stringify(origin ? { ...detail, origin } : detail)
6092
+ ]
6067
6093
  );
6068
6094
  }
6069
- /** Per-Brain activity feed, newest first (actor email joined for display). */
6070
- async listActivity(limit = 50) {
6095
+ /**
6096
+ * Per-Brain activity feed, newest first, with the actor's email and the object's current
6097
+ * title joined for display. `system: false` keeps only rows a person or agent wrote (an
6098
+ * actor is set): background jobs write thousands of rows and would push those out of the
6099
+ * window otherwise (BJ-80).
6100
+ */
6101
+ async listActivity(limit = 50, opts = {}) {
6071
6102
  return (await this.pool.query(
6072
6103
  `SELECT a.id, a.brain_id, a.actor_user_id, u.email AS actor_email,
6073
- a.action, a.object_id, a.detail, a.created_at
6074
- FROM audit_log a LEFT JOIN app_user u ON u.id = a.actor_user_id
6075
- WHERE a.brain_id = $1 ORDER BY a.created_at DESC LIMIT $2`,
6104
+ a.action, a.object_id, m.title AS object_title, m.type AS object_type,
6105
+ a.detail, a.created_at
6106
+ FROM audit_log a
6107
+ LEFT JOIN app_user u ON u.id = a.actor_user_id
6108
+ LEFT JOIN memory_object m ON m.id = a.object_id
6109
+ WHERE a.brain_id = $1${opts.system === false ? " AND a.actor_user_id IS NOT NULL" : ""}
6110
+ ORDER BY a.created_at DESC LIMIT $2`,
6076
6111
  [this.brainId, limit]
6077
6112
  )).rows;
6078
6113
  }
@@ -7370,6 +7405,7 @@ var init_src2 = __esm({
7370
7405
  init_tickets();
7371
7406
  init_ruleset();
7372
7407
  init_usage();
7408
+ init_audit_origin();
7373
7409
  }
7374
7410
  });
7375
7411
 
@@ -14644,7 +14680,7 @@ function pickDocTitle(synthTitle, ownTitle, slug, taken) {
14644
14680
  taken.set(normTitle2(title), slug);
14645
14681
  return title;
14646
14682
  }
14647
- async function generateDoku(brainId, opts = {}) {
14683
+ async function generateDokuInner(brainId, opts = {}) {
14648
14684
  const data = await loadDokuData(brainId, opts.root);
14649
14685
  if (data.features.length === 0 && data.days.length === 0) return null;
14650
14686
  const doku = buildDokuModel(data);
@@ -15008,7 +15044,7 @@ async function exportDoku(brainId, root) {
15008
15044
  const sync = await writeDokuTree(root, files);
15009
15045
  return { pages: files.length, ...sync };
15010
15046
  }
15011
- var DOKU_FILENAME, DOKU_DIR, MANIFEST, CHANGELOG_DAYS, sha1, exists, isModule, moduleName, isRepoPath, normPath, PAGE_SYSTEM, TAXONOMY_SYSTEM, CATEGORY_SYSTEM, ENTRY_NARRATIVE_SYSTEM, FLOW_SYSTEM, ARCH_SYSTEM, ARCH_FLOWS_SYSTEM, FEATURE_FLOW_SYSTEM, normTitle2;
15047
+ var DOKU_FILENAME, DOKU_DIR, MANIFEST, CHANGELOG_DAYS, sha1, exists, isModule, moduleName, isRepoPath, normPath, PAGE_SYSTEM, TAXONOMY_SYSTEM, CATEGORY_SYSTEM, ENTRY_NARRATIVE_SYSTEM, FLOW_SYSTEM, ARCH_SYSTEM, ARCH_FLOWS_SYSTEM, FEATURE_FLOW_SYSTEM, normTitle2, generateDoku;
15012
15048
  var init_doku = __esm({
15013
15049
  "packages/ingest/src/doku.ts"() {
15014
15050
  "use strict";
@@ -15101,6 +15137,7 @@ var init_doku = __esm({
15101
15137
  "Ground everything in the fact sheet. Invent nothing."
15102
15138
  ].join(" ");
15103
15139
  normTitle2 = (t) => t.toLowerCase().replace(/\s+/g, " ").trim();
15140
+ generateDoku = (...args) => withAuditOrigin("doku", () => generateDokuInner(...args));
15104
15141
  }
15105
15142
  });
15106
15143
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brainjar",
3
- "version": "0.3.721",
3
+ "version": "0.3.725",
4
4
  "description": "BrainJar CLI: turn a repository into a live, self-documenting Brain.",
5
5
  "type": "module",
6
6
  "bin": {