← Public packages
@hypercubed/aksk
AKSK setup planner for coding agents: tailored install plans, live peer-tool versions, managed templates, paste-in validators.
src/plan-setup.ts
122 lines · 5.1 KB · TypeScriptexport interface PlanStep {
lane: 'skills' | 'bootstrap' | 'init' | 'verify'
title: string
commands: string[]
note?: string
/** When present, the agent must ask the user this question and wait for the answer before running later steps. */
prompt?: string
}
export interface PlanInput {
/** One host id per install target (e.g. ['opencode', 'codex']). */
hosts?: string[]
/** Set true only after the user explicitly confirmed the target agents. Until then a Confirm step heads the plan and must be honored first. */
confirmed?: boolean
/** Deprecated: use hosts. Single-host shorthand; ignored when hosts is set. */
host?: string
/** new-machine = first time on this host (global bootstrap); new-repo = consumer repo on a bootstrapped host (init only); kit-contributor = working inside the kit repo itself (neither). Defaults to 'new-machine'. */
situation?: 'new-machine' | 'new-repo' | 'kit-contributor'
/** Kit source for `npx skills add`. No branch suffix: upstream `main` carries the merged v2.0. */
kitRef?: string
}
const KNOWN_HOSTS = new Set(['opencode', 'codex', 'claude', '*'])
/**
* Build an ordered AKSK setup plan for one situation.
* Use when a user or agent asks how to install the Agent Knowledge Starter Kit — it returns only the lanes they need instead of the full README sequence.
*
* @param input - Host id, situation, and optional kit ref (all optional; sane defaults applied)
* @returns Ordered steps with exact commands plus warnings (e.g. --all blast radius, positional <source> rule)
*
* @example
* import planSetup from 'kody:@hypercubed/aksk/plan-setup'
*
* const plan = await planSetup({ host: 'opencode', situation: 'new-repo' })
*/
export default async function planSetup(input: PlanInput = {}): Promise<{
situation: string
hosts: string[]
steps: PlanStep[]
warnings: string[]
}> {
const hosts = (input.hosts ?? (input.host ? [input.host] : [])).map((h) => h.trim()).filter(Boolean)
const situation = input.situation ?? 'new-machine'
const kitRef = input.kitRef ?? 'Hypercubed/Agent-Knowledge-Starter-Kit'
const warnings: string[] = []
for (const h of hosts) {
if (!KNOWN_HOSTS.has(h)) {
warnings.push(
`Unknown host id '${h}'. Known ids: opencode, codex, claude, '*'. Confirm with \`npx skills list -g\` after installing.`,
)
}
}
if (hosts.includes('*')) {
warnings.push(
'`-a *` / `--all` installs every skill into every agent integration the CLI knows about (many product directories, not just ~/.agents/skills/). Prefer `-a <one-agent>` unless that wide layout is intended.',
)
}
warnings.push(
'Positional <source> must come first: `npx skills add -g -a <source>` fails with `Missing required argument: source`.',
)
const steps: PlanStep[] = []
if (input.confirmed !== true) {
steps.push({
lane: 'skills',
title: 'Confirm target agents',
commands: [],
prompt:
`${hosts.length > 0 ? `Installing for: ${hosts.join(', ')}. ` : 'No target agents given. '}Which agents should the skills be installed for? Name each host id (e.g. opencode, codex, claude) or say "all" for every integration. If the list above is already correct, confirm and continue; otherwise re-run this plan with hosts=[...]. Do not proceed past this step without an explicit answer.`,
note: 'Skills install per-agent. The AKSK skills and the openspec skills must target the same agents; verify with `npx skills list -g` afterwards. Pass confirmed:true to skip this step on re-runs.',
})
}
if (situation === 'kit-contributor') {
return {
situation,
hosts,
steps: [],
warnings: [
'Working inside the kit repo itself: run neither aksk-bootstrap nor aksk-init here. The kit is the source, not a consumer — init would scaffold a consumer .agents/ into the source tree.',
],
}
}
if (hosts.length > 0) {
steps.push({
lane: 'skills',
title: 'Install shared skills (global + host mirrors)',
commands: hosts.map((h) => `npx skills add ${kitRef} -g -a ${h === '*' ? "'*'" : h}`),
note: 'npx (not npm exec) is required. One command per agent so every target is covered; verify with `npx skills list -g`.',
})
}
if (situation === 'new-machine') {
const agentFlag = hosts.length === 1 && hosts[0] !== '*' ? ` --agent ${hosts[0]}` : ''
steps.push({
lane: 'bootstrap',
title: 'Global bootstrap, once per user (aksk-bootstrap)',
commands: [
'npm i -g @fission-ai/openspec@^1.11.0 openwiki@^0.4.3',
`node ~/.agents/skills/aksk-bootstrap/scripts/bootstrap-global.mjs${agentFlag}`,
],
note: 'Idempotent: re-running on a bootstrapped host changes nothing. --agent scopes the openspec-skills install to the same host as the kit skills (needs kit v2.0.1+).',
})
}
steps.push({
lane: 'init',
title: 'Per-repo init (aksk-init, interactive)',
commands: ['node ~/.agents/skills/aksk-init/scripts/bootstrap-repo.mjs [repo-root]'],
note: 'Scaffolds .agents/ + AGENTS.md baseline first, then openspec/openwiki init, routing/lifecycle, wiki contract. Skip when inside the kit repo itself.',
})
steps.push({
lane: 'verify',
title: 'Verify peer tools',
commands: ['node ~/.agents/skills/aksk-bootstrap/scripts/check_peer_tools.mjs openspec openwiki'],
})
return { situation, hosts, steps, warnings }
}