@useorgx/wizard 0.1.66 → 0.1.68

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
@@ -2,12 +2,12 @@
2
2
 
3
3
  // src/cli.ts
4
4
 
5
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="783f771d-d176-55f3-b036-2be49833854e")}catch(e){}}();
5
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4b5dd32d-184b-560a-ae80-e8a055ae1bc4")}catch(e){}}();
6
6
  import * as clack from "@clack/prompts";
7
7
  import { spawnSync as spawnSync5 } from "child_process";
8
8
  import { readFileSync as readFileSync10 } from "fs";
9
9
  import { hostname } from "os";
10
- import { resolve as resolve4 } from "path";
10
+ import { resolve as resolve5 } from "path";
11
11
  import { Command } from "commander";
12
12
  import pc3 from "picocolors";
13
13
 
@@ -837,7 +837,7 @@ function parsePairingPollResult(value) {
837
837
  };
838
838
  }
839
839
  function sleep(ms) {
840
- return new Promise((resolve5) => setTimeout(resolve5, ms));
840
+ return new Promise((resolve6) => setTimeout(resolve6, ms));
841
841
  }
842
842
  async function startBrowserPairing(options, fetchImpl) {
843
843
  const data = await fetchJson({
@@ -950,12 +950,12 @@ h1{font-size:1.5rem;color:#b91c1c}p{color:#555;margin-top:.5rem}</style>
950
950
  <p>Return to your terminal and try again.</p>
951
951
  </div></body></html>`;
952
952
  function tryListen(port, hostname2) {
953
- return new Promise((resolve5, reject) => {
953
+ return new Promise((resolve6, reject) => {
954
954
  const server = createServer();
955
955
  server.once("error", reject);
956
956
  server.listen(port, hostname2, () => {
957
957
  server.removeListener("error", reject);
958
- resolve5(server);
958
+ resolve6(server);
959
959
  });
960
960
  });
961
961
  }
@@ -984,7 +984,7 @@ async function startLocalAuthServer(options) {
984
984
  const successHtml = options.successHtml ?? DEFAULT_SUCCESS_HTML;
985
985
  const errorHtml = options.errorHtml ?? DEFAULT_ERROR_HTML;
986
986
  const { server, port } = await bindServer(options.preferredPort, hostname2);
987
- const result = new Promise((resolve5, reject) => {
987
+ const result = new Promise((resolve6, reject) => {
988
988
  const timer = setTimeout(() => {
989
989
  server.close();
990
990
  reject(new Error("Timed out waiting for browser authorization."));
@@ -1027,7 +1027,7 @@ async function startLocalAuthServer(options) {
1027
1027
  res.writeHead(200, { "Content-Type": "text/html" }).end(successHtml);
1028
1028
  clearTimeout(timer);
1029
1029
  server.close();
1030
- resolve5({ code, state });
1030
+ resolve6({ code, state });
1031
1031
  });
1032
1032
  });
1033
1033
  return { port, result };
@@ -4013,7 +4013,7 @@ function formatCommandFailure(command, args, result) {
4013
4013
  return `${command} ${args.join(" ")} failed${result.exitCode >= 0 ? ` with exit code ${result.exitCode}` : ""}${detail ? `: ${detail}` : "."}`;
4014
4014
  }
4015
4015
  async function defaultCommandRunner(command, args) {
4016
- return await new Promise((resolve5) => {
4016
+ return await new Promise((resolve6) => {
4017
4017
  const child = spawn(command, [...args], {
4018
4018
  env: process.env,
4019
4019
  stdio: ["ignore", "pipe", "pipe"]
@@ -4028,7 +4028,7 @@ async function defaultCommandRunner(command, args) {
4028
4028
  });
4029
4029
  child.on("error", (error) => {
4030
4030
  const errorCode2 = typeof error === "object" && error && "code" in error ? String(error.code) : void 0;
4031
- resolve5({
4031
+ resolve6({
4032
4032
  exitCode: -1,
4033
4033
  stdout,
4034
4034
  stderr,
@@ -4036,7 +4036,7 @@ async function defaultCommandRunner(command, args) {
4036
4036
  });
4037
4037
  });
4038
4038
  child.on("close", (code) => {
4039
- resolve5({
4039
+ resolve6({
4040
4040
  exitCode: code ?? -1,
4041
4041
  stdout,
4042
4042
  stderr
@@ -6354,7 +6354,7 @@ function initializeWizardSentry() {
6354
6354
  Sentry.init({
6355
6355
  dsn,
6356
6356
  environment: process.env.ORGX_SENTRY_ENVIRONMENT || "production",
6357
- release: "useorgx-wizard@0.1.66",
6357
+ release: "useorgx-wizard@0.1.68",
6358
6358
  tracesSampleRate: sampleRate(process.env.ORGX_SENTRY_TRACES_SAMPLE_RATE),
6359
6359
  enableLogs: true,
6360
6360
  sendDefaultPii: false,
@@ -13766,9 +13766,9 @@ function buildWorkGraphHookReplayPatch(readResult) {
13766
13766
  }
13767
13767
 
13768
13768
  // src/lib/runtime-hooks.ts
13769
- import { copyFileSync, existsSync as existsSync9, mkdirSync as mkdirSync4, readdirSync as readdirSync6 } from "fs";
13770
- import { homedir as homedir3 } from "os";
13771
- import { dirname as dirname5, join as join8, resolve as resolve2 } from "path";
13769
+ import { copyFileSync, existsSync as existsSync10, mkdirSync as mkdirSync4, readdirSync as readdirSync6 } from "fs";
13770
+ import { homedir as homedir4 } from "os";
13771
+ import { dirname as dirname6, join as join9, resolve as resolve3 } from "path";
13772
13772
 
13773
13773
  // src/lib/session-summary-hook.ts
13774
13774
  var SESSION_SUMMARY_HOOK_MARKER = "orgx-session-summary.mjs";
@@ -14535,6 +14535,141 @@ if (invokedDirectly) {
14535
14535
  `;
14536
14536
  }
14537
14537
 
14538
+ // src/lib/client-continuity.ts
14539
+ import { existsSync as existsSync9 } from "fs";
14540
+ import { homedir as homedir3 } from "os";
14541
+ import { dirname as dirname5, join as join8, resolve as resolve2 } from "path";
14542
+ var CLIENT_CONTINUITY_SCHEMA_VERSION = "orgx-client-continuity/v1";
14543
+ function readJson(path) {
14544
+ return parseJsonObject(readTextIfExists(path));
14545
+ }
14546
+ function string(value) {
14547
+ return typeof value === "string" && value.trim() ? value.trim() : null;
14548
+ }
14549
+ function sharedCaptureReady(options) {
14550
+ return options.shared.summaryHookInstalled && options.shared.automaticDelivery;
14551
+ }
14552
+ function sharedNextAction(options) {
14553
+ return sharedCaptureReady(options) ? null : "Run orgx-wizard hooks install --targets all, then re-run hooks doctor --json.";
14554
+ }
14555
+ function wizardHookStatus(client, installed, options) {
14556
+ const captureReady = installed && sharedCaptureReady(options);
14557
+ const warnings = [
14558
+ ...!installed ? [`${client} runtime hooks are not installed.`] : [],
14559
+ ...!options.shared.summaryHookInstalled ? ["The shared bounded session-summary hook is missing."] : [],
14560
+ ...!options.shared.automaticDelivery ? ["ACK-gated automatic delivery is not configured."] : []
14561
+ ];
14562
+ return {
14563
+ client,
14564
+ state: captureReady ? "ready" : installed ? "attention_required" : "not_installed",
14565
+ installed,
14566
+ adapterVersion: null,
14567
+ captureReady,
14568
+ terminalBoundary: "session_end",
14569
+ warnings,
14570
+ nextAction: captureReady ? null : installed ? sharedNextAction(options) : `Run orgx-wizard hooks install --targets ${client}, then re-run hooks doctor --json.`
14571
+ };
14572
+ }
14573
+ function cursorStatus(paths, options) {
14574
+ const manifest = readJson(paths.cursorManifestPath);
14575
+ const hooks = readJson(paths.cursorHooksPath);
14576
+ const hookMap = hooks.hooks && typeof hooks.hooks === "object" && !Array.isArray(hooks.hooks) ? hooks.hooks : {};
14577
+ const installed = existsSync9(paths.cursorManifestPath) && existsSync9(paths.cursorHooksPath);
14578
+ const hasRunBoundary = ["afterAgentResponse", "stop", "sessionEnd"].every(
14579
+ (name) => Array.isArray(hookMap[name]) && hookMap[name].length > 0
14580
+ );
14581
+ const captureReady = installed && hasRunBoundary && sharedCaptureReady(options);
14582
+ const warnings = [
14583
+ ...!installed ? ["The managed Cursor companion plugin is not installed."] : [],
14584
+ ...installed && !hasRunBoundary ? ["Cursor is missing one or more terminal receipt hooks."] : [],
14585
+ ...!options.shared.summaryHookInstalled ? ["The shared bounded session-summary hook is missing."] : [],
14586
+ ...!options.shared.automaticDelivery ? ["ACK-gated automatic delivery is not configured."] : []
14587
+ ];
14588
+ return {
14589
+ client: "cursor",
14590
+ state: captureReady ? "ready" : installed ? "attention_required" : "not_installed",
14591
+ installed,
14592
+ adapterVersion: string(manifest.version),
14593
+ captureReady,
14594
+ terminalBoundary: "stop/session_end (afterAgentResponse CLI fallback)",
14595
+ warnings,
14596
+ nextAction: captureReady ? null : !installed || !hasRunBoundary ? "Run orgx-wizard plugins add cursor, reload Cursor, then re-run hooks doctor --json." : sharedNextAction(options)
14597
+ };
14598
+ }
14599
+ function openCodeStatus(paths, options) {
14600
+ const packageJson = readJson(paths.openCodePackagePath);
14601
+ const packageName = string(packageJson.name);
14602
+ const entry = string(packageJson.main) ?? "dist/index.js";
14603
+ const entryPath = resolve2(dirname5(paths.openCodePackagePath), entry);
14604
+ const bridgePath = join8(dirname5(entryPath), "sessionSummaryBridge.js");
14605
+ const bridge = readTextIfExists(bridgePath);
14606
+ const installed = packageName === "@useorgx/orgx-opencode-plugin" && existsSync9(entryPath);
14607
+ const hasRunBoundary = Boolean(
14608
+ bridge?.includes("session.idle") && bridge.includes("RunEnd")
14609
+ );
14610
+ const captureReady = installed && hasRunBoundary && sharedCaptureReady(options);
14611
+ const warnings = [
14612
+ ...!installed ? ["The stable OrgX OpenCode plugin entry point is not installed."] : [],
14613
+ ...installed && !hasRunBoundary ? ["OpenCode is missing the session.idle to RunEnd bridge."] : [],
14614
+ ...!options.shared.summaryHookInstalled ? ["The shared bounded session-summary hook is missing."] : [],
14615
+ ...!options.shared.automaticDelivery ? ["ACK-gated automatic delivery is not configured."] : []
14616
+ ];
14617
+ return {
14618
+ client: "opencode",
14619
+ state: captureReady ? "ready" : installed ? "attention_required" : "not_installed",
14620
+ installed,
14621
+ adapterVersion: string(packageJson.version),
14622
+ captureReady,
14623
+ terminalBoundary: "session.idle -> run_end",
14624
+ warnings,
14625
+ nextAction: captureReady ? null : !installed || !hasRunBoundary ? "Install the current @useorgx/orgx-opencode-plugin alpha package, then re-run hooks doctor --json." : sharedNextAction(options)
14626
+ };
14627
+ }
14628
+ function clientContinuityPathsForHome(home = homedir3()) {
14629
+ return {
14630
+ cursorManifestPath: join8(
14631
+ home,
14632
+ ".cursor",
14633
+ "plugins",
14634
+ "local",
14635
+ "cursor-plugin",
14636
+ ".cursor-plugin",
14637
+ "plugin.json"
14638
+ ),
14639
+ cursorHooksPath: join8(
14640
+ home,
14641
+ ".cursor",
14642
+ "plugins",
14643
+ "local",
14644
+ "cursor-plugin",
14645
+ "hooks",
14646
+ "hooks.json"
14647
+ ),
14648
+ openCodePackagePath: join8(
14649
+ home,
14650
+ ".config",
14651
+ "opencode",
14652
+ "plugins",
14653
+ "orgx-opencode-plugin",
14654
+ "package.json"
14655
+ )
14656
+ };
14657
+ }
14658
+ function inspectClientContinuity(options) {
14659
+ const paths = { ...clientContinuityPathsForHome(), ...options.paths };
14660
+ const clients = [
14661
+ wizardHookStatus("claude-code", options.shared.claudeCodeInstalled, options),
14662
+ wizardHookStatus("codex", options.shared.codexInstalled, options),
14663
+ cursorStatus(paths, options),
14664
+ openCodeStatus(paths, options)
14665
+ ];
14666
+ return {
14667
+ schemaVersion: CLIENT_CONTINUITY_SCHEMA_VERSION,
14668
+ state: clients.every((client) => client.captureReady) ? "ready" : "attention_required",
14669
+ clients
14670
+ };
14671
+ }
14672
+
14538
14673
  // src/lib/runtime-hooks.ts
14539
14674
  var HOOK_MARKER = "orgx-session-hook.mjs";
14540
14675
  var EMIT_HOOK_MARKER = "orgx-emit-execution-graph.mjs";
@@ -14561,23 +14696,23 @@ var CLAUDE_HOOK_EVENTS = [
14561
14696
  ];
14562
14697
  function currentPackagedCliPath() {
14563
14698
  if (!process.argv[1]) return "";
14564
- const candidate = resolve2(process.argv[1]);
14699
+ const candidate = resolve3(process.argv[1]);
14565
14700
  return /\.(?:cts|mts|ts|tsx)$/i.test(candidate) ? "" : candidate;
14566
14701
  }
14567
14702
  function defaultPaths(options = {}) {
14568
- const hookDir = join8(ORGX_WIZARD_CONFIG_HOME, "hooks");
14703
+ const hookDir = join9(ORGX_WIZARD_CONFIG_HOME, "hooks");
14569
14704
  return {
14570
- claudeSettingsPath: options.claudeSettingsPath ?? join8(CLAUDE_DIR, "settings.json"),
14571
- codexConfigPath: options.codexConfigPath ?? CODEX_CONFIG_PATH ?? join8(CODEX_DIR, "config.toml"),
14572
- codexHooksPath: options.codexHooksPath ?? join8(CODEX_DIR, "hooks.json"),
14573
- hookScriptPath: options.hookScriptPath ?? join8(hookDir, HOOK_MARKER),
14574
- emitHookScriptPath: options.emitHookScriptPath ?? join8(hookDir, EMIT_HOOK_MARKER),
14575
- summaryHookScriptPath: options.summaryHookScriptPath ?? join8(hookDir, SUMMARY_HOOK_MARKER),
14576
- sessionStateDir: options.sessionStateDir ?? join8(ORGX_WIZARD_CONFIG_HOME, "sessions"),
14577
- sessionSummaryQueueDir: options.sessionSummaryQueueDir ?? join8(ORGX_WIZARD_CONFIG_HOME, "session-summary-captures"),
14705
+ claudeSettingsPath: options.claudeSettingsPath ?? join9(CLAUDE_DIR, "settings.json"),
14706
+ codexConfigPath: options.codexConfigPath ?? CODEX_CONFIG_PATH ?? join9(CODEX_DIR, "config.toml"),
14707
+ codexHooksPath: options.codexHooksPath ?? join9(CODEX_DIR, "hooks.json"),
14708
+ hookScriptPath: options.hookScriptPath ?? join9(hookDir, HOOK_MARKER),
14709
+ emitHookScriptPath: options.emitHookScriptPath ?? join9(hookDir, EMIT_HOOK_MARKER),
14710
+ summaryHookScriptPath: options.summaryHookScriptPath ?? join9(hookDir, SUMMARY_HOOK_MARKER),
14711
+ sessionStateDir: options.sessionStateDir ?? join9(ORGX_WIZARD_CONFIG_HOME, "sessions"),
14712
+ sessionSummaryQueueDir: options.sessionSummaryQueueDir ?? join9(ORGX_WIZARD_CONFIG_HOME, "session-summary-captures"),
14578
14713
  deliveryNodePath: options.deliveryNodePath ?? process.execPath,
14579
14714
  deliveryCliPath: options.deliveryCliPath ?? currentPackagedCliPath(),
14580
- outboxPath: options.outboxPath ?? join8(hookDir, "events.jsonl")
14715
+ outboxPath: options.outboxPath ?? join9(hookDir, "events.jsonl")
14581
14716
  };
14582
14717
  }
14583
14718
  function countJsonlLines(path) {
@@ -14594,7 +14729,7 @@ function countSessionSummaryCaptures(path) {
14594
14729
  }
14595
14730
  function countSessionSummaryQuarantinedCaptures(path) {
14596
14731
  try {
14597
- return readdirSync6(join8(path, "quarantine")).filter(
14732
+ return readdirSync6(join9(path, "quarantine")).filter(
14598
14733
  (name) => name.includes(".malformed")
14599
14734
  ).length;
14600
14735
  } catch {
@@ -14606,7 +14741,7 @@ function backupPath(path, now) {
14606
14741
  return `${path}.bak.${timestamp}`;
14607
14742
  }
14608
14743
  function backupExisting(path, now) {
14609
- if (!existsSync9(path)) return null;
14744
+ if (!existsSync10(path)) return null;
14610
14745
  const backup = backupPath(path, now);
14611
14746
  copyFileSync(path, backup);
14612
14747
  return backup;
@@ -15117,18 +15252,28 @@ function inspectRuntimeHooks(options = {}) {
15117
15252
  const codexHooksRaw = readTextIfExists(paths.codexHooksPath);
15118
15253
  const claudeSettingsRaw = readTextIfExists(paths.claudeSettingsPath);
15119
15254
  const hasAutomaticDelivery = (raw) => Boolean(
15120
- raw && raw.includes("--delivery_node=") && raw.includes("--delivery_cli=") && raw.includes(paths.deliveryNodePath) && raw.includes(paths.deliveryCliPath) && existsSync9(paths.deliveryNodePath) && existsSync9(paths.deliveryCliPath)
15255
+ raw && raw.includes("--delivery_node=") && raw.includes("--delivery_cli=") && raw.includes(paths.deliveryNodePath) && raw.includes(paths.deliveryCliPath) && existsSync10(paths.deliveryNodePath) && existsSync10(paths.deliveryCliPath)
15121
15256
  );
15257
+ const installed = {
15258
+ claudeCode: hasOrgxHook(claudeSettingsRaw),
15259
+ codex: hasOrgxHook(codexHooksRaw),
15260
+ hookScript: existsSync10(paths.hookScriptPath),
15261
+ emitHookScript: existsSync10(paths.emitHookScriptPath),
15262
+ summaryHookScript: existsSync10(paths.summaryHookScriptPath),
15263
+ automaticDelivery: hasAutomaticDelivery(codexHooksRaw) || hasAutomaticDelivery(claudeSettingsRaw)
15264
+ };
15122
15265
  return {
15123
15266
  paths,
15124
- installed: {
15125
- claudeCode: hasOrgxHook(claudeSettingsRaw),
15126
- codex: hasOrgxHook(codexHooksRaw),
15127
- hookScript: existsSync9(paths.hookScriptPath),
15128
- emitHookScript: existsSync9(paths.emitHookScriptPath),
15129
- summaryHookScript: existsSync9(paths.summaryHookScriptPath),
15130
- automaticDelivery: hasAutomaticDelivery(codexHooksRaw) || hasAutomaticDelivery(claudeSettingsRaw)
15131
- },
15267
+ continuity: inspectClientContinuity({
15268
+ ...options.clientContinuityPaths ? { paths: options.clientContinuityPaths } : {},
15269
+ shared: {
15270
+ automaticDelivery: installed.automaticDelivery,
15271
+ claudeCodeInstalled: installed.claudeCode,
15272
+ codexInstalled: installed.codex,
15273
+ summaryHookInstalled: installed.summaryHookScript
15274
+ }
15275
+ }),
15276
+ installed,
15132
15277
  codex: {
15133
15278
  configExists: Boolean(codexConfigRaw),
15134
15279
  hooksEnabled: codexHooksEnabled(codexConfigRaw),
@@ -15154,7 +15299,7 @@ function installRuntimeHooks(targets, options = {}) {
15154
15299
  emitHookScript: false,
15155
15300
  summaryHookScript: false
15156
15301
  };
15157
- mkdirSync4(dirname5(paths.hookScriptPath), { recursive: true, mode: 448 });
15302
+ mkdirSync4(dirname6(paths.hookScriptPath), { recursive: true, mode: 448 });
15158
15303
  const scriptContent = buildRuntimeHookScriptContent();
15159
15304
  if (readTextIfExists(paths.hookScriptPath) !== scriptContent) {
15160
15305
  const backup = backupExisting(paths.hookScriptPath, now);
@@ -15162,7 +15307,7 @@ function installRuntimeHooks(targets, options = {}) {
15162
15307
  writeTextFile(paths.hookScriptPath, scriptContent, { mode: 448 });
15163
15308
  changed.hookScript = true;
15164
15309
  }
15165
- mkdirSync4(dirname5(paths.emitHookScriptPath), { recursive: true, mode: 448 });
15310
+ mkdirSync4(dirname6(paths.emitHookScriptPath), { recursive: true, mode: 448 });
15166
15311
  const emitScriptContent = buildExecutionGraphEmitScriptContent();
15167
15312
  if (readTextIfExists(paths.emitHookScriptPath) !== emitScriptContent) {
15168
15313
  const backup = backupExisting(paths.emitHookScriptPath, now);
@@ -15170,7 +15315,7 @@ function installRuntimeHooks(targets, options = {}) {
15170
15315
  writeTextFile(paths.emitHookScriptPath, emitScriptContent, { mode: 448 });
15171
15316
  changed.emitHookScript = true;
15172
15317
  }
15173
- mkdirSync4(dirname5(paths.summaryHookScriptPath), { recursive: true, mode: 448 });
15318
+ mkdirSync4(dirname6(paths.summaryHookScriptPath), { recursive: true, mode: 448 });
15174
15319
  const summaryScriptContent = buildSessionSummaryHookScriptContent();
15175
15320
  if (readTextIfExists(paths.summaryHookScriptPath) !== summaryScriptContent) {
15176
15321
  const backup = backupExisting(paths.summaryHookScriptPath, now);
@@ -15232,14 +15377,14 @@ function parseRuntimeHookTargets(value) {
15232
15377
  // src/lib/session-summary-queue.ts
15233
15378
  import {
15234
15379
  chmodSync as chmodSync2,
15235
- existsSync as existsSync10,
15380
+ existsSync as existsSync11,
15236
15381
  mkdirSync as mkdirSync5,
15237
15382
  readdirSync as readdirSync7,
15238
15383
  readFileSync as readFileSync8,
15239
15384
  renameSync as renameSync3,
15240
15385
  unlinkSync as unlinkSync2
15241
15386
  } from "fs";
15242
- import { basename as basename6, join as join9 } from "path";
15387
+ import { basename as basename6, join as join10 } from "path";
15243
15388
 
15244
15389
  // src/lib/session-summary-backfill.ts
15245
15390
  import { createReadStream, renameSync as renameSync2, statSync as statSync5, writeFileSync as writeFileSync4 } from "fs";
@@ -15654,27 +15799,27 @@ var SESSION_SUMMARY_CAPTURE_MAX_BYTES = 16 * 1024;
15654
15799
  var SESSION_SUMMARY_QUARANTINE_DIR_NAME = "quarantine";
15655
15800
  var SESSION_SUMMARY_QUARANTINE_FILE_SUFFIX = ".malformed";
15656
15801
  function sessionSummaryCaptureFiles(queueDir) {
15657
- if (!existsSync10(queueDir)) return [];
15802
+ if (!existsSync11(queueDir)) return [];
15658
15803
  try {
15659
- return readdirSync7(queueDir).filter((name) => name.endsWith(SESSION_SUMMARY_CAPTURE_FILE_SUFFIX)).sort().map((name) => join9(queueDir, name));
15804
+ return readdirSync7(queueDir).filter((name) => name.endsWith(SESSION_SUMMARY_CAPTURE_FILE_SUFFIX)).sort().map((name) => join10(queueDir, name));
15660
15805
  } catch {
15661
15806
  return [];
15662
15807
  }
15663
15808
  }
15664
15809
  function sessionSummaryQuarantineDir(queueDir) {
15665
- return join9(queueDir, SESSION_SUMMARY_QUARANTINE_DIR_NAME);
15810
+ return join10(queueDir, SESSION_SUMMARY_QUARANTINE_DIR_NAME);
15666
15811
  }
15667
15812
  function quarantineMalformedCapture(path, queueDir) {
15668
15813
  const quarantineDir = sessionSummaryQuarantineDir(queueDir);
15669
15814
  try {
15670
15815
  mkdirSync5(quarantineDir, { recursive: true, mode: 448 });
15671
- const baseTarget = join9(
15816
+ const baseTarget = join10(
15672
15817
  quarantineDir,
15673
15818
  `${basename6(path)}${SESSION_SUMMARY_QUARANTINE_FILE_SUFFIX}`
15674
15819
  );
15675
15820
  let target = baseTarget;
15676
15821
  let collision = 0;
15677
- while (existsSync10(target)) {
15822
+ while (existsSync11(target)) {
15678
15823
  collision += 1;
15679
15824
  target = `${baseTarget}.${collision}`;
15680
15825
  }
@@ -15691,6 +15836,24 @@ function quarantineMalformedCapture(path, queueDir) {
15691
15836
  function isRecord4(value) {
15692
15837
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
15693
15838
  }
15839
+ function expectsAutomaticReceipt(body) {
15840
+ const session = isRecord4(body.session) ? body.session : {};
15841
+ const metadata = isRecord4(session.metadata) ? session.metadata : {};
15842
+ const capture = isRecord4(metadata.capture) ? metadata.capture : {};
15843
+ const execution = isRecord4(metadata.execution) ? metadata.execution : {};
15844
+ const workContext = isRecord4(metadata.work_context) ? metadata.work_context : {};
15845
+ const actions = Array.isArray(execution.actions) ? execution.actions : [];
15846
+ const completed = execution.actions_completed_observed;
15847
+ return (capture.kind === "run_end" || capture.kind === "session_end") && execution.boundary === capture.kind && execution.terminal_observed === true && execution.action_capture_complete === true && typeof completed === "number" && completed > 0 && session.tool_calls === completed && execution.actions_omitted === 0 && execution.start_times_omitted === 0 && execution.pending_actions === 0 && actions.length === completed && actions.every((value) => {
15848
+ const action = isRecord4(value) ? value : {};
15849
+ return action.status !== "running" && typeof action.started_at === "string" && typeof action.completed_at === "string";
15850
+ }) && isRecord4(workContext.intent) && isRecord4(workContext.authority) && isRecord4(workContext.cost);
15851
+ }
15852
+ function confirmsAutomaticReceipt(response) {
15853
+ const body = isRecord4(response.body) ? response.body : {};
15854
+ const receipt = isRecord4(body.automatic_receipt) ? body.automatic_receipt : {};
15855
+ return receipt.ready === true && receipt.persisted === true && typeof receipt.receipt_id === "string" && receipt.receipt_id.length > 0;
15856
+ }
15694
15857
  function isSessionSummary(value) {
15695
15858
  if (!isRecord4(value)) return false;
15696
15859
  return typeof value.schema_version === "string" && typeof value.session_id === "string" && typeof value.source_client === "string";
@@ -15801,7 +15964,9 @@ async function flushSessionSummaryCaptures(options) {
15801
15964
  retained: 0,
15802
15965
  malformed: 0,
15803
15966
  quarantined: 0,
15804
- fallbackAcknowledged: 0
15967
+ fallbackAcknowledged: 0,
15968
+ receiptExpected: 0,
15969
+ receiptAcknowledged: 0
15805
15970
  };
15806
15971
  for (const path of selected) {
15807
15972
  const capture = readSessionSummaryCapture(path);
@@ -15820,11 +15985,21 @@ async function flushSessionSummaryCaptures(options) {
15820
15985
  let response;
15821
15986
  let usedFallback = false;
15822
15987
  try {
15823
- response = await options.send(primaryUrl, deliveryBody(capture), headers);
15988
+ const body = deliveryBody(capture);
15989
+ const receiptExpected = expectsAutomaticReceipt(body);
15990
+ if (receiptExpected) result.receiptExpected += 1;
15991
+ response = await options.send(primaryUrl, body, headers);
15824
15992
  if (!response.ok && (response.status === 404 || response.status === 405)) {
15825
15993
  response = await options.send(fallbackUrl, buildWorkGraphFallback(capture), headers);
15826
15994
  usedFallback = true;
15827
15995
  }
15996
+ if (response.ok && receiptExpected && !confirmsAutomaticReceipt(response)) {
15997
+ result.retained += 1;
15998
+ result.firstError ??= `HTTP ${response.status} did not confirm automatic receipt persistence for ${capture.capture_id}`;
15999
+ if (options.stopOnFailure) break;
16000
+ continue;
16001
+ }
16002
+ if (response.ok && receiptExpected) result.receiptAcknowledged += 1;
15828
16003
  } catch {
15829
16004
  response = { ok: false, status: 0 };
15830
16005
  }
@@ -15859,7 +16034,7 @@ import {
15859
16034
  unlinkSync as unlinkSync3,
15860
16035
  writeSync
15861
16036
  } from "fs";
15862
- import { join as join10 } from "path";
16037
+ import { join as join11 } from "path";
15863
16038
  var SESSION_SUMMARY_FLUSH_LOCK_NAME = ".flush.lock";
15864
16039
  var SESSION_SUMMARY_FLUSH_MAX_AGE_MS = 2 * 60 * 60 * 1e3;
15865
16040
  var MALFORMED_LOCK_GRACE_MS = 5 * 60 * 1e3;
@@ -15928,7 +16103,7 @@ function claimSessionSummaryFlushLease(queueDir, options = {}) {
15928
16103
  const pid = options.pid ?? process.pid;
15929
16104
  const token = options.token ?? randomUUID3();
15930
16105
  const isProcessAlive = options.isProcessAlive ?? processIsAlive;
15931
- const path = join10(queueDir, SESSION_SUMMARY_FLUSH_LOCK_NAME);
16106
+ const path = join11(queueDir, SESSION_SUMMARY_FLUSH_LOCK_NAME);
15932
16107
  const record = { token, pid, claimed_at: now.toISOString() };
15933
16108
  try {
15934
16109
  mkdirSync6(queueDir, { recursive: true, mode: 448 });
@@ -15986,7 +16161,7 @@ function createOrgxSpinner(text2) {
15986
16161
 
15987
16162
  // src/lib/workload-diagnosis.ts
15988
16163
  import { closeSync as closeSync3, openSync as openSync3, readSync as readSync2 } from "fs";
15989
- import { resolve as resolve3 } from "path";
16164
+ import { resolve as resolve4 } from "path";
15990
16165
 
15991
16166
  // src/lib/workload-diagnosis-schema.ts
15992
16167
  import { z as z2 } from "zod";
@@ -16339,7 +16514,7 @@ var MAX_HANDOFF_TOKEN_CHARACTERS = 7e3;
16339
16514
  var SENSITIVE_KEY2 = /(?:^|[_-])(?:authorization|cookie|credentials?|password|secrets?|session|tokens?|api[_-]?keys?|access[_-]?tokens?|refresh[_-]?tokens?|client[_-]?secrets?|private[_-]?keys?|database[_-]?(?:url|uri)|db[_-]?(?:url|uri))(?:$|[_-])/i;
16340
16515
  function readBoundedUtf8(source) {
16341
16516
  const shouldClose = source !== "-";
16342
- const fd = shouldClose ? openSync3(resolve3(source), "r") : 0;
16517
+ const fd = shouldClose ? openSync3(resolve4(source), "r") : 0;
16343
16518
  const buffer = Buffer.alloc(MAX_WORKLOAD_DIAGNOSIS_REQUEST_BYTES + 1);
16344
16519
  let offset = 0;
16345
16520
  try {
@@ -16715,6 +16890,9 @@ function printRuntimeHookInspection(report) {
16715
16890
  console.log(` ${ICON.skip} ${pc3.bold("capture queue")} ${pc3.dim(`${report.sessionSummaryCaptures} capture${report.sessionSummaryCaptures === 1 ? "" : "s"} at ${report.paths.sessionSummaryQueueDir}`)}`);
16716
16891
  console.log(` ${report.sessionSummaryQuarantinedCaptures === 0 ? ICON.skip : ICON.warn} ${pc3.bold("quarantine ")} ${pc3.dim(`${report.sessionSummaryQuarantinedCaptures} malformed capture${report.sessionSummaryQuarantinedCaptures === 1 ? "" : "s"}, recoverable on disk`)}`);
16717
16892
  console.log(` ${ICON.skip} ${pc3.bold("outbox ")} ${pc3.dim(`${report.outboxEvents} event${report.outboxEvents === 1 ? "" : "s"} at ${report.paths.outboxPath}`)}`);
16893
+ for (const client of report.continuity.clients) {
16894
+ console.log(` ${client.captureReady ? ICON.ok : ICON.warn} ${pc3.bold(client.client.padEnd(12))} ${client.captureReady ? pc3.green("capture ready") : pc3.yellow(client.state.replaceAll("_", " "))} ${pc3.dim(client.adapterVersion ?? client.terminalBoundary)}`);
16895
+ }
16718
16896
  }
16719
16897
  function printSessionSummaryFlush(result) {
16720
16898
  if (result.skipped) {
@@ -16726,10 +16904,17 @@ function printSessionSummaryFlush(result) {
16726
16904
  if (result.fallbackAcknowledged > 0) {
16727
16905
  console.log(` ${ICON.warn} ${pc3.bold("fallback ")} ${pc3.dim(`${result.fallbackAcknowledged} capture(s) delivered through the legacy Work Graph endpoint`)}`);
16728
16906
  }
16907
+ if (result.receiptExpected > 0) {
16908
+ const receiptStatus = `${result.receiptAcknowledged}/${result.receiptExpected} persisted`;
16909
+ const receiptIcon = result.receiptAcknowledged === result.receiptExpected ? ICON.ok : ICON.warn;
16910
+ console.log(
16911
+ ` ${receiptIcon} ${pc3.bold("receipts ")} ${pc3.dim(receiptStatus)}`
16912
+ );
16913
+ }
16729
16914
  if (result.firstError) console.log(` ${ICON.warn} ${pc3.dim(result.firstError)}`);
16730
16915
  }
16731
16916
  async function runSessionSummaryFlushCommand(options) {
16732
- const queueDir = resolve4(options.queue?.trim() || inspectRuntimeHooks().paths.sessionSummaryQueueDir);
16917
+ const queueDir = resolve5(options.queue?.trim() || inspectRuntimeHooks().paths.sessionSummaryQueueDir);
16733
16918
  const found = sessionSummaryCaptureFiles(queueDir).length;
16734
16919
  let result;
16735
16920
  if (found === 0) {
@@ -16741,6 +16926,8 @@ async function runSessionSummaryFlushCommand(options) {
16741
16926
  malformed: 0,
16742
16927
  quarantined: 0,
16743
16928
  fallbackAcknowledged: 0,
16929
+ receiptExpected: 0,
16930
+ receiptAcknowledged: 0,
16744
16931
  skipped: "empty_queue"
16745
16932
  };
16746
16933
  } else {
@@ -16758,6 +16945,8 @@ async function runSessionSummaryFlushCommand(options) {
16758
16945
  malformed: 0,
16759
16946
  quarantined: 0,
16760
16947
  fallbackAcknowledged: 0,
16948
+ receiptExpected: 0,
16949
+ receiptAcknowledged: 0,
16761
16950
  skipped: "already_running"
16762
16951
  };
16763
16952
  } else {
@@ -16783,7 +16972,17 @@ async function runSessionSummaryFlushCommand(options) {
16783
16972
  },
16784
16973
  options.background ? { timeoutMs: 8e3, retries: 0 } : { timeoutMs: 12e3, retries: 1 }
16785
16974
  );
16786
- return { ok: response.ok, status: response.status };
16975
+ let responseBody;
16976
+ try {
16977
+ responseBody = await response.json();
16978
+ } catch {
16979
+ responseBody = void 0;
16980
+ }
16981
+ return {
16982
+ ok: response.ok,
16983
+ status: response.status,
16984
+ body: responseBody
16985
+ };
16787
16986
  } catch {
16788
16987
  return { ok: false, status: 0 };
16789
16988
  }
@@ -16811,7 +17010,7 @@ async function runSessionSummaryFlushCommand(options) {
16811
17010
  }
16812
17011
  async function runHookBackfillCommand(options) {
16813
17012
  const paths = inspectRuntimeHooks().paths;
16814
- const spoolPath = resolve4(options.spool?.trim() || paths.outboxPath);
17013
+ const spoolPath = resolve5(options.spool?.trim() || paths.outboxPath);
16815
17014
  if (!fileExists(spoolPath)) {
16816
17015
  const message = `No hook spool found at ${spoolPath}`;
16817
17016
  if (options.json) {
@@ -16909,7 +17108,7 @@ async function runHookReplayCommand(options) {
16909
17108
  }
16910
17109
  const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
16911
17110
  const paths = inspectRuntimeHooks().paths;
16912
- const outboxPath = resolve4(options.outbox?.trim() || paths.outboxPath);
17111
+ const outboxPath = resolve5(options.outbox?.trim() || paths.outboxPath);
16913
17112
  const readResult = readRuntimeHookOutbox(outboxPath, parsePositiveInt(options.limit, 200));
16914
17113
  const replay = buildWorkGraphHookReplayPatch(readResult);
16915
17114
  if (replay.records === 0) {
@@ -16941,7 +17140,7 @@ async function runHookReplayCommand(options) {
16941
17140
  }
16942
17141
  function readAuditInput(options, interactive) {
16943
17142
  if (options.input?.trim()) {
16944
- return readFileSync10(resolve4(options.input.trim()), "utf8");
17143
+ return readFileSync10(resolve5(options.input.trim()), "utf8");
16945
17144
  }
16946
17145
  if (!process.stdin.isTTY) {
16947
17146
  return readFileSync10(0, "utf8");
@@ -16976,7 +17175,7 @@ function collectPathOption(value, previous = []) {
16976
17175
  ];
16977
17176
  }
16978
17177
  function parseClientExtractionFile(path) {
16979
- const resolvedPath = resolve4(path);
17178
+ const resolvedPath = resolve5(path);
16980
17179
  const parsed = JSON.parse(readFileSync10(resolvedPath, "utf8"));
16981
17180
  if (!isRecord(parsed)) {
16982
17181
  throw new Error(`AI-client extraction must be a JSON object: ${resolvedPath}`);
@@ -16999,8 +17198,8 @@ async function readAuditImports(options, interactive) {
16999
17198
  const missingSources = [];
17000
17199
  if (sources.length > 0) {
17001
17200
  const imported = loadAiSessionImports({
17002
- ...options.claudeProjectsDir?.trim() ? { claudeProjectsDir: resolve4(options.claudeProjectsDir.trim()) } : {},
17003
- ...options.codexSessionsDir?.trim() ? { codexSessionsDir: resolve4(options.codexSessionsDir.trim()) } : {},
17201
+ ...options.claudeProjectsDir?.trim() ? { claudeProjectsDir: resolve5(options.claudeProjectsDir.trim()) } : {},
17202
+ ...options.codexSessionsDir?.trim() ? { codexSessionsDir: resolve5(options.codexSessionsDir.trim()) } : {},
17004
17203
  limitPerSource: parsePositiveInteger(options.sessionLimit, 3, "--session-limit"),
17005
17204
  sinceDays: parsePositiveInteger(options.sessionDays, 30, "--session-days"),
17006
17205
  sources
@@ -17040,8 +17239,8 @@ async function readWorkGraphInputs(options, interactive) {
17040
17239
  const clientExtractions = readClientExtractions(options);
17041
17240
  const investigationSources = parseInvestigationSourceList(options.from);
17042
17241
  const investigationSourceData = investigationSources.length > 0 ? loadWorkGraphInvestigationSourceData({
17043
- ...options.claudeProjectsDir?.trim() ? { claudeProjectsDir: resolve4(options.claudeProjectsDir.trim()) } : {},
17044
- ...options.codexSessionsDir?.trim() ? { codexSessionsDir: resolve4(options.codexSessionsDir.trim()) } : {},
17242
+ ...options.claudeProjectsDir?.trim() ? { claudeProjectsDir: resolve5(options.claudeProjectsDir.trim()) } : {},
17243
+ ...options.codexSessionsDir?.trim() ? { codexSessionsDir: resolve5(options.codexSessionsDir.trim()) } : {},
17045
17244
  cwd: process.cwd(),
17046
17245
  limitPerSource: parsePositiveInteger(options.sessionLimit, 8, "--session-limit"),
17047
17246
  sinceDays: parsePositiveInteger(options.sessionDays, 45, "--session-days"),
@@ -17158,10 +17357,10 @@ async function runAuditCommand(options) {
17158
17357
  workspace
17159
17358
  });
17160
17359
  const markdown = renderSelfAuditMarkdown(plan);
17161
- const outputDir = resolve4(options.outputDir?.trim() || ".orgx/audits");
17360
+ const outputDir = resolve5(options.outputDir?.trim() || ".orgx/audits");
17162
17361
  const timestamp = plan.generated_at.replace(/[:.]/g, "-");
17163
- const jsonPath = resolve4(outputDir, `ai-native-self-audit-${timestamp}.json`);
17164
- const markdownPath = resolve4(outputDir, `ai-native-self-audit-${timestamp}.md`);
17362
+ const jsonPath = resolve5(outputDir, `ai-native-self-audit-${timestamp}.json`);
17363
+ const markdownPath = resolve5(outputDir, `ai-native-self-audit-${timestamp}.md`);
17165
17364
  writeJsonFile(jsonPath, plan);
17166
17365
  writeTextFile(markdownPath, markdown);
17167
17366
  if (options.json) {
@@ -17292,7 +17491,7 @@ async function runOperatingMapCommand(queryParts, options) {
17292
17491
  }
17293
17492
  function runWorkGraphExtractionSchemaCommand(options) {
17294
17493
  const protocol = buildWorkGraphExtractionProtocol();
17295
- const outputPath = options.output?.trim() ? resolve4(options.output.trim()) : "";
17494
+ const outputPath = options.output?.trim() ? resolve5(options.output.trim()) : "";
17296
17495
  if (outputPath) {
17297
17496
  if (options.json) {
17298
17497
  writeJsonFile(outputPath, protocol);
@@ -17322,8 +17521,8 @@ function normalizeRuntimePacketRole(role) {
17322
17521
  }
17323
17522
  function runWorkGraphRuntimeEventCommand(options) {
17324
17523
  const source = normalizeRuntimePacketSource(options.source);
17325
- const cwd = resolve4(options.cwd?.trim() || process.cwd());
17326
- const outputRoot = resolve4(cwd, options.outputDir?.trim() || ".orgx/work-graph/runtime-events");
17524
+ const cwd = resolve5(options.cwd?.trim() || process.cwd());
17525
+ const outputRoot = resolve5(cwd, options.outputDir?.trim() || ".orgx/work-graph/runtime-events");
17327
17526
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
17328
17527
  const timestamp = generatedAt.replace(/[:.]/g, "-");
17329
17528
  const summary = options.summary?.trim() || options.message?.trim();
@@ -17344,7 +17543,7 @@ function runWorkGraphRuntimeEventCommand(options) {
17344
17543
  collection_method: "runtime_packet",
17345
17544
  redaction_state: "agent_redacted"
17346
17545
  };
17347
- const path = resolve4(outputRoot, source, `${timestamp}-${process.pid}.jsonl`);
17546
+ const path = resolve5(outputRoot, source, `${timestamp}-${process.pid}.jsonl`);
17348
17547
  writeTextFile(path, `${JSON.stringify(packet)}
17349
17548
  `, { mode: 384 });
17350
17549
  if (options.json) {
@@ -17387,11 +17586,11 @@ async function runWorkGraphCommand(options, defaults = {}) {
17387
17586
  workspace
17388
17587
  });
17389
17588
  const markdown = renderWorkGraphMarkdown(report);
17390
- const outputDir = resolve4(commandOptions.outputDir?.trim() || ".orgx/work-graph");
17589
+ const outputDir = resolve5(commandOptions.outputDir?.trim() || ".orgx/work-graph");
17391
17590
  const timestamp = report.generated_at.replace(/[:.]/g, "-");
17392
- const jsonPath = resolve4(outputDir, `work-graph-report-${timestamp}.json`);
17393
- const markdownPath = resolve4(outputDir, `work-graph-report-${timestamp}.md`);
17394
- const agentBriefPath = resolve4(outputDir, `work-graph-agent-brief-${timestamp}.md`);
17591
+ const jsonPath = resolve5(outputDir, `work-graph-report-${timestamp}.json`);
17592
+ const markdownPath = resolve5(outputDir, `work-graph-report-${timestamp}.md`);
17593
+ const agentBriefPath = resolve5(outputDir, `work-graph-agent-brief-${timestamp}.md`);
17395
17594
  writeJsonFile(jsonPath, report);
17396
17595
  writeTextFile(markdownPath, markdown);
17397
17596
  let published = null;
@@ -17806,14 +18005,14 @@ async function readSingleKey() {
17806
18005
  const stdin = process.stdin;
17807
18006
  if (!stdin.isTTY) return null;
17808
18007
  const previousRawMode = stdin.isRaw === true;
17809
- return await new Promise((resolve5) => {
18008
+ return await new Promise((resolve6) => {
17810
18009
  const cleanup = (result) => {
17811
18010
  stdin.off("data", onData);
17812
18011
  if (stdin.isTTY) {
17813
18012
  stdin.setRawMode(previousRawMode);
17814
18013
  }
17815
18014
  stdin.pause();
17816
- resolve5(result);
18015
+ resolve6(result);
17817
18016
  };
17818
18017
  const onData = (chunk) => {
17819
18018
  const text2 = chunk.toString("utf8");
@@ -18578,7 +18777,7 @@ async function main() {
18578
18777
  initializeWizardSentry();
18579
18778
  const program = new Command();
18580
18779
  program.name("orgx-wizard").description("Add OrgX MCP configs, skills/rules, and companion plugins to your local AI tools.").showHelpAfterError();
18581
- const pkgVersion = true ? "0.1.66" : void 0;
18780
+ const pkgVersion = true ? "0.1.68" : void 0;
18582
18781
  program.version(pkgVersion ?? "unknown", "-V, --version");
18583
18782
  program.hook("preAction", (_thisCommand, actionCommand) => {
18584
18783
  if (Boolean(actionCommand.optsWithGlobals().json)) return;
@@ -19342,7 +19541,7 @@ async function main() {
19342
19541
  await runWorkGraphCommand(options, { from: "all" });
19343
19542
  });
19344
19543
  const hooks = program.command("hooks").description("Inspect or install passive OrgX runtime hooks for local agent clients.");
19345
- hooks.command("doctor").description("Show Codex and Claude Code runtime hook wiring status.").option("--json", "emit a JSON command summary").action(async (options) => {
19544
+ hooks.command("doctor").description("Show four-client continuity, runtime hook, queue, and delivery status.").option("--json", "emit a JSON command summary").action(async (options) => {
19346
19545
  const report = inspectRuntimeHooks();
19347
19546
  await safeTrackWizardTelemetry("hooks_doctor_ran", {
19348
19547
  command: "hooks doctor",
@@ -19622,4 +19821,4 @@ main().catch(async (error) => {
19622
19821
  process.exitCode = 1;
19623
19822
  });
19624
19823
  //# sourceMappingURL=cli.js.map
19625
- //# debugId=783f771d-d176-55f3-b036-2be49833854e
19824
+ //# debugId=4b5dd32d-184b-560a-ae80-e8a055ae1bc4