@alfe.ai/gateway 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/health.js +96 -8
  2. package/package.json +3 -3
package/dist/health.js CHANGED
@@ -109,6 +109,8 @@ const ID_PREFIXES = {
109
109
  identityVerification: "ivf",
110
110
  role: "role",
111
111
  directGrant: "dgr",
112
+ revision: "rev",
113
+ fact: "kfc",
112
114
  oauthConnection: "con",
113
115
  channel: "chn",
114
116
  oauthConnectionRequest: "crq",
@@ -1292,6 +1294,7 @@ const string$1 = (params) => {
1292
1294
  };
1293
1295
  const integer = /^-?\d+$/;
1294
1296
  const number$1 = /^-?\d+(?:\.\d+)?$/;
1297
+ const boolean$1 = /^(?:true|false)$/i;
1295
1298
  const lowercase = /^[^A-Z]*$/;
1296
1299
  const uppercase = /^[^a-z]*$/;
1297
1300
  //#endregion
@@ -2066,6 +2069,24 @@ const $ZodNumberFormat = /* @__PURE__ */ $constructor("$ZodNumberFormat", (inst,
2066
2069
  $ZodCheckNumberFormat.init(inst, def);
2067
2070
  $ZodNumber.init(inst, def);
2068
2071
  });
2072
+ const $ZodBoolean = /* @__PURE__ */ $constructor("$ZodBoolean", (inst, def) => {
2073
+ $ZodType.init(inst, def);
2074
+ inst._zod.pattern = boolean$1;
2075
+ inst._zod.parse = (payload, _ctx) => {
2076
+ if (def.coerce) try {
2077
+ payload.value = Boolean(payload.value);
2078
+ } catch (_) {}
2079
+ const input = payload.value;
2080
+ if (typeof input === "boolean") return payload;
2081
+ payload.issues.push({
2082
+ expected: "boolean",
2083
+ code: "invalid_type",
2084
+ input,
2085
+ inst
2086
+ });
2087
+ return payload;
2088
+ };
2089
+ });
2069
2090
  const $ZodUnknown = /* @__PURE__ */ $constructor("$ZodUnknown", (inst, def) => {
2070
2091
  $ZodType.init(inst, def);
2071
2092
  inst._zod.parse = (payload) => payload;
@@ -3046,6 +3067,13 @@ function _int(Class, params) {
3046
3067
  });
3047
3068
  }
3048
3069
  /* @__NO_SIDE_EFFECTS__ */
3070
+ function _boolean(Class, params) {
3071
+ return new Class({
3072
+ type: "boolean",
3073
+ ...normalizeParams(params)
3074
+ });
3075
+ }
3076
+ /* @__NO_SIDE_EFFECTS__ */
3049
3077
  function _unknown(Class) {
3050
3078
  return new Class({ type: "unknown" });
3051
3079
  }
@@ -3588,6 +3616,9 @@ const numberProcessor = (schema, ctx, _json, _params) => {
3588
3616
  }
3589
3617
  if (typeof multipleOf === "number") json.multipleOf = multipleOf;
3590
3618
  };
3619
+ const booleanProcessor = (_schema, _ctx, json, _params) => {
3620
+ json.type = "boolean";
3621
+ };
3591
3622
  const neverProcessor = (_schema, _ctx, json, _params) => {
3592
3623
  json.not = {};
3593
3624
  };
