@event4u/agent-config 9.30.0 → 9.32.0
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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +60 -292
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +32 -1
- package/dist/agent-src/rules/delegation-policy.md +11 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/scripts/work_engine/delivery_state.ts +6 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +332 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/refine.ts +106 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +50 -15
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +49 -15
- package/dist/agent-src/templates/scripts/work_engine/state.ts +74 -0
- package/dist/agent-src/templates/scripts/work_engine/state_io.ts +6 -0
- package/dist/cli-delegate/chunk-2WELHO3P.js +582 -0
- package/dist/cli-delegate/{chunk-IYTGIG2Y.js → chunk-542DZR4P.js} +118 -148
- package/dist/cli-delegate/{chunk-66OVWGB5.js → chunk-AG47LAGQ.js} +1 -1
- package/dist/cli-delegate/{chunk-MP3JT3IU.js → chunk-DS6BLDMG.js} +1 -1
- package/dist/cli-delegate/{chunk-O3CO5BFB.js → chunk-EJITJBJX.js} +12 -1
- package/dist/cli-delegate/{chunk-EQY4FLJB.js → chunk-ITIQSGOQ.js} +3 -3
- package/dist/cli-delegate/{chunk-LCFJIQ4J.js → chunk-JEJABGKB.js} +110 -6
- package/dist/cli-delegate/chunk-PZWRPRWP.js +38 -0
- package/dist/cli-delegate/{chunk-BTJNRUX3.js → chunk-QEEB4LHO.js} +1 -1
- package/dist/cli-delegate/{chunk-DDUNNFYX.js → chunk-UVKNIJH2.js} +2 -2
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +1 -1
- package/dist/cli-delegate/cmd_conformance.js +154 -41
- package/dist/cli-delegate/cmd_doctor.js +4 -3
- package/dist/cli-delegate/cmd_explain.js +2 -2
- package/dist/cli-delegate/cmd_export.js +4 -4
- package/dist/cli-delegate/cmd_handoff.js +168 -59
- package/dist/cli-delegate/cmd_mcp_available.js +1 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +4 -4
- package/dist/cli-delegate/cmd_route_audit.js +2 -2
- package/dist/cli-delegate/cmd_route_explain.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +19 -4
- package/dist/cli-delegate/cmd_settings_get.js +2 -55
- package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +4 -4
- package/dist/cli-delegate/cmd_uninstall.js +4 -4
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +4 -4
- package/dist/cli-delegate/cmd_versions.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +3 -3
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +1411 -810
- package/dist/install/install.mjs +121 -16
- package/dist/mcp/registry-manifest.json +1 -1
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +365 -143
- package/dist/scripts/_lib/agent_settings.js +111 -2
- package/dist/scripts/_lib/agent_settings.js.map +1 -1
- package/dist/server/schemas/settings.js +2 -2
- package/dist/server/schemas/settings.js.map +1 -1
- package/package.json +1 -1
- package/src/agent-src/templates/scripts/work_engine/delivery_state.ts +6 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +332 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/refine.ts +106 -1
- package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +50 -15
- package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +49 -15
- package/src/agent-src/templates/scripts/work_engine/state.ts +74 -0
- package/src/agent-src/templates/scripts/work_engine/state_io.ts +6 -0
- package/src/config/pack-size-budget.json +3 -2
- package/src/scripts/_cli/cmd_session_recycle.ts +25 -0
- package/src/scripts/_cli/explain_last/inputs.ts +13 -0
- package/src/scripts/_cli/handoff_generate.ts +36 -1
- package/src/scripts/_cli/handoff_sessions.ts +140 -9
- package/src/scripts/_lib/agent_settings.ts +119 -2
- package/src/scripts/_lib/carrier_divergence.ts +120 -2
- package/src/scripts/_lib/envelope_grounding.ts +206 -0
- package/src/scripts/_lib/host_capability.ts +79 -0
- package/src/scripts/_lib/session_eol.ts +85 -0
- package/src/scripts/_lib/subagent_capsule.ts +256 -1
- package/src/scripts/check_secret_leak.test.ts +43 -0
- package/src/scripts/check_secret_leak.ts +12 -0
- package/src/scripts/handoff_context_hook.ts +66 -18
- package/src/scripts/hooks/session_eol_hook.ts +12 -12
- package/src/scripts/hooks/turn_end_gate_hook.ts +296 -88
- package/src/scripts/language_mirror_hook.ts +69 -16
- package/src/scripts/measure_turn_end_gate.ts +129 -51
- package/src/scripts/report_carrier_divergence.ts +143 -30
- package/src/scripts/report_conformance_funnel.ts +18 -4
- package/src/scripts/routing_doctor.ts +25 -2
- package/src/scripts/schemas/dod.schema.json +45 -0
- package/src/server/schemas/settings.ts +2 -2
- package/dist/cli-delegate/chunk-RVGBH4XK.js +0 -142
package/dist/install/install.mjs
CHANGED
|
@@ -7374,7 +7374,7 @@ import * as fs18 from "node:fs";
|
|
|
7374
7374
|
import * as os7 from "node:os";
|
|
7375
7375
|
import * as path16 from "node:path";
|
|
7376
7376
|
import process3 from "node:process";
|
|
7377
|
-
import { fileURLToPath as
|
|
7377
|
+
import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
7378
7378
|
|
|
7379
7379
|
// src/scripts/_lib/json_pointers.ts
|
|
7380
7380
|
import { createHash } from "node:crypto";
|
|
@@ -9793,6 +9793,64 @@ import { createRequire as createRequire2 } from "node:module";
|
|
|
9793
9793
|
import * as fs12 from "node:fs";
|
|
9794
9794
|
import * as os6 from "node:os";
|
|
9795
9795
|
import * as path11 from "node:path";
|
|
9796
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
9797
|
+
|
|
9798
|
+
// src/shared/settingsCarveOut.ts
|
|
9799
|
+
var SETTINGS_CARVE_OUT = [
|
|
9800
|
+
{
|
|
9801
|
+
key: "projection.mode",
|
|
9802
|
+
reader: "src/scripts/install.ts:3409 _resolve_scoped_projection",
|
|
9803
|
+
absentResolvesTo: "legacy-all",
|
|
9804
|
+
reason: "The template fallback applies only when NO global settings file exists. Once a file exists, an absent key means legacy-all by documented contract, so an existing install is never silently narrowed on upgrade."
|
|
9805
|
+
},
|
|
9806
|
+
{
|
|
9807
|
+
key: "projection.rule_workspaces",
|
|
9808
|
+
reader: "src/install/rule_scope.ts:96 ruleScopeFromSettings",
|
|
9809
|
+
absentResolvesTo: "null \u2014 LEGACY_ALL, i.e. every rule ships including maintainer-only ones",
|
|
9810
|
+
reason: "Same upgrade contract as projection.mode, and the failure is louder: an absent list widens the projection instead of narrowing it."
|
|
9811
|
+
},
|
|
9812
|
+
{
|
|
9813
|
+
key: "discipline_profile",
|
|
9814
|
+
reader: "work_engine/_lib/agent_settings.ts:1263",
|
|
9815
|
+
absentResolvesTo: "essential, unconditionally",
|
|
9816
|
+
reason: "The template ships `auto`, which resolves to `off` on any measured-null model, any non-Claude host, and any host exposing no model id. Absent skips that resolution entirely and loads the essential tier everywhere."
|
|
9817
|
+
},
|
|
9818
|
+
{
|
|
9819
|
+
key: "chat_history.frequency",
|
|
9820
|
+
reader: "src/scripts/chat_history.ts:1140",
|
|
9821
|
+
absentResolvesTo: "per_phase",
|
|
9822
|
+
reason: "Canonical substitution is `per_turn`. Absent gives coarser capture than the shipped default \u2014 an audit-thinning change, which the class contract's own test 8 (what can the attacker HIDE) names as the severe direction."
|
|
9823
|
+
},
|
|
9824
|
+
{
|
|
9825
|
+
key: "profile.id",
|
|
9826
|
+
reader: "src/scripts/config/profiles.ts:221 resolve_profile",
|
|
9827
|
+
absentResolvesTo: "the id `developer`, but a DEGRADED profile \u2014 packs: [], personas: [], hints: []",
|
|
9828
|
+
reason: "Exactly the projection.mode shape: the template default is honoured only when no settings file exists. With a file present the id resolves but its profile body does not load, so the install silently loses every pack and persona."
|
|
9829
|
+
},
|
|
9830
|
+
{
|
|
9831
|
+
key: "quality.local_auto_run",
|
|
9832
|
+
reader: "src/scripts/lint_roadmap_ci_steps.ts:106",
|
|
9833
|
+
absentResolvesTo: "true \u2014 which DISABLES the CI-step gate",
|
|
9834
|
+
reason: "Inverted polarity, and the most dangerous row in the set: the template ships `false`, which ARMS the gate. Omitting the key would disarm a quality gate for every fresh install while the reference page says it is on."
|
|
9835
|
+
},
|
|
9836
|
+
{
|
|
9837
|
+
key: "onboarding.onboarded",
|
|
9838
|
+
reader: "src/scripts/onboarding_gate_hook.ts:99",
|
|
9839
|
+
absentResolvesTo: "gate skipped, as if onboarding had already completed",
|
|
9840
|
+
reason: "Absent behaves like `onboarded: true`, not like the template default `false`. Omitting it would skip the onboarding gate on precisely the fresh installs the gate exists for."
|
|
9841
|
+
},
|
|
9842
|
+
{
|
|
9843
|
+
key: "chat_history.enabled",
|
|
9844
|
+
reader: "src/scripts/chat_history.ts:1025 _read_chat_history_enabled",
|
|
9845
|
+
absentResolvesTo: "false",
|
|
9846
|
+
reason: "The reader falls back to false while the template ships true. This one is privacy-shaped: fixing the reader would start recording history for every install whose file lacks the key. Writing it explicitly keeps the decision visible in the file the user can read."
|
|
9847
|
+
}
|
|
9848
|
+
];
|
|
9849
|
+
function carveOutKeys() {
|
|
9850
|
+
return SETTINGS_CARVE_OUT.map((c) => c.key);
|
|
9851
|
+
}
|
|
9852
|
+
|
|
9853
|
+
// src/scripts/_lib/agent_settings.ts
|
|
9796
9854
|
var _require2 = createRequire2(import.meta.url);
|
|
9797
9855
|
var Logger = class {
|
|
9798
9856
|
name = "scripts._lib.agent_settings";
|
|
@@ -9890,7 +9948,45 @@ var MERGEABLE_KEYS = [
|
|
|
9890
9948
|
"knowledge.global_sharing.freshness.hypothesis_after_days",
|
|
9891
9949
|
"knowledge.global_sharing.freshness.stale_after_days"
|
|
9892
9950
|
];
|
|
9893
|
-
var
|
|
9951
|
+
var TEMPLATE_RELATIVE = path11.join("src", "config", "agent-settings.template.yml");
|
|
9952
|
+
var _PACKAGE_ROOT = path11.resolve(path11.dirname(fileURLToPath2(import.meta.url)), "..", "..", "..");
|
|
9953
|
+
function default_template_path() {
|
|
9954
|
+
return path11.join(_PACKAGE_ROOT, TEMPLATE_RELATIVE);
|
|
9955
|
+
}
|
|
9956
|
+
function _is_placeholder(value) {
|
|
9957
|
+
return typeof value === "string" && /^__[A-Z0-9_]+__$/.test(value);
|
|
9958
|
+
}
|
|
9959
|
+
function _prune_template(tree, excluded, prefix = "") {
|
|
9960
|
+
const out = {};
|
|
9961
|
+
for (const [key, value] of Object.entries(tree)) {
|
|
9962
|
+
const dotted = prefix === "" ? key : `${prefix}.${key}`;
|
|
9963
|
+
if (excluded.has(dotted) || _is_placeholder(value)) {
|
|
9964
|
+
continue;
|
|
9965
|
+
}
|
|
9966
|
+
if (_is_plain_dict(value)) {
|
|
9967
|
+
const child = _prune_template(value, excluded, dotted);
|
|
9968
|
+
if (Object.keys(child).length > 0) {
|
|
9969
|
+
out[key] = child;
|
|
9970
|
+
}
|
|
9971
|
+
continue;
|
|
9972
|
+
}
|
|
9973
|
+
out[key] = value;
|
|
9974
|
+
}
|
|
9975
|
+
return out;
|
|
9976
|
+
}
|
|
9977
|
+
var _template_defaults_cache = null;
|
|
9978
|
+
function template_defaults(template_path) {
|
|
9979
|
+
const use_cache = template_path === void 0;
|
|
9980
|
+
if (use_cache && _template_defaults_cache !== null) {
|
|
9981
|
+
return _deepcopy(_template_defaults_cache);
|
|
9982
|
+
}
|
|
9983
|
+
const parsed = _read_yaml(template_path ?? default_template_path()) ?? {};
|
|
9984
|
+
const pruned = _prune_template(parsed, new Set(carveOutKeys()));
|
|
9985
|
+
if (use_cache) {
|
|
9986
|
+
_template_defaults_cache = pruned;
|
|
9987
|
+
}
|
|
9988
|
+
return _deepcopy(pruned);
|
|
9989
|
+
}
|
|
9894
9990
|
var ANCHOR_AGENT_SETTINGS = "agent-settings";
|
|
9895
9991
|
var ANCHOR_AGENTS_DIR = "agents-dir";
|
|
9896
9992
|
var ANCHOR_GIT = "git";
|
|
@@ -10090,6 +10186,7 @@ function load_agent_settings(options = {}) {
|
|
|
10090
10186
|
const user_global_path = options.user_global_path ?? null;
|
|
10091
10187
|
const verbose = options.verbose ?? false;
|
|
10092
10188
|
const cwd = options.cwd ?? null;
|
|
10189
|
+
const template_path = options.template_path ?? null;
|
|
10093
10190
|
const user_global_raw = {};
|
|
10094
10191
|
for (const p of user_global_path ? [user_global_path] : user_global_settings_paths()) {
|
|
10095
10192
|
_deep_merge(user_global_raw, _read_yaml(p) ?? {});
|
|
@@ -10102,7 +10199,7 @@ function load_agent_settings(options = {}) {
|
|
|
10102
10199
|
);
|
|
10103
10200
|
}
|
|
10104
10201
|
const cascade = _resolve_cascade_paths(cwd, project_path);
|
|
10105
|
-
const merged =
|
|
10202
|
+
const merged = template_defaults(template_path ?? void 0);
|
|
10106
10203
|
_deep_merge(merged, user_global_filtered);
|
|
10107
10204
|
for (const p of cascade) {
|
|
10108
10205
|
const layer = _read_yaml(p) ?? {};
|
|
@@ -10238,10 +10335,18 @@ function _deep_merge(dst, src) {
|
|
|
10238
10335
|
}
|
|
10239
10336
|
}
|
|
10240
10337
|
}
|
|
10241
|
-
function
|
|
10242
|
-
|
|
10243
|
-
|
|
10244
|
-
|
|
10338
|
+
function _deepcopy(value) {
|
|
10339
|
+
if (Array.isArray(value)) {
|
|
10340
|
+
return value.map((v) => _deepcopy(v));
|
|
10341
|
+
}
|
|
10342
|
+
if (_is_plain_dict(value)) {
|
|
10343
|
+
const out = {};
|
|
10344
|
+
for (const [k, v] of Object.entries(value)) {
|
|
10345
|
+
out[k] = _deepcopy(v);
|
|
10346
|
+
}
|
|
10347
|
+
return out;
|
|
10348
|
+
}
|
|
10349
|
+
return value;
|
|
10245
10350
|
}
|
|
10246
10351
|
function _is_plain_dict(value) {
|
|
10247
10352
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -14967,10 +15072,10 @@ var settingsSchema = external_exports.object({
|
|
|
14967
15072
|
"Stop-slot turn-end gate (road-to-conformance-round5 Phase 3). Default off, and it is the only concern that can REFUSE a turn-end rather than a tool call \u2014 so it soaks behind an explicit opt-in before it binds. Round 5 measured the reason: both blocking carriers reached zero violations, neither advisory carrier did, and 19 wrong-language replies survived a pin that had fired 26-35 seconds earlier. A refused turn continues in the SAME turn and is never refused twice."
|
|
14968
15073
|
),
|
|
14969
15074
|
promissory: external_exports.boolean().default(true).describe(
|
|
14970
|
-
"Detector A of the turn-end gate: refuse a turn whose closing paragraph promises work not yet performed while asking the user nothing (20 measured occurrences). Inert while hooks.turn_end_gate.enabled is false."
|
|
15075
|
+
"Detector A of the turn-end gate: refuse a turn whose closing paragraph promises work not yet performed while asking the user nothing (20 measured occurrences). No fire rate is quoted here on purpose: the measured rate moved twice while the instrument itself was being corrected, so a number in a shipped description would be a moving target. Re-derive it with `measure-turn-end-gate --store <transcript dir>` against your own corpus before arming the gate. Inert while hooks.turn_end_gate.enabled is false."
|
|
14971
15076
|
),
|
|
14972
15077
|
language: external_exports.boolean().default(true).describe(
|
|
14973
|
-
"Detector B of the turn-end gate: refuse a turn whose
|
|
15078
|
+
"Detector B of the turn-end gate: refuse a turn whose reply is not in the pinned language (19 measured occurrences). Fenced code, inline code, quoted tool output, tables, URLs and paths are stripped first, and the remainder is then scored LEAD-FIRST by the same classifier that sets the pin \u2014 so the verdict usually comes from the reply opening, not from all of it. Sharing that classifier is deliberate: it stops the pin and the detector disagreeing about a turn. Accepted opt-in spellings for the switches below include YAML true/false and yes/no/on/off. Inert while hooks.turn_end_gate.enabled is false."
|
|
14974
15079
|
)
|
|
14975
15080
|
}).default({})
|
|
14976
15081
|
}),
|
|
@@ -16436,16 +16541,16 @@ import { spawnSync } from "node:child_process";
|
|
|
16436
16541
|
import * as fs17 from "node:fs";
|
|
16437
16542
|
import * as path15 from "node:path";
|
|
16438
16543
|
import process2 from "node:process";
|
|
16439
|
-
import { fileURLToPath as
|
|
16544
|
+
import { fileURLToPath as fileURLToPath4, pathToFileURL } from "node:url";
|
|
16440
16545
|
|
|
16441
16546
|
// src/scripts/_lib/package_root.ts
|
|
16442
16547
|
import * as fs16 from "node:fs";
|
|
16443
16548
|
import * as path14 from "node:path";
|
|
16444
|
-
import { fileURLToPath as
|
|
16549
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
16445
16550
|
var PACKAGE_NAME = "@event4u/agent-config";
|
|
16446
16551
|
var MAX_ASCENT = 16;
|
|
16447
16552
|
function resolvePackageRoot(fromUrlOrPath, legacyHops = 3) {
|
|
16448
|
-
const start = fromUrlOrPath.startsWith("file:") ?
|
|
16553
|
+
const start = fromUrlOrPath.startsWith("file:") ? fileURLToPath3(fromUrlOrPath) : fromUrlOrPath;
|
|
16449
16554
|
const startDir = path14.dirname(start);
|
|
16450
16555
|
let dir = startDir;
|
|
16451
16556
|
for (let i = 0; i < MAX_ASCENT; i++) {
|
|
@@ -16486,7 +16591,7 @@ var LEGACY_SETTINGS_FILES = [".agent-settings.yml", ".agent-user.yml"];
|
|
|
16486
16591
|
var LEGACY_STATE_FILENAME = ".implement-ticket-state.json";
|
|
16487
16592
|
var LEGACY_STATE_V1_FILENAME = ".work-state.json";
|
|
16488
16593
|
var LEGACY_AGENT_CONFIG_SHELL = "agent-config";
|
|
16489
|
-
var _HERE_DIR = path15.dirname(
|
|
16594
|
+
var _HERE_DIR = path15.dirname(fileURLToPath4(import.meta.url));
|
|
16490
16595
|
var ArgparseExit = class extends Error {
|
|
16491
16596
|
code;
|
|
16492
16597
|
constructor(code) {
|
|
@@ -17138,7 +17243,7 @@ function main(argv = null, options = {}) {
|
|
|
17138
17243
|
return _apply(project, out, err);
|
|
17139
17244
|
}
|
|
17140
17245
|
var _bundled = true;
|
|
17141
|
-
var _HERE =
|
|
17246
|
+
var _HERE = fileURLToPath4(import.meta.url);
|
|
17142
17247
|
function _isCliEntry() {
|
|
17143
17248
|
if (process2.argv[1] === void 0) {
|
|
17144
17249
|
return false;
|
|
@@ -17148,7 +17253,7 @@ function _isCliEntry() {
|
|
|
17148
17253
|
return true;
|
|
17149
17254
|
}
|
|
17150
17255
|
try {
|
|
17151
|
-
const here = fs17.realpathSync(
|
|
17256
|
+
const here = fs17.realpathSync(fileURLToPath4(import.meta.url));
|
|
17152
17257
|
const argv = fs17.realpathSync(path15.resolve(process2.argv[1]));
|
|
17153
17258
|
return here === argv;
|
|
17154
17259
|
} catch {
|
|
@@ -17168,7 +17273,7 @@ if (!_bundled && (_isCliEntry() || process2.argv[1] === _HERE)) {
|
|
|
17168
17273
|
}
|
|
17169
17274
|
|
|
17170
17275
|
// src/scripts/install.ts
|
|
17171
|
-
var _HERE2 =
|
|
17276
|
+
var _HERE2 = fileURLToPath5(import.meta.url);
|
|
17172
17277
|
var SystemExitError = class extends Error {
|
|
17173
17278
|
constructor(code) {
|
|
17174
17279
|
super(`system-exit-${code}`);
|
package/dist/mcp/server.json
CHANGED
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
"transport": {
|
|
10
10
|
"type": "stdio"
|
|
11
11
|
},
|
|
12
|
-
"version": "9.
|
|
12
|
+
"version": "9.32.0"
|
|
13
13
|
}
|
|
14
14
|
],
|
|
15
15
|
"repository": {
|
|
16
16
|
"source": "github",
|
|
17
17
|
"url": "https://github.com/event4u-app/agent-config"
|
|
18
18
|
},
|
|
19
|
-
"version": "9.
|
|
19
|
+
"version": "9.32.0"
|
|
20
20
|
}
|