← Public packages
@hypercubed/aksk
AKSK setup planner for coding agents: tailored install plans, live peer-tool versions, managed templates, paste-in validators.
src/resolve-versions.ts
91 lines · 3.5 KB · TypeScriptexport interface VersionPins {
'@fission-ai/openspec': string
openwiki: string
'openspec-skills-source': string
}
export interface ResolveInput {
/** When true, query the npm registry for latest versions (outbound HTTPS). On failure, falls back to bundled pins with a note. Defaults to false. */
refresh?: boolean
/** Scope the skills install command to one host via -a (mirrors plan-setup). Omit for -a '*' (every agent). Never bare --all: it expands to --skill '*' and overrides the -s filter. */
hosts?: string[]
}
/** Consumer openspec workflow skills. The `fission-ai/openspec` package also ships repo-maintainer skills (release-openspec, *-openspec-docs) for the openspec project itself — installing with bare `--all` pulls those in too. Filter installs to this list with `-s` (check `npx skills add --help` for repeat syntax). */
export const CONSUMER_OPENSPEC_SKILLS = [
'openspec-propose',
'openspec-explore',
'openspec-new-change',
'openspec-ff-change',
'openspec-continue-change',
'openspec-apply-change',
'openspec-update-change',
'openspec-sync-specs',
'openspec-verify-change',
'openspec-archive-change',
'openspec-bulk-archive-change',
'openspec-onboard',
]
/** Bundled pins, mirrored from the kit's references/versions.json. Safe offline default. */
export const PINS: VersionPins = {
'@fission-ai/openspec': '^1.11.0',
openwiki: '^0.4.3',
'openspec-skills-source': 'fission-ai/openspec',
}
async function fetchLatest(pkg: string): Promise<string | null> {
try {
const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(pkg).replace('%40', '@').replace('%2F', '/')}/latest`)
if (!res.ok) return null
const data = (await res.json()) as { version?: string }
return typeof data.version === 'string' ? data.version : null
} catch {
return null
}
}
/**
* Resolve AKSK peer-tool versions and the exact install commands.
* Use when setup instructions need versions newer than a stale doc pin — call with refresh:true for live npm data, or omit it for the deterministic offline default.
*
* @param input - Optional { refresh } flag for live registry lookup
* @returns Pinned ranges, ready-to-run install commands, and live versions when refresh succeeds
*
* @example
* import resolveVersions from 'kody:@hypercubed/aksk/resolve-versions'
*
* const v = await resolveVersions({ refresh: true })
*/
export default async function resolveVersions(input: ResolveInput = {}): Promise<{
pins: VersionPins
consumerSkills: string[]
installCommands: string[]
live: Record<string, string | null>
note: string
}> {
const live: Record<string, string | null> = { '@fission-ai/openspec': null, openwiki: null }
let note = 'Bundled pins (offline default, mirrored from the kit references/versions.json).'
if (input.refresh === true) {
const [spec, wiki] = await Promise.all([fetchLatest('@fission-ai/openspec'), fetchLatest('openwiki')])
live['@fission-ai/openspec'] = spec
live['openwiki'] = wiki
note =
spec && wiki
? `Live from npm registry at call time; pins remain the minimum supported range.`
: `Registry lookup failed; fell back to bundled pins.`
}
const scope = input.hosts?.length === 1 && input.hosts[0] !== '*' ? `-a ${input.hosts[0]}` : "-a '*'";
return {
pins: PINS,
consumerSkills: CONSUMER_OPENSPEC_SKILLS,
installCommands: [
`npm i -g @fission-ai/openspec@${PINS['@fission-ai/openspec']} openwiki@${PINS.openwiki}`,
`npx skills add ${PINS['openspec-skills-source']} -g ${scope} ${CONSUMER_OPENSPEC_SKILLS.map((s) => `-s ${s}`).join(' ')} -y`,
],
live,
note,
}
}