@@ -4063,6 +4094,14 @@ const ZodNumberFormat = /* @__PURE__ */ $constructor("ZodNumberFormat", (inst, d
4063
4094
  function int(params) {
4064
4095
  return /* @__PURE__ */ _int(ZodNumberFormat, params);
4065
4096
  }
4097
+ const ZodBoolean = /* @__PURE__ */ $constructor("ZodBoolean", (inst, def) => {
4098
+ $ZodBoolean.init(inst, def);
4099
+ ZodType.init(inst, def);
4100
+ inst._zod.processJSONSchema = (ctx, json, params) => booleanProcessor(inst, ctx, json, params);
4101
+ });
4102
+ function boolean(params) {
4103
+ return /* @__PURE__ */ _boolean(ZodBoolean, params);
4104
+ }
4066
4105
  const ZodUnknown = /* @__PURE__ */ $constructor("ZodUnknown", (inst, def) => {
4067
4106
  $ZodUnknown.init(inst, def);
4068
4107
  ZodType.init(inst, def);
@@ -4391,7 +4430,10 @@ enumValues({
4391
4430
  Month: "month",
4392
4431
  Year: "year"
4393
4432
  });
4394
- object({ gracePeriodDays: number().int().positive().optional() });
4433
+ object({
4434
+ gracePeriodDays: number().int().positive().optional(),
4435
+ launchDiscountEnabled: boolean().optional()
4436
+ });
4395
4437
  enumValues({
4396
4438
  ManagedHosting: "managed-hosting",
4397
4439
  PlatformTier: "platform-tier",
@@ -4399,12 +4441,13 @@ enumValues({
4399
4441
  Other: "other"
4400
4442
  });
4401
4443
  enumValues({
4402
- Free: "free",
4403
- Personal: "personal",
4404
- PersonalPlus: "personal_plus",
4405
- PersonalPro: "personal_pro",
4406
- Tier1: "tier_1",
4407
- Tier2: "tier_2"
4444
+ IndividualLite: "individual_lite",
4445
+ IndividualNormal: "individual_normal",
4446
+ IndividualPro: "individual_pro",
4447
+ IndividualMax: "individual_max",
4448
+ OrgFree: "org_free",
4449
+ OrgProfessional: "org_professional",
4450
+ OrgEnterprise: "org_enterprise"
4408
4451
  });
4409
4452
  enumValues({
4410
4453
  Pending: "pending",
@@ -5172,7 +5215,18 @@ const PROTOCOL_VERSION = 1;
5172
5215
  //#endregion
5173
5216
  //#region src/reconciliation.ts
5174
5217
  const log$2 = logger$1.child({ component: "Reconciliation" });
5218
+ /**
5219
+ * How many times reconcile will re-attempt activation of an intact integration
5220
+ * stuck in `error` (with no reinstall requested) before giving up and waiting
5221
+ * for a manual reinstall. Each reconcile pass = one cloud DESIRED_STATE push,
5222
+ * so these attempts are spread across pushes, not a tight loop. This lets a
5223
+ * transient activation failure (e.g. an `openclaw config set` racing a runtime
5224
+ * hot-reload) self-heal without the user clicking Reinstall.
5225
+ */
5226
+ const MAX_ERROR_ACTIVATE_ATTEMPTS = 3;
5175
5227
  var ReconciliationEngine = class {
5228
+ /** Consecutive re-activation attempts for an intact error-state integration, keyed by id. */
5229
+ activateAttempts = /* @__PURE__ */ new Map();
5176
5230
  constructor(manager) {
5177
5231
  this.manager = manager;
5178
5232
  }
@@ -5236,6 +5290,7 @@ var ReconciliationEngine = class {
5236
5290
  if (desired.reinstallRequestedAt && local.installedAt && desired.reinstallRequestedAt > local.installedAt) {
5237
5291
  log$2.info(`Reinstalling ${id} from error state (requested: ${desired.reinstallRequestedAt}, installed: ${local.installedAt})`);
5238
5292
  this.manager.resetReinstallAttempts(id);
5293
+ this.activateAttempts.delete(id);
5239
5294
  if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
5240
5295
  report.installed.push(id);
5241
5296
  report.activated.push(id);
@@ -5267,6 +5322,7 @@ var ReconciliationEngine = class {
5267
5322
  try {
5268
5323
  if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
5269
5324
  this.manager.resetReinstallAttempts(id);
5325
+ this.activateAttempts.delete(id);
5270
5326
  report.installed.push(id);
5271
5327
  report.activated.push(id);
5272
5328
  report.results.push({
@@ -5290,7 +5346,37 @@ var ReconciliationEngine = class {
5290
5346
  }
5291
5347
  return;
5292
5348
  }
5293
- log$2.warn(`Integration ${id} is in error state — waiting for reinstall request`);
5349
+ const activateAttempts = this.activateAttempts.get(id) ?? 0;
5350
+ if (activateAttempts < MAX_ERROR_ACTIVATE_ATTEMPTS) {
5351
+ this.activateAttempts.set(id, activateAttempts + 1);
5352
+ log$2.info(`Re-activating ${id} from error state (attempt ${String(activateAttempts + 1)}/${String(MAX_ERROR_ACTIVATE_ATTEMPTS)})`);
5353
+ try {
5354
+ if ((await this.manager.activate(id)).configApplied) report.configApplied = true;
5355
+ this.activateAttempts.delete(id);
5356
+ report.activated.push(id);
5357
+ report.results.push({
5358
+ integrationId: id,
5359
+ action: "activated",
5360
+ actualStatus: "active"
5361
+ });
5362
+ return;
5363
+ } catch (reactivateErr) {
5364
+ const reactivateMsg = reactivateErr instanceof Error ? reactivateErr.message : String(reactivateErr);
5365
+ log$2.warn(`Re-activation of ${id} from error state failed (attempt ${String(activateAttempts + 1)}/${String(MAX_ERROR_ACTIVATE_ATTEMPTS)}): ${reactivateMsg}`);
5366
+ report.errors.push({
5367
+ integrationId: id,
5368
+ error: reactivateMsg
5369
+ });
5370
+ report.results.push({
5371
+ integrationId: id,
5372
+ action: "error",
5373
+ actualStatus: "error",
5374
+ errorMessage: reactivateMsg
5375
+ });
5376
+ return;
5377
+ }
5378
+ }
5379
+ log$2.warn(`Integration ${id} is in error state — re-activation exhausted, waiting for reinstall request`);
5294
5380
  report.errors.push({
5295
5381
  integrationId: id,
5296
5382
  error: "Integration is in error state"
@@ -5317,6 +5403,7 @@ var ReconciliationEngine = class {
5317
5403
  if (desired.reinstallRequestedAt && local.installedAt && desired.reinstallRequestedAt > local.installedAt) {
5318
5404
  log$2.info(`Reinstall requested for ${id} (requested: ${desired.reinstallRequestedAt}, installed: ${local.installedAt})`);
5319
5405
  this.manager.resetReinstallAttempts(id);
5406
+ this.activateAttempts.delete(id);
5320
5407
  if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
5321
5408
  report.installed.push(id);
5322
5409
  report.activated.push(id);
@@ -5327,6 +5414,7 @@ var ReconciliationEngine = class {
5327
5414
  });
5328
5415
  return;
5329
5416
  }
5417
+ this.activateAttempts.delete(id);
5330
5418
  report.results.push({
5331
5419
  integrationId: id,
5332
5420
  action: "up_to_date",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/gateway",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Alfe local gateway daemon — persistent control plane for agent integrations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -22,11 +22,11 @@
22
22
  "pino-roll": "^1.2.0",
23
23
  "smol-toml": ">=1.6.1",
24
24
  "ws": "^8.18.0",
25
- "@alfe.ai/agent-api-client": "^0.2.2",
25
+ "@alfe.ai/agent-api-client": "^0.2.3",
26
26
  "@alfe.ai/ai-proxy-local": "^0.0.10",
27
27
  "@alfe.ai/config": "^0.0.9",
28
28
  "@alfe.ai/integration-manifest": "^0.2.1",
29
- "@alfe.ai/integrations": "^0.1.5",
29
+ "@alfe.ai/integrations": "^0.1.6",
30
30
  "@alfe.ai/mcp-bundler": "^0.2.1"
31
31
  },
32
32
  "license": "UNLICENSED",