@useorgx/wizard 0.1.43 → 0.1.44

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/cli.js CHANGED
@@ -6502,14 +6502,15 @@ function loadAiSessionImports(options) {
6502
6502
 
6503
6503
  // src/lib/work-graph-source-adapters.ts
6504
6504
  import { createHash as createHash3 } from "crypto";
6505
- import { existsSync as existsSync6, readdirSync as readdirSync4, readFileSync as readFileSync4, statSync as statSync4 } from "fs";
6505
+ import { execFileSync } from "child_process";
6506
+ import { closeSync, existsSync as existsSync6, openSync, readFileSync as readFileSync4, readdirSync as readdirSync4, readSync, statSync as statSync4 } from "fs";
6506
6507
  import { homedir as homedir2 } from "os";
6507
6508
  import { basename as basename3, join as join5, resolve } from "path";
6508
- var CLIENT_SOURCES = ["claude_code", "codex", "opencode", "goose", "cursor"];
6509
+ var CLIENT_SOURCES = ["claude_code", "codex", "opencode", "goose", "cursor", "github", "slack"];
6509
6510
  var DEFAULT_LIMIT_PER_SOURCE2 = 8;
6510
6511
  var DEFAULT_SINCE_DAYS2 = 45;
6511
6512
  var DEFAULT_MAX_BYTES_PER_FILE2 = 2e6;
6512
- var WORK_SIGNAL_PATTERN = /\b(decision|decided|tradeoff|artifact|implemented|created|changed|edited|shipped|verified|test|proof|commit|blocked|blocker|failed|fails|error|timeout|permission|owner|handoff|mcp__|orgx_|tool call|schema|zod|next action|follow[- ]?up|initiative|agent|skill|recipe|workflow|customer|business|launch|deploy)\b/i;
6513
+ var WORK_SIGNAL_PATTERN = /\b(decision|decided|approved|assigned|tradeoff|artifact|implemented|created|changed|edited|shipped|verified|test|proof|commit|pr|blocked|blocker|failed|fails|error|timeout|permission|owner|handoff|mcp__|orgx_|tool call|schema|zod|next action|follow[- ]?up|initiative|agent|skill|recipe|workflow|customer|business|launch|deploy)\b/i;
6513
6514
  function parseInvestigationSourceList(value) {
6514
6515
  if (!value?.trim() || value.trim().toLowerCase() === "manual") return [];
6515
6516
  const requested = value.split(",").map((item) => item.trim().toLowerCase().replace(/-/g, "_")).filter(Boolean);
@@ -6518,7 +6519,7 @@ function parseInvestigationSourceList(value) {
6518
6519
  const invalid = deduped.filter((source) => !CLIENT_SOURCES.includes(source));
6519
6520
  if (invalid.length > 0) {
6520
6521
  throw new Error(
6521
- `Unsupported investigation source: ${invalid.join(", ")}. Use claude, codex, opencode, goose, cursor, or all.`
6522
+ `Unsupported investigation source: ${invalid.join(", ")}. Use claude, codex, opencode, goose, cursor, github, slack, or all.`
6522
6523
  );
6523
6524
  }
6524
6525
  return deduped;
@@ -6585,6 +6586,10 @@ function clientLabel(client) {
6585
6586
  return "goose sessions";
6586
6587
  case "cursor":
6587
6588
  return "Cursor workspace evidence";
6589
+ case "github":
6590
+ return "Git/GitHub proof";
6591
+ case "slack":
6592
+ return "Slack coordination";
6588
6593
  }
6589
6594
  }
6590
6595
  function redactedText(value, limit = 900) {
@@ -6626,6 +6631,18 @@ function makeRawEvent(input) {
6626
6631
  redaction_applied: true
6627
6632
  };
6628
6633
  }
6634
+ function runRuntimeCli(command, args, cwd) {
6635
+ try {
6636
+ return execFileSync(command, args, {
6637
+ cwd,
6638
+ encoding: "utf8",
6639
+ stdio: ["ignore", "pipe", "ignore"],
6640
+ timeout: 5e3
6641
+ });
6642
+ } catch {
6643
+ return null;
6644
+ }
6645
+ }
6629
6646
  function parseJsonLine2(line) {
6630
6647
  try {
6631
6648
  return JSON.parse(line);
@@ -6633,6 +6650,25 @@ function parseJsonLine2(line) {
6633
6650
  return null;
6634
6651
  }
6635
6652
  }
6653
+ function readTextWindow(path, stats, maxBytes) {
6654
+ if (stats.size <= maxBytes) {
6655
+ return { text: readFileSync4(path, "utf8"), truncated: false };
6656
+ }
6657
+ const bytesToRead = Math.min(stats.size, maxBytes);
6658
+ const buffer = Buffer.alloc(bytesToRead);
6659
+ const fd = openSync(path, "r");
6660
+ try {
6661
+ readSync(fd, buffer, 0, bytesToRead, stats.size - bytesToRead);
6662
+ } finally {
6663
+ closeSync(fd);
6664
+ }
6665
+ const raw = buffer.toString("utf8");
6666
+ const firstNewline = raw.indexOf("\n");
6667
+ return {
6668
+ text: firstNewline >= 0 ? raw.slice(firstNewline + 1) : raw,
6669
+ truncated: true
6670
+ };
6671
+ }
6636
6672
  function asText2(value) {
6637
6673
  if (typeof value === "string") return value;
6638
6674
  if (Array.isArray(value)) {
@@ -6668,6 +6704,22 @@ function timestampFor(record, statsMtime) {
6668
6704
  }
6669
6705
  return new Date(statsMtime).toISOString();
6670
6706
  }
6707
+ function mapOrgxRuntimePacket(record, fallbackTimestamp) {
6708
+ if (!isRecord(record) || record.type !== "orgx_work_graph_runtime_event") return [];
6709
+ const timestamp = timestampFor(record, Date.parse(fallbackTimestamp));
6710
+ const role = record.role === "user" || record.role === "assistant" || record.role === "tool" || record.role === "meta" ? record.role : "meta";
6711
+ const toolName = stringField(record, "tool_name", "toolName", "name") ?? void 0;
6712
+ const text2 = asText2(record.content) || asText2(record.message) || asText2(record.text) || asText2(record.summary) || redactedText(JSON.stringify(record));
6713
+ const requestedKind = stringField(record, "event_kind", "kind");
6714
+ const kind = toolName ? requestedKind === "tool_call_error" ? "tool_call_error" : toolName.startsWith("mcp__") ? "mcp_tool_call" : "tool_call_start" : requestedKind === "decision" ? "assistant_reasoning" : requestedKind === "blocker" ? "tool_call_error" : requestedKind === "artifact" ? "file_edit" : requestedKind === "outcome" ? "test_run" : role === "user" ? "user_prompt" : "assistant_text";
6715
+ return [{
6716
+ kind,
6717
+ role,
6718
+ text: text2,
6719
+ ...toolName ? { toolName } : {},
6720
+ timestamp
6721
+ }];
6722
+ }
6671
6723
  function mapCodexRecord(record, fallbackTimestamp) {
6672
6724
  if (!isRecord(record)) return [];
6673
6725
  const timestamp = timestampFor(record, Date.parse(fallbackTimestamp));
@@ -6745,23 +6797,26 @@ function mapClaudeRecord(record, fallbackTimestamp) {
6745
6797
  }
6746
6798
  function readJsonlCandidate(candidate, options) {
6747
6799
  const stats = safeStat(candidate.path);
6748
- if (!stats || stats.size > options.maxBytesPerFile) {
6800
+ if (!stats) {
6749
6801
  return {
6802
+ collectionMethods: [],
6750
6803
  events: [],
6751
6804
  filesRead: 0,
6752
- filesSkipped: [{ path: candidate.path, reason: stats ? "schema_version_unsupported" : "permission_denied" }],
6805
+ filesSkipped: [{ path: candidate.path, reason: "permission_denied" }],
6753
6806
  notes: [],
6754
6807
  searchedSessions: 0
6755
6808
  };
6756
6809
  }
6757
- const lines = readFileSync4(candidate.path, "utf8").split(/\r?\n/);
6810
+ const window = readTextWindow(candidate.path, stats, options.maxBytesPerFile);
6811
+ const lines = window.text.split(/\r?\n/);
6758
6812
  const fallbackTimestamp = new Date(stats.mtimeMs).toISOString();
6759
6813
  const sessionId = basename3(candidate.path).replace(/\.[^.]+$/, "");
6760
6814
  const events = [];
6761
6815
  for (const [index, line] of lines.entries()) {
6762
6816
  if (!line.trim()) continue;
6763
6817
  const record = parseJsonLine2(line);
6764
- const mapped = candidate.source === "codex" ? mapCodexRecord(record, fallbackTimestamp) : candidate.source === "claude_code" ? mapClaudeRecord(record, fallbackTimestamp) : mapGenericJsonRecord(record, fallbackTimestamp);
6818
+ const runtimePacket = mapOrgxRuntimePacket(record, fallbackTimestamp);
6819
+ const mapped = runtimePacket.length > 0 ? runtimePacket : candidate.source === "codex" ? mapCodexRecord(record, fallbackTimestamp) : candidate.source === "claude_code" ? mapClaudeRecord(record, fallbackTimestamp) : mapGenericJsonRecord(record, fallbackTimestamp);
6765
6820
  for (const [partIndex, item] of mapped.entries()) {
6766
6821
  if (!item.text && !item.toolName) continue;
6767
6822
  events.push(makeRawEvent({
@@ -6771,6 +6826,7 @@ function readJsonlCandidate(candidate, options) {
6771
6826
  path: candidate.path,
6772
6827
  payload: {
6773
6828
  extraction_mode: candidate.extractionMode,
6829
+ collection_method: "local_store",
6774
6830
  relative_source_path: candidate.path,
6775
6831
  text_summary: redactedText(item.text),
6776
6832
  tool_name: item.toolName
@@ -6784,10 +6840,11 @@ function readJsonlCandidate(candidate, options) {
6784
6840
  }
6785
6841
  }
6786
6842
  return {
6843
+ collectionMethods: ["local_store"],
6787
6844
  events,
6788
6845
  filesRead: 1,
6789
6846
  filesSkipped: [],
6790
- notes: [],
6847
+ notes: window.truncated ? [`Read the latest ${options.maxBytesPerFile} bytes from oversized JSONL source instead of skipping it.`] : [],
6791
6848
  searchedSessions: 1
6792
6849
  };
6793
6850
  }
@@ -6819,6 +6876,7 @@ function readJsonCandidate(candidate, options) {
6819
6876
  const stats = safeStat(candidate.path);
6820
6877
  if (!stats || stats.size > options.maxBytesPerFile) {
6821
6878
  return {
6879
+ collectionMethods: [],
6822
6880
  events: [],
6823
6881
  filesRead: 0,
6824
6882
  filesSkipped: [{ path: candidate.path, reason: stats ? "schema_version_unsupported" : "permission_denied" }],
@@ -6831,6 +6889,7 @@ function readJsonCandidate(candidate, options) {
6831
6889
  parsed = JSON.parse(readFileSync4(candidate.path, "utf8"));
6832
6890
  } catch {
6833
6891
  return {
6892
+ collectionMethods: [],
6834
6893
  events: [],
6835
6894
  filesRead: 0,
6836
6895
  filesSkipped: [{ path: candidate.path, reason: "binary_or_corrupt" }],
@@ -6845,14 +6904,16 @@ function readJsonCandidate(candidate, options) {
6845
6904
  (record, index) => mapGenericJsonRecord(record, fallbackTimestamp).map(
6846
6905
  (item, partIndex) => makeRawEvent({
6847
6906
  client: candidate.source,
6848
- kind: item.kind,
6907
+ kind: candidate.source === "slack" ? "slack_message" : candidate.source === "github" && item.kind === "assistant_text" ? "pr_event" : item.kind,
6849
6908
  now: options.now,
6850
6909
  path: candidate.path,
6851
6910
  payload: {
6852
6911
  extraction_mode: candidate.extractionMode,
6912
+ collection_method: "local_store",
6853
6913
  relative_source_path: candidate.path,
6854
6914
  text_summary: redactedText(item.text),
6855
- tool_name: item.toolName
6915
+ tool_name: item.toolName,
6916
+ actor: isRecord(record) ? stringField(record, "user", "username", "actor", "author", "sender") : void 0
6856
6917
  },
6857
6918
  rawRowId: String(index),
6858
6919
  role: item.role,
@@ -6863,6 +6924,7 @@ function readJsonCandidate(candidate, options) {
6863
6924
  )
6864
6925
  );
6865
6926
  return {
6927
+ collectionMethods: ["local_store"],
6866
6928
  events,
6867
6929
  filesRead: 1,
6868
6930
  filesSkipped: [],
@@ -6893,6 +6955,7 @@ function readMarkdownCandidate(candidate, options) {
6893
6955
  const stats = safeStat(candidate.path);
6894
6956
  if (!stats || stats.size > options.maxBytesPerFile) {
6895
6957
  return {
6958
+ collectionMethods: [],
6896
6959
  events: [],
6897
6960
  filesRead: 0,
6898
6961
  filesSkipped: [{ path: candidate.path, reason: stats ? "schema_version_unsupported" : "permission_denied" }],
@@ -6910,6 +6973,7 @@ function readMarkdownCandidate(candidate, options) {
6910
6973
  path: candidate.path,
6911
6974
  payload: {
6912
6975
  extraction_mode: candidate.extractionMode,
6976
+ collection_method: "local_store",
6913
6977
  relative_source_path: candidate.path,
6914
6978
  text_summary: redactedText(text2, 1200),
6915
6979
  tool_usage_state: candidate.path.includes("mcp.json") ? "configured" : void 0
@@ -6920,6 +6984,7 @@ function readMarkdownCandidate(candidate, options) {
6920
6984
  uriSuffix: "markdown:0"
6921
6985
  });
6922
6986
  return {
6987
+ collectionMethods: ["local_store"],
6923
6988
  events: [event],
6924
6989
  filesRead: 1,
6925
6990
  filesSkipped: [],
@@ -6927,6 +6992,158 @@ function readMarkdownCandidate(candidate, options) {
6927
6992
  searchedSessions: 1
6928
6993
  };
6929
6994
  }
6995
+ function readGitReflogCandidate(candidate, options) {
6996
+ const stats = safeStat(candidate.path);
6997
+ if (!stats || stats.size > options.maxBytesPerFile) {
6998
+ return {
6999
+ collectionMethods: [],
7000
+ events: [],
7001
+ filesRead: 0,
7002
+ filesSkipped: [{ path: candidate.path, reason: stats ? "schema_version_unsupported" : "permission_denied" }],
7003
+ notes: [],
7004
+ searchedSessions: 0
7005
+ };
7006
+ }
7007
+ const lines = readFileSync4(candidate.path, "utf8").split(/\r?\n/).filter(Boolean).slice(-250);
7008
+ const events = [];
7009
+ const fallbackTimestamp = new Date(stats.mtimeMs).toISOString();
7010
+ for (const [index, line] of lines.entries()) {
7011
+ const [meta = "", message = ""] = line.split(" ");
7012
+ const parts = meta.trim().split(/\s+/);
7013
+ const commitSha = parts[1] ?? parts[0] ?? "";
7014
+ if (!/^[0-9a-f]{12,40}$/i.test(commitSha)) continue;
7015
+ const timestampSeconds = Number(parts.at(-2));
7016
+ const timestamp = Number.isFinite(timestampSeconds) ? new Date(timestampSeconds * 1e3).toISOString() : fallbackTimestamp;
7017
+ const actor = meta.match(/^[0-9a-f]{40}\s+[0-9a-f]{40}\s+(.+?)\s+\d+\s+[+-]\d{4}/i)?.[1]?.trim();
7018
+ const summary = message.trim() || `commit ${commitSha.slice(0, 12)}`;
7019
+ events.push(makeRawEvent({
7020
+ client: "github",
7021
+ kind: "commit",
7022
+ now: options.now,
7023
+ path: candidate.path,
7024
+ payload: {
7025
+ extraction_mode: candidate.extractionMode,
7026
+ collection_method: "local_store",
7027
+ relative_source_path: candidate.path,
7028
+ text_summary: redactedText(`Commit ${commitSha.slice(0, 12)}: ${summary}`),
7029
+ commit_sha: commitSha,
7030
+ actor,
7031
+ proof_kind: "commit_landed"
7032
+ },
7033
+ rawByteOffset: index,
7034
+ role: "meta",
7035
+ sessionId: "git-reflog-head",
7036
+ timestamp,
7037
+ uriSuffix: `reflog:${index}:${commitSha.slice(0, 12)}`
7038
+ }));
7039
+ }
7040
+ return {
7041
+ collectionMethods: ["local_store"],
7042
+ events,
7043
+ filesRead: 1,
7044
+ filesSkipped: [],
7045
+ notes: ["Git reflog evidence is local commit proof; remote PR metadata still requires a GitHub export or API-backed source."],
7046
+ searchedSessions: 1
7047
+ };
7048
+ }
7049
+ function collectGithubRuntimeCli(input) {
7050
+ const insideRepo = runRuntimeCli("git", ["rev-parse", "--is-inside-work-tree"], input.cwd)?.trim() === "true";
7051
+ if (!insideRepo) return null;
7052
+ const since = `${input.sinceDays} days ago`;
7053
+ const log = runRuntimeCli("git", [
7054
+ "log",
7055
+ `--since=${since}`,
7056
+ `--max-count=${Math.max(1, input.limit)}`,
7057
+ "--format=%H%x1f%an%x1f%aI%x1f%s"
7058
+ ], input.cwd);
7059
+ const events = [];
7060
+ const notes = ["GitHub source collected through the local git runtime CLI before falling back to repository files."];
7061
+ if (log?.trim()) {
7062
+ for (const [index, line] of log.trim().split(/\r?\n/).entries()) {
7063
+ const [commitSha, actor, timestamp, subject] = line.split("");
7064
+ if (!commitSha || !timestamp || !subject) continue;
7065
+ events.push(makeRawEvent({
7066
+ client: "github",
7067
+ kind: "commit",
7068
+ now: input.now,
7069
+ path: input.cwd,
7070
+ payload: {
7071
+ extraction_mode: "terminal_log",
7072
+ collection_method: "runtime_cli",
7073
+ runtime_cli: "git log",
7074
+ text_summary: redactedText(`Commit ${commitSha.slice(0, 12)}: ${subject}`),
7075
+ commit_sha: commitSha,
7076
+ actor: actor ? redactedText(actor, 120) : void 0,
7077
+ proof_kind: "commit_landed"
7078
+ },
7079
+ rawRowId: String(index),
7080
+ role: "meta",
7081
+ sessionId: "git-log",
7082
+ timestamp,
7083
+ uriSuffix: `git-log:${index}:${commitSha.slice(0, 12)}`
7084
+ }));
7085
+ }
7086
+ }
7087
+ const ghJson = runRuntimeCli("gh", [
7088
+ "pr",
7089
+ "list",
7090
+ "--state",
7091
+ "all",
7092
+ "--limit",
7093
+ String(Math.max(1, Math.min(30, input.limit))),
7094
+ "--json",
7095
+ "number,title,state,url,mergedAt,updatedAt,author,headRefName"
7096
+ ], input.cwd);
7097
+ if (ghJson?.trim()) {
7098
+ try {
7099
+ const prs = JSON.parse(ghJson);
7100
+ if (Array.isArray(prs)) {
7101
+ for (const [index, pr] of prs.entries()) {
7102
+ if (!isRecord(pr)) continue;
7103
+ const title = typeof pr.title === "string" ? pr.title : `PR ${String(pr.number ?? index + 1)}`;
7104
+ const timestamp = typeof pr.mergedAt === "string" && pr.mergedAt ? pr.mergedAt : typeof pr.updatedAt === "string" && pr.updatedAt ? pr.updatedAt : input.now.toISOString();
7105
+ const author = isRecord(pr.author) && typeof pr.author.login === "string" ? pr.author.login : void 0;
7106
+ events.push(makeRawEvent({
7107
+ client: "github",
7108
+ kind: "pr_event",
7109
+ now: input.now,
7110
+ path: input.cwd,
7111
+ payload: {
7112
+ extraction_mode: "terminal_log",
7113
+ collection_method: "runtime_cli",
7114
+ runtime_cli: "gh pr list",
7115
+ text_summary: redactedText(`PR ${String(pr.number ?? index + 1)} ${String(pr.state ?? "UNKNOWN")}: ${title}`),
7116
+ actor: author,
7117
+ pr_number: pr.number,
7118
+ pr_state: pr.state,
7119
+ pr_url: pr.url,
7120
+ proof_kind: pr.state === "MERGED" ? "commit_landed" : "pull_request_seen"
7121
+ },
7122
+ rawRowId: String(index),
7123
+ role: "meta",
7124
+ sessionId: "gh-pr-list",
7125
+ timestamp,
7126
+ uriSuffix: `gh-pr:${String(pr.number ?? index + 1)}`
7127
+ }));
7128
+ }
7129
+ }
7130
+ } catch {
7131
+ notes.push("gh pr list returned unreadable JSON; git commit evidence was still retained.");
7132
+ }
7133
+ } else {
7134
+ notes.push("GitHub CLI PR metadata was unavailable; install or authenticate gh to attach PR/review proof.");
7135
+ }
7136
+ if (events.length === 0) return null;
7137
+ return {
7138
+ collectionMethods: ["runtime_cli"],
7139
+ collector: "runtime_cli",
7140
+ events,
7141
+ filesRead: 0,
7142
+ filesSkipped: [],
7143
+ notes,
7144
+ searchedSessions: new Set(events.map((event) => event.session_id)).size
7145
+ };
7146
+ }
6930
7147
  function discoverCandidates(source, env, sinceMs) {
6931
7148
  const candidates = [];
6932
7149
  const addFiles = (paths, extractionMode, predicate) => {
@@ -6943,9 +7160,16 @@ function discoverCandidates(source, env, sinceMs) {
6943
7160
  }
6944
7161
  };
6945
7162
  if (source === "codex") {
6946
- addFiles([CODEX_SESSIONS_DIR], "jsonl", (path) => path.endsWith(".jsonl"));
7163
+ addFiles([
7164
+ "$CWD/.orgx/work-graph/runtime-events/codex",
7165
+ CODEX_SESSIONS_DIR
7166
+ ], "jsonl", (path) => path.endsWith(".jsonl"));
6947
7167
  } else if (source === "claude_code") {
6948
- addFiles([CLAUDE_PROJECTS_DIR], "jsonl", (path) => path.endsWith(".jsonl"));
7168
+ addFiles([
7169
+ "$CWD/.orgx/work-graph/runtime-events/claude-code",
7170
+ "$CWD/.orgx/work-graph/runtime-events/claude",
7171
+ CLAUDE_PROJECTS_DIR
7172
+ ], "jsonl", (path) => path.endsWith(".jsonl"));
6949
7173
  } else if (source === "opencode") {
6950
7174
  addFiles([
6951
7175
  "~/.local/share/opencode/storage/session",
@@ -6976,6 +7200,19 @@ function discoverCandidates(source, env, sinceMs) {
6976
7200
  "~/Library/Application Support/Cursor/User/workspaceStorage",
6977
7201
  "~/.config/Cursor/User/workspaceStorage"
6978
7202
  ], "sqlite", (path) => path.endsWith("state.vscdb"));
7203
+ } else if (source === "github") {
7204
+ addFiles(["$CWD/.git/logs/HEAD"], "terminal_log", (path) => path.endsWith("/.git/logs/HEAD"));
7205
+ addFiles([
7206
+ "$CWD/.orgx/github",
7207
+ "$CWD/.github/work-graph",
7208
+ "~/.orgx/github"
7209
+ ], "json", (path) => path.endsWith(".json"));
7210
+ } else if (source === "slack") {
7211
+ addFiles([
7212
+ "$CWD/.orgx/slack",
7213
+ "$CWD/.slack",
7214
+ "~/.orgx/slack"
7215
+ ], "json", (path) => path.endsWith(".json"));
6979
7216
  }
6980
7217
  return candidates.sort((a, b) => b.mtimeMs - a.mtimeMs);
6981
7218
  }
@@ -6990,10 +7227,23 @@ function discoverOverrideCandidates(source, root, sinceMs) {
6990
7227
  }
6991
7228
  return candidates.sort((a, b) => b.mtimeMs - a.mtimeMs);
6992
7229
  }
7230
+ function collectRuntimeCliSource(source, env, options) {
7231
+ if (source === "github") {
7232
+ return collectGithubRuntimeCli({
7233
+ cwd: env.cwd,
7234
+ limit: options.limit,
7235
+ now: options.now,
7236
+ sinceDays: options.sinceDays
7237
+ });
7238
+ }
7239
+ return null;
7240
+ }
6993
7241
  function findingTypeFromEvent(event) {
6994
7242
  const text2 = `${event.payload.text_summary ?? ""}
6995
7243
  ${event.payload.tool_name ?? ""}`;
6996
7244
  if (!WORK_SIGNAL_PATTERN.test(text2)) return null;
7245
+ if (event.kind === "commit" || event.kind === "pr_event") return "artifact";
7246
+ if (event.kind === "slack_message") return /\b(decision|approved|owner|handoff|blocked|launch)\b/i.test(text2) ? "decision" : "action";
6997
7247
  if (/\b(decision|decided|tradeoff|architecture|approval)\b/i.test(text2)) return "decision";
6998
7248
  if (/\b(blocked|blocker|failed|fails|error|timeout|permission|schema|zod|invalid)\b/i.test(text2)) return "blocker";
6999
7249
  if (/\b(artifact|implemented|created|changed|edited|commit|pr|file|shipped|deploy)\b/i.test(text2)) return "artifact";
@@ -7032,6 +7282,12 @@ function extractionFromEvents(input) {
7032
7282
  event_id: event.event_id,
7033
7283
  event_kind: event.kind,
7034
7284
  extraction_mode: event.payload.extraction_mode,
7285
+ collection_method: event.payload.collection_method,
7286
+ runtime_cli: event.payload.runtime_cli,
7287
+ actor: event.payload.actor,
7288
+ commit_sha: event.payload.commit_sha,
7289
+ proof_kind: event.payload.proof_kind ?? (event.kind === "commit" ? "commit_landed" : void 0),
7290
+ owner_ref: event.kind === "slack_message" ? event.payload.actor : void 0,
7035
7291
  provider: event.provider,
7036
7292
  tool_name: event.payload.tool_name
7037
7293
  }
@@ -7043,6 +7299,7 @@ function extractionFromEvents(input) {
7043
7299
  extraction_id: `${input.client}:investigation:${hash([input.client, input.events.map((event) => event.event_id)], 12)}`,
7044
7300
  source_client: workGraphSourceClient(input.client),
7045
7301
  source_label: clientLabel(input.client),
7302
+ collection_methods: [...new Set(input.collectionMethods)].sort(),
7046
7303
  searched_sources: [...new Set(input.events.map((event) => String(event.payload.relative_source_path ?? event.session_id)))].slice(0, 30),
7047
7304
  search_queries: [
7048
7305
  {
@@ -7072,6 +7329,7 @@ function loadWorkGraphInvestigationSourceData(options) {
7072
7329
  home: options.home ?? homedir2()
7073
7330
  };
7074
7331
  const sinceMs = now.getTime() - (options.sinceDays ?? DEFAULT_SINCE_DAYS2) * 24 * 60 * 60 * 1e3;
7332
+ const sinceDays = options.sinceDays ?? DEFAULT_SINCE_DAYS2;
7075
7333
  const limit = Math.max(1, options.limitPerSource ?? DEFAULT_LIMIT_PER_SOURCE2);
7076
7334
  const maxBytesPerFile = Math.max(1, options.maxBytesPerFile ?? DEFAULT_MAX_BYTES_PER_FILE2);
7077
7335
  const rawEvents = [];
@@ -7083,23 +7341,26 @@ function loadWorkGraphInvestigationSourceData(options) {
7083
7341
  if (options.claudeProjectsDir) sourceOverrides.set("claude_code", resolve(options.claudeProjectsDir));
7084
7342
  for (const source of options.sources) {
7085
7343
  const overrideRoot = sourceOverrides.get(source);
7344
+ const runtimeCliResult = overrideRoot ? null : collectRuntimeCliSource(source, env, { limit, now, sinceDays });
7086
7345
  const candidates = (overrideRoot ? discoverOverrideCandidates(source, overrideRoot, sinceMs) : discoverCandidates(source, env, sinceMs)).slice(0, limit);
7087
- if (candidates.length === 0) {
7346
+ if (!runtimeCliResult && candidates.length === 0) {
7088
7347
  missingSources.push(`${clientLabel(source)} store`);
7089
7348
  continue;
7090
7349
  }
7091
- const sourceEvents = [];
7350
+ const sourceEvents = runtimeCliResult ? [...runtimeCliResult.events] : [];
7351
+ const collectionMethods = runtimeCliResult ? [...runtimeCliResult.collectionMethods] : [];
7092
7352
  const filesSkipped = [];
7093
- let filesRead = 0;
7094
- const notes = [];
7353
+ let filesRead = runtimeCliResult?.filesRead ?? 0;
7354
+ const notes = runtimeCliResult?.notes ? [...runtimeCliResult.notes] : [];
7095
7355
  for (const candidate of candidates) {
7096
7356
  if (candidate.extractionMode === "sqlite") {
7097
7357
  filesSkipped.push({ path: candidate.path, reason: "schema_version_unsupported" });
7098
7358
  notes.push(`${candidate.path} detected; SQLite extraction is reserved for the cloud/runtime adapter reader.`);
7099
7359
  continue;
7100
7360
  }
7101
- const result = candidate.path.endsWith(".jsonl") ? readJsonlCandidate(candidate, { maxBytesPerFile, now }) : candidate.path.endsWith(".json") && !candidate.path.endsWith("mcp.json") ? readJsonCandidate(candidate, { maxBytesPerFile, now }) : readMarkdownCandidate(candidate, { maxBytesPerFile, now });
7361
+ const result = candidate.source === "github" && candidate.extractionMode === "terminal_log" ? readGitReflogCandidate(candidate, { maxBytesPerFile, now }) : candidate.path.endsWith(".jsonl") ? readJsonlCandidate(candidate, { maxBytesPerFile, now }) : candidate.path.endsWith(".json") && !candidate.path.endsWith("mcp.json") ? readJsonCandidate(candidate, { maxBytesPerFile, now }) : readMarkdownCandidate(candidate, { maxBytesPerFile, now });
7102
7362
  sourceEvents.push(...result.events);
7363
+ collectionMethods.push(...result.collectionMethods);
7103
7364
  filesRead += result.filesRead;
7104
7365
  filesSkipped.push(...result.filesSkipped);
7105
7366
  notes.push(...result.notes);
@@ -7107,6 +7368,7 @@ function loadWorkGraphInvestigationSourceData(options) {
7107
7368
  rawEvents.push(...sourceEvents);
7108
7369
  clientExtractions.push(extractionFromEvents({
7109
7370
  client: source,
7371
+ collectionMethods,
7110
7372
  events: sourceEvents,
7111
7373
  filesRead,
7112
7374
  filesSkipped,
@@ -7854,6 +8116,9 @@ function providerForClient2(client) {
7854
8116
  return "unknown";
7855
8117
  }
7856
8118
  function eventKindForFinding(finding) {
8119
+ if (finding.source_client === "github") return finding.type === "outcome" ? "test_run" : "commit";
8120
+ if (finding.source_client === "slack") return "slack_message";
8121
+ if (finding.source_client === "orgx_runtime_hook" || finding.source_client === "mcp") return "mcp_tool_call";
7857
8122
  if (finding.type === "decision") return "assistant_reasoning";
7858
8123
  if (finding.type === "artifact") return "file_edit";
7859
8124
  if (finding.type === "blocker") return "tool_call_error";
@@ -7882,6 +8147,10 @@ function rawEventFromFinding(finding, index, generatedAt) {
7882
8147
  finding_type: finding.type,
7883
8148
  source_id: finding.source_id,
7884
8149
  confidence: finding.confidence,
8150
+ commit_sha: finding.metadata.commit_sha,
8151
+ owner_ref: finding.metadata.owner_ref,
8152
+ proof_kind: finding.metadata.proof_kind,
8153
+ writeback_ref: finding.metadata.writeback_ref,
7885
8154
  redacted_verbatim: typeof finding.metadata.redacted_verbatim === "string" ? finding.metadata.redacted_verbatim : finding.summary.slice(0, 420)
7886
8155
  };
7887
8156
  return {
@@ -7985,7 +8254,31 @@ function bottleneckClassForText(text2) {
7985
8254
  if (/owner|handoff|dri|approval/i.test(text2)) return "human_handoff_missing";
7986
8255
  return null;
7987
8256
  }
7988
- function terminalForTrail(trail) {
8257
+ function terminalForTrail(trail, events = [], findings = []) {
8258
+ const proofRef = trail.evidence_refs[0];
8259
+ const proofFromEvent = events.find((event) => event.kind === "commit" || event.kind === "pr_event" || event.kind === "test_run");
8260
+ const mcpWriteback = events.find(
8261
+ (event) => event.kind === "mcp_tool_call" && /\borgx|complete_with_proof|record_outcome|writeback|orgx_emit_activity\b/i.test(
8262
+ `${event.payload.tool_name ?? ""}
8263
+ ${event.payload.text_summary ?? ""}`
8264
+ )
8265
+ );
8266
+ const githubFinding = findings.find(
8267
+ (finding) => finding.source_client === "github" || /commit_landed|pull request|github|commit/i.test(JSON.stringify(finding.metadata ?? {}))
8268
+ );
8269
+ const runtimeFinding = findings.find(
8270
+ (finding) => finding.source_client === "orgx_runtime_hook" || finding.source_client === "mcp" || /mcp_writeback_succeeded|complete_with_proof|record_outcome|orgx_emit_activity/i.test(JSON.stringify(finding.metadata ?? {}))
8271
+ );
8272
+ const proofState = (kind, ref) => ref ? { kind, ref } : { kind };
8273
+ const verifiedProof = proofFromEvent?.kind === "commit" || proofFromEvent?.kind === "pr_event" || githubFinding ? proofState("commit_landed", proofFromEvent?.event_id ?? githubFinding?.evidence_ref ?? proofRef) : proofFromEvent?.kind === "test_run" ? proofState("test_passed", proofFromEvent.event_id) : mcpWriteback || runtimeFinding ? proofState("mcp_writeback_succeeded", mcpWriteback?.event_id ?? runtimeFinding?.evidence_ref ?? proofRef) : null;
8274
+ if (verifiedProof) {
8275
+ return {
8276
+ state: "shipped",
8277
+ proof: verifiedProof,
8278
+ classified_by: "deterministic",
8279
+ classification_basis: ["terminal_proof_event_present"]
8280
+ };
8281
+ }
7989
8282
  if (trail.state === "verified" || trail.valence === "healthy") {
7990
8283
  return {
7991
8284
  state: "shipped",
@@ -8035,7 +8328,7 @@ function buildWorkLoops(input) {
8035
8328
  ...matchedFindings.map((finding) => finding.summary)
8036
8329
  ].join("\n");
8037
8330
  const bottleneck = bottleneckClassForText(text2);
8038
- const terminal = terminalForTrail(trail);
8331
+ const terminal = terminalForTrail(trail, matchedEvents, matchedFindings);
8039
8332
  const confidence = clamp(
8040
8333
  trail.confidence || matchedFindings.reduce((total, finding) => total + finding.confidence, 0) / Math.max(1, matchedFindings.length)
8041
8334
  );
@@ -8663,10 +8956,11 @@ function buildMirror(input) {
8663
8956
  const dropped = input.loops.filter((loop) => !loop.survived_critic).length;
8664
8957
  const terminal = topFamily?.shared_terminal_state ?? "ongoing";
8665
8958
  const terminalPhrase = `${articleFor(terminal)} ${terminal}`;
8959
+ const topSourceLabels = input.corpus.sources.filter((source) => source.status === "connected" || source.status === "partial").slice(0, 4).map((source) => source.brand.name).join(", ");
8666
8960
  const text2 = [
8667
- `You have AI-assisted work spread across ${sourceCount} connected or partial source${sourceCount === 1 ? "" : "s"}, but the execution record is still incomplete.`,
8668
- topFamily ? `The clearest repeated loop is ${topFamily.semantic_centroid}: ${topFamily.appearances} appearance${topFamily.appearances === 1 ? "" : "s"} with ${terminalPhrase} state.` : topLoop ? `The clearest work loop is "${topLoop.origin.intent}", but it still needs more chronology before OrgX should call it recurring.` : "The corpus did not produce a verified work loop yet.",
8669
- input.counterfactuals[0] ? `OrgX can point to the exact event where it would have called ${input.counterfactuals[0].orgx_capability.tool} and what entity it would have created.` : "Counterfactual repair is waiting on a higher-confidence loop with resolved citations.",
8961
+ `Your AI-assisted work spans ${sourceCount} connected or partial source${sourceCount === 1 ? "" : "s"}${topSourceLabels ? ` (${topSourceLabels})` : ""}, but the execution record is still incomplete.`,
8962
+ topFamily ? `The clearest repeated loop is "${topFamily.semantic_centroid}": ${topFamily.appearances} appearance${topFamily.appearances === 1 ? "" : "s"} ending in ${terminalPhrase} state.` : topLoop ? `The clearest work loop is "${topLoop.origin.intent}", but it needs more chronology before OrgX should call it recurring.` : "The corpus did not produce a verified work loop yet.",
8963
+ input.counterfactuals[0] ? `The earned repair is concrete: OrgX can point to the event where it would have called ${input.counterfactuals[0].orgx_capability.tool} and the entity it would have created.` : "Counterfactual repair is waiting on a higher-confidence loop with resolved citations.",
8670
8964
  `The current estimate is ${input.impact.time_saved_hours_per_week} recoverable hours/week, grounded in ${input.impact.basis[0] ?? "resolved work-loop evidence"}.`,
8671
8965
  dropped > 0 ? `${dropped} weak signal${dropped === 1 ? " was" : "s were"} kept out of the public readout because the citations or critic score did not clear the bar.` : "Every surfaced loop cleared citation verification and the critic floor."
8672
8966
  ].join(" ");
@@ -8939,6 +9233,9 @@ function titleFromText(text2, fallback) {
8939
9233
  if (lower.includes("mcp__orgx__orgx_search") && lower.includes("zod")) {
8940
9234
  return "OrgX MCP orgx_search is failing schema validation";
8941
9235
  }
9236
+ if (lower.includes("mcporgxlistentities") || lower.includes("listentities")) {
9237
+ return "OrgX entity lookup needs human-readable evidence mapping";
9238
+ }
8942
9239
  if (lower.includes("orgx_write") && lower.includes("auto_continue") && lower.includes("dispatch")) {
8943
9240
  return "orgx_write creates ready streams without dispatching agent runs";
8944
9241
  }
@@ -9177,7 +9474,7 @@ ${extractionText}`.toLowerCase();
9177
9474
  ...sourceClients.includes("slack") ? ["Slack coordination"] : []
9178
9475
  ];
9179
9476
  const inferredMissing = [
9180
- ...missingSources,
9477
+ ...missingSources.map(normalizeMissingSourceLabel),
9181
9478
  ...sourceClients.includes("slack") ? [] : ["Slack coordination"],
9182
9479
  ...sourceClients.includes("github") ? [] : ["GitHub PR/commit proof"],
9183
9480
  ...allText.includes("hook") || allText.includes("outbox") ? [] : ["Runtime hook outbox replay"]
@@ -9193,7 +9490,7 @@ ${extractionText}`.toLowerCase();
9193
9490
  });
9194
9491
  const partialCount = manifests.filter((manifest) => manifest.status === "partial").length;
9195
9492
  const coverageScore = clampScore2(
9196
- 28 + Math.min(34, connected.length * 7) + Math.min(18, findings.length * 2) + (sourceClients.includes("codex") ? 6 : 0) + (sourceClients.includes("claude") || sourceClients.includes("claude-code") ? 6 : 0) + (sourceClients.includes("cursor") ? 4 : 0) + (sourceClients.includes("opencode") ? 4 : 0) + (sourceClients.includes("goose") ? 4 : 0) - missing.length * 7 - partialCount * 3
9493
+ 28 + Math.min(34, connected.length * 7) + Math.min(18, findings.length * 2) + (sourceClients.includes("codex") ? 6 : 0) + (sourceClients.includes("claude") || sourceClients.includes("claude-code") ? 6 : 0) + (sourceClients.includes("cursor") ? 4 : 0) + (sourceClients.includes("opencode") ? 4 : 0) + (sourceClients.includes("goose") ? 4 : 0) + (sourceClients.includes("github") ? 6 : 0) + (sourceClients.includes("slack") ? 5 : 0) + (sourceClients.includes("orgx_runtime_hook") || sourceClients.includes("mcp") ? 7 : 0) - partialCount * 3
9197
9494
  );
9198
9495
  return {
9199
9496
  connected,
@@ -9206,7 +9503,7 @@ ${extractionText}`.toLowerCase();
9206
9503
  manifests,
9207
9504
  notes: [
9208
9505
  "OrgX/MCP writeback is one coverage signal; it is not required for the audit to find useful work.",
9209
- missing.length > 0 ? `Coverage is limited by missing sources: ${missing.join(", ")}.` : "Connected sources are sufficient for a first-pass operating profile, but still require user review."
9506
+ missing.length > 0 ? `Additional sources can raise the ceiling: ${missing.join(", ")}.` : "Connected sources are sufficient for a first-pass operating profile, but still require user review."
9210
9507
  ]
9211
9508
  };
9212
9509
  }
@@ -9334,6 +9631,17 @@ function labelForSourceClient(sourceClient) {
9334
9631
  return sourceClient.replace(/[-_]/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
9335
9632
  }
9336
9633
  }
9634
+ function normalizeMissingSourceLabel(source) {
9635
+ if (/slack/i.test(source)) return "Slack coordination";
9636
+ if (/github|git\/github|commit|pr/i.test(source)) return "GitHub PR/commit proof";
9637
+ if (/runtime|hook|outbox/i.test(source)) return "Runtime hook outbox replay";
9638
+ if (/codex/i.test(source)) return "Codex session history";
9639
+ if (/claude/i.test(source)) return "Claude Code sessions";
9640
+ if (/cursor/i.test(source)) return "Cursor workspace history";
9641
+ if (/opencode/i.test(source)) return "OpenCode sessions";
9642
+ if (/goose/i.test(source)) return "goose sessions";
9643
+ return source.replace(/\s+(?:store|readable events|audit-relevant session lines)$/i, "").trim();
9644
+ }
9337
9645
  function summarizeClientExtractions(clientExtractions) {
9338
9646
  return clientExtractions.map((extraction, index) => {
9339
9647
  const extractionId = normalizeClientExtractionId(extraction, index);
@@ -9341,6 +9649,7 @@ function summarizeClientExtractions(clientExtractions) {
9341
9649
  extraction_id: extractionId,
9342
9650
  source_client: normalizeSourceClient(extraction.source_client),
9343
9651
  source_label: extraction.source_label?.trim() || `${extraction.source_client || "Unknown"} AI-client extraction`,
9652
+ collection_methods: [...new Set(extraction.collection_methods ?? [])].sort(),
9344
9653
  searched_source_count: extraction.searched_sources?.length ?? 0,
9345
9654
  searched_session_count: extraction.extraction_quality?.searched_session_count ?? 0,
9346
9655
  skipped_session_count: extraction.extraction_quality?.skipped_session_count ?? 0,
@@ -9365,6 +9674,7 @@ function buildClientExtractionEvents(clientExtractions) {
9365
9674
  ].join(" "),
9366
9675
  evidence_ref: `${summary.extraction_id}:summary`,
9367
9676
  metadata: {
9677
+ collection_methods: summary.collection_methods,
9368
9678
  finding_count: summary.finding_count,
9369
9679
  query_count: summary.query_count,
9370
9680
  searched_source_count: summary.searched_source_count,
@@ -9397,6 +9707,10 @@ function buildAuditMethod(input) {
9397
9707
  const explicit = numberFromImportMetadata(source, "retained_line_count");
9398
9708
  return total + (explicit || source.text.split(/\r?\n/).filter(Boolean).length);
9399
9709
  }, 0);
9710
+ const extractionRetainedLines = extractionSummaries.reduce(
9711
+ (total, summary) => total + summary.finding_count,
9712
+ 0
9713
+ );
9400
9714
  const skippedFiles = input.imports.reduce(
9401
9715
  (total, source) => total + numberFromImportMetadata(source, "skipped_file_count"),
9402
9716
  0
@@ -9418,7 +9732,7 @@ function buildAuditMethod(input) {
9418
9732
  searched_session_files: input.imports.length + extractionSearchedSessions,
9419
9733
  skipped_session_files: skippedFiles + extractionSkippedSessions,
9420
9734
  searched_message_count: searchedMessages,
9421
- retained_evidence_lines: retainedLines,
9735
+ retained_evidence_lines: retainedLines + extractionRetainedLines,
9422
9736
  searched_source_groups: sourceGroups.length,
9423
9737
  extraction_lenses: input.extractionProtocol.schema.source_search_strategy.map((lens) => lens.lens),
9424
9738
  client_native_packs: nativePacks,
@@ -9870,7 +10184,7 @@ function estimateImpactProjection(input) {
9870
10184
  `${blockerEvents} blocker event${blockerEvents === 1 ? "" : "s"} at 45 minutes of reconstruction/coordination each.`,
9871
10185
  `${decisionEvents} decision event${decisionEvents === 1 ? "" : "s"} at 27 minutes of rediscovery/promotion each.`,
9872
10186
  `${missedCount} missed orchestration signal${missedCount === 1 ? "" : "s"} at 39 minutes of manual writeback each.`,
9873
- `${coverage.missing.length} missing source${coverage.missing.length === 1 ? "" : "s"} reducing attribution confidence.`
10187
+ `${coverage.missing.length} source gap${coverage.missing.length === 1 ? "" : "s"} increasing the AQ ceiling rather than lowering the current score.`
9874
10188
  ],
9875
10189
  assumptions: [
9876
10190
  "Uses a conservative $200/hour blended founder/operator cost for public-safe value estimates.",
@@ -9885,7 +10199,7 @@ function scoreExecutionQuality(input) {
9885
10199
  const unknownCount = findings.filter((finding) => finding.source_client === "unknown").length;
9886
10200
  const multiEventTrails = trails.filter((trail) => trail.events.length > 1).length;
9887
10201
  const evidenceCoverage = clampScore2(
9888
- (coverage.coverage_score ?? 50) + Math.min(18, coverage.connected.length * 3) - coverage.missing.length * 4
10202
+ (coverage.coverage_score ?? 50) + Math.min(18, coverage.connected.length * 3)
9889
10203
  );
9890
10204
  const sourceAttribution = clampScore2(
9891
10205
  34 + uniqueClients.filter((client) => client !== "unknown").length * 10 + (coverage.manifests?.filter((manifest) => manifest.status === "connected").length ?? 0) * 6 - unknownCount * 8
@@ -9914,10 +10228,305 @@ function scoreExecutionQuality(input) {
9914
10228
  notes: [
9915
10229
  "10/10 requires client-native extraction per source, multi-event chronology, source-specific evidence, and action recommendations tied to impact.",
9916
10230
  multiEventTrails === trails.length ? "Every evidence path has multiple events." : `${trails.length - multiEventTrails} finding${trails.length - multiEventTrails === 1 ? "" : "s"} still need more chronology before they should be called recurring.`,
9917
- coverage.missing.length > 0 ? `Missing source coverage: ${coverage.missing.join(", ")}.` : "No required source gaps were declared for this run."
10231
+ coverage.missing.length > 0 ? `AQ ceiling sources not connected yet: ${coverage.missing.join(", ")}.` : "No required source gaps were declared for this run."
10232
+ ]
10233
+ };
10234
+ }
10235
+ function scorePageQuality(input) {
10236
+ const { auditMethod, coverage, impact, mirror, recommendations, trails } = input;
10237
+ const body = `${mirror.headline}
10238
+ ${mirror.body}
10239
+ ${mirror.claims.map((claim) => claim.text).join("\n")}`;
10240
+ const lowerBody = body.toLowerCase();
10241
+ const namedMissingSources = coverage.missing.filter(
10242
+ (source) => lowerBody.includes(source.toLowerCase()) || lowerBody.includes(source.toLowerCase().replace(/ pr\/commit proof/i, ""))
10243
+ ).length;
10244
+ const evidenceRefs = new Set(mirror.claims.flatMap((claim) => claim.evidence_refs));
10245
+ const topTrail = selectPublicTopTrail(trails);
10246
+ const hasSpecificShape = /\b\d+ finding/.test(body) && /\b\d+ decision/.test(body) && /\b\d+ artifact/.test(body);
10247
+ const hasReaderFrame = /\byou\b|\byour\b/i.test(body);
10248
+ const hasPrivacyFrame = /\braw transcripts?\b/i.test(body);
10249
+ const hasImpactFrame = impact.time_saved_hours_per_week > 0 && /\brecoverable hours\/week\b|\bhours\/week\b/i.test(body) && /\$[0-9,]+\/month\b/i.test(body);
10250
+ const hasRepairFrame = recommendations.length > 0 && /\bnext repair\b|\blinked proof\b|\bowner-visible\b/i.test(body);
10251
+ const hasGapFrame = coverage.missing.length === 0 || /\bmissing proof\b|\bsource gap\b|\bproof chain\b/i.test(body) && namedMissingSources > 0;
10252
+ const awkwardCopyPenalty = [
10253
+ /\ba ongoing\b/i,
10254
+ /\[brief impact\]/i,
10255
+ /\bdetected across\b/i,
10256
+ /\bno evidence refs\b/i
10257
+ ].filter((pattern) => pattern.test(body)).length * 8;
10258
+ const clarity = clampScore2(
10259
+ 72 + (mirror.headline.length >= 24 && mirror.headline.length <= 96 ? 8 : 0) + (hasSpecificShape ? 10 : 0) + (topTrail ? 6 : 0) + (auditMethod.retained_evidence_lines > 0 ? 4 : 0) + (hasGapFrame ? 6 : 0) - awkwardCopyPenalty
10260
+ );
10261
+ const pageImpact = clampScore2(
10262
+ 64 + (hasImpactFrame ? 16 : 0) + (impact.estimated_monthly_value_usd > 0 ? 7 : 0) + (recommendations.length > 0 ? 8 : 0) + (topTrail?.impact_score && topTrail.impact_score >= 60 ? 5 : 0)
10263
+ );
10264
+ const resonance = clampScore2(
10265
+ 66 + (hasReaderFrame ? 10 : 0) + (/\boperating leak\b|\bbusiness system\b|\bproof chain\b/i.test(body) ? 10 : 0) + (coverage.connected.length >= 2 ? 4 : 0) + (trails.length >= 8 ? 6 : 0)
10266
+ );
10267
+ const trust = clampScore2(
10268
+ 62 + (hasPrivacyFrame ? 10 : 0) + (hasGapFrame ? 12 : 0) + Math.min(10, evidenceRefs.size * 2) + Math.min(6, namedMissingSources * 2)
10269
+ );
10270
+ const repairReadiness = clampScore2(
10271
+ 62 + (hasRepairFrame ? 14 : 0) + Math.min(12, recommendations.length * 4) + (recommendations.some((recommendation) => recommendation.priority === "p0") ? 8 : 0) + (coverage.missing.length > 0 && hasGapFrame ? 4 : 0)
10272
+ );
10273
+ const overall = clampScore2(
10274
+ clarity * 0.24 + pageImpact * 0.22 + resonance * 0.2 + trust * 0.18 + repairReadiness * 0.16
10275
+ );
10276
+ return {
10277
+ overall,
10278
+ clarity,
10279
+ impact: pageImpact,
10280
+ resonance,
10281
+ trust,
10282
+ repair_readiness: repairReadiness,
10283
+ notes: [
10284
+ "This rates the quality of the public readout, not the underlying work evidence score.",
10285
+ hasGapFrame ? "The readout names the proof gaps instead of hiding them." : "The readout should name the missing proof sources more explicitly.",
10286
+ hasRepairFrame ? "The page gives a concrete repair path tied to proof and ownership." : "The page needs a sharper next repair tied to owner-visible proof."
9918
10287
  ]
9919
10288
  };
9920
10289
  }
10290
+ function buildAgenticQuotient(input) {
10291
+ const { auditMethod, coverage, executionQuality, findings, recommendations, trails } = input;
10292
+ const connectedLabels = sortedUnique(coverage.connected);
10293
+ const connectedClients = sortedUnique(findings.map((finding) => finding.source_client).filter((client) => client !== "unknown"));
10294
+ const aiClientCount = connectedClients.filter(
10295
+ (client) => ["codex", "claude", "claude-code", "cursor", "opencode", "goose"].includes(client)
10296
+ ).length;
10297
+ const proofSourceCount = connectedClients.filter(
10298
+ (client) => ["github", "slack", "mcp", "orgx_runtime_hook"].includes(client)
10299
+ ).length;
10300
+ const toolSignalCount = findings.filter(
10301
+ (finding) => finding.type === "missed_orchestration_opportunity" || /\b(?:mcp__|tool|agent|skill|recipe|workflow)\b/i.test(`${finding.title}
10302
+ ${finding.summary}`)
10303
+ ).length;
10304
+ const decisionCount = findings.filter((finding) => finding.type === "decision").length;
10305
+ const artifactCount = findings.filter((finding) => finding.type === "artifact").length;
10306
+ const outcomeCount = findings.filter((finding) => finding.type === "outcome").length;
10307
+ const blockerCount = findings.filter((finding) => finding.type === "blocker").length;
10308
+ const verifiedTrailCount = trails.filter(
10309
+ (trail) => trail.state === "verified" || trail.valence === "healthy" || trail.events.some(
10310
+ (event) => event.event_type === "artifact_verified" || event.event_type === "outcome_recorded" || event.source_type === "github" || event.source_type === "orgx_runtime_hook" || event.source_type === "mcp"
10311
+ )
10312
+ ).length;
10313
+ const multiEventTrailCount = trails.filter((trail) => trail.events.length > 1).length;
10314
+ const sourceBonus = clampScore2(
10315
+ Math.min(18, connectedLabels.length * 3) + aiClientCount * 3 + proofSourceCount * 4
10316
+ );
10317
+ const rawStackScore = clampScore2(
10318
+ 24 + sourceBonus + Math.min(18, auditMethod.searched_session_files / 8) + Math.min(14, toolSignalCount * 2) + Math.min(12, findings.length) + (coverage.mcpObserved ? 5 : 0)
10319
+ );
10320
+ const rawDurabilityScore = clampScore2(
10321
+ 30 + Math.min(14, decisionCount * 3) + Math.min(14, artifactCount * 3) + Math.min(12, outcomeCount * 4) + Math.min(12, verifiedTrailCount * 4) + Math.min(10, multiEventTrailCount * 2) + (coverage.orgxMcpCalled ? 8 : 0) + Math.min(8, recommendations.length * 2)
10322
+ );
10323
+ const totalTrails = trails.length;
10324
+ const trailPassesCritic = (trail) => trail.events.length >= 2 && (trail.state === "verified" || trail.valence === "healthy" || trail.events.some(
10325
+ (event) => event.event_type === "artifact_verified" || event.event_type === "outcome_recorded" || event.source_type === "github" || event.source_type === "orgx_runtime_hook" || event.source_type === "mcp"
10326
+ ));
10327
+ const passingTrails = trails.filter(trailPassesCritic).length;
10328
+ const criticPassRatio = totalTrails > 0 ? passingTrails / totalTrails : 0.35;
10329
+ const chronologyDepth = executionQuality.trail_depth;
10330
+ const chronologyFactor = 0.55 + 0.45 * (Math.max(0, Math.min(100, chronologyDepth)) / 100);
10331
+ const criticFactor = 0.5 + 0.5 * Math.max(0, Math.min(1, criticPassRatio));
10332
+ const honestyMultiplier = Math.max(0.35, Math.min(1, criticFactor * chronologyFactor));
10333
+ const stackScore = clampScore2(rawStackScore * (0.7 + 0.3 * honestyMultiplier));
10334
+ const durabilityScore = clampScore2(rawDurabilityScore * honestyMultiplier);
10335
+ const aq = clampScore2(stackScore * 0.3 + durabilityScore * 0.7);
10336
+ const repairQuests = buildAgenticRepairQuests({
10337
+ coverage,
10338
+ findings,
10339
+ recommendations
10340
+ });
10341
+ const repairLift = repairQuests.reduce((total, quest) => total + quest.expected_aq_lift, 0);
10342
+ const ceiling = clampScore2(aq + Math.min(36, repairLift));
10343
+ const agenticGap = Math.max(0, ceiling - aq);
10344
+ const contextLeakScore = clampScore2(
10345
+ blockerCount * 10 + findings.filter((finding) => finding.type === "missed_orchestration_opportunity").length * 8 + trails.filter((trail) => trail.state === "blocked" || trail.state === "stale" || trail.valence === "risk").length * 4
10346
+ );
10347
+ const archetype = assignAgenticArchetype({
10348
+ stackScore,
10349
+ durabilityScore,
10350
+ contextLeakScore,
10351
+ agenticGap,
10352
+ criticPassRatio,
10353
+ coverage,
10354
+ findings
10355
+ });
10356
+ return {
10357
+ aq,
10358
+ stack_score: stackScore,
10359
+ durability_score: durabilityScore,
10360
+ agentic_gap: agenticGap,
10361
+ ceiling,
10362
+ source_bonus: sourceBonus,
10363
+ context_leak_score: contextLeakScore,
10364
+ archetype,
10365
+ repair_quests: repairQuests,
10366
+ notes: [
10367
+ "AQ is source-positive: connected sources, proof, and runtime writeback raise the current score; missing sources raise the ceiling and repair quests instead of lowering the current score.",
10368
+ `Audit quality remains separate at ${executionQuality.overall}/100 so the public page can be compelling without inflating evidence truth.`,
10369
+ `Honesty ceiling applied: critic-pass ${Math.round(criticPassRatio * 100)}% \xD7 chronology depth ${chronologyDepth}/100 caps the score at ${Math.round(100 * honestyMultiplier)}.`
10370
+ ]
10371
+ };
10372
+ }
10373
+ function buildAgenticRepairQuests(input) {
10374
+ const quests = [];
10375
+ const add = (quest) => {
10376
+ if (quests.some((existing) => existing.id === quest.id)) return;
10377
+ quests.push(quest);
10378
+ };
10379
+ for (const gap of input.coverage.missing) {
10380
+ if (/github|commit|pr/i.test(gap)) {
10381
+ add({
10382
+ id: "connect-github-proof",
10383
+ title: "Connect GitHub proof",
10384
+ expected_aq_lift: 12,
10385
+ reason: "Attach commits, PRs, reviews, and CI state to decisions and artifacts.",
10386
+ source_gap: gap,
10387
+ action_type: "connect_source"
10388
+ });
10389
+ } else if (/slack/i.test(gap)) {
10390
+ add({
10391
+ id: "connect-slack-coordination",
10392
+ title: "Connect Slack coordination",
10393
+ expected_aq_lift: 9,
10394
+ reason: "Attach owner, approval, and handoff context to the work graph.",
10395
+ source_gap: gap,
10396
+ action_type: "connect_source"
10397
+ });
10398
+ } else if (/runtime|hook|outbox/i.test(gap)) {
10399
+ add({
10400
+ id: "enable-runtime-hooks",
10401
+ title: "Enable runtime hooks",
10402
+ expected_aq_lift: 18,
10403
+ reason: "Convert agent work into durable OrgX writeback without relying on humans to remember reporting.",
10404
+ source_gap: gap,
10405
+ action_type: "enable_runtime_hook"
10406
+ });
10407
+ } else {
10408
+ add({
10409
+ id: `connect-${shortHash(gap, 8)}`,
10410
+ title: `Connect ${gap}`,
10411
+ expected_aq_lift: 5,
10412
+ reason: "Add another proof surface to increase confidence and source confluence.",
10413
+ source_gap: gap,
10414
+ action_type: "connect_source"
10415
+ });
10416
+ }
10417
+ }
10418
+ if (input.findings.some((finding) => finding.type === "decision")) {
10419
+ add({
10420
+ id: "promote-trapped-decisions",
10421
+ title: "Promote trapped decisions",
10422
+ expected_aq_lift: 7,
10423
+ reason: "Move decisions from session text into durable OrgX records with evidence refs.",
10424
+ action_type: "promote_decisions"
10425
+ });
10426
+ }
10427
+ if (input.findings.some((finding) => finding.type === "artifact")) {
10428
+ add({
10429
+ id: "attach-artifact-proof",
10430
+ title: "Attach proof to top artifacts",
10431
+ expected_aq_lift: 6,
10432
+ reason: "Link artifacts to commits, tests, deploys, or review proof.",
10433
+ action_type: "attach_proof"
10434
+ });
10435
+ }
10436
+ for (const recommendation of input.recommendations.slice(0, 1)) {
10437
+ add({
10438
+ id: `launch-${recommendation.id}`,
10439
+ title: recommendation.title,
10440
+ expected_aq_lift: recommendation.priority === "p0" ? 8 : 5,
10441
+ reason: recommendation.summary,
10442
+ action_type: "launch_repair"
10443
+ });
10444
+ }
10445
+ return quests.sort((left, right) => right.expected_aq_lift - left.expected_aq_lift).slice(0, 6);
10446
+ }
10447
+ function assignAgenticArchetype(input) {
10448
+ const { stackScore, durabilityScore, contextLeakScore, agenticGap, criticPassRatio } = input;
10449
+ const toolFailureCount = input.findings.filter(
10450
+ (finding) => finding.type === "blocker" && /\b(?:mcp|schema|tool|zod|invalid)\b/i.test(`${finding.title}
10451
+ ${finding.summary}`)
10452
+ ).length;
10453
+ const hauntingSignals = toolFailureCount + (input.coverage.mcpObserved ? 1 : 0) + (contextLeakScore >= 40 ? 1 : 0);
10454
+ const agentSignalCount = input.findings.filter(
10455
+ (finding) => /\b(?:agent|subagent|delegate|orchestrator|worker)\b/i.test(`${finding.title}
10456
+ ${finding.summary}`)
10457
+ ).length;
10458
+ const decisionCount = input.findings.filter((finding) => finding.type === "decision").length;
10459
+ if (stackScore >= 70 && durabilityScore >= 70 && agenticGap <= 15) {
10460
+ return {
10461
+ id: "ai_native_operator",
10462
+ label: "AI-Native Operator",
10463
+ roast: "The agents are working and the receipts mostly survive contact with reality.",
10464
+ truth: "Your work is both agent-rich and increasingly durable.",
10465
+ repair: "Scale the loop into weekly deltas and team-level source coverage."
10466
+ };
10467
+ }
10468
+ if (durabilityScore >= 80 && criticPassRatio >= 0.85 && contextLeakScore <= 20) {
10469
+ return {
10470
+ id: "proof_maximalist",
10471
+ label: "Proof Maximalist",
10472
+ roast: "Annoyingly competent. Receipts attached.",
10473
+ truth: "Verification and ownership are the strong parts of your system.",
10474
+ repair: "Use the proof base to widen the agent stack."
10475
+ };
10476
+ }
10477
+ if (stackScore >= 70 && durabilityScore <= 50 && hauntingSignals >= 3) {
10478
+ return {
10479
+ id: "mcp_necromancer",
10480
+ label: "MCP Necromancer",
10481
+ roast: "You summoned the tools; a few still need contracts.",
10482
+ truth: "Your stack is rich, but repeated tool failures are leaking context.",
10483
+ repair: "Add runtime hook replay and tool-contract proof before expanding the stack."
10484
+ };
10485
+ }
10486
+ if (stackScore >= 70 && durabilityScore > 50 && durabilityScore < 65) {
10487
+ return {
10488
+ id: "context_leaker",
10489
+ label: "Context Leaker",
10490
+ roast: "Your stack is cooking. Your operating memory is evaporating.",
10491
+ truth: "A lot is happening, but too much of it dies in sessions.",
10492
+ repair: "Enable runtime hooks, connect proof sources, and promote trapped decisions."
10493
+ };
10494
+ }
10495
+ if (agentSignalCount >= 3 && durabilityScore < 65) {
10496
+ return {
10497
+ id: "agent_wrangler",
10498
+ label: "Agent Wrangler",
10499
+ roast: "You have agents. They do not yet have an operating system.",
10500
+ truth: "Delegation is happening, but coordination proof is thin.",
10501
+ repair: "Promote owner-visible workstreams and attach proof to agent handoffs."
10502
+ };
10503
+ }
10504
+ if (decisionCount >= 2 && durabilityScore < 62) {
10505
+ return {
10506
+ id: "decision_ghost",
10507
+ label: "Decision Ghost",
10508
+ roast: "Your best calls are haunting transcripts instead of steering work.",
10509
+ truth: "Decision evidence exists, but durable decision records are weak.",
10510
+ repair: "Promote decisions with commit, owner, and outcome refs."
10511
+ };
10512
+ }
10513
+ if (stackScore < 60 && durabilityScore >= 68) {
10514
+ return {
10515
+ id: "careful_operator",
10516
+ label: "Careful Operator",
10517
+ roast: "Small stack, strong receipts.",
10518
+ truth: "You use fewer agents, but the work you do run tends to compound.",
10519
+ repair: "Add one new client or proof source without weakening durability."
10520
+ };
10521
+ }
10522
+ return {
10523
+ id: "prompt_tourist",
10524
+ label: "Prompt Tourist",
10525
+ roast: "You are early enough that the score is still honest, not embarrassing.",
10526
+ truth: "There is not enough durable agent work yet to call this a compounding system.",
10527
+ repair: "Pick one client, run real work through it, then connect proof."
10528
+ };
10529
+ }
9921
10530
  function inferFinalState(findings) {
9922
10531
  if (findings.some((finding) => finding.type === "blocker")) return "blocked";
9923
10532
  if (findings.some((finding) => finding.type === "artifact" || finding.type === "outcome" || /\b(shipped|completed|done|verified)\b/i.test(finding.summary))) {
@@ -10449,7 +11058,9 @@ function buildWorkGraphMirror(input) {
10449
11058
  trails.flatMap((trail) => trail.events.map((event) => event.source_type))
10450
11059
  );
10451
11060
  const sourcePhrase = sourceClients.length > 0 ? sourceClients.map(labelForSourceClient).join(", ") : coverage.connected.join(", ") || "local sources";
10452
- const headline = blockerCount > 0 ? "Your AI work is shipping, but the execution record is incomplete" : sourceGapCount > 0 ? "Your AI work is visible, but the proof chain is incomplete" : topPattern ? "Your work has a recurring operating pattern worth preserving" : topTrail ? "Your work is becoming an operating profile" : "Your work is leaving evidence OrgX can organize";
11061
+ const namedSourceGaps = coverage.missing.slice(0, 5);
11062
+ const sourceGapPhrase = namedSourceGaps.length > 0 ? namedSourceGaps.join(", ") : "no declared source gaps";
11063
+ const headline = blockerCount > 0 ? "AI-native receipts: your agents are working, but the proof chain is thin" : sourceGapCount > 0 ? "AI-native receipts: your sessions describe a business system, but the proof chain is thin" : topPattern ? "Your work has a recurring operating pattern worth preserving" : topTrail ? "Your work is becoming an operating profile" : "Your work is leaving evidence OrgX can organize";
10453
11064
  const domainPhrase = domains.length > 0 ? domains.slice(0, 4).map((domain) => domain.label).join(", ") : "the connected work surface";
10454
11065
  const toolPhrase = skillToolSignals.length > 0 ? skillToolSignals.slice(0, 4).map((signal) => signal.label).join(", ") : "client sessions and available tools";
10455
11066
  const primaryClaimRefs = topTrail?.evidence_refs ?? [];
@@ -10479,16 +11090,26 @@ function buildWorkGraphMirror(input) {
10479
11090
  confidence: impact.confidence
10480
11091
  }] : []
10481
11092
  ];
10482
- const searchClaim = auditMethod ? `OrgX searched ${auditMethod.searched_session_files} AI-client session files and ${auditMethod.searched_message_count} message turns across ${sourcePhrase}; it retained ${auditMethod.retained_evidence_lines} evidence lines and excluded raw transcripts.` : `OrgX searched your AI-client session evidence across ${sourcePhrase} without requiring OrgX tool calls to be present.`;
10483
- const topIssue = topTrail ? `The highest-risk issue is ${topTrail.title.toLowerCase()}.` : topPattern ? `The highest-risk pattern is ${topPattern.title.toLowerCase()}.` : "The first profile is forming from sparse evidence and should be reviewed before promotion.";
11093
+ const searchClaim = auditMethod ? `OrgX searched ${auditMethod.searched_session_files} AI-client session file${auditMethod.searched_session_files === 1 ? "" : "s"}${auditMethod.searched_message_count > 0 ? ` and ${auditMethod.searched_message_count} message turns` : ""} across ${sourcePhrase}; it kept ${auditMethod.retained_evidence_lines} public-safe evidence line${auditMethod.retained_evidence_lines === 1 ? "" : "s"} and left raw transcripts out.` : `OrgX searched your AI-client session evidence across ${sourcePhrase} without requiring OrgX tool calls to be present.`;
11094
+ const topIssue = topTrail ? `The clearest operating leak is "${topTrail.title}".` : topPattern ? `The clearest operating pattern is "${topPattern.title}".` : "The first profile is forming from sparse evidence and should be reviewed before promotion.";
11095
+ const proofGapSentence = sourceGapCount > 0 ? `What keeps the page from feeling decisive is not the amount of activity; it is missing proof from ${sourceGapPhrase}.` : "The proof chain is strong enough to publish as a first-pass operating profile, with human review still in the loop.";
11096
+ const evidenceShapeSentence = [
11097
+ `${trails.length} finding${trails.length === 1 ? "" : "s"}`,
11098
+ `${decisionCount} decision${decisionCount === 1 ? "" : "s"}`,
11099
+ `${artifactCount} artifact${artifactCount === 1 ? "" : "s"}`,
11100
+ blockerCount > 0 ? `${blockerCount} blocker${blockerCount === 1 ? "" : "s"}` : null
11101
+ ].filter(Boolean).join(", ");
11102
+ const recommendation = recommendations[0];
11103
+ const repairSentence = recommendation ? `The next repair is ${recommendation.title}: it should turn the strongest evidence path into owner-visible work with linked proof, not another summary.` : "The next move is to inspect the highest-confidence finding before publishing it.";
10484
11104
  const body = [
10485
11105
  searchClaim,
10486
- `It found ${trails.length} evidence-backed finding${trails.length === 1 ? "" : "s"} across ${domainPhrase}, with ${toolPhrase} showing up as the strongest skills, tools, or sources.`,
11106
+ "This is receipts over vibes: the score should rise when more runtime proof connects, not fall because a source is not installed yet.",
11107
+ `The shape is specific: ${evidenceShapeSentence} across ${domainPhrase}, with ${toolPhrase} showing up as the strongest skills, tools, or sources.`,
10487
11108
  topIssue,
10488
11109
  blockerCount > 0 ? `${blockerCount} blocker finding${blockerCount === 1 ? "" : "s"} show work returning as new work instead of becoming owner-visible resolution.` : `${decisionCount} decision finding${decisionCount === 1 ? "" : "s"} and ${artifactCount} artifact finding${artifactCount === 1 ? "" : "s"} show where work can become durable.`,
10489
- sourceGapCount > 0 ? `${sourceGapCount} source gap${sourceGapCount === 1 ? "" : "s"} still limit trust: ownership, handoffs, GitHub proof, Slack coordination, or later verification.` : "The connected sources are enough for a first public-safe profile, pending human review.",
11110
+ proofGapSentence,
10490
11111
  impact ? `Left unresolved, the profile estimates ${impact.time_saved_hours_per_week} recoverable hours/week and about $${impact.estimated_monthly_value_usd.toLocaleString("en-US")}/month in operator leverage.` : "",
10491
- recommendations[0] ? `The next repair is concrete: ${recommendations[0].title}.` : "The next move is to inspect the highest-confidence finding before publishing it."
11112
+ repairSentence
10492
11113
  ].filter(Boolean).join(" ");
10493
11114
  return {
10494
11115
  headline,
@@ -11049,6 +11670,22 @@ function buildSessionReconciliationReport(input) {
11049
11670
  skillToolSignals,
11050
11671
  trails
11051
11672
  });
11673
+ const pageQuality = scorePageQuality({
11674
+ auditMethod,
11675
+ coverage,
11676
+ impact: impactProjection,
11677
+ mirror,
11678
+ recommendations,
11679
+ trails
11680
+ });
11681
+ const agenticQuotient = buildAgenticQuotient({
11682
+ auditMethod,
11683
+ coverage,
11684
+ executionQuality,
11685
+ findings: allFindings,
11686
+ recommendations,
11687
+ trails
11688
+ });
11052
11689
  const tensionMetrics = buildTensionMetrics({
11053
11690
  coverage,
11054
11691
  impact: impactProjection,
@@ -11128,6 +11765,8 @@ function buildSessionReconciliationReport(input) {
11128
11765
  attribution_spine: attributionSpine,
11129
11766
  opportunity_score: opportunityScore,
11130
11767
  execution_quality: executionQuality,
11768
+ page_quality: pageQuality,
11769
+ agentic_quotient: agenticQuotient,
11131
11770
  impact_projection: impactProjection,
11132
11771
  investigation,
11133
11772
  initiative_kickoffs: initiativeKickoffs,
@@ -11175,7 +11814,58 @@ function renderWorkGraphExtractionProtocolMarkdown(protocol = buildWorkGraphExtr
11175
11814
  lines.push("```");
11176
11815
  return lines.join("\n");
11177
11816
  }
11178
- function renderWorkGraphMarkdown(report) {
11817
+ function markdownText(value, fallback) {
11818
+ if (typeof value !== "string") return fallback;
11819
+ const trimmed = value.trim();
11820
+ if (!trimmed || /^undefined$/i.test(trimmed) || /^null$/i.test(trimmed)) return fallback;
11821
+ return trimmed;
11822
+ }
11823
+ function markdownNumber(value, fallback = 0) {
11824
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
11825
+ }
11826
+ function markdownStrings(value) {
11827
+ return Array.isArray(value) ? value.filter((item) => typeof item === "string" && item.trim().length > 0) : [];
11828
+ }
11829
+ function markdownSources(value) {
11830
+ return markdownStrings(value).map((source) => labelForSourceClient(normalizeSourceClient(source))).join(", ") || "source evidence";
11831
+ }
11832
+ function markdownPublicTitle(title, fallback) {
11833
+ const source = markdownText(title, fallback);
11834
+ return titleFromText(source, fallback);
11835
+ }
11836
+ function markdownPublicTrails(report) {
11837
+ const primary = report.mirror.primary_trail_id ? report.trails.find((trail) => trail.id === report.mirror.primary_trail_id) : selectPublicTopTrail(report.trails);
11838
+ const ranked = [...report.trails].sort((left, right) => publicTrailRank(right) - publicTrailRank(left));
11839
+ return primary ? [primary, ...ranked.filter((trail) => trail.id !== primary.id)] : ranked;
11840
+ }
11841
+ function renderWorkGraphShareables(report, options) {
11842
+ const lines = [];
11843
+ lines.push("## Shareables");
11844
+ lines.push("");
11845
+ if (options.publicUrl) {
11846
+ lines.push(`Profile URL: ${options.publicUrl}`);
11847
+ const separator = options.publicUrl.includes("?") ? "&" : "?";
11848
+ lines.push(`Headline card: ${options.publicUrl}/opengraph-image?v=headline`);
11849
+ lines.push(`Stack card: ${options.publicUrl}/opengraph-image?v=stack`);
11850
+ lines.push(`Receipt card: ${options.publicUrl}/opengraph-image?v=receipt`);
11851
+ lines.push(`Gap card: ${options.publicUrl}/opengraph-image?v=gap`);
11852
+ lines.push(`Weekly wrapped card: ${options.publicUrl}/opengraph-image?v=wrapped`);
11853
+ lines.push(`Tracked share URL: ${options.publicUrl}${separator}ref=share&v=headline`);
11854
+ if (options.reviewUrl) lines.push(`Review URL: ${options.reviewUrl}`);
11855
+ } else {
11856
+ lines.push("- Publish with --public-share to create profile and share-card URLs.");
11857
+ }
11858
+ lines.push("");
11859
+ const aq = report.agentic_quotient;
11860
+ const topQuest = aq.repair_quests[0];
11861
+ lines.push("Suggested share copy:");
11862
+ lines.push(`- AQ ${aq.aq}. Stack ${aq.stack_score}. Durable ${aq.durability_score}. Gap ${aq.agentic_gap}. ${aq.archetype.label}. Receipts attached.`);
11863
+ lines.push(`- Just ran my AQ. ${topQuest ? `Next repair: ${topQuest.title} (+${topQuest.expected_aq_lift} AQ).` : "The gap is the game."}`);
11864
+ lines.push(`- Receipts > vibes. AQ ${aq.aq} with ${report.impact_projection.time_saved_hours_per_week}h/week recoverable.`);
11865
+ lines.push("");
11866
+ return lines;
11867
+ }
11868
+ function renderWorkGraphMarkdown(report, options = {}) {
11179
11869
  const lines = [];
11180
11870
  lines.push("# OrgX Investigation Engine");
11181
11871
  lines.push("");
@@ -11186,6 +11876,7 @@ function renderWorkGraphMarkdown(report) {
11186
11876
  lines.push(`Hydration key: ${report.signup_hydration.hydration_key}`);
11187
11877
  lines.push(`Final state: ${report.final_state}`);
11188
11878
  lines.push("");
11879
+ lines.push(...renderWorkGraphShareables(report, options));
11189
11880
  lines.push("## AI-Client Search Protocol");
11190
11881
  lines.push("");
11191
11882
  lines.push(`Schema: ${report.extraction_protocol.schema_version}`);
@@ -11221,7 +11912,7 @@ function renderWorkGraphMarkdown(report) {
11221
11912
  lines.push(`Earned counterfactuals: ${report.investigation.counterfactuals.length}`);
11222
11913
  lines.push("");
11223
11914
  lines.push("Mirror:");
11224
- lines.push(report.investigation.mirror_paragraph.text);
11915
+ lines.push(markdownText(report.investigation.mirror_paragraph.text, report.mirror.body));
11225
11916
  lines.push("");
11226
11917
  if (report.investigation.counterfactuals[0]) {
11227
11918
  const counterfactual = report.investigation.counterfactuals[0];
@@ -11262,7 +11953,7 @@ function renderWorkGraphMarkdown(report) {
11262
11953
  lines.push("- No domain clusters reached the public-summary threshold.");
11263
11954
  } else {
11264
11955
  for (const domain of report.domain_coverage) {
11265
- lines.push(`- ${domain.label}: ${domain.finding_count} findings across ${domain.source_clients.join(", ")}. ${domain.summary}`);
11956
+ lines.push(`- ${markdownText(domain.label, "Work evidence")}: ${markdownNumber(domain.finding_count)} findings across ${markdownSources(domain.source_clients)}. ${markdownText(domain.summary, "Evidence cluster retained for public review.")}`);
11266
11957
  }
11267
11958
  }
11268
11959
  lines.push("");
@@ -11272,7 +11963,8 @@ function renderWorkGraphMarkdown(report) {
11272
11963
  lines.push("- No repeated skill/tool signals reached the public-summary threshold.");
11273
11964
  } else {
11274
11965
  for (const signal of report.skill_tool_signals) {
11275
- lines.push(`- [${signal.kind}] ${signal.label}: ${signal.mention_count} mention${signal.mention_count === 1 ? "" : "s"} across ${signal.source_clients.join(", ")}.`);
11966
+ const mentionCount = markdownNumber(signal.mention_count);
11967
+ lines.push(`- [${markdownText(signal.kind, "source")}] ${markdownText(signal.label, "Work source")}: ${mentionCount} mention${mentionCount === 1 ? "" : "s"} across ${markdownSources(signal.source_clients)}.`);
11276
11968
  }
11277
11969
  }
11278
11970
  lines.push("");
@@ -11286,6 +11978,28 @@ function renderWorkGraphMarkdown(report) {
11286
11978
  lines.push(`Automation potential: ${report.opportunity_score.automation_potential}/100`);
11287
11979
  lines.push(`OrgX fit: ${report.opportunity_score.orgx_fit}/100`);
11288
11980
  lines.push("");
11981
+ lines.push("## Agentic Quotient");
11982
+ lines.push("");
11983
+ lines.push(`AQ: ${report.agentic_quotient.aq}/100`);
11984
+ lines.push(`Stack score: ${report.agentic_quotient.stack_score}/100`);
11985
+ lines.push(`Durability score: ${report.agentic_quotient.durability_score}/100`);
11986
+ lines.push(`Agentic gap: ${report.agentic_quotient.agentic_gap}`);
11987
+ lines.push(`Ceiling: ${report.agentic_quotient.ceiling}/100`);
11988
+ lines.push(`Archetype: ${report.agentic_quotient.archetype.label}`);
11989
+ lines.push(report.agentic_quotient.archetype.roast);
11990
+ lines.push(report.agentic_quotient.archetype.truth);
11991
+ lines.push("");
11992
+ if (report.agentic_quotient.repair_quests.length > 0) {
11993
+ lines.push("Repair quests:");
11994
+ for (const quest of report.agentic_quotient.repair_quests) {
11995
+ lines.push(`- +${quest.expected_aq_lift} AQ ${quest.title}: ${quest.reason}`);
11996
+ }
11997
+ lines.push("");
11998
+ }
11999
+ for (const note of report.agentic_quotient.notes) {
12000
+ lines.push(`- ${note}`);
12001
+ }
12002
+ lines.push("");
11289
12003
  lines.push("## Execution Quality");
11290
12004
  lines.push("");
11291
12005
  lines.push(`Overall: ${report.execution_quality.overall}/100`);
@@ -11299,6 +12013,18 @@ function renderWorkGraphMarkdown(report) {
11299
12013
  lines.push(`- ${note}`);
11300
12014
  }
11301
12015
  lines.push("");
12016
+ lines.push("## Page Quality");
12017
+ lines.push("");
12018
+ lines.push(`Overall: ${report.page_quality.overall}/100`);
12019
+ lines.push(`Clarity: ${report.page_quality.clarity}/100`);
12020
+ lines.push(`Impact: ${report.page_quality.impact}/100`);
12021
+ lines.push(`Resonance: ${report.page_quality.resonance}/100`);
12022
+ lines.push(`Trust: ${report.page_quality.trust}/100`);
12023
+ lines.push(`Repair readiness: ${report.page_quality.repair_readiness}/100`);
12024
+ for (const note of report.page_quality.notes) {
12025
+ lines.push(`- ${note}`);
12026
+ }
12027
+ lines.push("");
11302
12028
  lines.push("## Impact Projection");
11303
12029
  lines.push("");
11304
12030
  lines.push(`Time saved: ${report.impact_projection.time_saved_hours_per_week}h/week`);
@@ -11321,7 +12047,7 @@ function renderWorkGraphMarkdown(report) {
11321
12047
  lines.push("");
11322
12048
  lines.push("Source manifests:");
11323
12049
  for (const manifest of report.source_coverage.manifests) {
11324
- lines.push(`- [${manifest.status}] ${manifest.source_label}: ${manifest.finding_count} findings, ${manifest.searched_session_count} searched / ${manifest.skipped_session_count} skipped sessions, confidence ${manifest.confidence}`);
12050
+ lines.push(`- [${markdownText(manifest.status, "observed")}] ${markdownText(manifest.source_label, "Work source")}: ${markdownNumber(manifest.finding_count)} findings, ${markdownNumber(manifest.searched_session_count)} searched / ${markdownNumber(manifest.skipped_session_count)} skipped sessions, confidence ${markdownNumber(manifest.confidence)}`);
11325
12051
  }
11326
12052
  }
11327
12053
  lines.push("");
@@ -11332,19 +12058,23 @@ function renderWorkGraphMarkdown(report) {
11332
12058
  lines.push(report.mirror.body);
11333
12059
  lines.push("");
11334
12060
  for (const claim of report.mirror.claims) {
11335
- lines.push(`- ${claim.text} (${claim.evidence_refs.join(", ") || "no evidence refs"})`);
12061
+ lines.push(`- ${markdownText(claim.text, "Claim retained for review")} (${markdownStrings(claim.evidence_refs).join(", ") || "evidence refs pending"})`);
11336
12062
  }
11337
12063
  lines.push("");
11338
12064
  lines.push("## Operating Leakage");
11339
12065
  lines.push("");
11340
- for (const metric of report.tension_metrics) {
11341
- lines.push(`- ${metric.value} ${metric.label}: ${metric.explanation}`);
12066
+ if (report.tension_metrics.length === 0) {
12067
+ lines.push("- No operating leakage metrics reached the public-summary threshold.");
12068
+ } else {
12069
+ for (const metric of report.tension_metrics) {
12070
+ lines.push(`- ${markdownText(metric.value, "0")} ${markdownText(metric.label, "signal")}: ${markdownText(metric.explanation, "Evidence retained for review.")}`);
12071
+ }
11342
12072
  }
11343
12073
  lines.push("");
11344
12074
  lines.push("## Evidence Paths");
11345
12075
  lines.push("");
11346
- for (const trail of report.trails.slice(0, 12)) {
11347
- lines.push(`- [${trail.kind}] ${trail.title} \u2014 ${trail.state}, ${trail.valence}, ${trail.shape} (${trail.evidence_refs.join(", ")})`);
12076
+ for (const trail of markdownPublicTrails(report).slice(0, 12)) {
12077
+ lines.push(`- [${markdownText(trail.kind, "trail")}] ${markdownPublicTitle(trail.title, "Work trail")} - ${markdownText(trail.state, "observed")}, ${markdownText(trail.valence, "neutral")}, ${markdownText(trail.shape, "single_signal")} (${markdownStrings(trail.evidence_refs).join(", ") || "evidence refs pending"})`);
11348
12078
  }
11349
12079
  lines.push("");
11350
12080
  lines.push("## Recurring Patterns");
@@ -11353,14 +12083,14 @@ function renderWorkGraphMarkdown(report) {
11353
12083
  lines.push("- No recurring patterns detected yet.");
11354
12084
  } else {
11355
12085
  for (const pattern of report.recurring_patterns) {
11356
- lines.push(`- [${pattern.severity}] ${pattern.title}: ${pattern.root_cause_hypothesis}`);
12086
+ lines.push(`- [${markdownText(pattern.severity, "medium")}] ${markdownPublicTitle(pattern.title, "Recurring work pattern")}: ${markdownText(pattern.root_cause_hypothesis, "The same work shape is recurring without a durable repair.")}`);
11357
12087
  }
11358
12088
  }
11359
12089
  lines.push("");
11360
12090
  lines.push("## Top Findings");
11361
12091
  lines.push("");
11362
12092
  for (const finding of report.findings.slice(0, 12)) {
11363
- lines.push(`- [${finding.type}] ${finding.title} (${finding.evidence_ref})`);
12093
+ lines.push(`- [${markdownText(finding.type, "finding")}] ${markdownPublicTitle(finding.title, "Work finding")} (${markdownText(finding.evidence_ref, "evidence ref pending")})`);
11364
12094
  }
11365
12095
  lines.push("");
11366
12096
  lines.push("## Missed Orchestration");
@@ -12451,7 +13181,7 @@ async function readAuditImports(options, interactive) {
12451
13181
  }
12452
13182
  if (imports.length === 0) {
12453
13183
  const sourceHint = sources.length > 0 ? ` No audit-relevant lines were found in ${sources.join(", ")} sessions.` : "";
12454
- throw new Error(`Audit input is required.${sourceHint} Pass --input <file>, pipe text, or use --from claude,codex,opencode,goose,cursor,all.`);
13184
+ throw new Error(`Audit input is required.${sourceHint} Pass --input <file>, pipe text, or use --from claude,codex,opencode,goose,cursor,github,slack,all.`);
12455
13185
  }
12456
13186
  return {
12457
13187
  connectedSources,
@@ -12650,6 +13380,53 @@ function runWorkGraphExtractionSchemaCommand(options) {
12650
13380
  const markdown = renderWorkGraphExtractionProtocolMarkdown(protocol);
12651
13381
  console.log(markdown);
12652
13382
  }
13383
+ function normalizeRuntimePacketSource(source) {
13384
+ const normalized = source.trim().toLowerCase().replace(/_/g, "-");
13385
+ if (normalized === "codex") return "codex";
13386
+ if (normalized === "claude" || normalized === "claude-code" || normalized === "claude_code") return "claude-code";
13387
+ throw new Error("Unsupported runtime event source. Use codex or claude.");
13388
+ }
13389
+ function normalizeRuntimePacketRole(role) {
13390
+ const normalized = role?.trim().toLowerCase();
13391
+ if (normalized === "user" || normalized === "assistant" || normalized === "tool" || normalized === "meta") {
13392
+ return normalized;
13393
+ }
13394
+ return "assistant";
13395
+ }
13396
+ function runWorkGraphRuntimeEventCommand(options) {
13397
+ const source = normalizeRuntimePacketSource(options.source);
13398
+ const cwd = resolve2(options.cwd?.trim() || process.cwd());
13399
+ const outputRoot = resolve2(cwd, options.outputDir?.trim() || ".orgx/work-graph/runtime-events");
13400
+ const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
13401
+ const timestamp = generatedAt.replace(/[:.]/g, "-");
13402
+ const summary = options.summary?.trim() || options.message?.trim();
13403
+ if (!summary) {
13404
+ throw new Error("Runtime event summary is required. Pass --summary or --message.");
13405
+ }
13406
+ const packet = {
13407
+ type: "orgx_work_graph_runtime_event",
13408
+ schema_version: "1.0.0",
13409
+ source_client: source,
13410
+ timestamp: generatedAt,
13411
+ role: normalizeRuntimePacketRole(options.role),
13412
+ event_kind: options.eventKind?.trim() || "artifact",
13413
+ summary,
13414
+ content: summary,
13415
+ ...options.toolName?.trim() ? { tool_name: options.toolName.trim() } : {},
13416
+ cwd,
13417
+ collection_method: "runtime_packet",
13418
+ redaction_state: "agent_redacted"
13419
+ };
13420
+ const path = resolve2(outputRoot, source, `${timestamp}-${process.pid}.jsonl`);
13421
+ writeTextFile(path, `${JSON.stringify(packet)}
13422
+ `, { mode: 384 });
13423
+ if (options.json) {
13424
+ console.log(JSON.stringify({ ok: true, path, source, collectedBy: "work-graph profile --from all" }, null, 2));
13425
+ return;
13426
+ }
13427
+ console.log(` ${ICON.ok} ${pc3.green("runtime event")} ${pc3.dim(path)}`);
13428
+ console.log(` ${ICON.skip} ${pc3.dim("collect with")} ${pc3.bold("orgx-wizard work-graph profile --from all")}`);
13429
+ }
12653
13430
  async function runWorkGraphCommand(options, defaults = {}) {
12654
13431
  const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
12655
13432
  const commandOptions = {
@@ -12722,6 +13499,9 @@ async function runWorkGraphCommand(options, defaults = {}) {
12722
13499
  }
12723
13500
  }
12724
13501
  }
13502
+ if (published?.publicUrl || published?.reviewUrl) {
13503
+ writeTextFile(markdownPath, renderWorkGraphMarkdown(report, published));
13504
+ }
12725
13505
  if (commandOptions.json) {
12726
13506
  console.log(JSON.stringify({
12727
13507
  jsonPath,
@@ -12731,7 +13511,9 @@ async function runWorkGraphCommand(options, defaults = {}) {
12731
13511
  hydrationKey: report.signup_hydration.hydration_key,
12732
13512
  finalState: report.final_state,
12733
13513
  opportunityScore: report.opportunity_score,
13514
+ agenticQuotient: report.agentic_quotient,
12734
13515
  executionQuality: report.execution_quality,
13516
+ pageQuality: report.page_quality,
12735
13517
  impactProjection: report.impact_projection,
12736
13518
  missedOrchestration: report.missed_orchestration_opportunities.length,
12737
13519
  clientExtractionCount: report.client_extractions.length,
@@ -12751,7 +13533,10 @@ async function runWorkGraphCommand(options, defaults = {}) {
12751
13533
  console.log(` ${ICON.ok} ${pc3.green("state ")} ${pc3.dim(report.final_state)}`);
12752
13534
  console.log(` ${ICON.ok} ${pc3.green("extractions ")} ${pc3.dim(String(report.client_extractions.length))}`);
12753
13535
  console.log(` ${ICON.ok} ${pc3.green("score ")} ${pc3.dim(formatWorkGraphScoreLine(report.opportunity_score))}`);
12754
- console.log(` ${ICON.ok} ${pc3.green("quality ")} ${pc3.dim(`${report.execution_quality.overall}/100 \xB7 coverage ${report.source_coverage.coverage_score ?? 0}/100`)}`);
13536
+ console.log(` ${ICON.ok} ${pc3.green("AQ ")} ${pc3.dim(`${report.agentic_quotient.aq}/100 \xB7 Stack ${report.agentic_quotient.stack_score}/100 \xB7 Durable ${report.agentic_quotient.durability_score}/100 \xB7 Gap ${report.agentic_quotient.agentic_gap}`)}`);
13537
+ console.log(` ${ICON.ok} ${pc3.green("archetype ")} ${pc3.dim(report.agentic_quotient.archetype.label)}`);
13538
+ console.log(` ${ICON.ok} ${pc3.green("audit quality ")} ${pc3.dim(`${report.execution_quality.overall}/100 \xB7 coverage ${report.source_coverage.coverage_score ?? 0}/100`)}`);
13539
+ console.log(` ${ICON.ok} ${pc3.green("page quality ")} ${pc3.dim(`${report.page_quality.overall}/100 \xB7 clarity ${report.page_quality.clarity}/100 \xB7 trust ${report.page_quality.trust}/100`)}`);
12755
13540
  console.log(` ${ICON.ok} ${pc3.green("impact ")} ${pc3.dim(`${report.impact_projection.time_saved_hours_per_week}h/week \xB7 +${report.impact_projection.acceleration_percent}% acceleration \xB7 ~$${report.impact_projection.estimated_monthly_value_usd.toLocaleString("en-US")}/month`)}`);
12756
13541
  const missed = report.missed_orchestration_opportunities.length;
12757
13542
  const missedColor = missed > 0 ? pc3.yellow : pc3.green;
@@ -13728,7 +14513,7 @@ function printDoctorReport(report, assessment) {
13728
14513
  async function main() {
13729
14514
  const program = new Command();
13730
14515
  program.name("orgx-wizard").description("Add OrgX MCP configs, skills/rules, and companion plugins to your local AI tools.").showHelpAfterError();
13731
- const pkgVersion = true ? "0.1.43" : void 0;
14516
+ const pkgVersion = true ? "0.1.44" : void 0;
13732
14517
  program.version(pkgVersion ?? "unknown", "-V, --version");
13733
14518
  program.hook("preAction", (_thisCommand, actionCommand) => {
13734
14519
  if (Boolean(actionCommand.optsWithGlobals().json)) return;
@@ -14418,7 +15203,7 @@ async function main() {
14418
15203
  jsonOutput: Boolean(options.json)
14419
15204
  });
14420
15205
  });
14421
- program.command("audit").description("Run the AI-native Founder Loop self-audit from pasted or file-based AI-session context.").option("--input <path>", "AI-session transcript or summary file; stdin is used when piped").option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "3").option("--session-days <days>", "lookback window for local AI-session imports", "30").option("--codex-sessions-dir <path>", "override Codex sessions directory for audit import").option("--claude-projects-dir <path>", "override Claude projects directory for audit import").option("--source-label <label>", "label for the imported AI-session source").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only audits").option("--output-dir <path>", "directory for generated audit JSON and Markdown", ".orgx/audits").option("--attach-to-initiative <id>", "attach the generated audit artifact to an existing OrgX initiative").option("--create-initiative", "create an OrgX initiative from the generated audit plan").option("--write-follow-up", "create one approval-gated OrgX follow-up task from the audit recommendation").option("--workstream-id <id>", "optional workstream id for the generated follow-up task").option("--milestone-id <id>", "optional milestone id for the generated follow-up task").option("--dry-run", "exercise OrgX write paths without sending writes").option("--yes", "approve OrgX write flags in non-interactive mode").option("--json", "emit a JSON command summary").action(async (options) => {
15206
+ program.command("audit").description("Run the AI-native Founder Loop self-audit from pasted or file-based AI-session context.").option("--input <path>", "AI-session transcript or summary file; stdin is used when piped").option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, github, slack, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "3").option("--session-days <days>", "lookback window for local AI-session imports", "30").option("--codex-sessions-dir <path>", "override Codex sessions directory for audit import").option("--claude-projects-dir <path>", "override Claude projects directory for audit import").option("--source-label <label>", "label for the imported AI-session source").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only audits").option("--output-dir <path>", "directory for generated audit JSON and Markdown", ".orgx/audits").option("--attach-to-initiative <id>", "attach the generated audit artifact to an existing OrgX initiative").option("--create-initiative", "create an OrgX initiative from the generated audit plan").option("--write-follow-up", "create one approval-gated OrgX follow-up task from the audit recommendation").option("--workstream-id <id>", "optional workstream id for the generated follow-up task").option("--milestone-id <id>", "optional milestone id for the generated follow-up task").option("--dry-run", "exercise OrgX write paths without sending writes").option("--yes", "approve OrgX write flags in non-interactive mode").option("--json", "emit a JSON command summary").action(async (options) => {
14422
15207
  await safeTrackWizardTelemetry("audit_started", {
14423
15208
  attach_to_initiative: Boolean(options.attachToInitiative),
14424
15209
  command: "audit",
@@ -14436,14 +15221,17 @@ async function main() {
14436
15221
  });
14437
15222
  runWorkGraphExtractionSchemaCommand(options);
14438
15223
  });
14439
- workGraph.command("preview").description("Preview the OrgX Profile evidence findings without writing to OrgX.").option("--input <path>", "source transcript or summary file; stdin is used when piped").option("--extraction <path>", "structured AI-client extraction JSON; repeat or comma-separate for multiple clients", collectPathOption, []).option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "15").option("--session-days <days>", "lookback window for local AI-session imports", "60").option("--codex-sessions-dir <path>", "override Codex sessions directory for import").option("--claude-projects-dir <path>", "override Claude projects directory for import").option("--source-label <label>", "label for the imported manual source").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only previews").option("--output-dir <path>", "directory for generated Work Graph JSON and Markdown", ".orgx/work-graph").option("--json", "emit a JSON command summary").action(async (options) => {
15224
+ workGraph.command("runtime-event").description("Write a redacted Codex/Claude runtime packet into the Work Graph collector directory.").requiredOption("--source <source>", "agent source writing the packet: codex or claude").option("--summary <text>", "public-safe summary of the decision, artifact, blocker, outcome, or tool event").option("--message <text>", "alias for --summary").option("--event-kind <kind>", "event kind hint: decision, artifact, blocker, outcome, tool_call_error", "artifact").option("--role <role>", "source role: user, assistant, tool, or meta", "assistant").option("--tool-name <name>", "tool name when the packet represents a tool call").option("--cwd <path>", "workspace root that owns the collector directory").option("--output-dir <path>", "collector root relative to cwd", ".orgx/work-graph/runtime-events").option("--json", "emit a JSON summary").action((options) => {
15225
+ runWorkGraphRuntimeEventCommand(options);
15226
+ });
15227
+ workGraph.command("preview").description("Preview the OrgX Profile evidence findings without writing to OrgX.").option("--input <path>", "source transcript or summary file; stdin is used when piped").option("--extraction <path>", "structured AI-client extraction JSON; repeat or comma-separate for multiple clients", collectPathOption, []).option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, github, slack, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "15").option("--session-days <days>", "lookback window for local AI-session imports", "60").option("--codex-sessions-dir <path>", "override Codex sessions directory for import").option("--claude-projects-dir <path>", "override Claude projects directory for import").option("--source-label <label>", "label for the imported manual source").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only previews").option("--output-dir <path>", "directory for generated Work Graph JSON and Markdown", ".orgx/work-graph").option("--json", "emit a JSON command summary").action(async (options) => {
14440
15228
  await safeTrackWizardTelemetry("work_graph_preview_started", {
14441
15229
  command: "work-graph preview",
14442
15230
  from: options.from ?? "manual"
14443
15231
  });
14444
15232
  await runWorkGraphCommand(options);
14445
15233
  });
14446
- workGraph.command("profile").description("Build a local OrgX Profile with evidence findings, domain coverage, source confidence, and repair recommendations.").option("--input <path>", "source transcript or summary file; stdin is used when piped").option("--extraction <path>", "structured AI-client extraction JSON; repeat or comma-separate for multiple clients", collectPathOption, []).option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "25").option("--session-days <days>", "lookback window for local AI-session imports", "60").option("--codex-sessions-dir <path>", "override Codex sessions directory for import").option("--claude-projects-dir <path>", "override Claude projects directory for import").option("--source-label <label>", "label for the imported manual source").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only profiles").option("--output-dir <path>", "directory for generated Work Graph JSON and Markdown", ".orgx/work-graph").option("--publish", "publish the generated OrgX Profile to OrgX and return a shareable URL").option("--public-share", "create a public redacted /work-graph/<token> share when publishing").option("--attach-artifact", "attach the report as an OrgX artifact when an initiative/entity is provided").option("--attach-to-initiative <id>", "attach the report to an existing OrgX initiative").option("--entity-type <type>", "entity type for artifact attachment: project, initiative, milestone, task, decision").option("--entity-id <id>", "entity id for artifact attachment").option("--artifact-url <url>", "override the artifact URL stored in OrgX").option("--yes", "approve publish/write prompts in non-interactive mode").option("--json", "emit a JSON command summary").action(async (options) => {
15234
+ workGraph.command("profile").description("Build a local OrgX Profile with evidence findings, domain coverage, source confidence, and repair recommendations.").option("--input <path>", "source transcript or summary file; stdin is used when piped").option("--extraction <path>", "structured AI-client extraction JSON; repeat or comma-separate for multiple clients", collectPathOption, []).option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, github, slack, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "25").option("--session-days <days>", "lookback window for local AI-session imports", "60").option("--codex-sessions-dir <path>", "override Codex sessions directory for import").option("--claude-projects-dir <path>", "override Claude projects directory for import").option("--source-label <label>", "label for the imported manual source").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only profiles").option("--output-dir <path>", "directory for generated Work Graph JSON and Markdown", ".orgx/work-graph").option("--publish", "publish the generated OrgX Profile to OrgX and return a shareable URL").option("--public-share", "create a public redacted /work-graph/<token> share when publishing").option("--attach-artifact", "attach the report as an OrgX artifact when an initiative/entity is provided").option("--attach-to-initiative <id>", "attach the report to an existing OrgX initiative").option("--entity-type <type>", "entity type for artifact attachment: project, initiative, milestone, task, decision").option("--entity-id <id>", "entity id for artifact attachment").option("--artifact-url <url>", "override the artifact URL stored in OrgX").option("--yes", "approve publish/write prompts in non-interactive mode").option("--json", "emit a JSON command summary").action(async (options) => {
14447
15235
  await safeTrackWizardTelemetry("work_graph_profile_started", {
14448
15236
  command: "work-graph profile",
14449
15237
  from: options.from ?? "manual"
@@ -14451,7 +15239,7 @@ async function main() {
14451
15239
  await runWorkGraphCommand(options);
14452
15240
  });
14453
15241
  const sessions = program.command("sessions").description("Inspect and reconcile local AI sessions into OrgX-ready Work Graph reports.");
14454
- sessions.command("reconcile").description("Backfill recent Claude Code, Codex, OpenCode, goose, and Cursor sessions into a redacted OrgX Profile report.").option("--extraction <path>", "structured AI-client extraction JSON; repeat or comma-separate for multiple clients", collectPathOption, []).option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, or all", "all").option("--session-limit <count>", "max recent sessions to import per selected source", "25").option("--session-days <days>", "lookback window for local AI-session imports", "30").option("--codex-sessions-dir <path>", "override Codex sessions directory for import").option("--claude-projects-dir <path>", "override Claude projects directory for import").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only reconciliation").option("--output-dir <path>", "directory for generated Work Graph JSON and Markdown", ".orgx/work-graph").option("--publish", "publish the generated OrgX Profile to OrgX and return a shareable URL").option("--public-share", "create a public redacted /work-graph/<token> share when publishing").option("--attach-artifact", "attach the report as an OrgX artifact when an initiative/entity is provided").option("--attach-to-initiative <id>", "attach the report to an existing OrgX initiative").option("--entity-type <type>", "entity type for artifact attachment: project, initiative, milestone, task, decision").option("--entity-id <id>", "entity id for artifact attachment").option("--artifact-url <url>", "override the artifact URL stored in OrgX").option("--yes", "approve publish/write prompts in non-interactive mode").option("--json", "emit a JSON command summary").action(async (options) => {
15242
+ sessions.command("reconcile").description("Backfill recent Claude Code, Codex, OpenCode, goose, and Cursor sessions into a redacted OrgX Profile report.").option("--extraction <path>", "structured AI-client extraction JSON; repeat or comma-separate for multiple clients", collectPathOption, []).option("--from <sources>", "auto-import recent local AI sessions: claude, codex, opencode, goose, cursor, github, slack, or all", "all").option("--session-limit <count>", "max recent sessions to import per selected source", "25").option("--session-days <days>", "lookback window for local AI-session imports", "30").option("--codex-sessions-dir <path>", "override Codex sessions directory for import").option("--claude-projects-dir <path>", "override Claude projects directory for import").option("--workspace-id <id>", "workspace id override; defaults to the current OrgX workspace when authenticated").option("--workspace-name <name>", "workspace name override for local-only reconciliation").option("--output-dir <path>", "directory for generated Work Graph JSON and Markdown", ".orgx/work-graph").option("--publish", "publish the generated OrgX Profile to OrgX and return a shareable URL").option("--public-share", "create a public redacted /work-graph/<token> share when publishing").option("--attach-artifact", "attach the report as an OrgX artifact when an initiative/entity is provided").option("--attach-to-initiative <id>", "attach the report to an existing OrgX initiative").option("--entity-type <type>", "entity type for artifact attachment: project, initiative, milestone, task, decision").option("--entity-id <id>", "entity id for artifact attachment").option("--artifact-url <url>", "override the artifact URL stored in OrgX").option("--yes", "approve publish/write prompts in non-interactive mode").option("--json", "emit a JSON command summary").action(async (options) => {
14455
15243
  await safeTrackWizardTelemetry("sessions_reconcile_started", {
14456
15244
  command: "sessions reconcile",
14457
15245
  from: options.from ?? "all"