@useorgx/wizard 0.1.30 → 0.1.32

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
@@ -6234,6 +6234,19 @@ var ORGX_TOOL_SIGNAL_PATTERN = /\b(?:mcp__orgx__|orgx_emit_activity|orgx_apply_c
6234
6234
  var INSTRUCTION_BOILERPLATE_PATTERN = /^(?:#{1,6}\s*)?(?:agents\.md|instructions?|codex guardrails|precedence|read before you write|use exactly what was specified|don'?t confuse technologies|repo \+ scope hygiene|initiative \/ mcp discipline|ui quality bar|verification standards|secrets \+ safety|patch\/editing rules|commit \/ pr \/ merge protocol|output style|mcp integration|agent domains|skills|conventions)\b/i;
6235
6235
  var IMPERATIVE_BOILERPLATE_PATTERN = /^[-*]\s+(?:if the user|when the user|if mcp|when agents|never|always|do not|don'?t|default to|treat|produce|pick|verify|avoid|match|use exactly|keep system boundaries|quote bracketed|for orgx|when capture tooling|if no meaningful|do \*\*not\*\*)\b/i;
6236
6236
  var CODE_OR_DOC_NOISE_PATTERN = /^(?:[-*]\s*)?(?:https?:\/\/|\/|\.{0,2}\/|[A-Za-z]:\/|`{1,3}|"{1,2}[A-Za-z0-9:_-]+":|\d+\s*$|\d+\t|import\s|export\s|const\s|let\s|var\s|function\s|type\s|interface\s|CREATE\s+TABLE|ALTER\s+TABLE|SELECT\s+|INSERT\s+|UPDATE\s+|DELETE\s+)/i;
6237
+ var EMPTY_AUDIT_LABEL_PATTERN = /^(?:[-*]\s*)?(?:decision|artifact|receipt|proof|commitment|next action|follow[- ]?up|outcome|result|impact|roi|economics|open loop|gap|blocker|risk|owner|dri|rollback|quality score)\s*:\s*[\[{(;,]*$/i;
6238
+ var TYPE_SIGNATURE_NOISE_PATTERN = /^(?:[-*]\s*)?(?:decision|artifact|receipt|proof|commitment|next action|follow[- ]?up|outcome|result|impact|roi|economics|open loop|gap|blocker|risk|owner|dri|rollback|quality score)\s*:\s*[A-Za-z_$][\w$]*(?:<[^>]+>)?[\s,;)]*$/i;
6239
+ var TOOL_CATALOG_NOISE_PATTERN = /^(?:[-*]\s*)?(?:[a-z][\w.:-]*\s*\([^)]+\),?\s*){2,}$/i;
6240
+ var BARE_TOOL_SIGNAL_PATTERN = /^(?:\d+\.\s*|[-*]\s*)?(?:mcp__orgx__[\w-]*|orgx_emit_activity|orgx_apply_changeset|complete_with_proof|scaffold_initiative|get_task_with_context|ship_batch|record_outcome|orgx_free_audit)\s*$/i;
6241
+ var TOOL_QUESTION_NOISE_PATTERN = /^(?:\d+\.\s*)?\*\*[^*]+\*\*.*\?\s*(?:\([^)]*\b(?:mcp|scaffold_initiative|start_plan_session)\b[^)]*\)\.?)?$/i;
6242
+ var SOURCE_REFERENCE_NOISE_PATTERN = /(?:^|\s)(?:\.{0,2}\/)?(?:orgx|src|lib|workers|public|scripts|tests|apps|packages)\/[\w./-]+\.(?:ts|tsx|js|jsx|json|md|txt|sql|py)(?::\d+)?\b/i;
6243
+ var FILE_REFERENCE_NOISE_PATTERN = /\b[\w.-]+\.(?:ts|tsx|js|jsx|json|md|txt|sql|py)(?::\d+(?:[–-]\d+)?)?\b/i;
6244
+ var LOCAL_ASSET_REFERENCE_PATTERN = /(?:<BlogImage\b|source:\s*\/Users\/|\/blog\/[\w./-]+\.(?:png|jpg|jpeg|webp|gif))/i;
6245
+ var LINE_NUMBER_SOURCE_NOISE_PATTERN = /^\d+(?::|\s+)\s*/i;
6246
+ var TOOL_WORKFLOW_NOISE_PATTERN = /(?:→|->).*\b(?:scaffold_initiative|spawn_agent_task|record_outcome|submit_learning|get_outcome_attribution|mcp__orgx__)\b/i;
6247
+ var TOOL_FAILURE_PATTERN = /^(?:\d+\.\s*)?(?:mcp__orgx__[\w-]*|orgx_emit_activity|orgx_apply_changeset|complete_with_proof|scaffold_initiative|get_task_with_context|ship_batch|record_outcome|orgx_free_audit)\b.*\b(?:rejected|requires|failed|fails|error|invalid|unavailable|timeout|timed out|not\s+(?:called|dispatched|wired|created|available)|missing|broken)\b/i;
6248
+ var RUNTIME_FAILURE_PATTERN = /\b(?:mcp__orgx__[\w-]*|orgx_emit_activity|orgx_apply_changeset|complete_with_proof|scaffold_initiative|get_task_with_context|ship_batch|record_outcome|submit_learning|spawn_agent_task|agent run)\b.*\b(?:rejected|requires|failed|fails|error|invalid|unavailable|timeout|timed out|never|no\s+\w+|not\s+(?:called|dispatched|wired|created|available|append)|missing|broken|only\s+in\s+agent\s+skill\s+prompts)\b/i;
6249
+ var PROCESS_NARRATION_NOISE_PATTERN = /^(?:now i\b|let me\b|i (?:have|need|will|can)\b|i['’]ll\b|i['’]m\b|so\b.*\b(?:confirm|check|verify|fetches)\b)/i;
6237
6250
  function parseAiSessionSources(value) {
6238
6251
  if (!value?.trim()) return [];
6239
6252
  const requested = value.split(",").map((item) => item.trim().toLowerCase()).filter(Boolean);
@@ -6266,6 +6279,75 @@ function asText(value) {
6266
6279
  if (isRecord(value) && typeof value.text === "string") return value.text;
6267
6280
  return "";
6268
6281
  }
6282
+ function stringFromRecord(record, key) {
6283
+ const value = record[key];
6284
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
6285
+ }
6286
+ function numberFromRecord(record, key) {
6287
+ const value = record[key];
6288
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
6289
+ }
6290
+ function normalizeJsonAuditLine(line) {
6291
+ if (!line.startsWith("{")) return null;
6292
+ const parsed = parseJsonLine(line);
6293
+ if (!isRecord(parsed)) return null;
6294
+ const summary = stringFromRecord(parsed, "summary");
6295
+ const stats = isRecord(parsed.summary_stats) ? parsed.summary_stats : void 0;
6296
+ const requestedCount = stats ? numberFromRecord(stats, "requested_count") : void 0;
6297
+ const createdCount = stats ? numberFromRecord(stats, "created_count") : void 0;
6298
+ const failedCount = stats ? numberFromRecord(stats, "failed_count") : void 0;
6299
+ const hierarchy = isRecord(parsed.hierarchy) ? parsed.hierarchy : void 0;
6300
+ const initiative = hierarchy && isRecord(hierarchy.initiative) ? hierarchy.initiative : void 0;
6301
+ const initiativeTitle = initiative ? stringFromRecord(initiative, "title") ?? stringFromRecord(initiative, "name") : void 0;
6302
+ const initiativeError = initiative ? stringFromRecord(initiative, "error") : void 0;
6303
+ if (summary && requestedCount !== void 0 && createdCount !== void 0 && failedCount !== void 0 && /\bcreated\b/i.test(summary)) {
6304
+ const titleSuffix = initiativeTitle ? ` for ${initiativeTitle}` : "";
6305
+ const errorSuffix = initiativeError ? `; ${initiativeError.replace(/\.+$/, "")}` : "";
6306
+ if (failedCount > 0) {
6307
+ return `Blocker: OrgX scaffold created ${createdCount}/${requestedCount} entities${titleSuffix}${errorSuffix}.`;
6308
+ }
6309
+ return `Artifact: OrgX scaffold created ${createdCount}/${requestedCount} entities${titleSuffix}.`;
6310
+ }
6311
+ return null;
6312
+ }
6313
+ function normalizeAuditRelevantLine(line) {
6314
+ const trimmed = line.trim();
6315
+ if (!trimmed) return null;
6316
+ const jsonLine = normalizeJsonAuditLine(trimmed);
6317
+ if (jsonLine) return jsonLine;
6318
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) return null;
6319
+ if (SOURCE_REFERENCE_NOISE_PATTERN.test(trimmed)) return null;
6320
+ if (FILE_REFERENCE_NOISE_PATTERN.test(trimmed)) return null;
6321
+ if (LOCAL_ASSET_REFERENCE_PATTERN.test(trimmed)) return null;
6322
+ if (LINE_NUMBER_SOURCE_NOISE_PATTERN.test(trimmed)) return null;
6323
+ if (/^audit\s+\/Users\//i.test(trimmed)) return null;
6324
+ if (/^#{1,6}\s/.test(trimmed)) return null;
6325
+ if (PROCESS_NARRATION_NOISE_PATTERN.test(trimmed)) return null;
6326
+ if (/^(?:\d+\.\s*)?(?:[-*]\s*)?(?:\*\*)?\b(?:integration gaps|gaps between)\b/i.test(trimmed)) return null;
6327
+ if (/^\s*[-*]\s+the `?orgx`? mcp tools listed/i.test(trimmed)) return null;
6328
+ if (TOOL_WORKFLOW_NOISE_PATTERN.test(trimmed)) return null;
6329
+ const toolFailure = trimmed.match(TOOL_FAILURE_PATTERN);
6330
+ if (toolFailure) {
6331
+ return `Blocker: ${trimmed.replace(/^\d+\.\s*/, "")}`;
6332
+ }
6333
+ if (RUNTIME_FAILURE_PATTERN.test(trimmed)) {
6334
+ const label = /^no programmatic\b/i.test(trimmed) ? "Gap" : "Blocker";
6335
+ return `${label}: ${trimmed.replace(/^\d+\.\s*/, "")}`;
6336
+ }
6337
+ if (!AUDIT_RELEVANT_LINE_PATTERN.test(trimmed)) return null;
6338
+ if (!STRONG_AUDIT_LINE_PATTERN.test(trimmed) && !ORGX_TOOL_SIGNAL_PATTERN.test(trimmed)) return null;
6339
+ if (INSTRUCTION_BOILERPLATE_PATTERN.test(trimmed)) return null;
6340
+ if (IMPERATIVE_BOILERPLATE_PATTERN.test(trimmed)) return null;
6341
+ if (CODE_OR_DOC_NOISE_PATTERN.test(trimmed)) return null;
6342
+ if (EMPTY_AUDIT_LABEL_PATTERN.test(trimmed)) return null;
6343
+ if (TYPE_SIGNATURE_NOISE_PATTERN.test(trimmed)) return null;
6344
+ if (TOOL_CATALOG_NOISE_PATTERN.test(trimmed)) return null;
6345
+ if ((trimmed.match(/\b[a-z][\w.:-]*\s*\([^)]+\)/g) ?? []).length >= 2) return null;
6346
+ if (BARE_TOOL_SIGNAL_PATTERN.test(trimmed)) return null;
6347
+ if (TOOL_QUESTION_NOISE_PATTERN.test(trimmed)) return null;
6348
+ if (/^[-*]\s+all agents\b/i.test(trimmed)) return null;
6349
+ return trimmed;
6350
+ }
6269
6351
  function extractCodexMessageText(record) {
6270
6352
  if (!isRecord(record) || record.type !== "response_item" || !isRecord(record.payload)) {
6271
6353
  return "";
@@ -6289,9 +6371,7 @@ function extractClaudeMessageText(record) {
6289
6371
  return text2;
6290
6372
  }
6291
6373
  function keepAuditRelevantLines(text2) {
6292
- return text2.split(/\r?\n/).map((line) => line.trim()).filter(
6293
- (line) => line.length > 0 && AUDIT_RELEVANT_LINE_PATTERN.test(line) && (STRONG_AUDIT_LINE_PATTERN.test(line) || ORGX_TOOL_SIGNAL_PATTERN.test(line)) && !INSTRUCTION_BOILERPLATE_PATTERN.test(line) && !IMPERATIVE_BOILERPLATE_PATTERN.test(line) && !CODE_OR_DOC_NOISE_PATTERN.test(line)
6294
- );
6374
+ return text2.split(/\r?\n/).map((line) => normalizeAuditRelevantLine(line)).filter((line) => Boolean(line));
6295
6375
  }
6296
6376
  function collectJsonlFiles(root, source) {
6297
6377
  if (!existsSync5(root)) return [];
@@ -6900,6 +6980,19 @@ Rollback: ${plan.recommended_follow_up.rollback}`,
6900
6980
  import { createHash as createHash4 } from "crypto";
6901
6981
  var WORK_GRAPH_SCHEMA_VERSION = "2026-05-07";
6902
6982
  var WORK_GRAPH_FINGERPRINT_VERSION = "wgf_v1";
6983
+ var WORK_GRAPH_EXTRACTION_SCHEMA_VERSION = "2026-05-07.ai-client-search.v1";
6984
+ var WORK_GRAPH_FINDING_TYPES = [
6985
+ "action",
6986
+ "decision",
6987
+ "artifact",
6988
+ "blocker",
6989
+ "person",
6990
+ "business",
6991
+ "product_surface",
6992
+ "goal",
6993
+ "initiative_candidate",
6994
+ "missed_orchestration_opportunity"
6995
+ ];
6903
6996
  function clampScore2(value) {
6904
6997
  return Math.max(0, Math.min(100, Math.round(value)));
6905
6998
  }
@@ -6934,11 +7027,175 @@ function sourceClientForImport(source) {
6934
7027
  if (raw.includes("manual") || raw.includes("wizard-audit-input")) return "manual";
6935
7028
  return "unknown";
6936
7029
  }
7030
+ function normalizeSourceClient(value) {
7031
+ if (typeof value !== "string") return "unknown";
7032
+ const normalized = value.trim().toLowerCase();
7033
+ if (normalized === "codex" || normalized === "claude" || normalized === "claude-code" || normalized === "cursor" || normalized === "openclaw" || normalized === "slack" || normalized === "mcp" || normalized === "github" || normalized === "linear" || normalized === "manual" || normalized === "wizard" || normalized === "api") {
7034
+ return normalized;
7035
+ }
7036
+ if (normalized.includes("claude")) return "claude";
7037
+ if (normalized.includes("codex")) return "codex";
7038
+ if (normalized.includes("cursor")) return "cursor";
7039
+ if (normalized.includes("slack")) return "slack";
7040
+ if (normalized.includes("github")) return "github";
7041
+ if (normalized.includes("linear")) return "linear";
7042
+ if (normalized.includes("mcp")) return "mcp";
7043
+ return "unknown";
7044
+ }
7045
+ function normalizeFindingType(value) {
7046
+ if (typeof value !== "string") return null;
7047
+ const normalized = value.trim().toLowerCase();
7048
+ return WORK_GRAPH_FINDING_TYPES.includes(normalized) ? normalized : null;
7049
+ }
7050
+ function normalizeConfidence(value, fallback = 0.72) {
7051
+ if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
7052
+ return Math.max(0.1, Math.min(0.99, Number(value.toFixed(2))));
7053
+ }
6937
7054
  function titleFromText(text2, fallback) {
6938
7055
  const normalized = text2.replace(/^\s*(decision|artifact|commitment|next action|follow[- ]?up|outcome|roi|economics|open loop|gap|blocker|risk|goal)\s*:\s*/i, "").trim();
6939
7056
  const firstSentence = normalized.split(/[.!?]\s/)[0]?.trim() || normalized;
6940
7057
  return (firstSentence || fallback).slice(0, 160);
6941
7058
  }
7059
+ function normalizeClientExtractionId(extraction, index) {
7060
+ return extraction.extraction_id?.trim() || `${extraction.source_client || "unknown"}:client-extraction:${index + 1}`;
7061
+ }
7062
+ function buildWorkGraphExtractionProtocol() {
7063
+ const schema = {
7064
+ schema_version: WORK_GRAPH_EXTRACTION_SCHEMA_VERSION,
7065
+ mode: "ai_client_session_search",
7066
+ objective: "Search the AI client's own sessions, logs, tool calls, and local transcript index to extract durable work-graph evidence for OrgX.",
7067
+ privacy_contract: [
7068
+ "Do not return raw transcripts.",
7069
+ "Return short redacted verbatim snippets only when they materially support a finding.",
7070
+ "Prefer evidence refs, session ids, timestamps, source ids, and hashes over full content.",
7071
+ "Mark private customer/person data as private or redacted.",
7072
+ "Do not invent people, decisions, artifacts, or outcomes that are not supported by a source event."
7073
+ ],
7074
+ source_search_strategy: [
7075
+ {
7076
+ id: "decisions",
7077
+ lens: "Decision trails",
7078
+ query: "Find choices, tradeoffs, approvals, rejected options, contradictions, architecture calls, product calls, and decisions that were restated later.",
7079
+ return_when: "A choice shaped future work, blocked work, or should become durable organizational memory."
7080
+ },
7081
+ {
7082
+ id: "artifacts",
7083
+ lens: "Artifact trails",
7084
+ query: "Find created or modified artifacts: PRs, files, docs, designs, prompts, plans, reports, screenshots, deployed routes, tests, and verification receipts.",
7085
+ return_when: "The artifact has a source event, proof reference, downstream use, owner, or missing verification."
7086
+ },
7087
+ {
7088
+ id: "blockers",
7089
+ lens: "Blocker trails",
7090
+ query: "Find failed tool calls, timeouts, rejected validators, missing auth, missing source coverage, repeated unresolved questions, stalled owners, and external blockers.",
7091
+ return_when: "The blocker explains why work did not become durable, verified, assigned, or shipped."
7092
+ },
7093
+ {
7094
+ id: "people_businesses",
7095
+ lens: "People and business trails",
7096
+ query: "Find users, customers, buyers, stakeholders, reviewers, teams, businesses, accounts, and market signals connected to work or decisions.",
7097
+ return_when: "A person or business changes priority, ownership, revenue potential, customer pain, or follow-up urgency."
7098
+ },
7099
+ {
7100
+ id: "product_surfaces",
7101
+ lens: "Product surface trails",
7102
+ query: "Find surfaces such as live rooms, command center, widgets, plugins, wizard flows, public pages, APIs, MCP tools, Slack/GitHub/Linear integrations, and signup/claim flows.",
7103
+ return_when: "A surface was changed, verified, blocked, requested, or connected to a goal or artifact."
7104
+ },
7105
+ {
7106
+ id: "agents_tools_sources",
7107
+ lens: "Agent/tool/source trails",
7108
+ query: "Find agent runs, subagents, MCP calls, hook lifecycle events, tool availability, tool misses, source coverage, and runtime writeback behavior.",
7109
+ return_when: "The event proves whether OrgX was called, skipped, unavailable, or only mentioned in instructions."
7110
+ },
7111
+ {
7112
+ id: "outcomes_roi",
7113
+ lens: "Outcome and ROI trails",
7114
+ query: "Find shipped/completed work, test/browser/deploy verification, outcomes, time saved, cost, revenue, customer impact, attribution, and expected lift.",
7115
+ return_when: "The outcome can be tied to evidence and a prior decision, artifact, blocker, or source."
7116
+ },
7117
+ {
7118
+ id: "recurrence",
7119
+ lens: "Recurring patterns",
7120
+ query: "Find repeated shapes across sessions: trapped decisions, orphaned artifacts, missing owner, repeated work, source gaps, tooling mismatch, unverified outcomes, handoff friction, and unclaimed business signals.",
7121
+ return_when: "The same pattern appears across multiple sessions, days, tools, actors, or product surfaces."
7122
+ }
7123
+ ],
7124
+ required_output: {
7125
+ schema_version: WORK_GRAPH_EXTRACTION_SCHEMA_VERSION,
7126
+ extraction_id: "stable id for this extraction run",
7127
+ source_client: "codex | claude | claude-code | cursor | openclaw | slack | mcp | github | linear | manual | api | unknown",
7128
+ source_label: "human-readable source label",
7129
+ searched_sources: ["session/log/source group names searched"],
7130
+ search_queries: [
7131
+ {
7132
+ id: "decisions",
7133
+ lens: "Decision trails",
7134
+ query: "query actually used",
7135
+ result_count: 0
7136
+ }
7137
+ ],
7138
+ extraction_quality: {
7139
+ confidence: 0,
7140
+ searched_session_count: 0,
7141
+ skipped_session_count: 0,
7142
+ notes: ["limits, permissions, or gaps"]
7143
+ },
7144
+ findings: [
7145
+ {
7146
+ type: "decision | artifact | blocker | person | business | product_surface | goal | action | initiative_candidate | missed_orchestration_opportunity",
7147
+ title: "short durable title, not a raw line",
7148
+ summary: "one sentence explaining why this matters",
7149
+ source_id: "session/tool/source id",
7150
+ source_label: "source label",
7151
+ evidence_ref: "stable evidence pointer",
7152
+ confidence: 0,
7153
+ occurred_at: "ISO timestamp if known",
7154
+ actor_id: "redacted actor id if known",
7155
+ redacted_verbatim: "short supporting excerpt only",
7156
+ privacy_state: "public | redacted | private",
7157
+ metadata: {
7158
+ related_entity_names: [],
7159
+ related_source_ids: [],
7160
+ recurrence_count: 0,
7161
+ state: "observed | inferred | verified | blocked | missing_evidence"
7162
+ }
7163
+ }
7164
+ ]
7165
+ },
7166
+ quality_bar: [
7167
+ "Search broadly before summarizing; do not stop at the newest session if older sessions contain recurrence.",
7168
+ "Every finding must include a source id or evidence ref.",
7169
+ "A trail starts only from evidence-bearing work signals, not empty labels, code type signatures, tool catalogs, or guardrail text.",
7170
+ "Prefer fewer, higher-confidence findings over many shallow lines.",
7171
+ "Include negative evidence when OrgX/MCP was available but not called.",
7172
+ "Separate actual tool calls from textual mentions of tool names.",
7173
+ "Mark confidence below 0.6 when the finding is inferred from weak or single-source evidence.",
7174
+ "Do not emit raw JSON tool payloads; summarize the tool result into a blocker/artifact/outcome finding."
7175
+ ],
7176
+ reject_as_noise: [
7177
+ "AGENTS.md or system guardrail instructions.",
7178
+ "Source-code paths and line-number references unless the code change itself is the artifact.",
7179
+ "Bare labels like Decision:, Receipt:, Impact:, or proof: {.",
7180
+ "Type signatures such as outcome: string; or decision: ReviewableDecision;",
7181
+ "Tool catalogs and lists of available MCP tools.",
7182
+ "Planning narration like let me check, now I will inspect, or I need to verify.",
7183
+ "Generic MCP/AI commentary without a concrete work event."
7184
+ ]
7185
+ };
7186
+ const prompt = [
7187
+ "You are generating an OrgX Work Graph extraction from your own AI-client session/search logs.",
7188
+ "Search across available local sessions, transcripts, tool-call logs, hook events, and source indexes using every lens in the schema.",
7189
+ "Return JSON only. Match the required_output shape exactly. Do not return raw transcripts.",
7190
+ "The output will initiate Work Graph Trails, so every finding must be evidence-bearing and useful enough for a human to inspect."
7191
+ ].join(" ");
7192
+ return {
7193
+ schema_version: WORK_GRAPH_EXTRACTION_SCHEMA_VERSION,
7194
+ mode: "ai_client_session_search",
7195
+ prompt,
7196
+ schema
7197
+ };
7198
+ }
6942
7199
  function findingTypeForItem(item) {
6943
7200
  switch (item.type) {
6944
7201
  case "decision":
@@ -6961,8 +7218,19 @@ function evidenceRefFor(sourceId, index) {
6961
7218
  function includesAny2(text2, patterns) {
6962
7219
  return patterns.some((pattern) => pattern.test(text2));
6963
7220
  }
6964
- function buildCoverage(imports, connectedSources, missingSources) {
6965
- const allText = imports.map((source) => source.text).join("\n").toLowerCase();
7221
+ function buildCoverage(imports, connectedSources, missingSources, clientExtractions = []) {
7222
+ const extractionText = clientExtractions.flatMap((extraction) => [
7223
+ extraction.source_client,
7224
+ extraction.source_label ?? "",
7225
+ ...extraction.searched_sources ?? [],
7226
+ ...(extraction.findings ?? []).flatMap((finding) => [
7227
+ finding.title,
7228
+ finding.summary,
7229
+ finding.redacted_verbatim ?? ""
7230
+ ])
7231
+ ]).join("\n");
7232
+ const allText = `${imports.map((source) => source.text).join("\n")}
7233
+ ${extractionText}`.toLowerCase();
6966
7234
  const orgxObserved = /\borgx\b|useorgx|mcp__orgx__|orgx_/i.test(allText);
6967
7235
  const mcpObserved = /\bmcp\b|mcp__|tool call|tools\/call|call_tool|orgx_emit_activity/i.test(allText);
6968
7236
  const orgxMcpCalled = /mcp__orgx__|orgx_emit_activity|orgx_apply_changeset|complete_with_proof|scaffold_initiative/i.test(allText);
@@ -6976,6 +7244,75 @@ function buildCoverage(imports, connectedSources, missingSources) {
6976
7244
  skillOnlySignal
6977
7245
  };
6978
7246
  }
7247
+ function summarizeClientExtractions(clientExtractions) {
7248
+ return clientExtractions.map((extraction, index) => {
7249
+ const extractionId = normalizeClientExtractionId(extraction, index);
7250
+ return {
7251
+ extraction_id: extractionId,
7252
+ source_client: normalizeSourceClient(extraction.source_client),
7253
+ source_label: extraction.source_label?.trim() || `${extraction.source_client || "Unknown"} AI-client extraction`,
7254
+ searched_source_count: extraction.searched_sources?.length ?? 0,
7255
+ query_count: extraction.search_queries?.length ?? 0,
7256
+ finding_count: extraction.findings.length,
7257
+ confidence: normalizeConfidence(extraction.extraction_quality?.confidence, 0.74)
7258
+ };
7259
+ });
7260
+ }
7261
+ function buildClientExtractionEvents(clientExtractions) {
7262
+ return summarizeClientExtractions(clientExtractions).map((summary) => ({
7263
+ schema_version: WORK_GRAPH_SCHEMA_VERSION,
7264
+ source_client: summary.source_client,
7265
+ source_id: summary.extraction_id,
7266
+ source_label: summary.source_label,
7267
+ event_type: "client_extraction",
7268
+ text: [
7269
+ `${summary.finding_count} structured findings extracted by ${summary.source_client}.`,
7270
+ `${summary.query_count} search queries across ${summary.searched_source_count} searched source groups.`,
7271
+ `Extraction confidence: ${summary.confidence}.`
7272
+ ].join(" "),
7273
+ evidence_ref: `${summary.extraction_id}:summary`,
7274
+ metadata: {
7275
+ finding_count: summary.finding_count,
7276
+ query_count: summary.query_count,
7277
+ searched_source_count: summary.searched_source_count,
7278
+ raw_transcript_sent: false
7279
+ }
7280
+ }));
7281
+ }
7282
+ function buildClientExtractionFindings(clientExtractions) {
7283
+ const findings = [];
7284
+ clientExtractions.forEach((extraction, extractionIndex) => {
7285
+ const extractionId = normalizeClientExtractionId(extraction, extractionIndex);
7286
+ const sourceClient = normalizeSourceClient(extraction.source_client);
7287
+ const sourceLabel = extraction.source_label?.trim() || `${sourceClient} AI-client extraction`;
7288
+ extraction.findings.forEach((finding, findingIndex) => {
7289
+ const type = normalizeFindingType(finding.type);
7290
+ const title = finding.title?.trim();
7291
+ const summary = finding.summary?.trim();
7292
+ if (!type || !title || !summary) return;
7293
+ findings.push({
7294
+ type,
7295
+ title: title.slice(0, 180),
7296
+ summary,
7297
+ source_client: sourceClient,
7298
+ source_id: finding.source_id?.trim() || extractionId,
7299
+ evidence_ref: finding.evidence_ref?.trim() || `${extractionId}:F${findingIndex + 1}`,
7300
+ confidence: normalizeConfidence(finding.confidence, normalizeConfidence(extraction.extraction_quality?.confidence, 0.76)),
7301
+ metadata: {
7302
+ source_label: finding.source_label?.trim() || sourceLabel,
7303
+ extraction_id: extractionId,
7304
+ schema_version: extraction.schema_version ?? null,
7305
+ occurred_at: finding.occurred_at ?? null,
7306
+ actor_id: finding.actor_id ?? null,
7307
+ redacted_verbatim: finding.redacted_verbatim ?? null,
7308
+ privacy_state: finding.privacy_state ?? "redacted",
7309
+ ...finding.metadata ?? {}
7310
+ }
7311
+ });
7312
+ });
7313
+ });
7314
+ return findings;
7315
+ }
6979
7316
  function buildDerivedFindings(imports) {
6980
7317
  const findings = [];
6981
7318
  let derivedIndex = 0;
@@ -7746,17 +8083,26 @@ function buildWorkGraphFingerprint(input) {
7746
8083
  };
7747
8084
  }
7748
8085
  function buildSessionReconciliationReport(input) {
7749
- if (input.imports.length === 0) {
7750
- throw new Error("At least one source import is required to build a Work Graph report.");
8086
+ const clientExtractions = input.clientExtractions ?? [];
8087
+ if (input.imports.length === 0 && clientExtractions.length === 0) {
8088
+ throw new Error("At least one source import or AI-client extraction is required to build a Work Graph report.");
7751
8089
  }
7752
8090
  const generatedAt = input.generatedAt ?? (/* @__PURE__ */ new Date()).toISOString();
7753
- const connectedSources = input.connectedSources ?? input.imports.map((source) => source.sourceLabel);
8091
+ const clientExtractionSummaries = summarizeClientExtractions(clientExtractions);
8092
+ const connectedSources = sortedUnique([
8093
+ ...input.connectedSources ?? input.imports.map((source) => source.sourceLabel),
8094
+ ...clientExtractionSummaries.map((summary) => summary.source_label)
8095
+ ]);
7754
8096
  const missingSources = input.missingSources ?? [];
7755
- const coverage = buildCoverage(input.imports, connectedSources, missingSources);
7756
- const events = buildWorkGraphEvents(input.imports);
7757
- const findings = buildWorkGraphFindings(input.imports);
7758
- const missed = buildMissedOpportunities(coverage, findings);
7759
- const allFindings = [...findings, ...missed];
8097
+ const coverage = buildCoverage(input.imports, connectedSources, missingSources, clientExtractions);
8098
+ const events = [...buildWorkGraphEvents(input.imports), ...buildClientExtractionEvents(clientExtractions)];
8099
+ const findings = [...buildWorkGraphFindings(input.imports), ...buildClientExtractionFindings(clientExtractions)];
8100
+ const autoMissed = buildMissedOpportunities(coverage, findings);
8101
+ const extractedMissed = findings.filter((finding) => finding.type === "missed_orchestration_opportunity");
8102
+ const missed = [...extractedMissed, ...autoMissed].filter(
8103
+ (finding, index, all) => all.findIndex((candidate) => candidate.evidence_ref === finding.evidence_ref) === index
8104
+ );
8105
+ const allFindings = [...findings, ...autoMissed];
7760
8106
  const trails = buildWorkGraphTrails(allFindings, generatedAt);
7761
8107
  const recurringPatterns = buildRecurringPatterns(coverage, allFindings, trails);
7762
8108
  const opportunityScore = scoreOpportunity(coverage, allFindings);
@@ -7785,6 +8131,10 @@ function buildSessionReconciliationReport(input) {
7785
8131
  });
7786
8132
  const reportSeed = {
7787
8133
  generatedAt,
8134
+ clientExtractions: clientExtractions.map((extraction, index) => ({
8135
+ extractionId: normalizeClientExtractionId(extraction, index),
8136
+ findingHash: hashJson(extraction.findings)
8137
+ })),
7788
8138
  imports: input.imports.map((source) => ({
7789
8139
  sourceId: source.sourceId,
7790
8140
  textHash: hashJson(source.text)
@@ -7805,6 +8155,8 @@ function buildSessionReconciliationReport(input) {
7805
8155
  source_client: "wizard",
7806
8156
  session_id: sessionId,
7807
8157
  workspace: input.workspace,
8158
+ extraction_protocol: buildWorkGraphExtractionProtocol(),
8159
+ client_extractions: clientExtractionSummaries,
7808
8160
  source_coverage: coverage,
7809
8161
  final_state: inferFinalState(allFindings),
7810
8162
  events,
@@ -7821,6 +8173,46 @@ function buildSessionReconciliationReport(input) {
7821
8173
  raw_transcripts_sent: false
7822
8174
  };
7823
8175
  }
8176
+ function renderWorkGraphExtractionProtocolMarkdown(protocol = buildWorkGraphExtractionProtocol()) {
8177
+ const lines = [];
8178
+ lines.push("# OrgX Work Graph AI-Client Extraction Schema");
8179
+ lines.push("");
8180
+ lines.push(`Schema version: ${protocol.schema_version}`);
8181
+ lines.push(`Mode: ${protocol.mode}`);
8182
+ lines.push("");
8183
+ lines.push("## Prompt");
8184
+ lines.push("");
8185
+ lines.push(protocol.prompt);
8186
+ lines.push("");
8187
+ lines.push("## Objective");
8188
+ lines.push("");
8189
+ lines.push(protocol.schema.objective);
8190
+ lines.push("");
8191
+ lines.push("## Search Lenses");
8192
+ lines.push("");
8193
+ for (const lens of protocol.schema.source_search_strategy) {
8194
+ lines.push(`- ${lens.lens}: ${lens.query} Return when: ${lens.return_when}`);
8195
+ }
8196
+ lines.push("");
8197
+ lines.push("## Quality Bar");
8198
+ lines.push("");
8199
+ for (const item of protocol.schema.quality_bar) {
8200
+ lines.push(`- ${item}`);
8201
+ }
8202
+ lines.push("");
8203
+ lines.push("## Reject As Noise");
8204
+ lines.push("");
8205
+ for (const item of protocol.schema.reject_as_noise) {
8206
+ lines.push(`- ${item}`);
8207
+ }
8208
+ lines.push("");
8209
+ lines.push("## Required JSON Shape");
8210
+ lines.push("");
8211
+ lines.push("```json");
8212
+ lines.push(JSON.stringify(protocol.schema.required_output, null, 2));
8213
+ lines.push("```");
8214
+ return lines.join("\n");
8215
+ }
7824
8216
  function renderWorkGraphMarkdown(report) {
7825
8217
  const lines = [];
7826
8218
  lines.push("# OrgX Work Graph Reconciliation");
@@ -7832,6 +8224,26 @@ function renderWorkGraphMarkdown(report) {
7832
8224
  lines.push(`Hydration key: ${report.signup_hydration.hydration_key}`);
7833
8225
  lines.push(`Final state: ${report.final_state}`);
7834
8226
  lines.push("");
8227
+ lines.push("## AI-Client Search Protocol");
8228
+ lines.push("");
8229
+ lines.push(`Schema: ${report.extraction_protocol.schema_version}`);
8230
+ lines.push(report.extraction_protocol.prompt);
8231
+ lines.push("");
8232
+ lines.push("Search lenses:");
8233
+ for (const lens of report.extraction_protocol.schema.source_search_strategy) {
8234
+ lines.push(`- ${lens.lens}: ${lens.return_when}`);
8235
+ }
8236
+ lines.push("");
8237
+ lines.push("## Client Extractions");
8238
+ lines.push("");
8239
+ if (report.client_extractions.length === 0) {
8240
+ lines.push("- No structured AI-client extraction files were provided; fallback local session import was used.");
8241
+ } else {
8242
+ for (const extraction of report.client_extractions) {
8243
+ lines.push(`- ${extraction.source_label}: ${extraction.finding_count} findings, ${extraction.query_count} queries, ${extraction.searched_source_count} source groups, confidence ${extraction.confidence}`);
8244
+ }
8245
+ }
8246
+ lines.push("");
7835
8247
  lines.push("## Opportunity Score");
7836
8248
  lines.push("");
7837
8249
  lines.push(`Overall: ${report.opportunity_score.overall}/100`);
@@ -8380,6 +8792,29 @@ function parsePositiveInteger(value, fallback, label) {
8380
8792
  }
8381
8793
  return parsed;
8382
8794
  }
8795
+ function collectPathOption(value, previous = []) {
8796
+ return [
8797
+ ...previous,
8798
+ ...value.split(",").map((item) => item.trim()).filter(Boolean)
8799
+ ];
8800
+ }
8801
+ function parseClientExtractionFile(path) {
8802
+ const resolvedPath = resolve(path);
8803
+ const parsed = JSON.parse(readFileSync5(resolvedPath, "utf8"));
8804
+ if (!isRecord(parsed)) {
8805
+ throw new Error(`AI-client extraction must be a JSON object: ${resolvedPath}`);
8806
+ }
8807
+ if (!Array.isArray(parsed.findings)) {
8808
+ throw new Error(`AI-client extraction must include findings[]: ${resolvedPath}`);
8809
+ }
8810
+ if (typeof parsed.source_client !== "string" || !parsed.source_client.trim()) {
8811
+ throw new Error(`AI-client extraction must include source_client: ${resolvedPath}`);
8812
+ }
8813
+ return parsed;
8814
+ }
8815
+ function readClientExtractions(options) {
8816
+ return (options.extraction ?? []).map(parseClientExtractionFile);
8817
+ }
8383
8818
  async function readAuditImports(options, interactive) {
8384
8819
  const sources = parseAiSessionSources(options.from);
8385
8820
  const imports = [];
@@ -8419,6 +8854,38 @@ async function readAuditImports(options, interactive) {
8419
8854
  missingSources
8420
8855
  };
8421
8856
  }
8857
+ async function readWorkGraphInputs(options, interactive) {
8858
+ const clientExtractions = readClientExtractions(options);
8859
+ const shouldReadSessionImports = Boolean(
8860
+ options.from?.trim() || options.input?.trim() || clientExtractions.length === 0 || !process.stdin.isTTY && clientExtractions.length === 0
8861
+ );
8862
+ if (!shouldReadSessionImports) {
8863
+ return {
8864
+ clientExtractions,
8865
+ connectedSources: [],
8866
+ imports: [],
8867
+ missingSources: []
8868
+ };
8869
+ }
8870
+ let auditImports;
8871
+ try {
8872
+ auditImports = await readAuditImports(options, interactive);
8873
+ } catch (error) {
8874
+ if (clientExtractions.length === 0) throw error;
8875
+ const message = error instanceof Error ? error.message : String(error);
8876
+ auditImports = {
8877
+ connectedSources: [],
8878
+ imports: [],
8879
+ missingSources: [`fallback session import: ${message}`]
8880
+ };
8881
+ }
8882
+ return {
8883
+ clientExtractions,
8884
+ connectedSources: auditImports.connectedSources,
8885
+ imports: auditImports.imports,
8886
+ missingSources: auditImports.missingSources
8887
+ };
8888
+ }
8422
8889
  function requireWriteApproval(options, interactive) {
8423
8890
  const wantsWrite = Boolean(options.createInitiative || options.attachToInitiative || options.writeFollowUp);
8424
8891
  if (!wantsWrite || options.yes || options.dryRun) return true;
@@ -8529,24 +8996,42 @@ async function runAuditCommand(options) {
8529
8996
  console.log(` ${ICON.ok} ${pc3.green("follow-up ")} ${pc3.bold(followUp.title)} ${pc3.dim(followUp.id)}`);
8530
8997
  }
8531
8998
  }
8999
+ function runWorkGraphExtractionSchemaCommand(options) {
9000
+ const protocol = buildWorkGraphExtractionProtocol();
9001
+ const outputPath = options.output?.trim() ? resolve(options.output.trim()) : "";
9002
+ if (outputPath) {
9003
+ if (options.json) {
9004
+ writeJsonFile(outputPath, protocol);
9005
+ } else {
9006
+ writeTextFile(outputPath, renderWorkGraphExtractionProtocolMarkdown(protocol));
9007
+ }
9008
+ }
9009
+ if (options.json) {
9010
+ console.log(JSON.stringify(protocol, null, 2));
9011
+ return;
9012
+ }
9013
+ const markdown = renderWorkGraphExtractionProtocolMarkdown(protocol);
9014
+ console.log(markdown);
9015
+ }
8532
9016
  async function runWorkGraphCommand(options, defaults = {}) {
8533
9017
  const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
8534
9018
  const commandOptions = {
8535
9019
  ...options,
8536
9020
  ...options.from?.trim() ? {} : defaults.from ? { from: defaults.from } : {}
8537
9021
  };
8538
- const auditImports = await readAuditImports(commandOptions, interactive);
9022
+ const auditInputs = await readWorkGraphInputs(commandOptions, interactive);
8539
9023
  const workspace = await resolveAuditWorkspace(commandOptions);
8540
9024
  const report = buildSessionReconciliationReport({
9025
+ clientExtractions: auditInputs.clientExtractions,
8541
9026
  connectedSources: [
8542
- ...auditImports.connectedSources,
9027
+ ...auditInputs.connectedSources,
8543
9028
  ...workspace.id === "local-workspace" ? [] : ["OrgX workspace"]
8544
9029
  ],
8545
9030
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
8546
- imports: auditImports.imports,
9031
+ imports: auditInputs.imports,
8547
9032
  missingSources: [
8548
9033
  ...workspace.id === "local-workspace" ? ["OrgX workspace auth"] : [],
8549
- ...auditImports.missingSources
9034
+ ...auditInputs.missingSources
8550
9035
  ],
8551
9036
  workspace
8552
9037
  });
@@ -8567,6 +9052,7 @@ async function runWorkGraphCommand(options, defaults = {}) {
8567
9052
  finalState: report.final_state,
8568
9053
  opportunityScore: report.opportunity_score,
8569
9054
  missedOrchestration: report.missed_orchestration_opportunities.length,
9055
+ clientExtractionCount: report.client_extractions.length,
8570
9056
  kickoffCount: report.initiative_kickoffs.length,
8571
9057
  trailCount: report.trails.length,
8572
9058
  recurringPatternCount: report.recurring_patterns.length,
@@ -8579,6 +9065,7 @@ async function runWorkGraphCommand(options, defaults = {}) {
8579
9065
  console.log(` ${ICON.ok} ${pc3.green("report id ")} ${pc3.dim(report.report_id)}`);
8580
9066
  console.log(` ${ICON.ok} ${pc3.green("fingerprint ")} ${pc3.dim(report.work_graph_fingerprint)}`);
8581
9067
  console.log(` ${ICON.ok} ${pc3.green("state ")} ${pc3.dim(report.final_state)}`);
9068
+ console.log(` ${ICON.ok} ${pc3.green("extractions ")} ${pc3.dim(String(report.client_extractions.length))}`);
8582
9069
  console.log(` ${ICON.ok} ${pc3.green("score ")} ${pc3.dim(formatWorkGraphScoreLine(report.opportunity_score))}`);
8583
9070
  const missed = report.missed_orchestration_opportunities.length;
8584
9071
  const missedColor = missed > 0 ? pc3.yellow : pc3.green;
@@ -9551,9 +10038,10 @@ function printDoctorReport(report, assessment) {
9551
10038
  async function main() {
9552
10039
  const program = new Command();
9553
10040
  program.name("orgx-wizard").description("Add OrgX MCP configs, skills/rules, and companion plugins to your local AI tools.").showHelpAfterError();
9554
- const pkgVersion = true ? "0.1.30" : void 0;
10041
+ const pkgVersion = true ? "0.1.32" : void 0;
9555
10042
  program.version(pkgVersion ?? "unknown", "-V, --version");
9556
- program.hook("preAction", () => {
10043
+ program.hook("preAction", (_thisCommand, actionCommand) => {
10044
+ if (Boolean(actionCommand.optsWithGlobals().json)) return;
9557
10045
  console.log(renderBanner(pkgVersion));
9558
10046
  });
9559
10047
  program.command("setup").description("Add OrgX MCP configs, skills/rules, and companion plugins to detected tools.").option("--preset <name>", "run a setup bundle (currently: founder)").option("--workspace", "choose or change the default workspace during setup").option("--daily-brief", "configure Daily Brief even if setup already handled it").option("--skip-daily-brief", "skip Daily Brief prompts and remember the skip").action(async (options) => {
@@ -10251,14 +10739,21 @@ async function main() {
10251
10739
  await runAuditCommand(options);
10252
10740
  });
10253
10741
  const workGraph = program.command("work-graph").description("Build a redacted OrgX Work Graph report from AI-client, Slack, MCP, or manual context.");
10254
- workGraph.command("preview").description("Preview the live Work Graph opportunity map without writing to OrgX.").option("--input <path>", "source transcript or summary file; stdin is used when piped").option("--from <sources>", "auto-import recent local AI sessions: codex, claude, 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 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) => {
10742
+ workGraph.command("extraction-schema").description("Print the AI-client search schema used to extract Work Graph Trails from sessions and logs.").option("--output <path>", "write the schema prompt to a file").option("--json", "emit the protocol as JSON instead of Markdown").action(async (options) => {
10743
+ await safeTrackWizardTelemetry("work_graph_extraction_schema_started", {
10744
+ command: "work-graph extraction-schema",
10745
+ json: Boolean(options.json)
10746
+ });
10747
+ runWorkGraphExtractionSchemaCommand(options);
10748
+ });
10749
+ workGraph.command("preview").description("Preview the live Work Graph opportunity map 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: codex, claude, 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 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) => {
10255
10750
  await safeTrackWizardTelemetry("work_graph_preview_started", {
10256
10751
  command: "work-graph preview",
10257
10752
  from: options.from ?? "manual"
10258
10753
  });
10259
10754
  await runWorkGraphCommand(options);
10260
10755
  });
10261
- workGraph.command("profile").description("Build a local OrgX Profile with Work Graph Trails, Mirror, tensions, and launch recommendations.").option("--input <path>", "source transcript or summary file; stdin is used when piped").option("--from <sources>", "auto-import recent local AI sessions: codex, claude, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "5").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("--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("--json", "emit a JSON command summary").action(async (options) => {
10756
+ workGraph.command("profile").description("Build a local OrgX Profile with Work Graph Trails, Mirror, tensions, and launch 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: codex, claude, or all").option("--session-limit <count>", "max recent sessions to import per selected source", "5").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("--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("--json", "emit a JSON command summary").action(async (options) => {
10262
10757
  await safeTrackWizardTelemetry("work_graph_profile_started", {
10263
10758
  command: "work-graph profile",
10264
10759
  from: options.from ?? "manual"
@@ -10266,7 +10761,7 @@ async function main() {
10266
10761
  await runWorkGraphCommand(options);
10267
10762
  });
10268
10763
  const sessions = program.command("sessions").description("Inspect and reconcile local AI sessions into OrgX-ready Work Graph reports.");
10269
- sessions.command("reconcile").description("Backfill recent Codex and Claude sessions into a redacted Work Graph report.").option("--from <sources>", "auto-import recent local AI sessions: codex, claude, or all", "all").option("--session-limit <count>", "max recent sessions to import per selected source", "5").option("--session-days <days>", "lookback window for local AI-session imports", "7").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("--json", "emit a JSON command summary").action(async (options) => {
10764
+ sessions.command("reconcile").description("Backfill recent Codex and Claude sessions into a redacted Work Graph 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: codex, claude, or all", "all").option("--session-limit <count>", "max recent sessions to import per selected source", "5").option("--session-days <days>", "lookback window for local AI-session imports", "7").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("--json", "emit a JSON command summary").action(async (options) => {
10270
10765
  await safeTrackWizardTelemetry("sessions_reconcile_started", {
10271
10766
  command: "sessions reconcile",
10272
10767
  from: options.from ?? "all"