@event4u/agent-config 9.16.0 → 9.18.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/AGENTS.md +1 -1
- package/CHANGELOG.md +80 -130
- package/README.md +1 -1
- package/dist/agent-src/commands/agent-handoff.md +100 -48
- package/dist/agent-src/commands/challenge-me/vision.md +5 -0
- package/dist/agent-src/commands/commit.md +1 -1
- package/dist/agent-src/commands/condense.md +19 -64
- package/dist/agent-src/commands/evals/agent-handoff.json +13 -1
- package/dist/agent-src/commands/evals/rule-compliance-audit.json +46 -0
- package/dist/agent-src/commands/feature/plan.md +20 -0
- package/dist/agent-src/commands/feature/roadmap.md +19 -0
- package/dist/agent-src/commands/memory/promote.md +14 -1
- package/dist/agent-src/commands/mode.md +9 -5
- package/dist/agent-src/commands/optimize/deep.md +72 -11
- package/dist/agent-src/commands/pr/create.md +29 -0
- package/dist/agent-src/commands/roadmap/create.md +29 -0
- package/dist/agent-src/commands/rule-compliance-audit.md +28 -5
- package/dist/agent-src/contexts/authority/commit-mechanics.md +5 -5
- package/dist/agent-src/contexts/communication/rules-auto/guidelines-mechanics.md +1 -0
- package/dist/agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +6 -1
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +4 -1
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +27 -1
- package/dist/agent-src/contexts/execution/plan-confidence-gate.md +133 -0
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +5 -2
- package/dist/agent-src/profiles/agency.yml +3 -3
- package/dist/agent-src/profiles/content_creator.yml +2 -2
- package/dist/agent-src/profiles/developer.yml +2 -2
- package/dist/agent-src/profiles/finance.yml +1 -1
- package/dist/agent-src/profiles/founder.yml +2 -2
- package/dist/agent-src/profiles/ops.yml +2 -2
- package/dist/agent-src/rules/active-remediation.md +2 -0
- package/dist/agent-src/rules/architecture.md +4 -2
- package/dist/agent-src/rules/augment-edit-discipline.md +2 -0
- package/dist/agent-src/rules/autonomous-execution.md +1 -1
- package/dist/agent-src/rules/brand-consistency.md +10 -62
- package/dist/agent-src/rules/brand-source-of-truth.md +62 -11
- package/dist/agent-src/rules/broken-access-control.md +4 -0
- package/dist/agent-src/rules/cli-output-handling.md +5 -0
- package/dist/agent-src/rules/code-comment-discipline.md +3 -0
- package/dist/agent-src/rules/commit-conventions.md +2 -0
- package/dist/agent-src/rules/context-hygiene.md +3 -2
- package/dist/agent-src/rules/cross-source-consistency.md +3 -0
- package/dist/agent-src/rules/design-fidelity.md +2 -0
- package/dist/agent-src/rules/doc-screenshot-hygiene.md +2 -0
- package/dist/agent-src/rules/docker-commands.md +4 -0
- package/dist/agent-src/rules/domain-adoption-policy.md +2 -0
- package/dist/agent-src/rules/domain-safety-disclaimer.md +5 -2
- package/dist/agent-src/rules/domain-safety-pii.md +1 -1
- package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +9 -0
- package/dist/agent-src/rules/image-likeness-and-rights.md +4 -0
- package/dist/agent-src/rules/improve-before-implement.md +4 -0
- package/dist/agent-src/rules/laravel-routing.md +4 -0
- package/dist/agent-src/rules/legal-safety-floor.md +3 -0
- package/dist/agent-src/rules/lethal-trifecta-guard.md +3 -0
- package/dist/agent-src/rules/media-governance-routing.md +5 -0
- package/dist/agent-src/rules/minimal-safe-diff.md +2 -0
- package/dist/agent-src/rules/no-roadmap-references.md +2 -0
- package/dist/agent-src/rules/notes-first-reasoning.md +2 -0
- package/dist/agent-src/rules/output-discipline.md +9 -2
- package/dist/agent-src/rules/php-coding.md +2 -0
- package/dist/agent-src/rules/prefer-enums-over-literals.md +3 -0
- package/dist/agent-src/rules/provider-lifecycle-discipline.md +5 -0
- package/dist/agent-src/rules/roadmap-ci-steps-policy.md +2 -0
- package/dist/agent-src/rules/roadmap-progress-sync.md +2 -0
- package/dist/agent-src/rules/rule-type-governance.md +2 -0
- package/dist/agent-src/rules/scale-discipline.md +3 -0
- package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +9 -2
- package/dist/agent-src/rules/senior-engineering-discipline.md +6 -0
- package/dist/agent-src/rules/skill-quality.md +2 -0
- package/dist/agent-src/rules/source-confidentiality.md +4 -0
- package/dist/agent-src/rules/source-discovery-gate.md +3 -0
- package/dist/agent-src/rules/source-of-truth.md +2 -0
- package/dist/agent-src/rules/strategy-safety-floor.md +2 -0
- package/dist/agent-src/rules/think-before-action.md +5 -0
- package/dist/agent-src/rules/token-budget-discipline.md +2 -2
- package/dist/agent-src/rules/ui-audit-gate.md +2 -0
- package/dist/agent-src/rules/user-interaction.md +3 -4
- package/dist/agent-src/skills/build-buy-partner/SKILL.md +1 -1
- package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +4 -4
- package/dist/agent-src/skills/copilot-config/SKILL.md +1 -1
- package/dist/agent-src/skills/deep-reading-analyst/SKILL.md +7 -4
- package/dist/agent-src/skills/description-assist/SKILL.md +1 -1
- package/dist/agent-src/skills/design-intelligence/SKILL.md +6 -180
- package/dist/agent-src/skills/design-intelligence/references/context-and-registers.md +100 -0
- package/dist/agent-src/skills/design-intelligence/references/integration-mapping.md +91 -0
- package/dist/agent-src/skills/design-review/SKILL.md +4 -141
- package/dist/agent-src/skills/design-review/references/review-communication.md +92 -0
- package/dist/agent-src/skills/design-review/references/verification-automation.md +61 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +8 -27
- package/dist/agent-src/skills/existing-ui-audit/references/anti-slop-cross-reference.md +31 -0
- package/dist/agent-src/skills/fe-design/SKILL.md +4 -289
- package/dist/agent-src/skills/fe-design/references/design-patterns.md +227 -0
- package/dist/agent-src/skills/fe-design/references/design-read-and-memory.md +75 -0
- package/dist/agent-src/skills/market-entry-analysis/SKILL.md +1 -1
- package/dist/agent-src/skills/persona-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/readme-reviewer/SKILL.md +2 -1
- package/dist/agent-src/skills/roadmap-management/SKILL.md +10 -0
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +12 -1
- package/dist/agent-src/skills/rule-writing/SKILL.md +4 -2
- package/dist/agent-src/skills/skill-reviewer/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +3 -1
- package/dist/agent-src/skills/token-optimizer/SKILL.md +2 -2
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +6 -3
- package/dist/agent-src/templates/agent-settings.md +13 -15
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +6 -2
- package/dist/agent-src/templates/persona.md +2 -2
- package/dist/agent-src/templates/roadmaps.md +13 -1
- package/dist/agent-src/templates/rule.md +1 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/_fix_lane.ts +52 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +8 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/design.ts +6 -0
- package/dist/agent-src/templates/scripts/work_engine/intent/classify.ts +56 -4
- package/dist/agent-src/templates/skill.md +1 -1
- package/dist/cli/registry.js +3 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/chunk-AIIUU73N.js +2040 -0
- package/dist/cli-delegate/{chunk-ZXXJLL5K.js → chunk-BSLUHV2F.js} +127 -1487
- package/dist/cli-delegate/{chunk-H574KOUH.js → chunk-ELMFOQPW.js} +35 -1
- package/dist/cli-delegate/chunk-LF2KKJ4Q.js +183 -0
- package/dist/cli-delegate/chunk-VSYT7OHO.js +1382 -0
- package/dist/cli-delegate/chunk-XGA2NTU4.js +3727 -0
- package/dist/cli-delegate/cmd_conformance.js +4 -3
- package/dist/cli-delegate/cmd_converge.js +3 -3
- package/dist/cli-delegate/cmd_doctor.js +3 -2
- package/dist/cli-delegate/cmd_explain.js +36 -36
- package/dist/cli-delegate/cmd_export.js +4 -4
- package/dist/cli-delegate/cmd_handoff.js +1169 -0
- package/dist/cli-delegate/cmd_memory_get.js +35 -3754
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +4 -4
- package/dist/cli-delegate/cmd_route_audit.js +249 -0
- package/dist/cli-delegate/cmd_route_explain.js +285 -0
- package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
- 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 +3 -3
- package/dist/cli-delegate/cmd_upgrade.js +3 -3
- package/dist/cli-delegate/cmd_validate.js +4 -4
- package/dist/cli-delegate/cmd_versions.js +3 -3
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +84 -84
- 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 +602 -507
- package/dist/install/install.mjs +34 -0
- package/dist/mcp/awesome-mcp-servers.row.md +1 -1
- package/dist/mcp/mcp-cloudflare-catalogue.json +2 -2
- package/dist/mcp/registry-manifest.json +4 -4
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +25 -3
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_src.js +39 -6
- package/dist/scripts/_lib/agent_src.js.map +1 -1
- package/dist/server/schemas/settings.js +25 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/guidelines/abstraction-thresholds.md +53 -0
- package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -1
- package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +7 -0
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +2 -2
- package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +5 -3
- package/docs/guidelines/agent-infra/size-and-scope.md +8 -2
- package/docs/guidelines/component-oriented-and-oop-development.md +11 -6
- package/docs/guidelines/docs/readme-size-and-splitting.md +5 -2
- package/llms.txt +1 -0
- package/package.json +1 -1
- package/src/agent-src/templates/scripts/work_engine/directives/ui/_fix_lane.ts +52 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +8 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/design.ts +6 -0
- package/src/agent-src/templates/scripts/work_engine/intent/classify.ts +56 -4
- package/src/config/agent-settings.template.yml +68 -0
- package/src/config/evaluator-budgets.json +8 -11
- package/src/config/gate-coverage.yml +70 -0
- package/src/scripts/_cli/cmd_explain.ts +41 -36
- package/src/scripts/_cli/cmd_handoff.ts +405 -0
- package/src/scripts/_cli/cmd_route_audit.ts +290 -0
- package/src/scripts/_cli/cmd_route_explain.ts +269 -0
- package/src/scripts/_cli/handoff_generate.ts +453 -0
- package/src/scripts/_cli/handoff_sessions.ts +435 -0
- package/src/scripts/_dispatch.bash +32 -0
- package/src/scripts/_lib/agent_src.ts +36 -6
- package/src/scripts/_lib/git_env.ts +40 -0
- package/src/scripts/_lib/md_table.ts +27 -0
- package/src/scripts/_lib/planning_settings.ts +43 -0
- package/src/scripts/_lib/release_material.ts +156 -0
- package/src/scripts/_lib/router_match.ts +301 -0
- package/src/scripts/annotate_r1_outcomes.ts +258 -0
- package/src/scripts/check_completion_review.ts +1140 -0
- package/src/scripts/check_condensation.ts +2 -1
- package/src/scripts/check_finding_dispositions.ts +278 -0
- package/src/scripts/check_pack_size.ts +4 -3
- package/src/scripts/check_references.ts +1 -0
- package/src/scripts/check_release_highlights.ts +300 -0
- package/src/scripts/check_release_pr_shape.ts +4 -0
- package/src/scripts/check_release_surface_equality.ts +132 -0
- package/src/scripts/check_reply_consistency.ts +187 -138
- package/src/scripts/compile_router.ts +20 -3
- package/src/scripts/dispatch_r2_reviewer.ts +968 -0
- package/src/scripts/eval_ui_triviality.ts +156 -0
- package/src/scripts/handoff_context_hook.ts +148 -0
- package/src/scripts/hook_manifest.yaml +17 -7
- package/src/scripts/hooks/concern_registry.ts +2 -0
- package/src/scripts/lint_abstraction_thresholds.ts +327 -0
- package/src/scripts/lint_framework_leakage_allowlist.json +2 -2
- package/src/scripts/lint_plan_risk_register.ts +931 -0
- package/src/scripts/lint_profile_personas.ts +153 -0
- package/src/scripts/lint_token_budget_discipline.ts +148 -0
- package/src/scripts/lint_trigger_collisions.ts +257 -0
- package/src/scripts/release.ts +156 -32
- package/src/scripts/release_drill.ts +491 -0
- package/src/scripts/router_telemetry.ts +16 -290
- package/src/scripts/schemas/command.schema.json +33 -0
- package/src/scripts/schemas/rule.schema.json +10 -0
- package/src/scripts/self_review_gate.ts +41 -3
- package/src/scripts/skill_linter.ts +3 -1
- package/src/scripts/smoke/router.sh +1 -1
- package/src/scripts/update_counts.ts +60 -12
- package/src/server/schemas/settings.ts +41 -0
- package/dist/cli-delegate/{chunk-XX6TOPD7.js → chunk-WR6GTRHJ.js} +3 -3
|
@@ -32,6 +32,13 @@ import {
|
|
|
32
32
|
excludedRuleBasenames,
|
|
33
33
|
ruleScopeFromSettings
|
|
34
34
|
} from "./chunk-NXFWFAYV.js";
|
|
35
|
+
import {
|
|
36
|
+
resolvePackageRoot
|
|
37
|
+
} from "./chunk-MCJYCQPF.js";
|
|
38
|
+
import {
|
|
39
|
+
config_exports,
|
|
40
|
+
hardenedSpawnEnv
|
|
41
|
+
} from "./chunk-VSYT7OHO.js";
|
|
35
42
|
import {
|
|
36
43
|
PROJECT_ROOT_ENV,
|
|
37
44
|
ProjectRootError,
|
|
@@ -45,9 +52,6 @@ import {
|
|
|
45
52
|
resolve_with_fallback,
|
|
46
53
|
write_target
|
|
47
54
|
} from "./chunk-NDJLNC6Q.js";
|
|
48
|
-
import {
|
|
49
|
-
resolvePackageRoot
|
|
50
|
-
} from "./chunk-MCJYCQPF.js";
|
|
51
55
|
import {
|
|
52
56
|
require_dist
|
|
53
57
|
} from "./chunk-OY53J6II.js";
|
|
@@ -59,9 +63,9 @@ import {
|
|
|
59
63
|
// src/scripts/_cli/cmd_doctor.ts
|
|
60
64
|
var YAML = __toESM(require_dist(), 1);
|
|
61
65
|
import * as crypto3 from "node:crypto";
|
|
62
|
-
import * as
|
|
63
|
-
import * as
|
|
64
|
-
import * as
|
|
66
|
+
import * as fs6 from "node:fs";
|
|
67
|
+
import * as os3 from "node:os";
|
|
68
|
+
import * as path7 from "node:path";
|
|
65
69
|
import process2 from "node:process";
|
|
66
70
|
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
|
|
67
71
|
|
|
@@ -163,70 +167,6 @@ import { spawnSync } from "node:child_process";
|
|
|
163
167
|
import * as fs3 from "node:fs";
|
|
164
168
|
import * as path3 from "node:path";
|
|
165
169
|
|
|
166
|
-
// src/scripts/_lib/spawn_env.ts
|
|
167
|
-
var DENY_EXACT = /* @__PURE__ */ new Set([
|
|
168
|
-
// dynamic loader
|
|
169
|
-
"LD_PRELOAD",
|
|
170
|
-
"LD_LIBRARY_PATH",
|
|
171
|
-
"LD_AUDIT",
|
|
172
|
-
"DYLD_INSERT_LIBRARIES",
|
|
173
|
-
"DYLD_LIBRARY_PATH",
|
|
174
|
-
"DYLD_FRAMEWORK_PATH",
|
|
175
|
-
"GCONV_PATH",
|
|
176
|
-
// git command-injection
|
|
177
|
-
"GIT_EXTERNAL_DIFF",
|
|
178
|
-
"GIT_SSH",
|
|
179
|
-
"GIT_SSH_COMMAND",
|
|
180
|
-
"GIT_PROXY_COMMAND",
|
|
181
|
-
"GIT_PAGER",
|
|
182
|
-
"PAGER",
|
|
183
|
-
// git config-injection: GIT_ALTERNATE_OBJECT_DIRECTORIES can point git at
|
|
184
|
-
// attacker-controlled object stores; the GIT_CONFIG* family is handled by
|
|
185
|
-
// prefix below (it is a general arbitrary-config-injection primitive).
|
|
186
|
-
"GIT_ALTERNATE_OBJECT_DIRECTORIES",
|
|
187
|
-
// git path-redirection: GIT_DIR / GIT_INDEX_FILE / GIT_NAMESPACE point a
|
|
188
|
-
// child's git at an attacker-controlled repo, index file, or ref namespace
|
|
189
|
-
// — ordinary git ops then read and write attacker state (low severity,
|
|
190
|
-
// same family as GIT_ALTERNATE_OBJECT_DIRECTORIES above).
|
|
191
|
-
"GIT_DIR",
|
|
192
|
-
"GIT_INDEX_FILE",
|
|
193
|
-
"GIT_NAMESPACE",
|
|
194
|
-
// resolver hijack: HOSTALIASES remaps hostnames via an attacker file,
|
|
195
|
-
// redirecting any network fetch the child performs (CWE-427-adjacent).
|
|
196
|
-
"HOSTALIASES",
|
|
197
|
-
// runtime auto-exec hooks
|
|
198
|
-
"NODE_OPTIONS",
|
|
199
|
-
"BASH_ENV",
|
|
200
|
-
"ENV",
|
|
201
|
-
"PYTHONPATH",
|
|
202
|
-
"PYTHONSTARTUP",
|
|
203
|
-
"PYTHONINSPECT",
|
|
204
|
-
"PERL5OPT",
|
|
205
|
-
"PERL5LIB",
|
|
206
|
-
"RUBYOPT",
|
|
207
|
-
// shell field-splitting
|
|
208
|
-
"IFS"
|
|
209
|
-
]);
|
|
210
|
-
function isDeniedByFamily(name) {
|
|
211
|
-
if (name.startsWith("LD_") || name.startsWith("DYLD_")) return true;
|
|
212
|
-
if (name.startsWith("GIT_") && name.endsWith("_COMMAND")) return true;
|
|
213
|
-
if (name === "GIT_CONFIG" || name.startsWith("GIT_CONFIG_")) return true;
|
|
214
|
-
return false;
|
|
215
|
-
}
|
|
216
|
-
function hardenedSpawnEnv(overrides = {}) {
|
|
217
|
-
const out = {};
|
|
218
|
-
for (const [key, value] of Object.entries(process.env)) {
|
|
219
|
-
if (value === void 0) continue;
|
|
220
|
-
if (DENY_EXACT.has(key)) continue;
|
|
221
|
-
if (isDeniedByFamily(key)) continue;
|
|
222
|
-
out[key] = value;
|
|
223
|
-
}
|
|
224
|
-
for (const [key, value] of Object.entries(overrides)) {
|
|
225
|
-
out[key] = value;
|
|
226
|
-
}
|
|
227
|
-
return out;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
170
|
// src/scripts/ai_council/events_log.ts
|
|
231
171
|
import * as crypto from "node:crypto";
|
|
232
172
|
import * as fs2 from "node:fs";
|
|
@@ -2173,1316 +2113,16 @@ function _defaultStdin() {
|
|
|
2173
2113
|
};
|
|
2174
2114
|
}
|
|
2175
2115
|
|
|
2176
|
-
// src/scripts/
|
|
2177
|
-
|
|
2178
|
-
__export(config_exports, {
|
|
2179
|
-
COUNCIL_CONFIG_ENV: () => COUNCIL_CONFIG_ENV,
|
|
2180
|
-
COUNCIL_CONFIG_RELNAME: () => COUNCIL_CONFIG_RELNAME,
|
|
2181
|
-
COUNCIL_CONFIG_USER_GLOBAL_REL: () => COUNCIL_CONFIG_USER_GLOBAL_REL,
|
|
2182
|
-
CouncilConfigError: () => CouncilConfigError,
|
|
2183
|
-
_RAW_KEY_PREFIXES: () => _RAW_KEY_PREFIXES,
|
|
2184
|
-
_build_config: () => _build_config,
|
|
2185
|
-
load_council_config: () => load_council_config,
|
|
2186
|
-
resolve_api_key: () => resolve_api_key,
|
|
2187
|
-
resolve_config_path: () => resolve_config_path
|
|
2188
|
-
});
|
|
2189
|
-
var import_yaml = __toESM(require_dist(), 1);
|
|
2116
|
+
// src/scripts/_lib/environment_detector.ts
|
|
2117
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
2190
2118
|
import * as fs4 from "node:fs";
|
|
2191
2119
|
import * as os from "node:os";
|
|
2192
2120
|
import * as path4 from "node:path";
|
|
2193
|
-
var _VALID_PROVIDERS = /* @__PURE__ */ new Set([
|
|
2194
|
-
"anthropic",
|
|
2195
|
-
"openai",
|
|
2196
|
-
"gemini",
|
|
2197
|
-
"xai",
|
|
2198
|
-
"perplexity"
|
|
2199
|
-
]);
|
|
2200
|
-
var _VALID_MODES = /* @__PURE__ */ new Set(["api", "manual", "cli", "auto"]);
|
|
2201
|
-
var _RAW_KEY_PREFIXES = [
|
|
2202
|
-
"sk-",
|
|
2203
|
-
"sk-ant-",
|
|
2204
|
-
"ya29.",
|
|
2205
|
-
"AIza",
|
|
2206
|
-
"xai-",
|
|
2207
|
-
"pplx-",
|
|
2208
|
-
"gsk_"
|
|
2209
|
-
];
|
|
2210
|
-
var CouncilConfigError = class extends Error {
|
|
2211
|
-
constructor(message) {
|
|
2212
|
-
super(message);
|
|
2213
|
-
this.name = "CouncilConfigError";
|
|
2214
|
-
}
|
|
2215
|
-
};
|
|
2216
|
-
function _pyReprStr(s) {
|
|
2217
|
-
const hasSingle = s.includes("'");
|
|
2218
|
-
const hasDouble = s.includes('"');
|
|
2219
|
-
const quote = hasSingle && !hasDouble ? '"' : "'";
|
|
2220
|
-
let body = s.replace(/\\/g, "\\\\").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
|
|
2221
|
-
if (quote === "'") {
|
|
2222
|
-
body = body.replace(/'/g, "\\'");
|
|
2223
|
-
} else {
|
|
2224
|
-
body = body.replace(/"/g, '\\"');
|
|
2225
|
-
}
|
|
2226
|
-
return `${quote}${body}${quote}`;
|
|
2227
|
-
}
|
|
2228
|
-
function _pyReprFloat(value) {
|
|
2229
|
-
if (Number.isInteger(value) && Number.isFinite(value)) {
|
|
2230
|
-
return `${value}.0`;
|
|
2231
|
-
}
|
|
2232
|
-
if (value === Infinity) {
|
|
2233
|
-
return "inf";
|
|
2234
|
-
}
|
|
2235
|
-
if (value === -Infinity) {
|
|
2236
|
-
return "-inf";
|
|
2237
|
-
}
|
|
2238
|
-
if (Number.isNaN(value)) {
|
|
2239
|
-
return "nan";
|
|
2240
|
-
}
|
|
2241
|
-
return String(value);
|
|
2242
|
-
}
|
|
2243
|
-
function _pyRepr3(value) {
|
|
2244
|
-
if (value instanceof _Float) {
|
|
2245
|
-
return _pyReprFloat(value.value);
|
|
2246
|
-
}
|
|
2247
|
-
if (value === null || value === void 0) {
|
|
2248
|
-
return "None";
|
|
2249
|
-
}
|
|
2250
|
-
if (typeof value === "boolean") {
|
|
2251
|
-
return value ? "True" : "False";
|
|
2252
|
-
}
|
|
2253
|
-
if (typeof value === "string") {
|
|
2254
|
-
return _pyReprStr(value);
|
|
2255
|
-
}
|
|
2256
|
-
if (typeof value === "number") {
|
|
2257
|
-
return String(value);
|
|
2258
|
-
}
|
|
2259
|
-
if (Array.isArray(value)) {
|
|
2260
|
-
return `[${value.map((v) => _pyRepr3(v)).join(", ")}]`;
|
|
2261
|
-
}
|
|
2262
|
-
if (typeof value === "object") {
|
|
2263
|
-
const parts = [];
|
|
2264
|
-
for (const [k, v] of Object.entries(value)) {
|
|
2265
|
-
parts.push(`${_pyReprStr(k)}: ${_pyRepr3(v)}`);
|
|
2266
|
-
}
|
|
2267
|
-
return `{${parts.join(", ")}}`;
|
|
2268
|
-
}
|
|
2269
|
-
return String(value);
|
|
2270
|
-
}
|
|
2271
|
-
var _Float = class {
|
|
2272
|
-
constructor(value) {
|
|
2273
|
-
this.value = value;
|
|
2274
|
-
}
|
|
2275
|
-
value;
|
|
2276
|
-
};
|
|
2277
|
-
function _f(n) {
|
|
2278
|
-
return new _Float(n);
|
|
2279
|
-
}
|
|
2280
|
-
function _pyTypeName(value) {
|
|
2281
|
-
if (value === null || value === void 0) {
|
|
2282
|
-
return "NoneType";
|
|
2283
|
-
}
|
|
2284
|
-
if (typeof value === "boolean") {
|
|
2285
|
-
return "bool";
|
|
2286
|
-
}
|
|
2287
|
-
if (typeof value === "number") {
|
|
2288
|
-
return Number.isInteger(value) ? "int" : "float";
|
|
2289
|
-
}
|
|
2290
|
-
if (typeof value === "string") {
|
|
2291
|
-
return "str";
|
|
2292
|
-
}
|
|
2293
|
-
if (Array.isArray(value)) {
|
|
2294
|
-
return "list";
|
|
2295
|
-
}
|
|
2296
|
-
if (typeof value === "object") {
|
|
2297
|
-
return "dict";
|
|
2298
|
-
}
|
|
2299
|
-
return typeof value;
|
|
2300
|
-
}
|
|
2301
|
-
function _sortedListRepr(items) {
|
|
2302
|
-
const sorted = [...items].sort();
|
|
2303
|
-
return `[${sorted.map((s) => _pyReprStr(s)).join(", ")}]`;
|
|
2304
|
-
}
|
|
2305
|
-
function _pyOct(mode) {
|
|
2306
|
-
return `0o${mode.toString(8)}`;
|
|
2307
|
-
}
|
|
2308
|
-
function _pyInt2(value) {
|
|
2309
|
-
if (typeof value === "boolean") {
|
|
2310
|
-
return value ? 1 : 0;
|
|
2311
|
-
}
|
|
2312
|
-
if (typeof value === "number") {
|
|
2313
|
-
return Math.trunc(value);
|
|
2314
|
-
}
|
|
2315
|
-
if (typeof value === "string") {
|
|
2316
|
-
const trimmed = value.trim();
|
|
2317
|
-
if (/^[+-]?\d+$/.test(trimmed)) {
|
|
2318
|
-
return parseInt(trimmed, 10);
|
|
2319
|
-
}
|
|
2320
|
-
throw new CouncilConfigError(
|
|
2321
|
-
`invalid literal for int() with base 10: ${_pyReprStr(value)}`
|
|
2322
|
-
);
|
|
2323
|
-
}
|
|
2324
|
-
throw new CouncilConfigError(
|
|
2325
|
-
`int() argument must be a string or a number, not '${_pyTypeName(value)}'`
|
|
2326
|
-
);
|
|
2327
|
-
}
|
|
2328
|
-
function _pyFloat(value) {
|
|
2329
|
-
if (typeof value === "boolean") {
|
|
2330
|
-
return value ? 1 : 0;
|
|
2331
|
-
}
|
|
2332
|
-
if (typeof value === "number") {
|
|
2333
|
-
return value;
|
|
2334
|
-
}
|
|
2335
|
-
if (typeof value === "string") {
|
|
2336
|
-
const trimmed = value.trim();
|
|
2337
|
-
const parsed = Number(trimmed);
|
|
2338
|
-
if (trimmed !== "" && Number.isFinite(parsed)) {
|
|
2339
|
-
return parsed;
|
|
2340
|
-
}
|
|
2341
|
-
if (/^[+-]?inf(inity)?$/i.test(trimmed)) {
|
|
2342
|
-
return trimmed.startsWith("-") ? -Infinity : Infinity;
|
|
2343
|
-
}
|
|
2344
|
-
if (/^[+-]?nan$/i.test(trimmed)) {
|
|
2345
|
-
return NaN;
|
|
2346
|
-
}
|
|
2347
|
-
throw new CouncilConfigError(
|
|
2348
|
-
`could not convert string to float: ${_pyReprStr(value)}`
|
|
2349
|
-
);
|
|
2350
|
-
}
|
|
2351
|
-
throw new CouncilConfigError(
|
|
2352
|
-
`float() argument must be a string or a number, not '${_pyTypeName(value)}'`
|
|
2353
|
-
);
|
|
2354
|
-
}
|
|
2355
|
-
function _isBool(value) {
|
|
2356
|
-
return typeof value === "boolean";
|
|
2357
|
-
}
|
|
2358
|
-
function _isInt(value) {
|
|
2359
|
-
return typeof value === "number" && !Number.isNaN(value) && Number.isInteger(value);
|
|
2360
|
-
}
|
|
2361
|
-
function _isNumber(value) {
|
|
2362
|
-
return typeof value === "number";
|
|
2363
|
-
}
|
|
2364
|
-
function _isDict(value) {
|
|
2365
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2366
|
-
}
|
|
2367
|
-
function _isStr(value) {
|
|
2368
|
-
return typeof value === "string";
|
|
2369
|
-
}
|
|
2370
|
-
function _isList(value) {
|
|
2371
|
-
return Array.isArray(value);
|
|
2372
|
-
}
|
|
2373
|
-
function _getOr(d, key, fallback) {
|
|
2374
|
-
const v = d[key];
|
|
2375
|
-
if (v === void 0) {
|
|
2376
|
-
return fallback;
|
|
2377
|
-
}
|
|
2378
|
-
if (v === null || v === false || v === 0 || v === "" || Array.isArray(v) && v.length === 0 || _isDict(v) && Object.keys(v).length === 0) {
|
|
2379
|
-
return fallback;
|
|
2380
|
-
}
|
|
2381
|
-
return v;
|
|
2382
|
-
}
|
|
2383
|
-
function _get(d, key, fallback) {
|
|
2384
|
-
const v = d[key];
|
|
2385
|
-
return v === void 0 ? fallback : v;
|
|
2386
|
-
}
|
|
2387
|
-
var _VALID_NECESSITY_MODES = /* @__PURE__ */ new Set([
|
|
2388
|
-
"off",
|
|
2389
|
-
"educate",
|
|
2390
|
-
"block",
|
|
2391
|
-
"warn-only"
|
|
2392
|
-
]);
|
|
2393
|
-
var _VALID_DISCLOSURE_MODES = /* @__PURE__ */ new Set([
|
|
2394
|
-
"always",
|
|
2395
|
-
"above_threshold",
|
|
2396
|
-
"off"
|
|
2397
|
-
]);
|
|
2398
|
-
var _VALID_CHAIRMAN_MODES = /* @__PURE__ */ new Set(["host", "member", "auto"]);
|
|
2399
|
-
var COUNCIL_CONFIG_RELNAME = ".ai-council.yml";
|
|
2400
|
-
var COUNCIL_CONFIG_USER_GLOBAL_REL = "settings/.ai-council.yml";
|
|
2401
|
-
var COUNCIL_CONFIG_ENV = "AI_COUNCIL_CONFIG";
|
|
2402
|
-
function _expanduser(p) {
|
|
2403
|
-
if (p === "~") {
|
|
2404
|
-
return os.homedir();
|
|
2405
|
-
}
|
|
2406
|
-
if (p.startsWith("~/") || process.platform === "win32" && p.startsWith("~\\")) {
|
|
2407
|
-
return path4.join(os.homedir(), p.slice(2));
|
|
2408
|
-
}
|
|
2409
|
-
return p;
|
|
2410
|
-
}
|
|
2411
|
-
function _isAbsoluteLikePython(p) {
|
|
2412
|
-
if (process.platform === "win32") {
|
|
2413
|
-
return /^[a-zA-Z]:[\\/]/.test(p) || /^([\\/]{2})[^\\/]+[\\/][^\\/]+/.test(p);
|
|
2414
|
-
}
|
|
2415
|
-
return p.startsWith("/");
|
|
2416
|
-
}
|
|
2417
|
-
function resolve_config_path(project_root, options = {}) {
|
|
2418
|
-
void project_root;
|
|
2419
|
-
const env_map = options.env != null ? options.env : process.env;
|
|
2420
|
-
const override = env_map[COUNCIL_CONFIG_ENV];
|
|
2421
|
-
if (override) {
|
|
2422
|
-
return _expanduser(override);
|
|
2423
|
-
}
|
|
2424
|
-
const found = resolve_with_fallback(
|
|
2425
|
-
COUNCIL_CONFIG_USER_GLOBAL_REL,
|
|
2426
|
-
{ env: options.env ?? null }
|
|
2427
|
-
);
|
|
2428
|
-
if (found !== null) {
|
|
2429
|
-
return found;
|
|
2430
|
-
}
|
|
2431
|
-
return write_target(COUNCIL_CONFIG_USER_GLOBAL_REL, {
|
|
2432
|
-
env: options.env ?? null
|
|
2433
|
-
});
|
|
2434
|
-
}
|
|
2435
|
-
function load_council_config(p) {
|
|
2436
|
-
if (!fs4.existsSync(p)) {
|
|
2437
|
-
throw new CouncilConfigError(
|
|
2438
|
-
`Council config not found at ${p}. Create it per docs/contracts/ai-council-config.md.`
|
|
2439
|
-
);
|
|
2440
|
-
}
|
|
2441
|
-
let raw;
|
|
2442
|
-
try {
|
|
2443
|
-
const text = fs4.readFileSync(p, "utf-8");
|
|
2444
|
-
const parsed = (0, import_yaml.parse)(text, { version: "1.1" });
|
|
2445
|
-
raw = parsed === null || parsed === void 0 ? {} : parsed;
|
|
2446
|
-
} catch (exc) {
|
|
2447
|
-
if (exc instanceof CouncilConfigError) {
|
|
2448
|
-
throw exc;
|
|
2449
|
-
}
|
|
2450
|
-
const msg = exc instanceof Error ? exc.message : String(exc);
|
|
2451
|
-
throw new CouncilConfigError(`${p}: invalid YAML \u2014 ${msg}`);
|
|
2452
|
-
}
|
|
2453
|
-
if (!_isDict(raw)) {
|
|
2454
|
-
throw new CouncilConfigError(`${p}: top-level must be a mapping.`);
|
|
2455
|
-
}
|
|
2456
|
-
return _build_config(raw, p);
|
|
2457
|
-
}
|
|
2458
|
-
function _build_config(raw, source_path) {
|
|
2459
|
-
const enabled = _get(raw, "enabled", false);
|
|
2460
|
-
if (!_isBool(enabled)) {
|
|
2461
|
-
throw new CouncilConfigError("`enabled` must be a bool.");
|
|
2462
|
-
}
|
|
2463
|
-
const defaults = _build_defaults(_asDict(_getOr(raw, "defaults", {})));
|
|
2464
|
-
const cost_budget = _build_cost_budget(
|
|
2465
|
-
_asDict(_getOr(raw, "cost_budget", {}))
|
|
2466
|
-
);
|
|
2467
|
-
const members_raw = _getOr(raw, "members", {});
|
|
2468
|
-
if (!_isDict(members_raw)) {
|
|
2469
|
-
throw new CouncilConfigError("`members` must be a mapping.");
|
|
2470
|
-
}
|
|
2471
|
-
const members = /* @__PURE__ */ new Map();
|
|
2472
|
-
for (const [name, cfg] of Object.entries(members_raw)) {
|
|
2473
|
-
members.set(
|
|
2474
|
-
name,
|
|
2475
|
-
_build_member(name, _asDict(_orEmpty(cfg)), defaults.mode)
|
|
2476
|
-
);
|
|
2477
|
-
}
|
|
2478
|
-
const advisors_raw = _getOr(raw, "advisors", {});
|
|
2479
|
-
if (!_isDict(advisors_raw)) {
|
|
2480
|
-
throw new CouncilConfigError("`advisors` must be a mapping.");
|
|
2481
|
-
}
|
|
2482
|
-
const advisors = /* @__PURE__ */ new Map();
|
|
2483
|
-
for (const [adv_name, adv_cfg] of Object.entries(advisors_raw)) {
|
|
2484
|
-
advisors.set(adv_name, _build_advisor(adv_name, _asDict(_orEmpty(adv_cfg))));
|
|
2485
|
-
}
|
|
2486
|
-
for (const adv of advisors.values()) {
|
|
2487
|
-
if (!adv.enabled) {
|
|
2488
|
-
continue;
|
|
2489
|
-
}
|
|
2490
|
-
const bound = members.get(adv.member);
|
|
2491
|
-
if (bound === void 0) {
|
|
2492
|
-
throw new CouncilConfigError(
|
|
2493
|
-
`advisors.${adv.name}.member=${_pyReprStr(adv.member)}: no such member in the \`members\` block.`
|
|
2494
|
-
);
|
|
2495
|
-
}
|
|
2496
|
-
if (!bound.enabled) {
|
|
2497
|
-
throw new CouncilConfigError(
|
|
2498
|
-
`advisors.${adv.name}.member=${_pyReprStr(adv.member)}: member exists but is disabled. Enable the member or disable the advisor.`
|
|
2499
|
-
);
|
|
2500
|
-
}
|
|
2501
|
-
}
|
|
2502
|
-
const consensus = _build_consensus_scoring(
|
|
2503
|
-
_asDict(_getOr(raw, "consensus_scoring", {}))
|
|
2504
|
-
);
|
|
2505
|
-
const cli_call_budget = _build_cli_call_budget(
|
|
2506
|
-
_asDict(_getOr(raw, "cli_call_budget", {}))
|
|
2507
|
-
);
|
|
2508
|
-
const necessity_classifier = _build_necessity_classifier(
|
|
2509
|
-
_asDict(_getOr(raw, "necessity_classifier", {}))
|
|
2510
|
-
);
|
|
2511
|
-
const model_downgrade = _build_model_downgrade(
|
|
2512
|
-
_asDict(_getOr(raw, "model_downgrade", {}))
|
|
2513
|
-
);
|
|
2514
|
-
const debate = _build_debate(_asDict(_getOr(raw, "debate", {})));
|
|
2515
|
-
const decision_replay = _build_decision_replay(
|
|
2516
|
-
_asDict(_getOr(raw, "decision_replay", {})),
|
|
2517
|
-
"decision_replay"
|
|
2518
|
-
);
|
|
2519
|
-
const stance_tally = _build_stance_tally(
|
|
2520
|
-
_asDict(_getOr(raw, "stance_tally", {})),
|
|
2521
|
-
"stance_tally"
|
|
2522
|
-
);
|
|
2523
|
-
const chairman = _build_chairman(
|
|
2524
|
-
_asDict(_getOr(raw, "chairman", {})),
|
|
2525
|
-
"chairman",
|
|
2526
|
-
members
|
|
2527
|
-
);
|
|
2528
|
-
const debate_gates = _build_debate_gates(
|
|
2529
|
-
_asDict(_getOr(raw, "debate_gates", {})),
|
|
2530
|
-
"debate_gates"
|
|
2531
|
-
);
|
|
2532
|
-
const restate = _build_restate(_asDict(_getOr(raw, "restate", {})), "restate");
|
|
2533
|
-
const decision_resolution = _build_decision_resolution(
|
|
2534
|
-
_asDict(_getOr(raw, "decision_resolution", {}))
|
|
2535
|
-
);
|
|
2536
|
-
const routing = _build_routing(_asDict(_getOr(raw, "routing", {})), members);
|
|
2537
|
-
const low_impact = _build_low_impact(
|
|
2538
|
-
_asDict(_getOr(raw, "low_impact", {})),
|
|
2539
|
-
members,
|
|
2540
|
-
routing
|
|
2541
|
-
);
|
|
2542
|
-
_reject_top_level_locked_dispatch(raw);
|
|
2543
|
-
const lens_overrides = _build_lens_overrides(
|
|
2544
|
-
_asDict(_getOr(raw, "lenses", {}))
|
|
2545
|
-
);
|
|
2546
|
-
return {
|
|
2547
|
-
enabled,
|
|
2548
|
-
defaults,
|
|
2549
|
-
cost_budget,
|
|
2550
|
-
members,
|
|
2551
|
-
advisors,
|
|
2552
|
-
consensus_scoring: consensus,
|
|
2553
|
-
cli_call_budget,
|
|
2554
|
-
necessity_classifier,
|
|
2555
|
-
model_downgrade,
|
|
2556
|
-
debate,
|
|
2557
|
-
decision_replay,
|
|
2558
|
-
stance_tally,
|
|
2559
|
-
chairman,
|
|
2560
|
-
debate_gates,
|
|
2561
|
-
restate,
|
|
2562
|
-
decision_resolution,
|
|
2563
|
-
routing,
|
|
2564
|
-
low_impact,
|
|
2565
|
-
lens_overrides,
|
|
2566
|
-
source_path
|
|
2567
|
-
};
|
|
2568
|
-
}
|
|
2569
|
-
function _orEmpty(value) {
|
|
2570
|
-
if (value === null || value === void 0 || value === false || value === 0 || value === "" || Array.isArray(value) && value.length === 0 || _isDict(value) && Object.keys(value).length === 0) {
|
|
2571
|
-
return {};
|
|
2572
|
-
}
|
|
2573
|
-
return value;
|
|
2574
|
-
}
|
|
2575
|
-
function _asDict(value) {
|
|
2576
|
-
return value;
|
|
2577
|
-
}
|
|
2578
|
-
function _build_necessity_classifier(d) {
|
|
2579
|
-
if (!_isDict(d)) {
|
|
2580
|
-
throw new CouncilConfigError("`necessity_classifier` must be a mapping.");
|
|
2581
|
-
}
|
|
2582
|
-
const enabled = _get(d, "enabled", true);
|
|
2583
|
-
if (!_isBool(enabled)) {
|
|
2584
|
-
throw new CouncilConfigError(
|
|
2585
|
-
"`necessity_classifier.enabled` must be a bool."
|
|
2586
|
-
);
|
|
2587
|
-
}
|
|
2588
|
-
const mode = _get(d, "mode", "educate");
|
|
2589
|
-
if (!(_isStr(mode) && _VALID_NECESSITY_MODES.has(mode))) {
|
|
2590
|
-
throw new CouncilConfigError(
|
|
2591
|
-
`necessity_classifier.mode=${_pyRepr3(mode)} not in ${_sortedListRepr(_VALID_NECESSITY_MODES)}.`
|
|
2592
|
-
);
|
|
2593
|
-
}
|
|
2594
|
-
const user_explicit_mode = _get(d, "user_explicit_mode", "warn-only");
|
|
2595
|
-
if (!(_isStr(user_explicit_mode) && _VALID_NECESSITY_MODES.has(user_explicit_mode))) {
|
|
2596
|
-
throw new CouncilConfigError(
|
|
2597
|
-
`necessity_classifier.user_explicit_mode=${_pyRepr3(user_explicit_mode)} not in ${_sortedListRepr(_VALID_NECESSITY_MODES)}.`
|
|
2598
|
-
);
|
|
2599
|
-
}
|
|
2600
|
-
return {
|
|
2601
|
-
enabled: Boolean(enabled),
|
|
2602
|
-
mode,
|
|
2603
|
-
user_explicit_mode
|
|
2604
|
-
};
|
|
2605
|
-
}
|
|
2606
|
-
function _build_model_downgrade(d) {
|
|
2607
|
-
if (!_isDict(d)) {
|
|
2608
|
-
throw new CouncilConfigError("`model_downgrade` must be a mapping.");
|
|
2609
|
-
}
|
|
2610
|
-
const enabled = _get(d, "enabled", true);
|
|
2611
|
-
if (!_isBool(enabled)) {
|
|
2612
|
-
throw new CouncilConfigError("`model_downgrade.enabled` must be a bool.");
|
|
2613
|
-
}
|
|
2614
|
-
const auto_apply = _get(d, "auto_apply", false);
|
|
2615
|
-
if (!_isBool(auto_apply)) {
|
|
2616
|
-
throw new CouncilConfigError("`model_downgrade.auto_apply` must be a bool.");
|
|
2617
|
-
}
|
|
2618
|
-
const override_raw = _get(d, "model_tier_override", {});
|
|
2619
|
-
if (!_isDict(override_raw)) {
|
|
2620
|
-
throw new CouncilConfigError("`model_downgrade.model_tier_override` must be a mapping.");
|
|
2621
|
-
}
|
|
2622
|
-
const model_tier_override = {};
|
|
2623
|
-
for (const [k, v] of Object.entries(override_raw)) {
|
|
2624
|
-
if (!_isStr(v) || v.length === 0) {
|
|
2625
|
-
throw new CouncilConfigError(
|
|
2626
|
-
`\`model_downgrade.model_tier_override.${k}\` must be a non-empty string model id.`
|
|
2627
|
-
);
|
|
2628
|
-
}
|
|
2629
|
-
model_tier_override[k] = v;
|
|
2630
|
-
}
|
|
2631
|
-
return { enabled: Boolean(enabled), auto_apply: Boolean(auto_apply), model_tier_override };
|
|
2632
|
-
}
|
|
2633
|
-
function _build_cost_disclosure(d, scope) {
|
|
2634
|
-
if (!_isDict(d)) {
|
|
2635
|
-
throw new CouncilConfigError(`\`${scope}\` must be a mapping.`);
|
|
2636
|
-
}
|
|
2637
|
-
const mode = _get(d, "mode", "always");
|
|
2638
|
-
if (!(_isStr(mode) && _VALID_DISCLOSURE_MODES.has(mode))) {
|
|
2639
|
-
throw new CouncilConfigError(
|
|
2640
|
-
`${scope}.mode=${_pyRepr3(mode)} not in ${_sortedListRepr(_VALID_DISCLOSURE_MODES)}.`
|
|
2641
|
-
);
|
|
2642
|
-
}
|
|
2643
|
-
const threshold = _pyFloat(_get(d, "threshold_usd", 1));
|
|
2644
|
-
if (threshold < 0) {
|
|
2645
|
-
throw new CouncilConfigError(
|
|
2646
|
-
`${scope}.threshold_usd must be >= 0 (got ${_pyRepr3(_f(threshold))}).`
|
|
2647
|
-
);
|
|
2648
|
-
}
|
|
2649
|
-
const show_per_member = _get(d, "show_per_member", true);
|
|
2650
|
-
if (!_isBool(show_per_member)) {
|
|
2651
|
-
throw new CouncilConfigError(`\`${scope}.show_per_member\` must be a bool.`);
|
|
2652
|
-
}
|
|
2653
|
-
return {
|
|
2654
|
-
mode,
|
|
2655
|
-
threshold_usd: threshold,
|
|
2656
|
-
show_per_member: Boolean(show_per_member)
|
|
2657
|
-
};
|
|
2658
|
-
}
|
|
2659
|
-
function _build_debate(d) {
|
|
2660
|
-
if (!_isDict(d)) {
|
|
2661
|
-
throw new CouncilConfigError("`debate` must be a mapping.");
|
|
2662
|
-
}
|
|
2663
|
-
const cap = _pyFloat(_get(d, "max_cost_usd", 5));
|
|
2664
|
-
if (cap < 0) {
|
|
2665
|
-
throw new CouncilConfigError(
|
|
2666
|
-
`debate.max_cost_usd must be >= 0 (got ${_pyRepr3(_f(cap))}; use 0 to disable the cap).`
|
|
2667
|
-
);
|
|
2668
|
-
}
|
|
2669
|
-
const disclosure_raw = _getOr(d, "cost_disclosure", {});
|
|
2670
|
-
const disclosure = _build_cost_disclosure(
|
|
2671
|
-
_asDict(disclosure_raw),
|
|
2672
|
-
"debate.cost_disclosure"
|
|
2673
|
-
);
|
|
2674
|
-
return { max_cost_usd: cap, cost_disclosure: disclosure };
|
|
2675
|
-
}
|
|
2676
|
-
function _build_decision_replay(d, scope) {
|
|
2677
|
-
if (!_isDict(d)) {
|
|
2678
|
-
throw new CouncilConfigError(`\`${scope}\` must be a mapping.`);
|
|
2679
|
-
}
|
|
2680
|
-
const enabled = _get(d, "enabled", true);
|
|
2681
|
-
if (!_isBool(enabled)) {
|
|
2682
|
-
throw new CouncilConfigError(`\`${scope}.enabled\` must be a bool.`);
|
|
2683
|
-
}
|
|
2684
|
-
const include_args = _get(d, "include_member_arguments", true);
|
|
2685
|
-
if (!_isBool(include_args)) {
|
|
2686
|
-
throw new CouncilConfigError(
|
|
2687
|
-
`\`${scope}.include_member_arguments\` must be a bool.`
|
|
2688
|
-
);
|
|
2689
|
-
}
|
|
2690
|
-
return {
|
|
2691
|
-
enabled: Boolean(enabled),
|
|
2692
|
-
include_member_arguments: Boolean(include_args)
|
|
2693
|
-
};
|
|
2694
|
-
}
|
|
2695
|
-
function _build_stance_tally(d, scope) {
|
|
2696
|
-
if (!_isDict(d)) {
|
|
2697
|
-
throw new CouncilConfigError(`\`${scope}\` must be a mapping.`);
|
|
2698
|
-
}
|
|
2699
|
-
const enabled = _get(d, "enabled", false);
|
|
2700
|
-
if (!_isBool(enabled)) {
|
|
2701
|
-
throw new CouncilConfigError(`\`${scope}.enabled\` must be a bool.`);
|
|
2702
|
-
}
|
|
2703
|
-
return { enabled: Boolean(enabled) };
|
|
2704
|
-
}
|
|
2705
|
-
function _build_chairman(d, scope, members) {
|
|
2706
|
-
if (!_isDict(d)) {
|
|
2707
|
-
throw new CouncilConfigError(`\`${scope}\` must be a mapping.`);
|
|
2708
|
-
}
|
|
2709
|
-
const mode = _get(d, "mode", "host");
|
|
2710
|
-
if (!(_isStr(mode) && _VALID_CHAIRMAN_MODES.has(mode))) {
|
|
2711
|
-
throw new CouncilConfigError(
|
|
2712
|
-
`\`${scope}.mode\`=${_pyRepr3(mode)} not in ${_sortedListRepr(_VALID_CHAIRMAN_MODES)}.`
|
|
2713
|
-
);
|
|
2714
|
-
}
|
|
2715
|
-
let member = null;
|
|
2716
|
-
const rawMember = _get(d, "member", null);
|
|
2717
|
-
if (rawMember !== null && rawMember !== void 0) {
|
|
2718
|
-
if (!_isStr(rawMember)) {
|
|
2719
|
-
throw new CouncilConfigError(`\`${scope}.member\` must be a string.`);
|
|
2720
|
-
}
|
|
2721
|
-
member = rawMember;
|
|
2722
|
-
}
|
|
2723
|
-
if (mode === "member") {
|
|
2724
|
-
if (member === null) {
|
|
2725
|
-
throw new CouncilConfigError(
|
|
2726
|
-
`\`${scope}.mode\` is 'member' but \`${scope}.member\` is unset.`
|
|
2727
|
-
);
|
|
2728
|
-
}
|
|
2729
|
-
const bound = members.get(member);
|
|
2730
|
-
if (bound === void 0) {
|
|
2731
|
-
throw new CouncilConfigError(
|
|
2732
|
-
`\`${scope}.member\`=${_pyReprStr(member)}: no such member in the \`members\` block.`
|
|
2733
|
-
);
|
|
2734
|
-
}
|
|
2735
|
-
if (!bound.enabled) {
|
|
2736
|
-
throw new CouncilConfigError(
|
|
2737
|
-
`\`${scope}.member\`=${_pyReprStr(member)}: member exists but is disabled.`
|
|
2738
|
-
);
|
|
2739
|
-
}
|
|
2740
|
-
}
|
|
2741
|
-
return { mode, member };
|
|
2742
|
-
}
|
|
2743
|
-
function _build_debate_gates(d, scope) {
|
|
2744
|
-
if (!_isDict(d)) {
|
|
2745
|
-
throw new CouncilConfigError(`\`${scope}\` must be a mapping.`);
|
|
2746
|
-
}
|
|
2747
|
-
const enabled = _get(d, "enabled", false);
|
|
2748
|
-
if (!_isBool(enabled)) {
|
|
2749
|
-
throw new CouncilConfigError(`\`${scope}.enabled\` must be a bool.`);
|
|
2750
|
-
}
|
|
2751
|
-
return { enabled: Boolean(enabled) };
|
|
2752
|
-
}
|
|
2753
|
-
function _build_restate(d, scope) {
|
|
2754
|
-
if (!_isDict(d)) {
|
|
2755
|
-
throw new CouncilConfigError(`\`${scope}\` must be a mapping.`);
|
|
2756
|
-
}
|
|
2757
|
-
const enabled = _get(d, "enabled", false);
|
|
2758
|
-
if (!_isBool(enabled)) {
|
|
2759
|
-
throw new CouncilConfigError(`\`${scope}.enabled\` must be a bool.`);
|
|
2760
|
-
}
|
|
2761
|
-
return { enabled: Boolean(enabled) };
|
|
2762
|
-
}
|
|
2763
|
-
var _VALID_RESOLUTION_MODES = /* @__PURE__ */ new Set([
|
|
2764
|
-
"agent",
|
|
2765
|
-
"council",
|
|
2766
|
-
"user"
|
|
2767
|
-
]);
|
|
2768
|
-
var _IMPACT_CLASSES = [
|
|
2769
|
-
"trivial",
|
|
2770
|
-
"low_impact",
|
|
2771
|
-
"medium_impact",
|
|
2772
|
-
"high_impact",
|
|
2773
|
-
"user_required"
|
|
2774
|
-
];
|
|
2775
|
-
var _LOCKED_IMPACT_CLASSES = /* @__PURE__ */ new Set([
|
|
2776
|
-
"high_impact",
|
|
2777
|
-
"user_required"
|
|
2778
|
-
]);
|
|
2779
|
-
var _DEFAULT_RESOLUTION_MODES = {
|
|
2780
|
-
trivial: "agent",
|
|
2781
|
-
low_impact: "agent",
|
|
2782
|
-
medium_impact: "council",
|
|
2783
|
-
high_impact: "user",
|
|
2784
|
-
user_required: "user"
|
|
2785
|
-
};
|
|
2786
|
-
function _build_decision_resolution(d) {
|
|
2787
|
-
if (!_isDict(d)) {
|
|
2788
|
-
throw new CouncilConfigError("`decision_resolution` must be a mapping.");
|
|
2789
|
-
}
|
|
2790
|
-
const enabled = _get(d, "enabled", true);
|
|
2791
|
-
if (!_isBool(enabled)) {
|
|
2792
|
-
throw new CouncilConfigError(
|
|
2793
|
-
"`decision_resolution.enabled` must be a bool."
|
|
2794
|
-
);
|
|
2795
|
-
}
|
|
2796
|
-
const classes_raw = _getOr(d, "classes", {});
|
|
2797
|
-
if (!_isDict(classes_raw)) {
|
|
2798
|
-
throw new CouncilConfigError(
|
|
2799
|
-
"`decision_resolution.classes` must be a mapping."
|
|
2800
|
-
);
|
|
2801
|
-
}
|
|
2802
|
-
const classes = /* @__PURE__ */ new Map();
|
|
2803
|
-
for (const cls of _IMPACT_CLASSES) {
|
|
2804
|
-
const entry_raw = _orEmpty(classes_raw[cls] ?? null);
|
|
2805
|
-
if (!_isDict(entry_raw)) {
|
|
2806
|
-
throw new CouncilConfigError(
|
|
2807
|
-
`\`decision_resolution.classes.${cls}\` must be a mapping.`
|
|
2808
|
-
);
|
|
2809
|
-
}
|
|
2810
|
-
const mode = _get(entry_raw, "mode", _DEFAULT_RESOLUTION_MODES[cls]);
|
|
2811
|
-
if (!(_isStr(mode) && _VALID_RESOLUTION_MODES.has(mode))) {
|
|
2812
|
-
throw new CouncilConfigError(
|
|
2813
|
-
`decision_resolution.classes.${cls}.mode=${_pyRepr3(mode)} not in ${_sortedListRepr(_VALID_RESOLUTION_MODES)}.`
|
|
2814
|
-
);
|
|
2815
|
-
}
|
|
2816
|
-
if (_LOCKED_IMPACT_CLASSES.has(cls) && mode !== "user") {
|
|
2817
|
-
throw new CouncilConfigError(
|
|
2818
|
-
`decision_resolution.classes.${cls}.mode=${_pyRepr3(mode)}: class \`${cls}\` is LOCKED to \`user\` (Iron Law) \u2014 high-impact and user-required decisions never bypass the user.`
|
|
2819
|
-
);
|
|
2820
|
-
}
|
|
2821
|
-
if (_LOCKED_IMPACT_CLASSES.has(cls) && "dispatch" in entry_raw) {
|
|
2822
|
-
throw new CouncilConfigError(
|
|
2823
|
-
`decision_resolution.classes.${cls}.dispatch=${_pyRepr3(entry_raw.dispatch)}: dispatch is not configurable for high-impact / user-required decisions \u2014 always full council.`
|
|
2824
|
-
);
|
|
2825
|
-
}
|
|
2826
|
-
const threshold = _pyFloat(_get(entry_raw, "confidence_threshold", 0.6));
|
|
2827
|
-
if (!(0 <= threshold && threshold <= 1)) {
|
|
2828
|
-
throw new CouncilConfigError(
|
|
2829
|
-
`decision_resolution.classes.${cls}.confidence_threshold must be in [0.0, 1.0] (got ${_pyRepr3(_f(threshold))}).`
|
|
2830
|
-
);
|
|
2831
|
-
}
|
|
2832
|
-
classes.set(cls, { mode, confidence_threshold: threshold });
|
|
2833
|
-
}
|
|
2834
|
-
const fast_path_raw = _getOr(d, "fast_path", {});
|
|
2835
|
-
if (!_isDict(fast_path_raw)) {
|
|
2836
|
-
throw new CouncilConfigError(
|
|
2837
|
-
"`decision_resolution.fast_path` must be a mapping."
|
|
2838
|
-
);
|
|
2839
|
-
}
|
|
2840
|
-
const fast_path = _build_fast_path(_asDict(fast_path_raw));
|
|
2841
|
-
return { enabled: Boolean(enabled), classes, fast_path };
|
|
2842
|
-
}
|
|
2843
|
-
function _build_fast_path(d) {
|
|
2844
|
-
const max_members = _get(d, "max_members", 2);
|
|
2845
|
-
if (!_isInt(max_members) || _isBool(max_members)) {
|
|
2846
|
-
throw new CouncilConfigError(
|
|
2847
|
-
`decision_resolution.fast_path.max_members must be an int (got ${_pyTypeName(max_members)}).`
|
|
2848
|
-
);
|
|
2849
|
-
}
|
|
2850
|
-
if (max_members < 1 || max_members > 2) {
|
|
2851
|
-
throw new CouncilConfigError(
|
|
2852
|
-
`decision_resolution.fast_path.max_members must be 1 or 2 (got ${max_members}). Fast-path is by design a 1-2 member lookup \u2014 wider fan-out belongs in the standard council path.`
|
|
2853
|
-
);
|
|
2854
|
-
}
|
|
2855
|
-
const max_rounds = _get(d, "max_rounds", 1);
|
|
2856
|
-
if (max_rounds !== 1) {
|
|
2857
|
-
throw new CouncilConfigError(
|
|
2858
|
-
`decision_resolution.fast_path.max_rounds is LOCKED to 1 (got ${_pyRepr3(max_rounds)}). Multi-round fast-paths defeat the purpose \u2014 escalate to standard council instead.`
|
|
2859
|
-
);
|
|
2860
|
-
}
|
|
2861
|
-
const max_tokens = _get(d, "max_tokens", 2500);
|
|
2862
|
-
if (!_isInt(max_tokens) || _isBool(max_tokens) || max_tokens <= 0) {
|
|
2863
|
-
throw new CouncilConfigError(
|
|
2864
|
-
`decision_resolution.fast_path.max_tokens must be a positive int (got ${_pyRepr3(max_tokens)}).`
|
|
2865
|
-
);
|
|
2866
|
-
}
|
|
2867
|
-
const max_cost_raw = _get(d, "max_cost_usd", 0.05);
|
|
2868
|
-
if (_isBool(max_cost_raw) || !_isNumber(max_cost_raw)) {
|
|
2869
|
-
throw new CouncilConfigError(
|
|
2870
|
-
`decision_resolution.fast_path.max_cost_usd must be a number (got ${_pyTypeName(max_cost_raw)}).`
|
|
2871
|
-
);
|
|
2872
|
-
}
|
|
2873
|
-
const max_cost = _pyFloat(max_cost_raw);
|
|
2874
|
-
if (max_cost <= 0) {
|
|
2875
|
-
throw new CouncilConfigError(
|
|
2876
|
-
`decision_resolution.fast_path.max_cost_usd must be > 0 (got ${_pyRepr3(_f(max_cost))}).`
|
|
2877
|
-
);
|
|
2878
|
-
}
|
|
2879
|
-
const fuzzy_match = _build_fuzzy_match(_asDict(_getOr(d, "fuzzy_match", {})));
|
|
2880
|
-
return {
|
|
2881
|
-
max_members,
|
|
2882
|
-
max_rounds: 1,
|
|
2883
|
-
max_tokens,
|
|
2884
|
-
max_cost_usd: max_cost,
|
|
2885
|
-
fuzzy_match
|
|
2886
|
-
};
|
|
2887
|
-
}
|
|
2888
|
-
function _build_fuzzy_match(d) {
|
|
2889
|
-
if (!_isDict(d)) {
|
|
2890
|
-
throw new CouncilConfigError(
|
|
2891
|
-
"decision_resolution.fast_path.fuzzy_match must be a mapping."
|
|
2892
|
-
);
|
|
2893
|
-
}
|
|
2894
|
-
const enabled = _get(d, "enabled", false);
|
|
2895
|
-
if (!_isBool(enabled)) {
|
|
2896
|
-
throw new CouncilConfigError(
|
|
2897
|
-
`decision_resolution.fast_path.fuzzy_match.enabled must be a bool (got ${_pyTypeName(enabled)}).`
|
|
2898
|
-
);
|
|
2899
|
-
}
|
|
2900
|
-
const threshold_raw = _get(d, "threshold", 0.92);
|
|
2901
|
-
if (_isBool(threshold_raw) || !_isNumber(threshold_raw)) {
|
|
2902
|
-
throw new CouncilConfigError(
|
|
2903
|
-
`decision_resolution.fast_path.fuzzy_match.threshold must be a number (got ${_pyTypeName(threshold_raw)}).`
|
|
2904
|
-
);
|
|
2905
|
-
}
|
|
2906
|
-
const threshold = _pyFloat(threshold_raw);
|
|
2907
|
-
if (!(0 < threshold && threshold <= 1)) {
|
|
2908
|
-
throw new CouncilConfigError(
|
|
2909
|
-
`decision_resolution.fast_path.fuzzy_match.threshold must be in (0.0, 1.0] (got ${_pyRepr3(_f(threshold))}).`
|
|
2910
|
-
);
|
|
2911
|
-
}
|
|
2912
|
-
return { enabled, threshold };
|
|
2913
|
-
}
|
|
2914
|
-
function _build_lens_overrides(d) {
|
|
2915
|
-
if (!_isDict(d)) {
|
|
2916
|
-
throw new CouncilConfigError("`lenses` must be a mapping.");
|
|
2917
|
-
}
|
|
2918
|
-
const nc_overrides = /* @__PURE__ */ new Map();
|
|
2919
|
-
const nc_user_overrides = /* @__PURE__ */ new Map();
|
|
2920
|
-
const md_overrides = /* @__PURE__ */ new Map();
|
|
2921
|
-
const cd_overrides = /* @__PURE__ */ new Map();
|
|
2922
|
-
const dr_overrides = /* @__PURE__ */ new Map();
|
|
2923
|
-
for (const [lens_name, lens_cfg] of Object.entries(d)) {
|
|
2924
|
-
if (!_isDict(lens_cfg)) {
|
|
2925
|
-
throw new CouncilConfigError(
|
|
2926
|
-
`\`lenses.${lens_name}\` must be a mapping.`
|
|
2927
|
-
);
|
|
2928
|
-
}
|
|
2929
|
-
const nc_block = lens_cfg.necessity_classifier;
|
|
2930
|
-
if (nc_block !== void 0 && nc_block !== null) {
|
|
2931
|
-
if (!_isDict(nc_block)) {
|
|
2932
|
-
throw new CouncilConfigError(
|
|
2933
|
-
`\`lenses.${lens_name}.necessity_classifier\` must be a mapping.`
|
|
2934
|
-
);
|
|
2935
|
-
}
|
|
2936
|
-
const mode = nc_block.mode;
|
|
2937
|
-
if (mode !== void 0 && mode !== null) {
|
|
2938
|
-
if (!(_isStr(mode) && _VALID_NECESSITY_MODES.has(mode))) {
|
|
2939
|
-
throw new CouncilConfigError(
|
|
2940
|
-
`lenses.${lens_name}.necessity_classifier.mode=${_pyRepr3(mode)} not in ${_sortedListRepr(_VALID_NECESSITY_MODES)}.`
|
|
2941
|
-
);
|
|
2942
|
-
}
|
|
2943
|
-
nc_overrides.set(lens_name, mode);
|
|
2944
|
-
}
|
|
2945
|
-
const user_mode = nc_block.user_explicit_mode;
|
|
2946
|
-
if (user_mode !== void 0 && user_mode !== null) {
|
|
2947
|
-
if (!(_isStr(user_mode) && _VALID_NECESSITY_MODES.has(user_mode))) {
|
|
2948
|
-
throw new CouncilConfigError(
|
|
2949
|
-
`lenses.${lens_name}.necessity_classifier.user_explicit_mode=${_pyRepr3(user_mode)} not in ${_sortedListRepr(_VALID_NECESSITY_MODES)}.`
|
|
2950
|
-
);
|
|
2951
|
-
}
|
|
2952
|
-
nc_user_overrides.set(lens_name, user_mode);
|
|
2953
|
-
}
|
|
2954
|
-
}
|
|
2955
|
-
const md_block = lens_cfg.model_downgrade;
|
|
2956
|
-
if (md_block !== void 0 && md_block !== null) {
|
|
2957
|
-
if (!_isDict(md_block)) {
|
|
2958
|
-
throw new CouncilConfigError(
|
|
2959
|
-
`\`lenses.${lens_name}.model_downgrade\` must be a mapping.`
|
|
2960
|
-
);
|
|
2961
|
-
}
|
|
2962
|
-
const md_enabled = _get(md_block, "enabled", true);
|
|
2963
|
-
if (!_isBool(md_enabled)) {
|
|
2964
|
-
throw new CouncilConfigError(
|
|
2965
|
-
`\`lenses.${lens_name}.model_downgrade.enabled\` must be a bool.`
|
|
2966
|
-
);
|
|
2967
|
-
}
|
|
2968
|
-
const md_auto = _get(md_block, "auto_apply", false);
|
|
2969
|
-
if (!_isBool(md_auto)) {
|
|
2970
|
-
throw new CouncilConfigError(
|
|
2971
|
-
`\`lenses.${lens_name}.model_downgrade.auto_apply\` must be a bool.`
|
|
2972
|
-
);
|
|
2973
|
-
}
|
|
2974
|
-
md_overrides.set(lens_name, {
|
|
2975
|
-
enabled: Boolean(md_enabled),
|
|
2976
|
-
auto_apply: Boolean(md_auto),
|
|
2977
|
-
model_tier_override: {}
|
|
2978
|
-
});
|
|
2979
|
-
}
|
|
2980
|
-
const cd_block = lens_cfg.cost_disclosure;
|
|
2981
|
-
if (cd_block !== void 0 && cd_block !== null) {
|
|
2982
|
-
cd_overrides.set(
|
|
2983
|
-
lens_name,
|
|
2984
|
-
_build_cost_disclosure(
|
|
2985
|
-
_asDict(cd_block),
|
|
2986
|
-
`lenses.${lens_name}.cost_disclosure`
|
|
2987
|
-
)
|
|
2988
|
-
);
|
|
2989
|
-
}
|
|
2990
|
-
const dr_block = lens_cfg.decision_replay;
|
|
2991
|
-
if (dr_block !== void 0 && dr_block !== null) {
|
|
2992
|
-
dr_overrides.set(
|
|
2993
|
-
lens_name,
|
|
2994
|
-
_build_decision_replay(
|
|
2995
|
-
_asDict(dr_block),
|
|
2996
|
-
`lenses.${lens_name}.decision_replay`
|
|
2997
|
-
)
|
|
2998
|
-
);
|
|
2999
|
-
}
|
|
3000
|
-
}
|
|
3001
|
-
return {
|
|
3002
|
-
necessity_classifier_mode: nc_overrides,
|
|
3003
|
-
necessity_classifier_user_explicit_mode: nc_user_overrides,
|
|
3004
|
-
model_downgrade: md_overrides,
|
|
3005
|
-
cost_disclosure: cd_overrides,
|
|
3006
|
-
decision_replay: dr_overrides
|
|
3007
|
-
};
|
|
3008
|
-
}
|
|
3009
|
-
function _build_consensus_scoring(d) {
|
|
3010
|
-
if (!_isDict(d)) {
|
|
3011
|
-
throw new CouncilConfigError("`consensus_scoring` must be a mapping.");
|
|
3012
|
-
}
|
|
3013
|
-
const strong = _pyFloat(_get(d, "strong_threshold", 0.7));
|
|
3014
|
-
const minority = _pyFloat(_get(d, "minority_threshold", 0.4));
|
|
3015
|
-
if (!(0 <= minority && minority <= strong && strong <= 1)) {
|
|
3016
|
-
throw new CouncilConfigError(
|
|
3017
|
-
`consensus_scoring thresholds broken: require 0 <= minority (${_pyNum(minority)}) <= strong (${_pyNum(strong)}) <= 1.`
|
|
3018
|
-
);
|
|
3019
|
-
}
|
|
3020
|
-
const lenses_raw = _get(d, "lenses", ["analysis"]);
|
|
3021
|
-
if (!_isList(lenses_raw) || !lenses_raw.every((x) => _isStr(x))) {
|
|
3022
|
-
throw new CouncilConfigError(
|
|
3023
|
-
"`consensus_scoring.lenses` must be a list of strings."
|
|
3024
|
-
);
|
|
3025
|
-
}
|
|
3026
|
-
return {
|
|
3027
|
-
enabled: Boolean(_pyTruthy2(_get(d, "enabled", false))),
|
|
3028
|
-
strong_threshold: strong,
|
|
3029
|
-
minority_threshold: minority,
|
|
3030
|
-
lenses: lenses_raw
|
|
3031
|
-
};
|
|
3032
|
-
}
|
|
3033
|
-
var _VALID_MEMBER_MODES = /* @__PURE__ */ new Set(["cli", "api"]);
|
|
3034
|
-
function _build_defaults(d) {
|
|
3035
|
-
if (!_isDict(d)) {
|
|
3036
|
-
throw new CouncilConfigError("`defaults` must be a mapping.");
|
|
3037
|
-
}
|
|
3038
|
-
const mode = _get(d, "mode", "api");
|
|
3039
|
-
if (!(_isStr(mode) && _VALID_MODES.has(mode))) {
|
|
3040
|
-
throw new CouncilConfigError(
|
|
3041
|
-
`defaults.mode=${_pyRepr3(mode)} not in ${_sortedListRepr(_VALID_MODES)}.`
|
|
3042
|
-
);
|
|
3043
|
-
}
|
|
3044
|
-
const member_mode = _get(d, "member_mode", "cli");
|
|
3045
|
-
if (!(_isStr(member_mode) && _VALID_MEMBER_MODES.has(member_mode))) {
|
|
3046
|
-
throw new CouncilConfigError(
|
|
3047
|
-
`defaults.member_mode=${_pyRepr3(member_mode)} not in ${_sortedListRepr(_VALID_MEMBER_MODES)}.`
|
|
3048
|
-
);
|
|
3049
|
-
}
|
|
3050
|
-
return {
|
|
3051
|
-
mode,
|
|
3052
|
-
member_mode,
|
|
3053
|
-
min_rounds: _pyInt2(_get(d, "min_rounds", 2)),
|
|
3054
|
-
deep_min_rounds: _pyInt2(_get(d, "deep_min_rounds", 3)),
|
|
3055
|
-
max_output_tokens: _pyInt2(_get(d, "max_output_tokens", 0)),
|
|
3056
|
-
session_retention_days: _pyInt2(_get(d, "session_retention_days", 7)),
|
|
3057
|
-
debate_max_rounds: _pyInt2(_get(d, "debate_max_rounds", 4))
|
|
3058
|
-
};
|
|
3059
|
-
}
|
|
3060
|
-
var _VALID_DISPATCH_MODES = /* @__PURE__ */ new Set(["full", "single"]);
|
|
3061
|
-
function _build_routing(d, members) {
|
|
3062
|
-
if (!_isDict(d)) {
|
|
3063
|
-
throw new CouncilConfigError("`routing` must be a mapping.");
|
|
3064
|
-
}
|
|
3065
|
-
const chain_raw = _get(d, "solo_member_fallback_chain", []);
|
|
3066
|
-
if (!_isList(chain_raw)) {
|
|
3067
|
-
throw new CouncilConfigError(
|
|
3068
|
-
`\`routing.solo_member_fallback_chain\` must be a list (got ${_pyTypeName(chain_raw)}).`
|
|
3069
|
-
);
|
|
3070
|
-
}
|
|
3071
|
-
const chain = [];
|
|
3072
|
-
const seen = /* @__PURE__ */ new Set();
|
|
3073
|
-
for (let idx = 0; idx < chain_raw.length; idx++) {
|
|
3074
|
-
const entry = chain_raw[idx];
|
|
3075
|
-
if (!_isStr(entry) || entry.trim() === "") {
|
|
3076
|
-
throw new CouncilConfigError(
|
|
3077
|
-
`routing.solo_member_fallback_chain[${idx}]: each entry must be a non-empty string (got ${_pyRepr3(entry)}).`
|
|
3078
|
-
);
|
|
3079
|
-
}
|
|
3080
|
-
if (seen.has(entry)) {
|
|
3081
|
-
throw new CouncilConfigError(
|
|
3082
|
-
`routing.solo_member_fallback_chain[${idx}]: duplicate entry ${_pyReprStr(entry)} \u2014 chain order must be unique.`
|
|
3083
|
-
);
|
|
3084
|
-
}
|
|
3085
|
-
if (!members.has(entry)) {
|
|
3086
|
-
throw new CouncilConfigError(
|
|
3087
|
-
`routing.solo_member_fallback_chain[${idx}]=${_pyReprStr(entry)}: no such member in the \`members\` block.`
|
|
3088
|
-
);
|
|
3089
|
-
}
|
|
3090
|
-
seen.add(entry);
|
|
3091
|
-
chain.push(entry);
|
|
3092
|
-
}
|
|
3093
|
-
const timeout_raw = _get(d, "auth_check_timeout_seconds", 3);
|
|
3094
|
-
if (!_isInt(timeout_raw) || _isBool(timeout_raw) || !(1 <= timeout_raw && timeout_raw <= 30)) {
|
|
3095
|
-
throw new CouncilConfigError(
|
|
3096
|
-
`routing.auth_check_timeout_seconds must be an int in [1, 30] (got ${_pyRepr3(timeout_raw)}).`
|
|
3097
|
-
);
|
|
3098
|
-
}
|
|
3099
|
-
return {
|
|
3100
|
-
solo_member_fallback_chain: chain,
|
|
3101
|
-
auth_check_timeout_seconds: timeout_raw
|
|
3102
|
-
};
|
|
3103
|
-
}
|
|
3104
|
-
function _build_low_impact(d, members, routing) {
|
|
3105
|
-
if (!_isDict(d)) {
|
|
3106
|
-
throw new CouncilConfigError("`low_impact` must be a mapping.");
|
|
3107
|
-
}
|
|
3108
|
-
const dispatch = _get(d, "dispatch", "full");
|
|
3109
|
-
if (!(_isStr(dispatch) && _VALID_DISPATCH_MODES.has(dispatch))) {
|
|
3110
|
-
throw new CouncilConfigError(
|
|
3111
|
-
`low_impact.dispatch=${_pyRepr3(dispatch)} not in ${_sortedListRepr(_VALID_DISPATCH_MODES)}.`
|
|
3112
|
-
);
|
|
3113
|
-
}
|
|
3114
|
-
if (dispatch === "single") {
|
|
3115
|
-
const enabled_in_chain = routing.solo_member_fallback_chain.filter(
|
|
3116
|
-
(name) => members.get(name) !== void 0 && members.get(name).enabled
|
|
3117
|
-
);
|
|
3118
|
-
if (enabled_in_chain.length === 0) {
|
|
3119
|
-
throw new CouncilConfigError(
|
|
3120
|
-
`low_impact.dispatch='single' requires at least one enabled member in routing.solo_member_fallback_chain (chain=${_pyRepr3([...routing.solo_member_fallback_chain])}). Enable a chain member or set dispatch back to 'full'.`
|
|
3121
|
-
);
|
|
3122
|
-
}
|
|
3123
|
-
}
|
|
3124
|
-
const shadow_raw = _get(d, "shadow_sample_rate", 0.1);
|
|
3125
|
-
if (_isBool(shadow_raw) || !_isNumber(shadow_raw)) {
|
|
3126
|
-
throw new CouncilConfigError(
|
|
3127
|
-
`low_impact.shadow_sample_rate must be a number (got ${_pyTypeName(shadow_raw)}).`
|
|
3128
|
-
);
|
|
3129
|
-
}
|
|
3130
|
-
const shadow = _pyFloat(shadow_raw);
|
|
3131
|
-
if (!(0 <= shadow && shadow <= 1)) {
|
|
3132
|
-
throw new CouncilConfigError(
|
|
3133
|
-
`low_impact.shadow_sample_rate must be in [0.0, 1.0] (got ${_pyRepr3(_f(shadow))}).`
|
|
3134
|
-
);
|
|
3135
|
-
}
|
|
3136
|
-
const floor_raw = _get(d, "solo_confidence_floor", 0.7);
|
|
3137
|
-
if (_isBool(floor_raw) || !_isNumber(floor_raw)) {
|
|
3138
|
-
throw new CouncilConfigError(
|
|
3139
|
-
`low_impact.solo_confidence_floor must be a number (got ${_pyTypeName(floor_raw)}).`
|
|
3140
|
-
);
|
|
3141
|
-
}
|
|
3142
|
-
const floor = _pyFloat(floor_raw);
|
|
3143
|
-
if (!(0 <= floor && floor <= 1)) {
|
|
3144
|
-
throw new CouncilConfigError(
|
|
3145
|
-
`low_impact.solo_confidence_floor must be in [0.0, 1.0] (got ${_pyRepr3(_f(floor))}).`
|
|
3146
|
-
);
|
|
3147
|
-
}
|
|
3148
|
-
return {
|
|
3149
|
-
dispatch,
|
|
3150
|
-
shadow_sample_rate: shadow,
|
|
3151
|
-
solo_confidence_floor: floor
|
|
3152
|
-
};
|
|
3153
|
-
}
|
|
3154
|
-
function _reject_top_level_locked_dispatch(raw) {
|
|
3155
|
-
for (const cls of _LOCKED_IMPACT_CLASSES) {
|
|
3156
|
-
const block = raw[cls];
|
|
3157
|
-
if (!_isDict(block)) {
|
|
3158
|
-
continue;
|
|
3159
|
-
}
|
|
3160
|
-
if ("dispatch" in block) {
|
|
3161
|
-
throw new CouncilConfigError(
|
|
3162
|
-
`${cls}.dispatch=${_pyRepr3(block.dispatch)}: dispatch is not configurable for high-impact / user-required decisions \u2014 always full council.`
|
|
3163
|
-
);
|
|
3164
|
-
}
|
|
3165
|
-
if ("solo_confidence_floor" in block) {
|
|
3166
|
-
throw new CouncilConfigError(
|
|
3167
|
-
`${cls}.solo_confidence_floor=${_pyRepr3(block.solo_confidence_floor)}: irrelevant on high-impact / user-required classes \u2014 they never dispatch solo. Set on \`low_impact\` instead.`
|
|
3168
|
-
);
|
|
3169
|
-
}
|
|
3170
|
-
}
|
|
3171
|
-
}
|
|
3172
|
-
function _build_cost_budget(d) {
|
|
3173
|
-
if (!_isDict(d)) {
|
|
3174
|
-
throw new CouncilConfigError("`cost_budget` must be a mapping.");
|
|
3175
|
-
}
|
|
3176
|
-
const cb = {
|
|
3177
|
-
max_input_tokens: _pyInt2(_get(d, "max_input_tokens", 5e5)),
|
|
3178
|
-
max_output_tokens: _pyInt2(_get(d, "max_output_tokens", 2e5)),
|
|
3179
|
-
max_calls: _pyInt2(_get(d, "max_calls", 50)),
|
|
3180
|
-
max_total_usd: _pyFloat(_get(d, "max_total_usd", 20)),
|
|
3181
|
-
daily_limit_usd: _pyFloat(_get(d, "daily_limit_usd", 0))
|
|
3182
|
-
};
|
|
3183
|
-
const fields = [
|
|
3184
|
-
["max_input_tokens", false],
|
|
3185
|
-
["max_output_tokens", false],
|
|
3186
|
-
["max_calls", false],
|
|
3187
|
-
["max_total_usd", true],
|
|
3188
|
-
["daily_limit_usd", true]
|
|
3189
|
-
];
|
|
3190
|
-
for (const [fname, isFloat] of fields) {
|
|
3191
|
-
const val = cb[fname];
|
|
3192
|
-
if (val < 0) {
|
|
3193
|
-
throw new CouncilConfigError(
|
|
3194
|
-
`cost_budget.${fname} must be >= 0 (got ${isFloat ? _pyRepr3(_f(val)) : _pyRepr3(val)}).`
|
|
3195
|
-
);
|
|
3196
|
-
}
|
|
3197
|
-
}
|
|
3198
|
-
return cb;
|
|
3199
|
-
}
|
|
3200
|
-
function _build_member(name, cfg, default_mode = "api") {
|
|
3201
|
-
if (!_VALID_PROVIDERS.has(name)) {
|
|
3202
|
-
throw new CouncilConfigError(
|
|
3203
|
-
`members.${name}: unknown provider; valid: ${_sortedListRepr(_VALID_PROVIDERS)}.`
|
|
3204
|
-
);
|
|
3205
|
-
}
|
|
3206
|
-
const member_enabled = Boolean(_pyTruthy2(_get(cfg, "enabled", false)));
|
|
3207
|
-
const modelVal = _get(cfg, "model", null);
|
|
3208
|
-
const model = _pyTruthy2(modelVal) ? modelVal : "";
|
|
3209
|
-
const api_key_ref_raw = _get(cfg, "api_key_ref", null);
|
|
3210
|
-
const api_key_ref = api_key_ref_raw === void 0 ? null : api_key_ref_raw;
|
|
3211
|
-
const member_mode_raw = _get(cfg, "mode", null);
|
|
3212
|
-
const member_mode = member_mode_raw === void 0 ? null : member_mode_raw;
|
|
3213
|
-
if (member_mode !== null && !(_isStr(member_mode) && _VALID_MODES.has(member_mode))) {
|
|
3214
|
-
throw new CouncilConfigError(
|
|
3215
|
-
`members.${name}.mode=${_pyRepr3(member_mode)} not in ${_sortedListRepr(_VALID_MODES)}.`
|
|
3216
|
-
);
|
|
3217
|
-
}
|
|
3218
|
-
const effective_mode = member_mode !== null ? member_mode : default_mode;
|
|
3219
|
-
const binary_raw = _get(cfg, "binary", null);
|
|
3220
|
-
const binary = binary_raw === void 0 ? null : binary_raw;
|
|
3221
|
-
if (binary !== null) {
|
|
3222
|
-
if (!_isStr(binary) || binary.trim() === "") {
|
|
3223
|
-
throw new CouncilConfigError(
|
|
3224
|
-
`members.${name}.binary must be a non-empty string when set.`
|
|
3225
|
-
);
|
|
3226
|
-
}
|
|
3227
|
-
if (effective_mode !== "cli" && effective_mode !== "auto") {
|
|
3228
|
-
throw new CouncilConfigError(
|
|
3229
|
-
`members.${name}.binary is only valid when the member's effective mode is 'cli' or 'auto' (got ${_pyRepr3(effective_mode)}). Set \`mode: cli\` on the member or \`defaults.mode: cli\` to use this field.`
|
|
3230
|
-
);
|
|
3231
|
-
}
|
|
3232
|
-
}
|
|
3233
|
-
if (member_enabled) {
|
|
3234
|
-
if (!model) {
|
|
3235
|
-
throw new CouncilConfigError(
|
|
3236
|
-
`members.${name}: enabled members require a non-empty \`model\`.`
|
|
3237
|
-
);
|
|
3238
|
-
}
|
|
3239
|
-
if (effective_mode === "api" && !_pyTruthy2(api_key_ref)) {
|
|
3240
|
-
throw new CouncilConfigError(
|
|
3241
|
-
`members.${name}: enabled api-mode members require an \`api_key_ref\`.`
|
|
3242
|
-
);
|
|
3243
|
-
}
|
|
3244
|
-
}
|
|
3245
|
-
if (api_key_ref !== null) {
|
|
3246
|
-
_validate_api_key_ref(`members.${name}`, api_key_ref);
|
|
3247
|
-
}
|
|
3248
|
-
const ladder_raw = _getOr(cfg, "model_ladder", []);
|
|
3249
|
-
if (!_isList(ladder_raw)) {
|
|
3250
|
-
throw new CouncilConfigError(
|
|
3251
|
-
`members.${name}.model_ladder must be a list (got ${_pyTypeName(ladder_raw)}).`
|
|
3252
|
-
);
|
|
3253
|
-
}
|
|
3254
|
-
let ladder = [];
|
|
3255
|
-
if (ladder_raw.length > 0) {
|
|
3256
|
-
const entries = [];
|
|
3257
|
-
for (const entry of ladder_raw) {
|
|
3258
|
-
if (!_isStr(entry) || entry.trim() === "") {
|
|
3259
|
-
throw new CouncilConfigError(
|
|
3260
|
-
`members.${name}.model_ladder entries must be non-empty strings (got ${_pyRepr3(entry)}).`
|
|
3261
|
-
);
|
|
3262
|
-
}
|
|
3263
|
-
entries.push(entry);
|
|
3264
|
-
}
|
|
3265
|
-
if (member_enabled && model && !entries.includes(model)) {
|
|
3266
|
-
throw new CouncilConfigError(
|
|
3267
|
-
`members.${name}.model_ladder must include the active \`model\` (${_pyReprStr(model)}); got ${_pyRepr3(entries)}.`
|
|
3268
|
-
);
|
|
3269
|
-
}
|
|
3270
|
-
ladder = entries;
|
|
3271
|
-
}
|
|
3272
|
-
const participate_raw = _get(cfg, "participate_low_impact", false);
|
|
3273
|
-
if (!_isBool(participate_raw)) {
|
|
3274
|
-
throw new CouncilConfigError(
|
|
3275
|
-
`members.${name}.participate_low_impact must be a bool (got ${_pyTypeName(participate_raw)}).`
|
|
3276
|
-
);
|
|
3277
|
-
}
|
|
3278
|
-
const tier_raw = _get(cfg, "tier", null);
|
|
3279
|
-
let tier = null;
|
|
3280
|
-
if (tier_raw !== null && tier_raw !== void 0) {
|
|
3281
|
-
if (typeof tier_raw !== "number" || !Number.isInteger(tier_raw) || tier_raw < 1) {
|
|
3282
|
-
throw new CouncilConfigError(
|
|
3283
|
-
`members.${name}.tier must be an integer >= 1 when set (got ${_pyRepr3(tier_raw)}).`
|
|
3284
|
-
);
|
|
3285
|
-
}
|
|
3286
|
-
tier = tier_raw;
|
|
3287
|
-
}
|
|
3288
|
-
const prompt_cache_raw = _get(cfg, "prompt_cache", null);
|
|
3289
|
-
let prompt_cache_ttl = "5m";
|
|
3290
|
-
if (prompt_cache_raw !== null && prompt_cache_raw !== void 0 && !_isBool(prompt_cache_raw)) {
|
|
3291
|
-
if (!_isDict(prompt_cache_raw)) {
|
|
3292
|
-
throw new CouncilConfigError(
|
|
3293
|
-
`members.${name}.prompt_cache must be a bool or a mapping (got ${_pyTypeName(prompt_cache_raw)}).`
|
|
3294
|
-
);
|
|
3295
|
-
}
|
|
3296
|
-
const ttl_raw = _get(prompt_cache_raw, "ttl", "5m");
|
|
3297
|
-
if (ttl_raw !== "5m" && ttl_raw !== "1h") {
|
|
3298
|
-
throw new CouncilConfigError(
|
|
3299
|
-
`members.${name}.prompt_cache.ttl must be '5m' or '1h' (got ${_pyRepr3(ttl_raw)}). '5m' remains the default until a pre-registered 30-debate gap sample clears 40% at >=5-minute inter-round gaps.`
|
|
3300
|
-
);
|
|
3301
|
-
}
|
|
3302
|
-
prompt_cache_ttl = ttl_raw;
|
|
3303
|
-
}
|
|
3304
|
-
return {
|
|
3305
|
-
name,
|
|
3306
|
-
enabled: member_enabled,
|
|
3307
|
-
model,
|
|
3308
|
-
api_key_ref: api_key_ref ?? null,
|
|
3309
|
-
mode: member_mode ?? null,
|
|
3310
|
-
binary: binary ?? null,
|
|
3311
|
-
model_ladder: ladder,
|
|
3312
|
-
participate_low_impact: participate_raw,
|
|
3313
|
-
tier,
|
|
3314
|
-
prompt_cache_ttl
|
|
3315
|
-
};
|
|
3316
|
-
}
|
|
3317
|
-
function _build_cli_call_budget(d) {
|
|
3318
|
-
if (!_isDict(d)) {
|
|
3319
|
-
throw new CouncilConfigError("`cli_call_budget` must be a mapping.");
|
|
3320
|
-
}
|
|
3321
|
-
const raw_caps = _getOr(d, "max_calls_per_day", {});
|
|
3322
|
-
if (!_isDict(raw_caps)) {
|
|
3323
|
-
throw new CouncilConfigError(
|
|
3324
|
-
"`cli_call_budget.max_calls_per_day` must be a mapping."
|
|
3325
|
-
);
|
|
3326
|
-
}
|
|
3327
|
-
const caps = /* @__PURE__ */ new Map();
|
|
3328
|
-
for (const [provider, value] of Object.entries(raw_caps)) {
|
|
3329
|
-
if (!_VALID_PROVIDERS.has(provider)) {
|
|
3330
|
-
throw new CouncilConfigError(
|
|
3331
|
-
`cli_call_budget.max_calls_per_day.${provider}: unknown provider; valid: ${_sortedListRepr(_VALID_PROVIDERS)}.`
|
|
3332
|
-
);
|
|
3333
|
-
}
|
|
3334
|
-
if (!_isInt(value) || _isBool(value) || value < 0) {
|
|
3335
|
-
throw new CouncilConfigError(
|
|
3336
|
-
`cli_call_budget.max_calls_per_day.${provider} must be a non-negative integer (got ${_pyRepr3(value)}).`
|
|
3337
|
-
);
|
|
3338
|
-
}
|
|
3339
|
-
caps.set(provider, value);
|
|
3340
|
-
}
|
|
3341
|
-
const warn_at_raw = _get(d, "warn_at", 0.8);
|
|
3342
|
-
if (_isBool(warn_at_raw) || !_isNumber(warn_at_raw)) {
|
|
3343
|
-
throw new CouncilConfigError(
|
|
3344
|
-
`cli_call_budget.warn_at must be a number in [0.0, 1.0] (got ${_pyRepr3(warn_at_raw)}).`
|
|
3345
|
-
);
|
|
3346
|
-
}
|
|
3347
|
-
const warn_at = _pyFloat(warn_at_raw);
|
|
3348
|
-
if (!(0 <= warn_at && warn_at <= 1)) {
|
|
3349
|
-
throw new CouncilConfigError(
|
|
3350
|
-
`cli_call_budget.warn_at must be in [0.0, 1.0] (got ${_pyNum(warn_at)}).`
|
|
3351
|
-
);
|
|
3352
|
-
}
|
|
3353
|
-
return { max_calls_per_day: caps, warn_at };
|
|
3354
|
-
}
|
|
3355
|
-
function _build_advisor(name, cfg) {
|
|
3356
|
-
if (!_isDict(cfg)) {
|
|
3357
|
-
throw new CouncilConfigError(`advisors.${name}: must be a mapping.`);
|
|
3358
|
-
}
|
|
3359
|
-
const member = _get(cfg, "member", null);
|
|
3360
|
-
if (!(_isStr(member) && _VALID_PROVIDERS.has(member))) {
|
|
3361
|
-
throw new CouncilConfigError(
|
|
3362
|
-
`advisors.${name}.member=${_pyRepr3(member)} not a valid provider; valid: ${_sortedListRepr(_VALID_PROVIDERS)}.`
|
|
3363
|
-
);
|
|
3364
|
-
}
|
|
3365
|
-
const personaVal = _get(cfg, "persona", null);
|
|
3366
|
-
const persona = _pyTruthy2(personaVal) ? personaVal : `personas/advisors/${name}.md`;
|
|
3367
|
-
const modelVal = _get(cfg, "model", null);
|
|
3368
|
-
const model = modelVal === void 0 ? null : modelVal;
|
|
3369
|
-
if (model !== null && !_isStr(model)) {
|
|
3370
|
-
throw new CouncilConfigError(
|
|
3371
|
-
`advisors.${name}.model must be a string when set.`
|
|
3372
|
-
);
|
|
3373
|
-
}
|
|
3374
|
-
return {
|
|
3375
|
-
name,
|
|
3376
|
-
enabled: Boolean(_pyTruthy2(_get(cfg, "enabled", false))),
|
|
3377
|
-
member,
|
|
3378
|
-
persona,
|
|
3379
|
-
model: model ?? null
|
|
3380
|
-
};
|
|
3381
|
-
}
|
|
3382
|
-
function _validate_api_key_ref(scope, ref) {
|
|
3383
|
-
if (!_isStr(ref) || ref === "") {
|
|
3384
|
-
throw new CouncilConfigError(`${scope}.api_key_ref must be a non-empty string.`);
|
|
3385
|
-
}
|
|
3386
|
-
if (_RAW_KEY_PREFIXES.some((prefix) => ref.startsWith(prefix))) {
|
|
3387
|
-
throw new CouncilConfigError(
|
|
3388
|
-
`${scope}.api_key_ref looks like a raw API key. Use \`file:<path>\` (0600) or \`env:<VAR>\` \u2014 never inline secrets.`
|
|
3389
|
-
);
|
|
3390
|
-
}
|
|
3391
|
-
if (ref.startsWith("file:")) {
|
|
3392
|
-
if (ref.slice("file:".length).trim() === "") {
|
|
3393
|
-
throw new CouncilConfigError(`${scope}.api_key_ref \`file:\` ref missing path.`);
|
|
3394
|
-
}
|
|
3395
|
-
return;
|
|
3396
|
-
}
|
|
3397
|
-
if (ref.startsWith("env:")) {
|
|
3398
|
-
if (ref.slice("env:".length).trim() === "") {
|
|
3399
|
-
throw new CouncilConfigError(
|
|
3400
|
-
`${scope}.api_key_ref \`env:\` ref missing variable name.`
|
|
3401
|
-
);
|
|
3402
|
-
}
|
|
3403
|
-
return;
|
|
3404
|
-
}
|
|
3405
|
-
throw new CouncilConfigError(
|
|
3406
|
-
`${scope}.api_key_ref must start with \`file:\` or \`env:\` (got ${_pyRepr3(ref)}).`
|
|
3407
|
-
);
|
|
3408
|
-
}
|
|
3409
|
-
function resolve_api_key(ref, scope = "api_key_ref") {
|
|
3410
|
-
_validate_api_key_ref(scope, ref);
|
|
3411
|
-
if (ref.startsWith("env:")) {
|
|
3412
|
-
const variable = ref.slice("env:".length).trim();
|
|
3413
|
-
if (variable === "") {
|
|
3414
|
-
throw new CouncilConfigError(`${scope}: \`env:\` ref missing variable name.`);
|
|
3415
|
-
}
|
|
3416
|
-
const value2 = (process.env[variable] ?? "").trim();
|
|
3417
|
-
if (value2 === "") {
|
|
3418
|
-
throw new CouncilConfigError(
|
|
3419
|
-
`${scope}: env var ${_pyReprStr(variable)} is unset or empty.`
|
|
3420
|
-
);
|
|
3421
|
-
}
|
|
3422
|
-
return value2;
|
|
3423
|
-
}
|
|
3424
|
-
const spec = ref.slice("file:".length).trim();
|
|
3425
|
-
if (spec === "") {
|
|
3426
|
-
throw new CouncilConfigError(`${scope}: \`file:\` ref missing path.`);
|
|
3427
|
-
}
|
|
3428
|
-
let resolved = _expanduser(spec);
|
|
3429
|
-
if (!_isAbsoluteLikePython(resolved)) {
|
|
3430
|
-
const found = resolve_with_fallback(spec);
|
|
3431
|
-
if (found === null) {
|
|
3432
|
-
const target = write_target(spec);
|
|
3433
|
-
throw new CouncilConfigError(
|
|
3434
|
-
`${scope}: key file not found at ${target} (or legacy fallback).`
|
|
3435
|
-
);
|
|
3436
|
-
}
|
|
3437
|
-
resolved = found;
|
|
3438
|
-
}
|
|
3439
|
-
if (!fs4.existsSync(resolved)) {
|
|
3440
|
-
throw new CouncilConfigError(`${scope}: key file does not exist at ${resolved}.`);
|
|
3441
|
-
}
|
|
3442
|
-
const mode = fs4.statSync(resolved).mode & 4095;
|
|
3443
|
-
if (mode !== 384) {
|
|
3444
|
-
throw new CouncilConfigError(
|
|
3445
|
-
`${scope}: unsafe permissions on ${resolved}: got ${_pyOct(mode)}, expected 0o600. Fix: chmod 600 ${resolved}`
|
|
3446
|
-
);
|
|
3447
|
-
}
|
|
3448
|
-
const value = fs4.readFileSync(resolved, "utf-8").trim();
|
|
3449
|
-
if (value === "") {
|
|
3450
|
-
throw new CouncilConfigError(`${scope}: key file at ${resolved} is empty.`);
|
|
3451
|
-
}
|
|
3452
|
-
return value;
|
|
3453
|
-
}
|
|
3454
|
-
function _pyNum(value) {
|
|
3455
|
-
return _pyReprFloat(value);
|
|
3456
|
-
}
|
|
3457
|
-
function _pyTruthy2(value) {
|
|
3458
|
-
if (value === null || value === void 0) {
|
|
3459
|
-
return false;
|
|
3460
|
-
}
|
|
3461
|
-
if (typeof value === "boolean") {
|
|
3462
|
-
return value;
|
|
3463
|
-
}
|
|
3464
|
-
if (typeof value === "number") {
|
|
3465
|
-
return value !== 0;
|
|
3466
|
-
}
|
|
3467
|
-
if (typeof value === "string") {
|
|
3468
|
-
return value !== "";
|
|
3469
|
-
}
|
|
3470
|
-
if (Array.isArray(value)) {
|
|
3471
|
-
return value.length > 0;
|
|
3472
|
-
}
|
|
3473
|
-
return Object.keys(value).length > 0;
|
|
3474
|
-
}
|
|
3475
|
-
|
|
3476
|
-
// src/scripts/_lib/environment_detector.ts
|
|
3477
|
-
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
3478
|
-
import * as fs5 from "node:fs";
|
|
3479
|
-
import * as os2 from "node:os";
|
|
3480
|
-
import * as path5 from "node:path";
|
|
3481
2121
|
|
|
3482
2122
|
// src/install/toolDetection.ts
|
|
3483
|
-
import { existsSync as
|
|
3484
|
-
import { homedir
|
|
3485
|
-
import { delimiter as delimiter2, join as
|
|
2123
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
2124
|
+
import { homedir } from "node:os";
|
|
2125
|
+
import { delimiter as delimiter2, join as join4 } from "node:path";
|
|
3486
2126
|
var TOOL_SIGNALS = {
|
|
3487
2127
|
"claude-code": { bins: ["claude"], homePaths: [".claude", ".claude.json", ".config/claude"] },
|
|
3488
2128
|
"claude-desktop": { absPaths: ["/Applications/Claude.app"], homePaths: ["Library/Application Support/Claude", ".config/Claude"] },
|
|
@@ -3527,8 +2167,8 @@ function resolveBinaryPath(name, pathEnv) {
|
|
|
3527
2167
|
for (const dir of pathEnv.split(delimiter2)) {
|
|
3528
2168
|
if (dir.length === 0) continue;
|
|
3529
2169
|
for (const candidate of [name, `${name}.exe`, `${name}.cmd`]) {
|
|
3530
|
-
const full =
|
|
3531
|
-
if (
|
|
2170
|
+
const full = join4(dir, candidate);
|
|
2171
|
+
if (existsSync3(full)) return full;
|
|
3532
2172
|
}
|
|
3533
2173
|
}
|
|
3534
2174
|
return null;
|
|
@@ -3538,10 +2178,10 @@ function binOnPath(name, pathEnv) {
|
|
|
3538
2178
|
}
|
|
3539
2179
|
function isToolInstalled(signal, home, pathEnv) {
|
|
3540
2180
|
for (const rel of signal.homePaths ?? []) {
|
|
3541
|
-
if (
|
|
2181
|
+
if (existsSync3(join4(home, rel))) return true;
|
|
3542
2182
|
}
|
|
3543
2183
|
for (const abs of signal.absPaths ?? []) {
|
|
3544
|
-
if (
|
|
2184
|
+
if (existsSync3(abs)) return true;
|
|
3545
2185
|
}
|
|
3546
2186
|
for (const bin of signal.bins ?? []) {
|
|
3547
2187
|
if (binOnPath(bin, pathEnv)) return true;
|
|
@@ -3549,7 +2189,7 @@ function isToolInstalled(signal, home, pathEnv) {
|
|
|
3549
2189
|
return false;
|
|
3550
2190
|
}
|
|
3551
2191
|
function detectInstalledTools(opts = {}) {
|
|
3552
|
-
const home = opts.home ??
|
|
2192
|
+
const home = opts.home ?? homedir();
|
|
3553
2193
|
const pathEnv = opts.pathEnv ?? process.env["PATH"] ?? "";
|
|
3554
2194
|
const out = {};
|
|
3555
2195
|
for (const [id, signal] of Object.entries(TOOL_SIGNALS)) {
|
|
@@ -3600,12 +2240,12 @@ function classifyBilling(provider, source) {
|
|
|
3600
2240
|
function codexHome(env) {
|
|
3601
2241
|
const map = env ?? process.env;
|
|
3602
2242
|
const override = (map["CODEX_HOME"] ?? "").trim();
|
|
3603
|
-
return override !== "" ? override :
|
|
2243
|
+
return override !== "" ? override : path4.join(homeOf(env), ".codex");
|
|
3604
2244
|
}
|
|
3605
2245
|
function homeOf(env) {
|
|
3606
2246
|
const map = env ?? process.env;
|
|
3607
2247
|
const injected = (map["HOME"] ?? "").trim();
|
|
3608
|
-
return injected !== "" ? injected :
|
|
2248
|
+
return injected !== "" ? injected : os.homedir();
|
|
3609
2249
|
}
|
|
3610
2250
|
var VERSION_PROBE_TIMEOUT_MS = 2e3;
|
|
3611
2251
|
function defaultProbeVersion(binary) {
|
|
@@ -3625,14 +2265,14 @@ ${res.stderr ?? ""}`;
|
|
|
3625
2265
|
}
|
|
3626
2266
|
function isFile(p) {
|
|
3627
2267
|
try {
|
|
3628
|
-
return
|
|
2268
|
+
return fs4.statSync(p).isFile();
|
|
3629
2269
|
} catch {
|
|
3630
2270
|
return false;
|
|
3631
2271
|
}
|
|
3632
2272
|
}
|
|
3633
2273
|
function exists(p) {
|
|
3634
2274
|
try {
|
|
3635
|
-
return
|
|
2275
|
+
return fs4.existsSync(p);
|
|
3636
2276
|
} catch {
|
|
3637
2277
|
return false;
|
|
3638
2278
|
}
|
|
@@ -3640,7 +2280,7 @@ function exists(p) {
|
|
|
3640
2280
|
function classifyCodexAuth(authPath) {
|
|
3641
2281
|
let data;
|
|
3642
2282
|
try {
|
|
3643
|
-
data = JSON.parse(
|
|
2283
|
+
data = JSON.parse(fs4.readFileSync(authPath, "utf-8"));
|
|
3644
2284
|
} catch {
|
|
3645
2285
|
return "cli-api-key";
|
|
3646
2286
|
}
|
|
@@ -3657,18 +2297,18 @@ function cliSubscriptionEvidence(provider, home, env, claudeConfigDir) {
|
|
|
3657
2297
|
if (provider === "anthropic") {
|
|
3658
2298
|
const configDir = claudeConfigDir;
|
|
3659
2299
|
for (const rel of [".credentials.json", "credentials.json"]) {
|
|
3660
|
-
const p =
|
|
2300
|
+
const p = path4.join(configDir, rel);
|
|
3661
2301
|
if (isFile(p)) return { source: "cli-subscription", evidence: p };
|
|
3662
2302
|
}
|
|
3663
2303
|
return null;
|
|
3664
2304
|
}
|
|
3665
2305
|
if (provider === "openai") {
|
|
3666
|
-
const p =
|
|
2306
|
+
const p = path4.join(codexHome(env), "auth.json");
|
|
3667
2307
|
if (isFile(p)) return { source: classifyCodexAuth(p), evidence: p };
|
|
3668
2308
|
return null;
|
|
3669
2309
|
}
|
|
3670
2310
|
if (provider === "gemini") {
|
|
3671
|
-
const p =
|
|
2311
|
+
const p = path4.join(home, ".gemini", "oauth_creds.json");
|
|
3672
2312
|
if (isFile(p)) return { source: "cli-subscription", evidence: p };
|
|
3673
2313
|
return null;
|
|
3674
2314
|
}
|
|
@@ -3700,7 +2340,7 @@ function detectHosts(opts) {
|
|
|
3700
2340
|
function detectAuth(opts) {
|
|
3701
2341
|
const env = opts.env ?? process.env;
|
|
3702
2342
|
const home = opts.home ?? homeOf(opts.env);
|
|
3703
|
-
const claudeConfigDir = opts.home === void 0 && opts.env === void 0 ? claude_config_dir() : (env["CLAUDE_CONFIG_DIR"] ?? "").trim() ||
|
|
2343
|
+
const claudeConfigDir = opts.home === void 0 && opts.env === void 0 ? claude_config_dir() : (env["CLAUDE_CONFIG_DIR"] ?? "").trim() || path4.join(home, ".claude");
|
|
3704
2344
|
const auth = [];
|
|
3705
2345
|
const keys = [];
|
|
3706
2346
|
for (const provider of knownProviders()) {
|
|
@@ -3754,7 +2394,7 @@ function detectEnvironment(opts = {}) {
|
|
|
3754
2394
|
}
|
|
3755
2395
|
|
|
3756
2396
|
// src/scripts/_cli/detection_report.ts
|
|
3757
|
-
import * as
|
|
2397
|
+
import * as path5 from "node:path";
|
|
3758
2398
|
|
|
3759
2399
|
// src/scripts/ai_council/transport_resolver.ts
|
|
3760
2400
|
var VALID_TRANSPORT_MODES = /* @__PURE__ */ new Set([
|
|
@@ -3943,7 +2583,7 @@ function cliBinaryPresent(environment, provider, binaryOverride) {
|
|
|
3943
2583
|
const expected = PROVIDER_CLI_META[provider]?.[0];
|
|
3944
2584
|
if (expected === void 0) return false;
|
|
3945
2585
|
return environment.hosts.some(
|
|
3946
|
-
(h) => h.binary !== null && stripExe(
|
|
2586
|
+
(h) => h.binary !== null && stripExe(path5.basename(h.binary)) === expected
|
|
3947
2587
|
);
|
|
3948
2588
|
}
|
|
3949
2589
|
function stripExe(name) {
|
|
@@ -4104,9 +2744,9 @@ function absentCouncilFacts(configPath) {
|
|
|
4104
2744
|
|
|
4105
2745
|
// src/scripts/ai_team/review_gate.ts
|
|
4106
2746
|
import * as crypto2 from "node:crypto";
|
|
4107
|
-
import * as
|
|
4108
|
-
import * as
|
|
4109
|
-
import * as
|
|
2747
|
+
import * as fs5 from "node:fs";
|
|
2748
|
+
import * as os2 from "node:os";
|
|
2749
|
+
import * as path6 from "node:path";
|
|
4110
2750
|
|
|
4111
2751
|
// src/scripts/ai_team/config.ts
|
|
4112
2752
|
var AI_TEAM_REVIEW_GATE_DEFAULTS = Object.freeze({
|
|
@@ -4123,16 +2763,16 @@ var AI_TEAM_DEFAULTS = Object.freeze({
|
|
|
4123
2763
|
});
|
|
4124
2764
|
|
|
4125
2765
|
// src/scripts/ai_team/review_gate.ts
|
|
4126
|
-
var GATE_LEDGER_RELPATH =
|
|
2766
|
+
var GATE_LEDGER_RELPATH = path6.join("agents", "runtime", "team", "events.log");
|
|
4127
2767
|
var _CODEX_PLUGIN_DATA_DIRNAME = `${CODEX_PLUGIN_ID}-${CODEX_MARKETPLACE_NAME}`;
|
|
4128
2768
|
function _workspace_state_segment(workspace_root) {
|
|
4129
2769
|
let canonical = workspace_root;
|
|
4130
2770
|
try {
|
|
4131
|
-
canonical =
|
|
2771
|
+
canonical = fs5.realpathSync.native(workspace_root);
|
|
4132
2772
|
} catch {
|
|
4133
2773
|
canonical = workspace_root;
|
|
4134
2774
|
}
|
|
4135
|
-
const slug_source =
|
|
2775
|
+
const slug_source = path6.basename(workspace_root) || "workspace";
|
|
4136
2776
|
const slug = slug_source.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "workspace";
|
|
4137
2777
|
const hash = crypto2.createHash("sha256").update(canonical).digest("hex").slice(0, 16);
|
|
4138
2778
|
return `${slug}-${hash}`;
|
|
@@ -4142,19 +2782,19 @@ function upstream_state_dir_candidates(workspace_root) {
|
|
|
4142
2782
|
const candidates = [];
|
|
4143
2783
|
const env = (process.env["CLAUDE_PLUGIN_DATA"] ?? "").trim();
|
|
4144
2784
|
if (env !== "") {
|
|
4145
|
-
candidates.push(
|
|
2785
|
+
candidates.push(path6.join(env, "state", segment));
|
|
4146
2786
|
}
|
|
4147
2787
|
candidates.push(
|
|
4148
|
-
|
|
2788
|
+
path6.join(claude_config_dir(), "plugins", "data", _CODEX_PLUGIN_DATA_DIRNAME, "state", segment)
|
|
4149
2789
|
);
|
|
4150
|
-
candidates.push(
|
|
2790
|
+
candidates.push(path6.join(os2.tmpdir(), "codex-companion", segment));
|
|
4151
2791
|
return candidates;
|
|
4152
2792
|
}
|
|
4153
2793
|
function upstream_gate_enabled(workspace_root) {
|
|
4154
2794
|
for (const dir of upstream_state_dir_candidates(workspace_root)) {
|
|
4155
2795
|
let parsed;
|
|
4156
2796
|
try {
|
|
4157
|
-
parsed = JSON.parse(
|
|
2797
|
+
parsed = JSON.parse(fs5.readFileSync(path6.join(dir, "state.json"), "utf-8"));
|
|
4158
2798
|
} catch {
|
|
4159
2799
|
continue;
|
|
4160
2800
|
}
|
|
@@ -4212,15 +2852,15 @@ var ArgparseExit = class extends Error {
|
|
|
4212
2852
|
code;
|
|
4213
2853
|
};
|
|
4214
2854
|
function expanduser(p) {
|
|
4215
|
-
if (p === "~") return
|
|
2855
|
+
if (p === "~") return os3.homedir();
|
|
4216
2856
|
if (p.startsWith("~/") || p.startsWith("~\\")) {
|
|
4217
|
-
return
|
|
2857
|
+
return path7.join(os3.homedir(), p.slice(2));
|
|
4218
2858
|
}
|
|
4219
2859
|
return p;
|
|
4220
2860
|
}
|
|
4221
2861
|
function pathExists(p) {
|
|
4222
2862
|
try {
|
|
4223
|
-
|
|
2863
|
+
fs6.statSync(p);
|
|
4224
2864
|
return true;
|
|
4225
2865
|
} catch {
|
|
4226
2866
|
return false;
|
|
@@ -4228,27 +2868,27 @@ function pathExists(p) {
|
|
|
4228
2868
|
}
|
|
4229
2869
|
function isFile2(p) {
|
|
4230
2870
|
try {
|
|
4231
|
-
return
|
|
2871
|
+
return fs6.statSync(p).isFile();
|
|
4232
2872
|
} catch {
|
|
4233
2873
|
return false;
|
|
4234
2874
|
}
|
|
4235
2875
|
}
|
|
4236
2876
|
function isDir(p) {
|
|
4237
2877
|
try {
|
|
4238
|
-
return
|
|
2878
|
+
return fs6.statSync(p).isDirectory();
|
|
4239
2879
|
} catch {
|
|
4240
2880
|
return false;
|
|
4241
2881
|
}
|
|
4242
2882
|
}
|
|
4243
2883
|
function resolvePath(p) {
|
|
4244
2884
|
try {
|
|
4245
|
-
return
|
|
2885
|
+
return fs6.realpathSync(path7.resolve(p));
|
|
4246
2886
|
} catch {
|
|
4247
|
-
return
|
|
2887
|
+
return path7.resolve(p);
|
|
4248
2888
|
}
|
|
4249
2889
|
}
|
|
4250
2890
|
function readText(p) {
|
|
4251
|
-
return
|
|
2891
|
+
return fs6.readFileSync(p, "utf-8");
|
|
4252
2892
|
}
|
|
4253
2893
|
function _jsonStrAscii(s) {
|
|
4254
2894
|
let out = '"';
|
|
@@ -4359,7 +2999,7 @@ function _resolve_project_root(arg) {
|
|
|
4359
2999
|
}
|
|
4360
3000
|
var _INSTALL_MODE_MARKER_REL = "agents/.agent-state/install-mode.txt";
|
|
4361
3001
|
function _detect_install_mode(project_root) {
|
|
4362
|
-
const marker =
|
|
3002
|
+
const marker = path7.join(project_root, _INSTALL_MODE_MARKER_REL);
|
|
4363
3003
|
if (isFile2(marker)) {
|
|
4364
3004
|
let value;
|
|
4365
3005
|
try {
|
|
@@ -4371,9 +3011,9 @@ function _detect_install_mode(project_root) {
|
|
|
4371
3011
|
return [value, "marker-file"];
|
|
4372
3012
|
}
|
|
4373
3013
|
}
|
|
4374
|
-
const has_agents_md = pathExists(
|
|
3014
|
+
const has_agents_md = pathExists(path7.join(project_root, "AGENTS.md"));
|
|
4375
3015
|
const has_copilot = pathExists(
|
|
4376
|
-
|
|
3016
|
+
path7.join(project_root, ".github", "copilot-instructions.md")
|
|
4377
3017
|
);
|
|
4378
3018
|
if (has_agents_md && has_copilot) {
|
|
4379
3019
|
return ["full", "heuristic"];
|
|
@@ -4393,7 +3033,7 @@ function _settings_layer_chain(project_root) {
|
|
|
4393
3033
|
return layers;
|
|
4394
3034
|
}
|
|
4395
3035
|
function _detect_wrapper(project_root) {
|
|
4396
|
-
const wrapper =
|
|
3036
|
+
const wrapper = path7.join(project_root, "agent-config");
|
|
4397
3037
|
if (!pathExists(wrapper)) {
|
|
4398
3038
|
return { path: String(wrapper), exists: false, embedded_root: null };
|
|
4399
3039
|
}
|
|
@@ -4460,14 +3100,14 @@ function _emit_context_text(ctx) {
|
|
|
4460
3100
|
}
|
|
4461
3101
|
function _resolve_path(project_root, raw) {
|
|
4462
3102
|
let p = expanduser(raw);
|
|
4463
|
-
if (!
|
|
4464
|
-
p =
|
|
3103
|
+
if (!path7.isAbsolute(p)) {
|
|
3104
|
+
p = path7.join(project_root, p);
|
|
4465
3105
|
}
|
|
4466
3106
|
return p;
|
|
4467
3107
|
}
|
|
4468
3108
|
function _sha256(p) {
|
|
4469
3109
|
try {
|
|
4470
|
-
const data =
|
|
3110
|
+
const data = fs6.readFileSync(p);
|
|
4471
3111
|
return crypto3.createHash("sha256").update(data).digest("hex");
|
|
4472
3112
|
} catch {
|
|
4473
3113
|
return null;
|
|
@@ -4476,7 +3116,7 @@ function _sha256(p) {
|
|
|
4476
3116
|
var PACKAGE_TAG_ID = "event4u/agent-config";
|
|
4477
3117
|
var _FRONTMATTER_PACKAGE_RE = /^package:\s*(.+?)\s*$/m;
|
|
4478
3118
|
function _read_inline_package_tag(p) {
|
|
4479
|
-
if (
|
|
3119
|
+
if (path7.extname(p) !== ".md") {
|
|
4480
3120
|
return NO_FRONTMATTER;
|
|
4481
3121
|
}
|
|
4482
3122
|
let text;
|
|
@@ -4605,13 +3245,13 @@ function rglob(root) {
|
|
|
4605
3245
|
const walk = (dir) => {
|
|
4606
3246
|
let entries;
|
|
4607
3247
|
try {
|
|
4608
|
-
entries =
|
|
3248
|
+
entries = fs6.readdirSync(dir, { withFileTypes: true });
|
|
4609
3249
|
} catch {
|
|
4610
3250
|
return;
|
|
4611
3251
|
}
|
|
4612
3252
|
entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
4613
3253
|
for (const ent of entries) {
|
|
4614
|
-
const full =
|
|
3254
|
+
const full = path7.join(dir, ent.name);
|
|
4615
3255
|
out.push(full);
|
|
4616
3256
|
let dirLike = ent.isDirectory();
|
|
4617
3257
|
if (ent.isSymbolicLink()) {
|
|
@@ -4686,9 +3326,9 @@ function _foreign_records(project_root, foreign) {
|
|
|
4686
3326
|
return out;
|
|
4687
3327
|
}
|
|
4688
3328
|
function relativeTo(p, base) {
|
|
4689
|
-
const rel =
|
|
3329
|
+
const rel = path7.relative(base, p);
|
|
4690
3330
|
if (rel === "") return rel;
|
|
4691
|
-
if (rel.startsWith("..") ||
|
|
3331
|
+
if (rel.startsWith("..") || path7.isAbsolute(rel)) {
|
|
4692
3332
|
return null;
|
|
4693
3333
|
}
|
|
4694
3334
|
return rel;
|
|
@@ -4752,7 +3392,7 @@ var MANIFEST_REQUIRED_CHECK_IDS = /* @__PURE__ */ new Set([
|
|
|
4752
3392
|
]);
|
|
4753
3393
|
var INSTALL_MODE_MARKER_RELATIVE = "agents/.agent-state/install-mode.txt";
|
|
4754
3394
|
function _is_global_only_consumer(project_root) {
|
|
4755
|
-
return isFile2(
|
|
3395
|
+
return isFile2(path7.join(project_root, INSTALL_MODE_MARKER_RELATIVE)) || isDir(path7.join(project_root, "agents", "overrides"));
|
|
4756
3396
|
}
|
|
4757
3397
|
var REPAIR_IDS = ["wizard-state"];
|
|
4758
3398
|
var MCP_BETA_GATES = [
|
|
@@ -4772,7 +3412,7 @@ var STATUS_SYMBOLS = {
|
|
|
4772
3412
|
var MIN_PYTHON = [3, 10];
|
|
4773
3413
|
function _check_scope(project_root) {
|
|
4774
3414
|
for (const marker of ["pnpm-workspace.yaml", "lerna.json"]) {
|
|
4775
|
-
if (pathExists(
|
|
3415
|
+
if (pathExists(path7.join(project_root, marker))) {
|
|
4776
3416
|
return {
|
|
4777
3417
|
id: "scope",
|
|
4778
3418
|
status: "warn",
|
|
@@ -4781,7 +3421,7 @@ function _check_scope(project_root) {
|
|
|
4781
3421
|
};
|
|
4782
3422
|
}
|
|
4783
3423
|
}
|
|
4784
|
-
const pkg =
|
|
3424
|
+
const pkg = path7.join(project_root, "package.json");
|
|
4785
3425
|
if (pathExists(pkg)) {
|
|
4786
3426
|
try {
|
|
4787
3427
|
const data = JSON.parse(readText(pkg));
|
|
@@ -4806,23 +3446,23 @@ function _check_scope(project_root) {
|
|
|
4806
3446
|
var _PLACEHOLDER_EMAIL_RE = /^(t@t\.t|.*@example\.(com|org)|.*@localhost)$/i;
|
|
4807
3447
|
var _PLACEHOLDER_NAME_RE = /^(t|test|user|nobody|x)$/i;
|
|
4808
3448
|
function _git_config_path(project_root) {
|
|
4809
|
-
const gd =
|
|
3449
|
+
const gd = path7.join(project_root, ".git");
|
|
4810
3450
|
try {
|
|
4811
|
-
const st =
|
|
3451
|
+
const st = fs6.statSync(gd);
|
|
4812
3452
|
if (st.isDirectory()) {
|
|
4813
|
-
return
|
|
3453
|
+
return path7.join(gd, "config");
|
|
4814
3454
|
}
|
|
4815
3455
|
const m = readText(gd).match(/^gitdir:\s*(.+)\s*$/m);
|
|
4816
3456
|
if (m === null) {
|
|
4817
3457
|
return null;
|
|
4818
3458
|
}
|
|
4819
|
-
const gdPath =
|
|
4820
|
-
const commondirFile =
|
|
3459
|
+
const gdPath = path7.resolve(project_root, m[1].trim());
|
|
3460
|
+
const commondirFile = path7.join(gdPath, "commondir");
|
|
4821
3461
|
if (pathExists(commondirFile)) {
|
|
4822
|
-
const common =
|
|
4823
|
-
return
|
|
3462
|
+
const common = path7.resolve(gdPath, readText(commondirFile).trim());
|
|
3463
|
+
return path7.join(common, "config");
|
|
4824
3464
|
}
|
|
4825
|
-
return
|
|
3465
|
+
return path7.join(gdPath, "config");
|
|
4826
3466
|
} catch {
|
|
4827
3467
|
return null;
|
|
4828
3468
|
}
|
|
@@ -4855,7 +3495,7 @@ function _check_git_identity(project_root) {
|
|
|
4855
3495
|
}
|
|
4856
3496
|
let ident = _parse_git_user(readText(cfgPath));
|
|
4857
3497
|
if (ident.name === null && ident.email === null) {
|
|
4858
|
-
const globalCfg =
|
|
3498
|
+
const globalCfg = path7.join(os3.homedir(), ".gitconfig");
|
|
4859
3499
|
if (pathExists(globalCfg)) {
|
|
4860
3500
|
ident = _parse_git_user(readText(globalCfg));
|
|
4861
3501
|
}
|
|
@@ -4916,7 +3556,7 @@ function _package_root() {
|
|
|
4916
3556
|
}
|
|
4917
3557
|
function _current_package_version() {
|
|
4918
3558
|
try {
|
|
4919
|
-
const data = JSON.parse(readText(
|
|
3559
|
+
const data = JSON.parse(readText(path7.join(_package_root(), "package.json")));
|
|
4920
3560
|
const v = data["version"];
|
|
4921
3561
|
if (typeof v === "string" && v.trim()) {
|
|
4922
3562
|
return v.trim();
|
|
@@ -4960,7 +3600,7 @@ function _check_lockfile_freshness(manifest) {
|
|
|
4960
3600
|
};
|
|
4961
3601
|
}
|
|
4962
3602
|
function shutilWhich(name) {
|
|
4963
|
-
if (
|
|
3603
|
+
if (path7.dirname(name) !== "." && (name.includes("/") || name.includes("\\"))) {
|
|
4964
3604
|
return isExecutableFile(name) ? name : null;
|
|
4965
3605
|
}
|
|
4966
3606
|
const pathEnv = process2.env["PATH"] || "";
|
|
@@ -4973,12 +3613,12 @@ function shutilWhich(name) {
|
|
|
4973
3613
|
if (seenDirs.has(d)) continue;
|
|
4974
3614
|
seenDirs.add(d);
|
|
4975
3615
|
for (const ext of exts) {
|
|
4976
|
-
const candidate =
|
|
3616
|
+
const candidate = path7.join(d, name + (ext === "" ? "" : ext.toLowerCase() === ext ? ext : ext));
|
|
4977
3617
|
if (isExecutableFile(candidate)) {
|
|
4978
3618
|
return candidate;
|
|
4979
3619
|
}
|
|
4980
3620
|
if (ext !== "") {
|
|
4981
|
-
const upper =
|
|
3621
|
+
const upper = path7.join(d, name + ext);
|
|
4982
3622
|
if (isExecutableFile(upper)) return upper;
|
|
4983
3623
|
}
|
|
4984
3624
|
}
|
|
@@ -4987,10 +3627,10 @@ function shutilWhich(name) {
|
|
|
4987
3627
|
}
|
|
4988
3628
|
function isExecutableFile(p) {
|
|
4989
3629
|
try {
|
|
4990
|
-
const st =
|
|
3630
|
+
const st = fs6.statSync(p);
|
|
4991
3631
|
if (!st.isFile()) return false;
|
|
4992
3632
|
if (process2.platform === "win32") return true;
|
|
4993
|
-
|
|
3633
|
+
fs6.accessSync(p, fs6.constants.X_OK);
|
|
4994
3634
|
return true;
|
|
4995
3635
|
} catch {
|
|
4996
3636
|
return false;
|
|
@@ -5054,7 +3694,7 @@ function _check_claude_plugin() {
|
|
|
5054
3694
|
remedy: ""
|
|
5055
3695
|
};
|
|
5056
3696
|
}
|
|
5057
|
-
const projection =
|
|
3697
|
+
const projection = path7.join(os3.homedir(), ".claude", "skills");
|
|
5058
3698
|
const projection_present = isDir(projection);
|
|
5059
3699
|
if (projection_present) {
|
|
5060
3700
|
return {
|
|
@@ -5091,8 +3731,8 @@ function _check_claude_command_wrappers() {
|
|
|
5091
3731
|
remedy: ""
|
|
5092
3732
|
};
|
|
5093
3733
|
}
|
|
5094
|
-
const anchor =
|
|
5095
|
-
const commands_dir =
|
|
3734
|
+
const anchor = path7.join(os3.homedir(), ".claude");
|
|
3735
|
+
const commands_dir = path7.join(anchor, "commands");
|
|
5096
3736
|
if (!isDir(commands_dir)) {
|
|
5097
3737
|
return {
|
|
5098
3738
|
id: "claude-command-wrappers",
|
|
@@ -5101,8 +3741,8 @@ function _check_claude_command_wrappers() {
|
|
|
5101
3741
|
remedy: ""
|
|
5102
3742
|
};
|
|
5103
3743
|
}
|
|
5104
|
-
const flat_probe =
|
|
5105
|
-
const wrapper_probe =
|
|
3744
|
+
const flat_probe = fs6.existsSync(path7.join(commands_dir, "commit.md"));
|
|
3745
|
+
const wrapper_probe = fs6.existsSync(path7.join(anchor, "skills", "commit", "SKILL.md"));
|
|
5106
3746
|
if (wrapper_probe) {
|
|
5107
3747
|
return {
|
|
5108
3748
|
id: "claude-command-wrappers",
|
|
@@ -5127,7 +3767,7 @@ function _check_claude_command_wrappers() {
|
|
|
5127
3767
|
};
|
|
5128
3768
|
}
|
|
5129
3769
|
function _check_surface_state() {
|
|
5130
|
-
const matrix_path =
|
|
3770
|
+
const matrix_path = path7.join(_package_root(), "src", "config", "surface-matrix.yml");
|
|
5131
3771
|
if (!isFile2(matrix_path)) {
|
|
5132
3772
|
return {
|
|
5133
3773
|
id: "surface-state",
|
|
@@ -5151,7 +3791,7 @@ function _check_surface_state() {
|
|
|
5151
3791
|
remedy: "agent-config upgrade (reinstalls the package data files)"
|
|
5152
3792
|
};
|
|
5153
3793
|
}
|
|
5154
|
-
const _expand = (p) => p.startsWith("~/") ?
|
|
3794
|
+
const _expand = (p) => p.startsWith("~/") ? path7.join(os3.homedir(), p.slice(2)) : path7.join(_package_root(), p);
|
|
5155
3795
|
const violations = [];
|
|
5156
3796
|
const remedies = [];
|
|
5157
3797
|
let checked = 0;
|
|
@@ -5193,7 +3833,7 @@ function _check_surface_state() {
|
|
|
5193
3833
|
}
|
|
5194
3834
|
function pathExistsAny(p) {
|
|
5195
3835
|
try {
|
|
5196
|
-
|
|
3836
|
+
fs6.statSync(p);
|
|
5197
3837
|
return true;
|
|
5198
3838
|
} catch {
|
|
5199
3839
|
return false;
|
|
@@ -5209,13 +3849,13 @@ function _check_hook_wiring() {
|
|
|
5209
3849
|
remedy: ""
|
|
5210
3850
|
};
|
|
5211
3851
|
}
|
|
5212
|
-
const settings_path =
|
|
3852
|
+
const settings_path = path7.join(os3.homedir(), ".claude", "settings.json");
|
|
5213
3853
|
let missing;
|
|
5214
3854
|
try {
|
|
5215
3855
|
const matrix = build_claude_hook_matrix(
|
|
5216
|
-
|
|
3856
|
+
path7.join(_package_root(), "src", "scripts", "hook_manifest.yaml")
|
|
5217
3857
|
);
|
|
5218
|
-
const settings = pathExists(settings_path) ? JSON.parse(
|
|
3858
|
+
const settings = pathExists(settings_path) ? JSON.parse(fs6.readFileSync(settings_path, "utf8")) : {};
|
|
5219
3859
|
const hooks = (settings["hooks"] ?? {}) || {};
|
|
5220
3860
|
missing = Object.keys(matrix).filter((ev) => {
|
|
5221
3861
|
const groups = hooks[ev];
|
|
@@ -5290,7 +3930,7 @@ function _check_mcp_mode(project_root) {
|
|
|
5290
3930
|
];
|
|
5291
3931
|
const found = [];
|
|
5292
3932
|
for (const [rel, label] of candidates) {
|
|
5293
|
-
const p =
|
|
3933
|
+
const p = path7.join(project_root, rel);
|
|
5294
3934
|
if (!pathExists(p)) {
|
|
5295
3935
|
continue;
|
|
5296
3936
|
}
|
|
@@ -5322,7 +3962,7 @@ function _check_mcp_mode(project_root) {
|
|
|
5322
3962
|
};
|
|
5323
3963
|
}
|
|
5324
3964
|
function _check_offline_readiness() {
|
|
5325
|
-
const script =
|
|
3965
|
+
const script = path7.join(_package_root(), "src", "scripts", "hermetic-install.sh");
|
|
5326
3966
|
if (!pathExists(script)) {
|
|
5327
3967
|
return {
|
|
5328
3968
|
id: "offline-readiness",
|
|
@@ -5380,7 +4020,7 @@ function _check_stale_orphans() {
|
|
|
5380
4020
|
(a, b) => a < b ? -1 : a > b ? 1 : 0
|
|
5381
4021
|
);
|
|
5382
4022
|
for (const root_name of ownedSorted) {
|
|
5383
|
-
const root =
|
|
4023
|
+
const root = path7.join(anchor, root_name);
|
|
5384
4024
|
if (!isDir(root)) {
|
|
5385
4025
|
continue;
|
|
5386
4026
|
}
|
|
@@ -5395,7 +4035,7 @@ function _check_stale_orphans() {
|
|
|
5395
4035
|
if (rel === null) {
|
|
5396
4036
|
continue;
|
|
5397
4037
|
}
|
|
5398
|
-
const relPosix = rel.split(
|
|
4038
|
+
const relPosix = rel.split(path7.sep).join("/");
|
|
5399
4039
|
if (recorded_set.has(relPosix)) {
|
|
5400
4040
|
continue;
|
|
5401
4041
|
}
|
|
@@ -5450,14 +4090,14 @@ function _check_rule_scope_drift(project_root) {
|
|
|
5450
4090
|
let rules_dir = null;
|
|
5451
4091
|
let found = 0;
|
|
5452
4092
|
for (const rel of _RULE_PROJECTION_DIRS) {
|
|
5453
|
-
const cand =
|
|
4093
|
+
const cand = path7.join(project_root, rel);
|
|
5454
4094
|
if (!isDir(cand)) {
|
|
5455
4095
|
continue;
|
|
5456
4096
|
}
|
|
5457
4097
|
let count = 0;
|
|
5458
4098
|
try {
|
|
5459
|
-
for (const name of
|
|
5460
|
-
if (name.endsWith(".md") && isFile2(
|
|
4099
|
+
for (const name of fs6.readdirSync(cand)) {
|
|
4100
|
+
if (name.endsWith(".md") && isFile2(path7.join(cand, name))) {
|
|
5461
4101
|
count += 1;
|
|
5462
4102
|
}
|
|
5463
4103
|
}
|
|
@@ -5511,14 +4151,14 @@ function _check_rule_scope_drift(project_root) {
|
|
|
5511
4151
|
};
|
|
5512
4152
|
}
|
|
5513
4153
|
function _check_duplicate_scope_rules(project_root, userRulesDirOverride) {
|
|
5514
|
-
const user_rules_dir = userRulesDirOverride ??
|
|
4154
|
+
const user_rules_dir = userRulesDirOverride ?? path7.join(os3.homedir(), ".claude", "rules");
|
|
5515
4155
|
let project_rules_dir = null;
|
|
5516
4156
|
if (_is_source_repo(project_root)) {
|
|
5517
|
-
const cand =
|
|
4157
|
+
const cand = path7.join(project_root, "dist", "agent-src", "rules");
|
|
5518
4158
|
if (isDir(cand)) project_rules_dir = cand;
|
|
5519
4159
|
} else {
|
|
5520
4160
|
for (const rel of _RULE_PROJECTION_DIRS) {
|
|
5521
|
-
const cand =
|
|
4161
|
+
const cand = path7.join(project_root, rel);
|
|
5522
4162
|
if (isDir(cand)) {
|
|
5523
4163
|
project_rules_dir = cand;
|
|
5524
4164
|
break;
|
|
@@ -5587,7 +4227,7 @@ function _check_mcp_beta_readiness(project_root) {
|
|
|
5587
4227
|
}
|
|
5588
4228
|
const pending = [];
|
|
5589
4229
|
for (const [gate_id, rel] of MCP_BETA_GATES) {
|
|
5590
|
-
if (!pathExists(
|
|
4230
|
+
if (!pathExists(path7.join(project_root, rel))) {
|
|
5591
4231
|
pending.push(`${gate_id} (${rel})`);
|
|
5592
4232
|
}
|
|
5593
4233
|
}
|
|
@@ -5608,7 +4248,7 @@ function _check_mcp_beta_readiness(project_root) {
|
|
|
5608
4248
|
}
|
|
5609
4249
|
function _check_tier_usage_readiness(project_root) {
|
|
5610
4250
|
const settings_file = project_settings_path(project_root);
|
|
5611
|
-
let log_path =
|
|
4251
|
+
let log_path = path7.join(project_root, ".agent-tier-usage.jsonl");
|
|
5612
4252
|
let enabled = false;
|
|
5613
4253
|
if (isFile2(settings_file)) {
|
|
5614
4254
|
let raw;
|
|
@@ -5627,7 +4267,7 @@ function _check_tier_usage_readiness(project_root) {
|
|
|
5627
4267
|
const outputRaw = tu["output"];
|
|
5628
4268
|
const output = typeof outputRaw === "object" && outputRaw !== null && !Array.isArray(outputRaw) ? outputRaw : {};
|
|
5629
4269
|
if (typeof output["path"] === "string" && output["path"].trim()) {
|
|
5630
|
-
log_path =
|
|
4270
|
+
log_path = path7.join(project_root, output["path"].trim());
|
|
5631
4271
|
}
|
|
5632
4272
|
const val = tu["enabled"];
|
|
5633
4273
|
if (typeof val === "boolean") {
|
|
@@ -5652,7 +4292,7 @@ function _check_tier_usage_readiness(project_root) {
|
|
|
5652
4292
|
return {
|
|
5653
4293
|
id: "tier-usage-readiness",
|
|
5654
4294
|
status: "warn",
|
|
5655
|
-
message: `tier-usage telemetry on but ${
|
|
4295
|
+
message: `tier-usage telemetry on but ${path7.basename(log_path)} not yet written \u2014 no signal accumulated`,
|
|
5656
4296
|
remedy: "run any tracked command to seed the log; the dispatcher writes one record per invocation"
|
|
5657
4297
|
};
|
|
5658
4298
|
}
|
|
@@ -5667,7 +4307,7 @@ function _check_tier_usage_readiness(project_root) {
|
|
|
5667
4307
|
return {
|
|
5668
4308
|
id: "tier-usage-readiness",
|
|
5669
4309
|
status: "fail",
|
|
5670
|
-
message: `cannot read ${
|
|
4310
|
+
message: `cannot read ${path7.basename(log_path)}: ${osErrorStr(exc)}`,
|
|
5671
4311
|
remedy: "fix permissions on the tier-usage log"
|
|
5672
4312
|
};
|
|
5673
4313
|
}
|
|
@@ -5698,7 +4338,7 @@ function _check_tier_usage_readiness(project_root) {
|
|
|
5698
4338
|
return {
|
|
5699
4339
|
id: "tier-usage-readiness",
|
|
5700
4340
|
status: "fail",
|
|
5701
|
-
message: `${total} record(s) in ${
|
|
4341
|
+
message: `${total} record(s) in ${path7.basename(log_path)} but 0 passed the privacy floor \u2014 report would refuse to render`,
|
|
5702
4342
|
remedy: "inspect the log; the dispatcher is writing records the contract forbids (paths, argv, message bodies)"
|
|
5703
4343
|
};
|
|
5704
4344
|
}
|
|
@@ -5706,19 +4346,19 @@ function _check_tier_usage_readiness(project_root) {
|
|
|
5706
4346
|
return {
|
|
5707
4347
|
id: "tier-usage-readiness",
|
|
5708
4348
|
status: "warn",
|
|
5709
|
-
message: `${
|
|
4349
|
+
message: `${path7.basename(log_path)} present but empty \u2014 no signal yet`,
|
|
5710
4350
|
remedy: "run any tracked command to seed the log"
|
|
5711
4351
|
};
|
|
5712
4352
|
}
|
|
5713
4353
|
return {
|
|
5714
4354
|
id: "tier-usage-readiness",
|
|
5715
4355
|
status: "ok",
|
|
5716
|
-
message: `${valid} record(s) past the privacy floor in ${
|
|
4356
|
+
message: `${valid} record(s) past the privacy floor in ${path7.basename(log_path)} \u2014 retiering signal available`,
|
|
5717
4357
|
remedy: ""
|
|
5718
4358
|
};
|
|
5719
4359
|
}
|
|
5720
4360
|
function readText0(p) {
|
|
5721
|
-
return
|
|
4361
|
+
return fs6.readFileSync(p, "utf-8");
|
|
5722
4362
|
}
|
|
5723
4363
|
function osErrorStr(exc) {
|
|
5724
4364
|
if (exc && typeof exc === "object" && "message" in exc) {
|
|
@@ -5729,8 +4369,8 @@ function osErrorStr(exc) {
|
|
|
5729
4369
|
var _CLI_PROVIDER_META = PROVIDER_CLI_META;
|
|
5730
4370
|
function _check_council_cli(project_root) {
|
|
5731
4371
|
const { load_cli_call_counts: load_cli_call_counts2 } = clients_exports;
|
|
5732
|
-
const { load_council_config
|
|
5733
|
-
const council_path =
|
|
4372
|
+
const { load_council_config, resolve_config_path } = config_exports;
|
|
4373
|
+
const council_path = resolve_config_path(project_root);
|
|
5734
4374
|
if (!pathExists(String(council_path))) {
|
|
5735
4375
|
return {
|
|
5736
4376
|
id: "council-cli",
|
|
@@ -5741,7 +4381,7 @@ function _check_council_cli(project_root) {
|
|
|
5741
4381
|
}
|
|
5742
4382
|
let cfg;
|
|
5743
4383
|
try {
|
|
5744
|
-
cfg =
|
|
4384
|
+
cfg = load_council_config(council_path);
|
|
5745
4385
|
} catch (exc) {
|
|
5746
4386
|
return {
|
|
5747
4387
|
id: "council-cli",
|
|
@@ -5839,14 +4479,14 @@ function _codex_home() {
|
|
|
5839
4479
|
}
|
|
5840
4480
|
function _team_codex_binary_name(project_root) {
|
|
5841
4481
|
const default_bin = _CLI_PROVIDER_META["openai"][0];
|
|
5842
|
-
const { load_council_config
|
|
5843
|
-
const council_path =
|
|
4482
|
+
const { load_council_config, resolve_config_path } = config_exports;
|
|
4483
|
+
const council_path = resolve_config_path(project_root);
|
|
5844
4484
|
if (!pathExists(String(council_path))) {
|
|
5845
4485
|
return default_bin;
|
|
5846
4486
|
}
|
|
5847
4487
|
let cfg;
|
|
5848
4488
|
try {
|
|
5849
|
-
cfg =
|
|
4489
|
+
cfg = load_council_config(council_path);
|
|
5850
4490
|
} catch {
|
|
5851
4491
|
return default_bin;
|
|
5852
4492
|
}
|
|
@@ -5891,7 +4531,7 @@ function _epoch_seconds(value) {
|
|
|
5891
4531
|
function _codex_auth_expiry(auth_path) {
|
|
5892
4532
|
let data;
|
|
5893
4533
|
try {
|
|
5894
|
-
data = JSON.parse(
|
|
4534
|
+
data = JSON.parse(fs6.readFileSync(auth_path, "utf-8"));
|
|
5895
4535
|
} catch {
|
|
5896
4536
|
return null;
|
|
5897
4537
|
}
|
|
@@ -5927,14 +4567,14 @@ function _read_ai_team_block(project_root) {
|
|
|
5927
4567
|
}
|
|
5928
4568
|
var _detection_memo = null;
|
|
5929
4569
|
function _read_council_facts(project_root) {
|
|
5930
|
-
const { load_council_config
|
|
5931
|
-
const config_path = String(
|
|
4570
|
+
const { load_council_config, resolve_config_path } = config_exports;
|
|
4571
|
+
const config_path = String(resolve_config_path(project_root));
|
|
5932
4572
|
if (!pathExists(config_path)) {
|
|
5933
4573
|
return absentCouncilFacts(config_path);
|
|
5934
4574
|
}
|
|
5935
4575
|
let cfg;
|
|
5936
4576
|
try {
|
|
5937
|
-
cfg =
|
|
4577
|
+
cfg = load_council_config(config_path);
|
|
5938
4578
|
} catch {
|
|
5939
4579
|
return absentCouncilFacts(config_path);
|
|
5940
4580
|
}
|
|
@@ -6054,7 +4694,7 @@ function _check_team(project_root) {
|
|
|
6054
4694
|
if (binary_resolved === null) {
|
|
6055
4695
|
remedies.push("install the codex CLI: `npm install -g @openai/codex`");
|
|
6056
4696
|
}
|
|
6057
|
-
const auth_path =
|
|
4697
|
+
const auth_path = path7.join(_codex_home(), "auth.json");
|
|
6058
4698
|
const authed = pathExists(auth_path);
|
|
6059
4699
|
let auth_str;
|
|
6060
4700
|
if (!authed) {
|
|
@@ -6134,7 +4774,7 @@ function _check_unsupported_combos(manifest) {
|
|
|
6134
4774
|
};
|
|
6135
4775
|
}
|
|
6136
4776
|
function _wizard_state_path() {
|
|
6137
|
-
return
|
|
4777
|
+
return path7.join(event4u_root(), "state", "wizard-state.json");
|
|
6138
4778
|
}
|
|
6139
4779
|
function _check_wizard_state() {
|
|
6140
4780
|
const state_pth = _wizard_state_path();
|
|
@@ -6214,7 +4854,7 @@ function _check_wizard_state() {
|
|
|
6214
4854
|
};
|
|
6215
4855
|
}
|
|
6216
4856
|
function _check_settings_review_pending() {
|
|
6217
|
-
const delta_pth =
|
|
4857
|
+
const delta_pth = path7.join(event4u_root(), "state", "settings-delta.json");
|
|
6218
4858
|
if (!pathExists(delta_pth)) {
|
|
6219
4859
|
return {
|
|
6220
4860
|
id: "settings-review-pending",
|
|
@@ -6240,7 +4880,7 @@ function _check_settings_review_pending() {
|
|
|
6240
4880
|
}
|
|
6241
4881
|
function _check_memory_merge_union(project_root) {
|
|
6242
4882
|
const remedy = "run: npx tsx src/scripts/sync_gitattributes.ts (or `agent-config refresh --project`)";
|
|
6243
|
-
const target =
|
|
4883
|
+
const target = path7.join(project_root, DEFAULT_GITATTRIBUTES);
|
|
6244
4884
|
if (!pathExists(target)) {
|
|
6245
4885
|
return {
|
|
6246
4886
|
id: "memory-merge-union",
|
|
@@ -6722,7 +5362,7 @@ function _run_repair(opts) {
|
|
|
6722
5362
|
};
|
|
6723
5363
|
if (exists2) {
|
|
6724
5364
|
try {
|
|
6725
|
-
|
|
5365
|
+
fs6.unlinkSync(state_pth);
|
|
6726
5366
|
} catch (exc) {
|
|
6727
5367
|
payload["action"] = "error";
|
|
6728
5368
|
payload["error"] = osErrorStr(exc);
|
|
@@ -6817,13 +5457,13 @@ function _isCliEntry() {
|
|
|
6817
5457
|
if (process2.argv[1] === void 0) {
|
|
6818
5458
|
return false;
|
|
6819
5459
|
}
|
|
6820
|
-
const argvUrl = pathToFileURL(
|
|
5460
|
+
const argvUrl = pathToFileURL(path7.resolve(process2.argv[1])).href;
|
|
6821
5461
|
if (import.meta.url === argvUrl) {
|
|
6822
5462
|
return true;
|
|
6823
5463
|
}
|
|
6824
5464
|
try {
|
|
6825
|
-
const here =
|
|
6826
|
-
const argv =
|
|
5465
|
+
const here = fs6.realpathSync(fileURLToPath2(import.meta.url));
|
|
5466
|
+
const argv = fs6.realpathSync(path7.resolve(process2.argv[1]));
|
|
6827
5467
|
return here === argv;
|
|
6828
5468
|
} catch {
|
|
6829
5469
|
return false;
|