multilingual-absa / .opencode /gsd-core /bin /lib /capability-activation.cjs
Aryan Mishra
feat: initial commit - Multilingual ABSA project setup with 6 phases, 36 requirements
a6b96c2
Raw
History Blame Contribute Delete
4.65 kB
"use strict";
/**
* Capability activation helpers.
*
* Shared by the Capability State Resolver and Loop Resolver so config-key
* activation uses one precedence chain and one prototype-pollution guard.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
// eslint-disable-next-line @typescript-eslint/no-require-imports
const planningWorkspaceMod = require("./planning-workspace.cjs");
const { planningDir, planningRoot } = planningWorkspaceMod;
function _getNestedConfigValue(config, dotKey) {
const segments = dotKey.split('.');
let current = config;
for (const seg of segments) {
if (seg === '__proto__' || seg === 'constructor' || seg === 'prototype') {
return { found: false, value: undefined };
}
if (typeof current !== 'object' || current === null) {
return { found: false, value: undefined };
}
const cur = current;
if (!Object.prototype.hasOwnProperty.call(cur, seg)) {
return { found: false, value: undefined };
}
current = cur[seg];
}
return { found: true, value: current };
}
const _warnedRawConfigPaths = new Set();
function _readRawConfigKey(filePath, dotKey) {
try {
const raw = node_fs_1.default.readFileSync(filePath, 'utf8');
let parsed;
try {
parsed = JSON.parse(raw);
}
catch {
if (!_warnedRawConfigPaths.has(filePath)) {
_warnedRawConfigPaths.add(filePath);
try {
process.stderr.write(`gsd-tools: warning: failed to parse ${filePath} as JSON β€” skipping for activation resolution\n`);
}
catch { /* stderr might be closed */ }
}
return { found: false, value: undefined };
}
return _getNestedConfigValue(parsed, dotKey);
}
catch {
return { found: false, value: undefined };
}
}
/**
* Resolve the raw value for a dotted config key using the four-level precedence
* walk. Returns { found, value } with the RAW value (not coerced to boolean),
* so callers can decide how to interpret the value (boolean gate vs. raw config
* value for numeric/string settings like security_asvs_level).
*
* Precedence (mirrors _resolveActivationValue):
* 1. loadConfig result (config arg) β€” guarded nested-lookup.
* 2. Workstream config.json at planningDir(cwd)/config.json.
* 3. Root config.json at planningRoot(cwd)/config.json (only if path differs).
* 4. registry.configSchema[dotKey].default β€” schema default.
* 5. Absent β†’ { found: false, value: undefined }.
*/
function resolveConfigKey(dotKey, opts) {
const { config, cwd, registry } = opts;
// Level 1: loadConfig result
const fromConfig = _getNestedConfigValue(config, dotKey);
if (fromConfig.found)
return { found: true, value: fromConfig.value };
// Level 2 + 3: raw config.json files (only when cwd is available)
if (cwd) {
const wsConfigPath = node_path_1.default.join(planningDir(cwd), 'config.json');
const rootConfigPath = node_path_1.default.join(planningRoot(cwd), 'config.json');
const fromWs = _readRawConfigKey(wsConfigPath, dotKey);
if (fromWs.found)
return { found: true, value: fromWs.value };
if (wsConfigPath !== rootConfigPath) {
const fromRoot = _readRawConfigKey(rootConfigPath, dotKey);
if (fromRoot.found)
return { found: true, value: fromRoot.value };
}
}
// Level 4: registry configSchema default
const schemaMap = registry['configSchema'];
if (schemaMap && typeof schemaMap === 'object' && !Array.isArray(schemaMap)
&& Object.prototype.hasOwnProperty.call(schemaMap, dotKey)) {
const schemaEntry = schemaMap[dotKey];
if (schemaEntry && typeof schemaEntry === 'object' && schemaEntry !== null) {
const def = schemaEntry['default'];
if (def !== undefined)
return { found: true, value: def };
}
}
// Level 5: absent
return { found: false, value: undefined };
}
function _resolveActivationValue(dotKey, config, cwd, registry) {
const r = resolveConfigKey(dotKey, { config, cwd, registry });
return r.found ? Boolean(r.value) : false;
}
module.exports = {
_getNestedConfigValue,
_readRawConfigKey,
_resolveActivationValue,
resolveConfigKey,
};