@cmmd-center/forge 0.9.6 → 0.9.7

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/bin.cjs CHANGED
@@ -301957,8 +301957,52 @@ function serializeNativeToolActivity(activity) {
301957
301957
  }
301958
301958
  };
301959
301959
  }
301960
+ /** The failure activities `appendProviderFailureActivity` emits, all `provider.*.failed`. */
301961
+ function isProviderFailureActivity(activity) {
301962
+ return activity.kind.startsWith("provider.") && activity.kind.endsWith(".failed");
301963
+ }
301964
+ function failureDetail(activity) {
301965
+ const payload = activity.payload;
301966
+ if (!payload || typeof payload !== "object" || !("detail" in payload)) return null;
301967
+ const detail = payload.detail;
301968
+ return typeof detail === "string" && detail.trim() ? detail.trim() : null;
301969
+ }
301970
+ /**
301971
+ * Replicates why a turn failed.
301972
+ *
301973
+ * Without this a failure never crossed the replication boundary — only `tool.`
301974
+ * activities were serialized — so durable history could not show one and every
301975
+ * failure reached the user as an endless "Working" spinner. Measured in
301976
+ * production on 2026-08-30: zero failure events had EVER been recorded against
301977
+ * 652 tool_call rows, which is how a workspace-path block, a broker-token
301978
+ * refusal and a dispatch into a deleted directory all looked identical.
301979
+ *
301980
+ * `error_summary` is used rather than a new kind because both the Forge
301981
+ * protocol and CMMD's ingest schema already accept it; nothing here needed a
301982
+ * contract change. The detail carries the actionable sentence, so it is joined
301983
+ * onto the summary — the event has no separate detail field.
301984
+ */
301985
+ function serializeProviderFailureActivity(activity) {
301986
+ if (!isProviderFailureActivity(activity)) return null;
301987
+ const summary = text(activity.summary, 4e3);
301988
+ if (summary === null) return null;
301989
+ const detail = failureDetail(activity);
301990
+ return {
301991
+ sourceSequence: null,
301992
+ event: {
301993
+ eventId: `activity:${activity.id}`,
301994
+ occurredAt: canonicalRuntimeEventTimestamp(activity.createdAt),
301995
+ kind: "error_summary",
301996
+ summary: text(detail === null ? summary : `${summary}: ${detail}`, 4e3) ?? summary
301997
+ }
301998
+ };
301999
+ }
301960
302000
  function serializeRuntimeThreadEvents(thread) {
301961
302001
  const messages = thread.messages.flatMap(serializeThreadMessage);
302002
+ const failureActivities = thread.activities.flatMap((activity) => {
302003
+ const event = serializeProviderFailureActivity(activity);
302004
+ return event === null ? [] : [event];
302005
+ });
301962
302006
  const replicaActivities = thread.activities.flatMap((activity) => {
301963
302007
  const event = serializeReplicaActivity(activity);
301964
302008
  return event === null ? [] : [event];
@@ -301970,7 +302014,8 @@ function serializeRuntimeThreadEvents(thread) {
301970
302014
  return [
301971
302015
  ...messages,
301972
302016
  ...replicaActivities,
301973
- ...toolActivities
302017
+ ...toolActivities,
302018
+ ...failureActivities
301974
302019
  ].toSorted((left, right) => {
301975
302020
  if (left.sourceSequence !== null && right.sourceSequence !== null) return left.sourceSequence - right.sourceSequence;
301976
302021
  if (left.sourceSequence !== null) return -1;
package/dist/bin.mjs CHANGED
@@ -22,7 +22,7 @@ import { createCipheriv, createDecipheriv, createHash, createHmac, createPublicK
22
22
  import * as FS$1 from "node:fs";
23
23
  import fs, { accessSync, chmodSync, constants, createReadStream, existsSync, mkdirSync, mkdtempSync, promises, readFile, readFileSync, readdir, readdirSync, realpathSync, rmSync, statSync, writeFileSync } from "node:fs";
24
24
  import * as NodeOS from "node:os";
25
- import $U, { homedir, networkInterfaces, tmpdir } from "node:os";
25
+ import os, { homedir, networkInterfaces, tmpdir } from "node:os";
26
26
  import * as Path$1 from "node:path";
27
27
  import path, { basename, delimiter, dirname, extname, isAbsolute, join, posix, relative, resolve, sep } from "node:path";
28
28
  import { pathToFileURL } from "node:url";
@@ -52183,7 +52183,7 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
52183
52183
  const min = forceColor || 0;
52184
52184
  if (env.TERM === "dumb") return min;
52185
52185
  if (process$1.platform === "win32") {
52186
- const osRelease = $U.release().split(".");
52186
+ const osRelease = os.release().split(".");
52187
52187
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
52188
52188
  return 1;
52189
52189
  }
@@ -54626,7 +54626,7 @@ var require_ProcessDetector = /* @__PURE__ */ __commonJSMin(((exports) => {
54626
54626
  exports.processDetector = void 0;
54627
54627
  const api_1 = (init_esm$1(), __toCommonJS(esm_exports$1));
54628
54628
  const semconv_1 = require_semconv$1();
54629
- const os$3 = __require("os");
54629
+ const os$4 = __require("os");
54630
54630
  /**
54631
54631
  * ProcessDetector will be used to detect the resources related current process running
54632
54632
  * and being instrumented from the NodeJS Process module.
@@ -54648,7 +54648,7 @@ var require_ProcessDetector = /* @__PURE__ */ __commonJSMin(((exports) => {
54648
54648
  };
54649
54649
  if (process.argv.length > 1) attributes[semconv_1.ATTR_PROCESS_COMMAND] = process.argv[1];
54650
54650
  try {
54651
- const userInfo = os$3.userInfo();
54651
+ const userInfo = os$4.userInfo();
54652
54652
  attributes[semconv_1.ATTR_PROCESS_OWNER] = userInfo.username;
54653
54653
  } catch (e) {
54654
54654
  api_1.diag.debug(`error obtaining process owner: ${e}`);
@@ -76150,7 +76150,7 @@ var require_node_gyp_build = /* @__PURE__ */ __commonJSMin(((exports, module) =>
76150
76150
  var fs$6 = __require("fs");
76151
76151
  var path$5 = __require("path");
76152
76152
  var url$1 = __require("url");
76153
- var os$2 = __require("os");
76153
+ var os$3 = __require("os");
76154
76154
  var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
76155
76155
  var vars = process.config && process.config.variables || {};
76156
76156
  var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
@@ -76158,8 +76158,8 @@ var require_node_gyp_build = /* @__PURE__ */ __commonJSMin(((exports, module) =>
76158
76158
  var abi = versions.modules;
76159
76159
  if (versions.deno || process.isBun) abi = "unsupported";
76160
76160
  var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
76161
- var arch = process.env.npm_config_arch || os$2.arch();
76162
- var platform = process.env.npm_config_platform || os$2.platform();
76161
+ var arch = process.env.npm_config_arch || os$3.arch();
76162
+ var platform = process.env.npm_config_platform || os$3.platform();
76163
76163
  var libc = process.env.LIBC || (isMusl(platform) ? "musl" : "glibc");
76164
76164
  var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
76165
76165
  var uv = (versions.uv || "").split(".")[0];
@@ -93794,7 +93794,7 @@ const launchDetached = (launch) => gen(function* () {
93794
93794
  });
93795
93795
  const OpenLive = effect(Open, gen(function* () {
93796
93796
  const open = yield* tryPromise({
93797
- try: () => import("./open-D8mGyWmt.mjs"),
93797
+ try: () => import("./open-FIgTDosf.mjs"),
93798
93798
  catch: (cause) => new OpenError$1({
93799
93799
  message: "failed to load browser opener",
93800
93800
  cause
@@ -186176,7 +186176,7 @@ var Vce = {
186176
186176
  function Ve() {
186177
186177
  return Vce;
186178
186178
  }
186179
- var Us = $U.homedir(), lk = $U.tmpdir(), { env: Vc } = process$1, Yce = (e) => {
186179
+ var Us = os.homedir(), lk = os.tmpdir(), { env: Vc } = process$1, Yce = (e) => {
186180
186180
  let t = path.join(Us, "Library");
186181
186181
  return {
186182
186182
  data: path.join(t, "Application Support", e),
@@ -196376,12 +196376,12 @@ function qZ(e, t) {
196376
196376
  }
196377
196377
  return n;
196378
196378
  }
196379
- var os$1 = "https://code.claude.com/docs/en", kKe = [
196379
+ var os$2 = "https://code.claude.com/docs/en", kKe = [
196380
196380
  {
196381
196381
  matches: (e) => e.path === "permissions.defaultMode" && e.code === "invalid_value",
196382
196382
  tip: {
196383
196383
  suggestion: "Valid modes: \"acceptEdits\" (ask before file changes), \"plan\" (analysis only), \"bypassPermissions\" (auto-accept all), or \"default\" (standard behavior)",
196384
- docLink: `${os$1}/iam#permission-modes`
196384
+ docLink: `${os$2}/iam#permission-modes`
196385
196385
  }
196386
196386
  },
196387
196387
  {
@@ -196396,7 +196396,7 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
196396
196396
  matches: (e) => e.path.startsWith("env.") && e.code === "invalid_type",
196397
196397
  tip: {
196398
196398
  suggestion: "Environment variables must be strings. Wrap numbers and booleans in quotes. Example: \"DEBUG\": \"true\", \"PORT\": \"3000\"",
196399
- docLink: `${os$1}/settings#environment-variables`
196399
+ docLink: `${os$2}/settings#environment-variables`
196400
196400
  }
196401
196401
  },
196402
196402
  {
@@ -196407,14 +196407,14 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
196407
196407
  matches: (e) => e.path.startsWith("hooks.") && e.code === "invalid_key",
196408
196408
  tip: {
196409
196409
  suggestion: "Not a recognized hook event. Common events: PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, SessionEnd, Stop. Check spelling and capitalization.",
196410
- docLink: `${os$1}/hooks`
196410
+ docLink: `${os$2}/hooks`
196411
196411
  }
196412
196412
  },
196413
196413
  {
196414
196414
  matches: (e) => /\.hooks\.\d+\.command$/.test(e.path) && e.code === "invalid_type" && e.received === "undefined",
196415
196415
  tip: {
196416
196416
  suggestion: "Command hooks require `command`. For exec form (no shell), set `command` to the executable and `args` to its arguments: {\"type\": \"command\", \"command\": \"echo\", \"args\": [\"hi\"]}. For shell form, set `command` to the full shell string: {\"type\": \"command\", \"command\": \"echo hi\"}.",
196417
- docLink: `${os$1}/hooks#exec-form-and-shell-form`
196417
+ docLink: `${os$2}/hooks#exec-form-and-shell-form`
196418
196418
  }
196419
196419
  },
196420
196420
  {
@@ -196429,7 +196429,7 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
196429
196429
  matches: (e) => e.code === "unrecognized_keys",
196430
196430
  tip: {
196431
196431
  suggestion: "Check for typos or refer to the documentation for valid fields",
196432
- docLink: `${os$1}/settings`
196432
+ docLink: `${os$2}/settings`
196433
196433
  }
196434
196434
  },
196435
196435
  {
@@ -196444,13 +196444,13 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
196444
196444
  matches: (e) => e.path === "permissions.additionalDirectories" && e.code === "invalid_type",
196445
196445
  tip: {
196446
196446
  suggestion: "Must be an array of directory paths. Example: [\"~/projects\", \"/tmp/workspace\"]. You can also use --add-dir flag or /add-dir command",
196447
- docLink: `${os$1}/iam#working-directories`
196447
+ docLink: `${os$2}/iam#working-directories`
196448
196448
  }
196449
196449
  }
196450
196450
  ], AKe = {
196451
- permissions: `${os$1}/iam#configuring-permissions`,
196452
- env: `${os$1}/settings#environment-variables`,
196453
- hooks: `${os$1}/hooks`
196451
+ permissions: `${os$2}/iam#configuring-permissions`,
196452
+ env: `${os$2}/settings#environment-variables`,
196453
+ hooks: `${os$2}/hooks`
196454
196454
  };
196455
196455
  function GZ(e) {
196456
196456
  let t = kKe.find((r) => r.matches(e));
@@ -260595,7 +260595,7 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
260595
260595
  var dgram = __require("dgram");
260596
260596
  var thunky = require_thunky();
260597
260597
  var events = __require("events");
260598
- var os = __require("os");
260598
+ var os$1 = __require("os");
260599
260599
  var noop = function() {};
260600
260600
  module.exports = function(opts) {
260601
260601
  if (!opts) opts = {};
@@ -260726,14 +260726,14 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
260726
260726
  return that;
260727
260727
  };
260728
260728
  function defaultInterface() {
260729
- var networks = os.networkInterfaces();
260729
+ var networks = os$1.networkInterfaces();
260730
260730
  var names = Object.keys(networks);
260731
260731
  for (var i = 0; i < names.length; i++) {
260732
260732
  var net = networks[names[i]];
260733
260733
  for (var j = 0; j < net.length; j++) {
260734
260734
  var iface = net[j];
260735
260735
  if (isIPv4(iface.family) && !iface.internal) {
260736
- if (os.platform() === "darwin" && names[i] === "en0") return iface.address;
260736
+ if (os$1.platform() === "darwin" && names[i] === "en0") return iface.address;
260737
260737
  return "0.0.0.0";
260738
260738
  }
260739
260739
  }
@@ -260741,7 +260741,7 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
260741
260741
  return "127.0.0.1";
260742
260742
  }
260743
260743
  function allInterfaces() {
260744
- var networks = os.networkInterfaces();
260744
+ var networks = os$1.networkInterfaces();
260745
260745
  var names = Object.keys(networks);
260746
260746
  var res = [];
260747
260747
  for (var i = 0; i < names.length; i++) {
@@ -301412,8 +301412,52 @@ function serializeNativeToolActivity(activity) {
301412
301412
  }
301413
301413
  };
301414
301414
  }
301415
+ /** The failure activities `appendProviderFailureActivity` emits, all `provider.*.failed`. */
301416
+ function isProviderFailureActivity(activity) {
301417
+ return activity.kind.startsWith("provider.") && activity.kind.endsWith(".failed");
301418
+ }
301419
+ function failureDetail(activity) {
301420
+ const payload = activity.payload;
301421
+ if (!payload || typeof payload !== "object" || !("detail" in payload)) return null;
301422
+ const detail = payload.detail;
301423
+ return typeof detail === "string" && detail.trim() ? detail.trim() : null;
301424
+ }
301425
+ /**
301426
+ * Replicates why a turn failed.
301427
+ *
301428
+ * Without this a failure never crossed the replication boundary — only `tool.`
301429
+ * activities were serialized — so durable history could not show one and every
301430
+ * failure reached the user as an endless "Working" spinner. Measured in
301431
+ * production on 2026-08-30: zero failure events had EVER been recorded against
301432
+ * 652 tool_call rows, which is how a workspace-path block, a broker-token
301433
+ * refusal and a dispatch into a deleted directory all looked identical.
301434
+ *
301435
+ * `error_summary` is used rather than a new kind because both the Forge
301436
+ * protocol and CMMD's ingest schema already accept it; nothing here needed a
301437
+ * contract change. The detail carries the actionable sentence, so it is joined
301438
+ * onto the summary — the event has no separate detail field.
301439
+ */
301440
+ function serializeProviderFailureActivity(activity) {
301441
+ if (!isProviderFailureActivity(activity)) return null;
301442
+ const summary = text(activity.summary, 4e3);
301443
+ if (summary === null) return null;
301444
+ const detail = failureDetail(activity);
301445
+ return {
301446
+ sourceSequence: null,
301447
+ event: {
301448
+ eventId: `activity:${activity.id}`,
301449
+ occurredAt: canonicalRuntimeEventTimestamp(activity.createdAt),
301450
+ kind: "error_summary",
301451
+ summary: text(detail === null ? summary : `${summary}: ${detail}`, 4e3) ?? summary
301452
+ }
301453
+ };
301454
+ }
301415
301455
  function serializeRuntimeThreadEvents(thread) {
301416
301456
  const messages = thread.messages.flatMap(serializeThreadMessage);
301457
+ const failureActivities = thread.activities.flatMap((activity) => {
301458
+ const event = serializeProviderFailureActivity(activity);
301459
+ return event === null ? [] : [event];
301460
+ });
301417
301461
  const replicaActivities = thread.activities.flatMap((activity) => {
301418
301462
  const event = serializeReplicaActivity(activity);
301419
301463
  return event === null ? [] : [event];
@@ -301425,7 +301469,8 @@ function serializeRuntimeThreadEvents(thread) {
301425
301469
  return [
301426
301470
  ...messages,
301427
301471
  ...replicaActivities,
301428
- ...toolActivities
301472
+ ...toolActivities,
301473
+ ...failureActivities
301429
301474
  ].toSorted((left, right) => {
301430
301475
  if (left.sourceSequence !== null && right.sourceSequence !== null) return left.sourceSequence - right.sourceSequence;
301431
301476
  if (left.sourceSequence !== null) return -1;
@@ -311532,7 +311577,7 @@ const connectLoginCommand = make$32("login", {
311532
311577
  })).json();
311533
311578
  },
311534
311579
  openBrowser: async (url) => {
311535
- const open = (await import("./open-D8mGyWmt.mjs")).default;
311580
+ const open = (await import("./open-FIgTDosf.mjs")).default;
311536
311581
  await open(url);
311537
311582
  return true;
311538
311583
  },
@@ -2,7 +2,7 @@
2
2
 
3
3
  import childProcess, { execFile } from "node:child_process";
4
4
  import fs from "node:fs";
5
- import $U from "node:os";
5
+ import os from "node:os";
6
6
  import path from "node:path";
7
7
  import { fileURLToPath } from "node:url";
8
8
  import process from "node:process";
@@ -49,7 +49,7 @@ function isInsideContainer() {
49
49
  //#region ../../node_modules/.bun/is-wsl@3.1.1/node_modules/is-wsl/index.js
50
50
  const isWsl = () => {
51
51
  if (process.platform !== "linux") return false;
52
- if ($U.release().toLowerCase().includes("microsoft")) {
52
+ if (os.release().toLowerCase().includes("microsoft")) {
53
53
  if (isInsideContainer()) return false;
54
54
  return true;
55
55
  }
@@ -589,4 +589,4 @@ defineLazyProperty(apps, "safari", () => detectPlatformBinary({ darwin: "Safari"
589
589
  //#endregion
590
590
  export { apps, open as default, openApp };
591
591
 
592
- //# sourceMappingURL=open-D8mGyWmt.mjs.map
592
+ //# sourceMappingURL=open-FIgTDosf.mjs.map
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "cmmd-forge": "dist/bin.mjs"
10
10
  },
11
11
  "type": "module",
12
- "version": "0.9.6",
12
+ "version": "0.9.7",
13
13
  "engines": {
14
14
  "node": "^22.16 || ^23.11 || >=24.10"
15
15
  },