/** * Activation-time self-check of the DSH contract the bundle depends on. * * Pure shape inspection: no ctx service is invoked, only checked for presence. * A DSH upgrade may rename or remove a service; the check turns that into a * visible `not-ok` line (activation log plus the `dsh-harness-check` command) * instead of a TypeError at first use. */ const CONTRACT = [ { feature: 'guards', label: 'tools.guard', available: (ctx) => typeof ctx?.tools?.guard === 'function', }, { feature: 'bootstrap', label: 'ctx.on (agent/pre-step)', available: (ctx) => typeof ctx?.on === 'function', }, { feature: 'commands', label: 'ctx.inject', available: (ctx) => typeof ctx?.inject === 'function', }, { feature: 'workingDirectory', label: 'workingDirectory.get', available: (ctx) => typeof ctx?.workingDirectory?.get === 'function', }, ] /** * Inspect a ctx-like object without calling anything on it. * @returns {{feature: 'guards'|'bootstrap'|'commands'|'workingDirectory', * ok: boolean, detail: string}[]} */ export function collectSelfCheck(ctxLike) { return CONTRACT.map(({ feature, label, available }) => { const ok = available(ctxLike) return { feature, ok, detail: ok ? `${label}: available` : `${label}: missing or not a function`, } }) }