@holdpoint/cli 0.1.0-alpha.20 → 0.1.0-alpha.22
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/dist/{chunk-COPLLMYJ.js → chunk-5TMH2JOD.js} +26 -1
- package/dist/chunk-5TMH2JOD.js.map +1 -0
- package/dist/index.js +2 -2
- package/dist/init-LXQG4KBI.js +8 -0
- package/dist/templates/HOLDPOINT_REFERENCE.md +27 -0
- package/dist/templates/default.yaml +25 -0
- package/package.json +12 -12
- package/dist/chunk-COPLLMYJ.js.map +0 -1
- package/dist/init-FNQ5GQBD.js +0 -8
- /package/dist/{init-FNQ5GQBD.js.map → init-LXQG4KBI.js.map} +0 -0
|
@@ -325,6 +325,30 @@ context:
|
|
|
325
325
|
guides: {}
|
|
326
326
|
conditions: []
|
|
327
327
|
checks:
|
|
328
|
+
- id: karpathy-practices
|
|
329
|
+
label: "Karpathy coding practices"
|
|
330
|
+
on: session_start
|
|
331
|
+
inject:
|
|
332
|
+
text: |
|
|
333
|
+
## Coding practices (enforced by Holdpoint)
|
|
334
|
+
|
|
335
|
+
1. Read all relevant files fully before making any change.
|
|
336
|
+
2. Make the smallest change that satisfies the task. No unsolicited refactors.
|
|
337
|
+
3. Edit existing code surgically. Do not rewrite what you were not asked to rewrite.
|
|
338
|
+
4. Do not add logging, tests, types, or abstractions that were not asked for.
|
|
339
|
+
5. If a test suite exists, it must pass before you stop.
|
|
340
|
+
6. Complete exactly what was asked. Log adjacent issues separately, don't fix them.
|
|
341
|
+
|
|
342
|
+
- id: check-test-suite
|
|
343
|
+
label: "Test suite passes"
|
|
344
|
+
on: before_done
|
|
345
|
+
prompt: "If this project has a test suite (package.json test script, pytest, go test, etc.), confirm it passes. If you did not run it, run it now before finishing."
|
|
346
|
+
|
|
347
|
+
- id: check-minimal-change
|
|
348
|
+
label: "Change is minimal and scoped"
|
|
349
|
+
on: before_done
|
|
350
|
+
prompt: "Review every file you changed. Remove any addition that was not explicitly requested \u2014 unused imports, debug logs, reformatted blocks, unrequested refactors. Confirm the diff is surgical."
|
|
351
|
+
|
|
328
352
|
- id: lint
|
|
329
353
|
label: "Lint codebase"
|
|
330
354
|
cmd: "echo 'Add your lint command here'"
|
|
@@ -475,6 +499,7 @@ ${cursorRules}`, "utf8");
|
|
|
475
499
|
}
|
|
476
500
|
console.log(`
|
|
477
501
|
${chalk2.cyan("Next steps:")}
|
|
502
|
+
Karpathy coding practices are active via ${chalk2.yellow("checks.yaml")}
|
|
478
503
|
1. Edit ${chalk2.yellow("checks.yaml")} to customise your eval checkpoints
|
|
479
504
|
2. Address any ${chalk2.yellow("\u2192")} items above (full notes in ${chalk2.yellow("HOLDPOINT_PREREQUISITES.md")})
|
|
480
505
|
3. Commit ${chalk2.yellow("checks.yaml")}, ${chalk2.yellow("HOLDPOINT_PREREQUISITES.md")}, and the generated engine files
|
|
@@ -493,4 +518,4 @@ export {
|
|
|
493
518
|
spliceBreadcrumb,
|
|
494
519
|
initCommand
|
|
495
520
|
};
|
|
496
|
-
//# sourceMappingURL=chunk-
|
|
521
|
+
//# sourceMappingURL=chunk-5TMH2JOD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/init.ts","../src/detect.ts","../src/templates.ts","../src/lib/preflight.ts","../src/claude-settings.ts","../src/cursor-hooks.ts","../src/lib/instructions-breadcrumb.ts"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { buildConfigJson, buildEngine } from \"@holdpoint/engine-copilot\";\nimport { buildEngineJson as buildClaudeEngineJson } from \"@holdpoint/engine-claude\";\nimport {\n buildCheckScript as buildCursorCheckScript,\n buildEngine as buildCursorEngine,\n buildHooksJson as buildCursorHooksJson,\n} from \"@holdpoint/engine-cursor\";\nimport {\n buildConfigToml as buildCodexConfigToml,\n buildHooksJson as buildCodexHooksJson,\n buildCheckScript as buildCodexCheckScript,\n} from \"@holdpoint/engine-codex\";\nimport { parseHoldpointYaml } from \"@holdpoint/yaml-core\";\nimport type { AgentType } from \"@holdpoint/types\";\nimport { detectPackageManager, type PackageManager } from \"../detect.js\";\nimport { ensureBundledFile } from \"../templates.js\";\nimport { runPreflight, printPreflight } from \"../lib/preflight.js\";\nimport { mergeClaudeSettings } from \"../claude-settings.js\";\nimport { mergeCursorHooks } from \"../cursor-hooks.js\";\nimport { spliceBreadcrumb } from \"../lib/instructions-breadcrumb.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nfunction getDefaultTemplatePath(): string {\n const candidates = [\n join(__dirname, \"templates\", \"default.yaml\"), // dist/templates/ (published package)\n join(__dirname, \"../../../templates\", \"default.yaml\"), // monorepo dev fallback\n join(process.cwd(), \"templates\", \"default.yaml\"), // cwd fallback\n ];\n for (const p of candidates) {\n if (existsSync(p)) return p;\n }\n return \"\";\n}\n\n// Offline/zero-dep fallback written only when `templates/default.yaml` cannot be\n// resolved (see getDefaultTemplatePath). `templates/default.yaml` is the canonical\n// source of truth for the shared karpathy-practices / check-test-suite /\n// check-minimal-change checks — keep the wording of those checks here in sync with\n// it whenever they change.\nconst MINIMAL_CHECKS_YAML = `version: 1\ncontext:\n guides: {}\nconditions: []\nchecks:\n - id: karpathy-practices\n label: \"Karpathy coding practices\"\n on: session_start\n inject:\n text: |\n ## Coding practices (enforced by Holdpoint)\n\n 1. Read all relevant files fully before making any change.\n 2. Make the smallest change that satisfies the task. No unsolicited refactors.\n 3. Edit existing code surgically. Do not rewrite what you were not asked to rewrite.\n 4. Do not add logging, tests, types, or abstractions that were not asked for.\n 5. If a test suite exists, it must pass before you stop.\n 6. Complete exactly what was asked. Log adjacent issues separately, don't fix them.\n\n - id: check-test-suite\n label: \"Test suite passes\"\n on: before_done\n prompt: \"If this project has a test suite (package.json test script, pytest, go test, etc.), confirm it passes. If you did not run it, run it now before finishing.\"\n\n - id: check-minimal-change\n label: \"Change is minimal and scoped\"\n on: before_done\n prompt: \"Review every file you changed. Remove any addition that was not explicitly requested — unused imports, debug logs, reformatted blocks, unrequested refactors. Confirm the diff is surgical.\"\n\n - id: lint\n label: \"Lint codebase\"\n cmd: \"echo 'Add your lint command here'\"\n\n - id: jsdoc\n label: \"JSDoc on changed public functions\"\n prompt: \"Ensure all changed public functions and exports have JSDoc comments.\"\n`;\n\nconst MINIMAL_MASTER_PROMPT = `# Holdpoint\n\nRun \\`holdpoint check\\` before marking any task complete.\nSee \\`checks.yaml\\` for the full list of checks.\n`;\n\nconst MINIMAL_HOLDPOINT_REFERENCE = `# Holdpoint reference\n\nRead \\`MASTER_PROMPT.md\\` first for the mandatory workflow, then use this file for deeper project-specific Holdpoint notes.\n`;\n\nconst MINIMAL_PREREQUISITES = `# Holdpoint prerequisites\n\nHoldpoint installed repo-local engine integrations for one or more AI coding agents. Before relying on them locally, review these setup notes:\n\n- **GitHub Copilot CLI** — Holdpoint's \\`.github/extensions/holdpoint/extension.mjs\\` uses the Copilot CLI **EXTENSIONS** feature. Today that feature is gated behind experimental mode. In Copilot CLI, run \\`/experimental on\\` so **EXTENSIONS** appears in the enabled feature set before using Holdpoint locally.\n- **Cursor** — project-level hooks run in trusted workspaces. After opening the repo in Cursor, confirm the workspace is trusted and review Settings → Hooks if hooks do not fire.\n- **OpenAI Codex** — project-level hooks require trust approval. Run \\`codex trust\\` in the Codex TUI or review the hook with \\`/hooks\\`.\n- **General** — Holdpoint expects Node.js 18+ and a git repository so \\`holdpoint init\\`, \\`holdpoint update\\`, and \\`holdpoint check\\` can run normally.\n\nDocs: https://holdpoint.dev/docs\n`;\n\n/**\n * Initialise Holdpoint in the current project.\n *\n * Writes `checks.yaml` (from the unified default template), `checks.immutable.json`,\n * engine files for each target agent (Copilot, Claude, Cursor, Codex),\n * and repo-local handoff docs such as `HOLDPOINT_PREREQUISITES.md`.\n * Defaults to installing all four agents; pass `--agent` to restrict to one.\n */\nexport async function initCommand(options: { agent?: string }): Promise<void> {\n const spinner = ora(\"Initialising Holdpoint…\").start();\n\n // Default: install for all agents. Pass --agent=copilot|claude|cursor to restrict.\n const agentOpt = options.agent;\n const agents: AgentType[] =\n !agentOpt || agentOpt === \"all\"\n ? [\"copilot\", \"claude\", \"cursor\", \"codex\"]\n : [agentOpt as AgentType];\n\n spinner.text = `Installing for: ${chalk.cyan(agents.join(\", \"))}`;\n\n // Detect package manager once — used both for template substitution and devDep install.\n const pm = detectPackageManager();\n\n // 1. Read or create checks.yaml\n let yamlContent = MINIMAL_CHECKS_YAML;\n if (!existsSync(\"checks.yaml\")) {\n const templatePath = getDefaultTemplatePath();\n if (templatePath) {\n yamlContent = readFileSync(templatePath, \"utf8\");\n }\n // Substitute the package manager so checks use the right runner (npm/yarn/pnpm).\n if (pm !== \"pnpm\") {\n yamlContent = yamlContent.replace(/\\bpnpm\\b/g, pm);\n }\n writeFileSync(\"checks.yaml\", yamlContent, \"utf8\");\n } else {\n yamlContent = readFileSync(\"checks.yaml\", \"utf8\");\n }\n\n const config = parseHoldpointYaml(yamlContent);\n\n // 2. Write checks.immutable.json — read by holdpoint-check.mjs at runtime\n const generatedDir = \".github/holdpoint/generated\";\n mkdirSync(generatedDir, { recursive: true });\n writeFileSync(`${generatedDir}/checks.immutable.json`, buildConfigJson(config), \"utf8\");\n\n // 3. Install engine files for each target agent\n if (agents.includes(\"copilot\")) {\n // extension.mjs handles both session context injection (onSessionStart) and\n // check enforcement (onPreToolUse → task_complete). No separate hooks files needed.\n const extDir = \".github/extensions/holdpoint\";\n mkdirSync(extDir, { recursive: true });\n writeFileSync(join(extDir, \"extension.mjs\"), buildEngine(config), \"utf8\");\n spliceBreadcrumb(\".github/copilot-instructions.md\");\n }\n\n if (agents.includes(\"claude\")) {\n mkdirSync(\".claude\", { recursive: true });\n const settingsPath = \".claude/settings.json\";\n let existing: Record<string, unknown> = {};\n if (existsSync(settingsPath)) {\n try {\n existing = JSON.parse(readFileSync(settingsPath, \"utf8\")) as Record<string, unknown>;\n } catch {\n /* ignore */\n }\n }\n const holdpointHooks = JSON.parse(buildClaudeEngineJson(config)) as Record<string, unknown>;\n writeFileSync(\n settingsPath,\n JSON.stringify(mergeClaudeSettings(existing, holdpointHooks), null, 2),\n \"utf8\",\n );\n spliceBreadcrumb(\"CLAUDE.md\");\n }\n\n if (agents.includes(\"cursor\")) {\n mkdirSync(\".cursor\", { recursive: true });\n const cursorHooksPath = \".cursor/hooks.json\";\n let existingHooks: Record<string, unknown> = {};\n if (existsSync(cursorHooksPath)) {\n try {\n existingHooks = JSON.parse(readFileSync(cursorHooksPath, \"utf8\")) as Record<\n string,\n unknown\n >;\n } catch {\n /* ignore */\n }\n }\n const cursorHooks = JSON.parse(buildCursorHooksJson(config)) as Record<string, unknown>;\n writeFileSync(\n cursorHooksPath,\n JSON.stringify(mergeCursorHooks(existingHooks, cursorHooks), null, 2) + \"\\n\",\n \"utf8\",\n );\n writeFileSync(\".cursor/holdpoint-hook.mjs\", buildCursorCheckScript(), \"utf8\");\n\n const cursorRules = buildCursorEngine(config);\n const cursorPath = \".cursorrules\";\n if (existsSync(cursorPath)) {\n const existing = readFileSync(cursorPath, \"utf8\");\n if (!existing.includes(\"Holdpoint Rules\")) {\n writeFileSync(cursorPath, `${existing.trimEnd()}\\n\\n${cursorRules}`, \"utf8\");\n }\n } else {\n writeFileSync(cursorPath, cursorRules, \"utf8\");\n }\n spliceBreadcrumb(\".cursor/rules/holdpoint.md\");\n }\n\n if (agents.includes(\"codex\")) {\n mkdirSync(\".codex\", { recursive: true });\n writeFileSync(\".codex/hooks.json\", buildCodexHooksJson(config), \"utf8\");\n writeFileSync(\".codex/holdpoint-check.mjs\", buildCodexCheckScript(config), \"utf8\");\n writeFileSync(\".codex/config.toml\", buildCodexConfigToml(), \"utf8\");\n spliceBreadcrumb(\"AGENTS.md\");\n }\n\n // 4. Create repo-local guidance files if not present\n ensureBundledFile(\"MASTER_PROMPT.md\", \"MASTER_PROMPT.md\", MINIMAL_MASTER_PROMPT);\n ensureBundledFile(\n \"HOLDPOINT_REFERENCE.md\",\n \"HOLDPOINT_REFERENCE.md\",\n MINIMAL_HOLDPOINT_REFERENCE,\n );\n ensureBundledFile(\n \"HOLDPOINT_PREREQUISITES.md\",\n \"HOLDPOINT_PREREQUISITES.md\",\n MINIMAL_PREREQUISITES,\n );\n\n // Install holdpoint as a devDependency so hooks resolve via node_modules/.bin\n // rather than downloading on every hook fire via npx.\n spinner.text = \"Installing holdpoint as a devDependency…\";\n const installCmds: Record<PackageManager, string> = {\n pnpm: \"pnpm add -D holdpoint\",\n yarn: \"yarn add --dev holdpoint\",\n npm: \"npm install --save-dev holdpoint\",\n };\n const installCmd = installCmds[pm];\n try {\n execSync(installCmd, { stdio: \"pipe\" });\n spinner.succeed(chalk.bold.green(\"Holdpoint initialised!\"));\n } catch {\n spinner.warn(\n chalk.yellow(`Holdpoint initialised, but could not install the package automatically.`) +\n `\\n Run manually: ${chalk.yellow(installCmd)}`,\n );\n }\n\n // Per-agent preflight: surface the Copilot `/experimental on` step and Codex\n // `codex trust` step at install time.\n // instead of burying them in HOLDPOINT_PREREQUISITES.md where users\n // routinely miss them.\n const preflight = runPreflight(agents);\n printPreflight(preflight);\n\n // If `holdpoint` is already on PATH (typically because the user has the\n // global install), use the bare command. Otherwise fall back to `npx\n // holdpoint` so the suggested commands actually work for users who only\n // have the local devDep.\n let holdpointInvocation = \"npx holdpoint\";\n try {\n execSync(\"command -v holdpoint\", { stdio: \"pipe\" });\n holdpointInvocation = \"holdpoint\";\n } catch {\n // not on PATH — keep the npx fallback\n }\n\n console.log(`\n${chalk.cyan(\"Next steps:\")}\n Karpathy coding practices are active via ${chalk.yellow(\"checks.yaml\")}\n 1. Edit ${chalk.yellow(\"checks.yaml\")} to customise your eval checkpoints\n 2. Address any ${chalk.yellow(\"→\")} items above (full notes in ${chalk.yellow(\"HOLDPOINT_PREREQUISITES.md\")})\n 3. Commit ${chalk.yellow(\"checks.yaml\")}, ${chalk.yellow(\"HOLDPOINT_PREREQUISITES.md\")}, and the generated engine files\n 4. Run ${chalk.yellow(holdpointInvocation)} ${chalk.yellow(\"check\")} at any time to validate\n\n Visual builder: ${chalk.yellow(holdpointInvocation + \" builder\")} (opens the daemon at /builder)\n Agents: ${chalk.cyan(agents.join(\", \"))}\n`);\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport type { AgentType } from \"@holdpoint/types\";\n\nexport type PackageManager = \"pnpm\" | \"yarn\" | \"npm\";\n\n/** Detect which package manager owns the current project by checking lock files. */\nexport function detectPackageManager(): PackageManager {\n if (existsSync(\"pnpm-lock.yaml\")) return \"pnpm\";\n if (existsSync(\"yarn.lock\")) return \"yarn\";\n return \"npm\";\n}\n\n/** @deprecated Use detectInstalledAgents() — single-agent detection is no longer the default. */\nexport function detectAgent(): AgentType {\n if (existsSync(\".github/extensions\")) return \"copilot\";\n if (existsSync(\".claude\")) return \"claude\";\n if (existsSync(\".cursor/hooks.json\")) return \"cursor\";\n if (existsSync(\".cursorrules\")) return \"cursor\";\n if (existsSync(\".codex\")) return \"codex\";\n return \"unknown\";\n}\n\n/**\n * Returns every agent whose Holdpoint engine files are already present in the\n * current working directory. Used by `holdpoint update` so it regenerates only\n * the engines that were previously installed.\n */\nexport function detectInstalledAgents(): AgentType[] {\n const agents: AgentType[] = [];\n if (existsSync(\".github/extensions/holdpoint/extension.mjs\")) agents.push(\"copilot\");\n if (existsSync(\".claude/settings.json\")) agents.push(\"claude\");\n if (existsSync(\".cursor/hooks.json\")) {\n try {\n if (readFileSync(\".cursor/hooks.json\", \"utf8\").includes(\"HOLDPOINT_MANAGED=cursor\")) {\n agents.push(\"cursor\");\n }\n } catch {\n /* ignore unreadable file */\n }\n }\n if (existsSync(\".cursorrules\")) {\n try {\n if (\n !agents.includes(\"cursor\") &&\n readFileSync(\".cursorrules\", \"utf8\").includes(\"Holdpoint Rules\")\n ) {\n agents.push(\"cursor\");\n }\n } catch {\n /* ignore unreadable file */\n }\n }\n // Detect Codex by the generated check script (more specific than .codex/ existence)\n if (existsSync(\".codex/holdpoint-check.mjs\")) agents.push(\"codex\");\n return agents;\n}\n","import { copyFileSync, existsSync, writeFileSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport function getBundledTemplatePath(filename: string): string {\n const candidates = [\n join(__dirname, \"templates\", filename), // dist/templates/ (published package)\n join(__dirname, \"../../../templates\", filename), // monorepo dev fallback\n join(process.cwd(), \"templates\", filename), // cwd fallback\n ];\n for (const candidate of candidates) {\n if (existsSync(candidate)) return candidate;\n }\n return \"\";\n}\n\nexport function ensureBundledFile(\n outputPath: string,\n templateFilename: string,\n fallbackContent: string,\n): boolean {\n if (existsSync(outputPath)) {\n return false;\n }\n\n const templatePath = getBundledTemplatePath(templateFilename);\n if (templatePath) {\n copyFileSync(templatePath, outputPath);\n } else {\n writeFileSync(outputPath, fallbackContent, \"utf8\");\n }\n\n return true;\n}\n","import { execSync } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport type { AgentType } from \"@holdpoint/types\";\n\n/**\n * Result of a single preflight check for one agent.\n *\n * - `ok`: the agent's toolchain is detected and ready to use.\n * - `action_required`: we can be specific about something the user must do\n * (install a tool, enable a feature, approve a hook) — `command` is set.\n * - `unknown`: detection failed but we can't be sure what the user needs.\n */\nexport type PreflightStatus = \"ok\" | \"action_required\" | \"unknown\";\n\nexport interface PreflightResult {\n agent: AgentType;\n status: PreflightStatus;\n /** One-line human-readable summary, no trailing newline. */\n message: string;\n /** When `action_required`, the exact command the user should run next. */\n command?: string;\n /** When set, points at HOLDPOINT_PREREQUISITES.md or external docs. */\n docs?: string;\n}\n\n/**\n * Run silently — used for tool detection where we expect failure to be common\n * and don't want stderr bleeding into the init spinner output.\n */\nfunction silentExec(cmd: string): { ok: boolean; stdout: string } {\n try {\n const stdout = execSync(cmd, { stdio: [\"ignore\", \"pipe\", \"ignore\"] }).toString();\n return { ok: true, stdout };\n } catch {\n return { ok: false, stdout: \"\" };\n }\n}\n\n/**\n * Copilot CLI preflight.\n *\n * We can detect `gh` and the `gh-copilot` extension reliably, but the\n * `/experimental on` requirement is runtime state inside the Copilot CLI\n * session itself — there's no clean filesystem signal. So we always remind\n * users to enable it, even when everything else looks healthy.\n */\nfunction checkCopilot(): PreflightResult {\n const gh = silentExec(\"gh --version\");\n if (!gh.ok) {\n return {\n agent: \"copilot\",\n status: \"action_required\",\n message: \"GitHub CLI not found on PATH\",\n command: \"brew install gh # or: https://cli.github.com/\",\n };\n }\n\n // `gh copilot --version` exits non-zero if the extension isn't installed.\n const copilot = silentExec(\"gh copilot --version\");\n if (!copilot.ok) {\n return {\n agent: \"copilot\",\n status: \"action_required\",\n message: \"Copilot CLI extension not installed\",\n command: \"gh extension install github/gh-copilot\",\n };\n }\n\n return {\n agent: \"copilot\",\n status: \"action_required\",\n message: \"Copilot CLI detected — experimental mode required for EXTENSIONS\",\n command: \"Inside Copilot CLI, run: /experimental on\",\n };\n}\n\n/**\n * Claude Code preflight. Settings live at `.claude/settings.json`, which we\n * write ourselves during init, so the only failure mode is the binary\n * missing from PATH (in which case the user still wants the settings file\n * written — they may be invoking Claude Code from a different machine).\n */\nfunction checkClaude(): PreflightResult {\n const claude = silentExec(\"claude --version\");\n if (!claude.ok) {\n return {\n agent: \"claude\",\n status: \"unknown\",\n message: \"Claude Code binary not on PATH (hooks still written for when it is)\",\n };\n }\n return {\n agent: \"claude\",\n status: \"ok\",\n message: \"Claude Code detected — hooks installed at .claude/settings.json\",\n };\n}\n\n/**\n * Cursor preflight. Project `.cursor/hooks.json` hooks run only in trusted\n * workspaces, which is runtime state inside Cursor and not reliably readable\n * from disk, so init prints the trust/debugging reminder every time.\n */\nfunction checkCursor(): PreflightResult {\n return {\n agent: \"cursor\",\n status: \"ok\",\n message: \"Cursor — .cursor/hooks.json gate + .cursor/rules breadcrumb installed\",\n docs: \"https://holdpoint.dev/docs#cursor\",\n };\n}\n\n/**\n * Codex preflight. Project-level hooks require trust approval inside the\n * Codex TUI, which is runtime state we can't read from disk reliably across\n * Codex versions — so this mirrors the Copilot pattern: detect the binary,\n * always remind the user about `codex trust`.\n */\nfunction checkCodex(): PreflightResult {\n const codex = silentExec(\"codex --version\");\n if (!codex.ok) {\n return {\n agent: \"codex\",\n status: \"action_required\",\n message: \"Codex CLI not found on PATH\",\n command: \"Install Codex: https://github.com/openai/codex\",\n };\n }\n return {\n agent: \"codex\",\n status: \"action_required\",\n message: \"Codex detected — project-level hooks require trust approval\",\n command: \"In the Codex TUI: codex trust (or /hooks to review)\",\n };\n}\n\n// `AgentType` includes \"unknown\" for the stack-detection fallback path, but\n// only the four real agents have a preflight to run. `Partial` keeps this\n// honest instead of forcing a no-op stub.\nconst CHECKS: Partial<Record<AgentType, () => PreflightResult>> = {\n copilot: checkCopilot,\n claude: checkClaude,\n cursor: checkCursor,\n codex: checkCodex,\n};\n\n/**\n * Run preflight for the given agents and return results in input order.\n * Agents without a registered check are silently skipped — the caller's\n * agent list is the source of truth.\n *\n * Intentionally pure apart from `execSync` so callers can decide whether\n * to print, summarise, or fail-fast on the results.\n */\nexport function runPreflight(agents: readonly AgentType[]): PreflightResult[] {\n return agents.flatMap((agent) => {\n const check = CHECKS[agent];\n return check ? [check()] : [];\n });\n}\n\n/**\n * Pretty-print preflight results to stdout in the style used by `holdpoint init`.\n * Always groups by status so action items don't get lost between OKs.\n */\nexport function printPreflight(results: readonly PreflightResult[]): void {\n if (results.length === 0) return;\n\n const ok = results.filter((r) => r.status === \"ok\");\n const unknown = results.filter((r) => r.status === \"unknown\");\n const action = results.filter((r) => r.status === \"action_required\");\n\n console.log(\"\");\n console.log(chalk.bold(\"Agent preflight:\"));\n\n for (const r of ok) {\n console.log(` ${chalk.green(\"✓\")} ${r.agent.padEnd(7)} ${chalk.dim(r.message)}`);\n }\n for (const r of unknown) {\n console.log(` ${chalk.dim(\"?\")} ${r.agent.padEnd(7)} ${chalk.dim(r.message)}`);\n }\n for (const r of action) {\n console.log(` ${chalk.yellow(\"→\")} ${chalk.bold(r.agent.padEnd(7))} ${r.message}`);\n if (r.command) console.log(` ${chalk.cyan(r.command)}`);\n }\n}\n","type JsonObject = Record<string, unknown>;\n\nconst HOLDPOINT_CLAUDE_HOOK_MARKER = \"HOLDPOINT_MANAGED=claude\";\n\nfunction isObject(value: unknown): value is JsonObject {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction asHookArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nfunction isManagedHookCommand(value: unknown): boolean {\n return (\n isObject(value) &&\n typeof value.command === \"string\" &&\n value.command.includes(HOLDPOINT_CLAUDE_HOOK_MARKER)\n );\n}\n\nfunction isLegacyManagedHookCommand(value: unknown): boolean {\n if (!isObject(value) || typeof value.command !== \"string\") return false;\n return (\n value.command === \"node_modules/.bin/holdpoint event --engine claude --from-hook || true\" ||\n value.command === \"node_modules/.bin/holdpoint check --staged\"\n );\n}\n\nfunction isManagedHookEntry(value: unknown): boolean {\n if (!isObject(value)) return false;\n const hooks = asHookArray(value.hooks);\n return (\n hooks.length > 0 &&\n (hooks.every(isManagedHookCommand) || hooks.every(isLegacyManagedHookCommand))\n );\n}\n\n/**\n * Merge generated Holdpoint hooks into .claude/settings.json without clobbering\n * user-owned hooks. Re-runs remove only entries carrying Holdpoint's marker.\n */\nexport function mergeClaudeSettings(existing: JsonObject, generated: JsonObject): JsonObject {\n const existingHooks = isObject(existing.hooks) ? existing.hooks : {};\n const generatedHooks = isObject(generated.hooks) ? generated.hooks : {};\n const mergedHooks: JsonObject = {};\n\n for (const eventName of new Set([\n ...Object.keys(existingHooks),\n ...Object.keys(generatedHooks),\n ])) {\n const preserved = asHookArray(existingHooks[eventName]).filter(\n (entry) => !isManagedHookEntry(entry),\n );\n const next = asHookArray(generatedHooks[eventName]);\n if (preserved.length > 0 || next.length > 0) {\n mergedHooks[eventName] = [...preserved, ...next];\n }\n }\n\n return { ...existing, ...generated, hooks: mergedHooks };\n}\n","type JsonObject = Record<string, unknown>;\n\nconst HOLDPOINT_CURSOR_HOOK_MARKER = \"HOLDPOINT_MANAGED=cursor\";\n\nfunction isObject(value: unknown): value is JsonObject {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction asHookArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nfunction isManagedCursorHook(value: unknown): boolean {\n return (\n isObject(value) &&\n typeof value.command === \"string\" &&\n (value.command.includes(HOLDPOINT_CURSOR_HOOK_MARKER) ||\n value.command.includes(\".cursor/holdpoint-hook.mjs\"))\n );\n}\n\n/**\n * Merge generated Holdpoint Cursor hooks into `.cursor/hooks.json` without\n * clobbering user/partner hooks. Re-runs remove only entries carrying\n * Holdpoint's marker or the generated hook script path.\n */\nexport function mergeCursorHooks(existing: JsonObject, generated: JsonObject): JsonObject {\n const existingHooks = isObject(existing.hooks) ? existing.hooks : {};\n const generatedHooks = isObject(generated.hooks) ? generated.hooks : {};\n const mergedHooks: JsonObject = {};\n\n for (const eventName of new Set([\n ...Object.keys(existingHooks),\n ...Object.keys(generatedHooks),\n ])) {\n const preserved = asHookArray(existingHooks[eventName]).filter(\n (entry) => !isManagedCursorHook(entry),\n );\n const next = asHookArray(generatedHooks[eventName]);\n if (preserved.length > 0 || next.length > 0) {\n mergedHooks[eventName] = [...preserved, ...next];\n }\n }\n\n return { ...existing, ...generated, hooks: mergedHooks };\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nconst START_MARKER =\n \"<!-- HOLDPOINT_MANAGED — content between these markers is auto-generated by holdpoint init / holdpoint update -->\";\nconst END_MARKER = \"<!-- /HOLDPOINT_MANAGED -->\";\n\n/** Canonical breadcrumb content. Same wording for every agent on purpose. */\nexport const BREADCRUMB_BODY = `## Holdpoint workflow\n\nThis repo uses [Holdpoint](https://holdpoint.dev) to gate task completion on deterministic checks.\n\nBefore marking any task done:\n\n1. Run \\`holdpoint check\\` (or it will run automatically via Stop / TaskCompleted hooks).\n2. Fix any failures. Re-run until exit 0.\n3. Never bypass with \\`--no-verify\\` or by skipping the agent's stop hook.\n\nFull workflow reference: [\\`MASTER_PROMPT.md\\`](./MASTER_PROMPT.md) (always injected at session start).\nDeep reference: [\\`HOLDPOINT_REFERENCE.md\\`](./HOLDPOINT_REFERENCE.md) (read on demand).\nActive checks: [\\`checks.yaml\\`](./checks.yaml).`;\n\n/**\n * Idempotently splice the Holdpoint breadcrumb into a markdown instructions file.\n * - If the file is missing and createIfMissing: write a new file containing only the breadcrumb block.\n * - If the file has the markers: replace content between them.\n * - If the file exists but has no markers: append the breadcrumb block separated by a blank line.\n * Content outside the markers is never touched.\n */\nexport function spliceBreadcrumb(\n filePath: string,\n body: string = BREADCRUMB_BODY,\n createIfMissing = true,\n): void {\n const block = `${START_MARKER}\\n\\n${body}\\n\\n${END_MARKER}`;\n if (!existsSync(filePath)) {\n if (!createIfMissing) return;\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, block + \"\\n\", \"utf8\");\n return;\n }\n const existing = readFileSync(filePath, \"utf8\");\n const startIdx = existing.indexOf(START_MARKER);\n const endIdx = existing.indexOf(END_MARKER);\n if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {\n const before = existing.slice(0, startIdx);\n const after = existing.slice(endIdx + END_MARKER.length);\n writeFileSync(filePath, before + block + after, \"utf8\");\n return;\n }\n const sep = existing.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n writeFileSync(filePath, existing + sep + block + \"\\n\", \"utf8\");\n}\n"],"mappings":"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","names":["execSync","existsSync","readFileSync","writeFileSync","mkdirSync","join","dirname","fileURLToPath","chalk","existsSync","isObject","asHookArray","existsSync","readFileSync","writeFileSync","dirname","__dirname","dirname","fileURLToPath","join","existsSync","chalk","readFileSync","writeFileSync","mkdirSync","execSync"]}
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
mergeClaudeSettings,
|
|
7
7
|
mergeCursorHooks,
|
|
8
8
|
spliceBreadcrumb
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-5TMH2JOD.js";
|
|
10
10
|
|
|
11
11
|
// src/index.ts
|
|
12
12
|
import { Command } from "commander";
|
|
@@ -123,7 +123,7 @@ async function checkCommand(options) {
|
|
|
123
123
|
console.error(chalk.dim("Skipped. Run `holdpoint init` when you're ready."));
|
|
124
124
|
process.exit(1);
|
|
125
125
|
}
|
|
126
|
-
const { initCommand: initCommand2 } = await import("./init-
|
|
126
|
+
const { initCommand: initCommand2 } = await import("./init-LXQG4KBI.js");
|
|
127
127
|
await initCommand2({});
|
|
128
128
|
console.log(
|
|
129
129
|
chalk.dim("\nReview ") + chalk.yellow("checks.yaml") + chalk.dim(" and run ") + chalk.yellow("holdpoint check") + chalk.dim(" again when you're ready.")
|
|
@@ -341,6 +341,33 @@ Provided by Holdpoint — use this to avoid knowledge-cutoff confusion.
|
|
|
341
341
|
|
|
342
342
|
---
|
|
343
343
|
|
|
344
|
+
## `security_scan`
|
|
345
|
+
|
|
346
|
+
At the start of a fresh session Holdpoint runs a lightweight security scan and injects
|
|
347
|
+
a banner as session context when something is worth surfacing:
|
|
348
|
+
|
|
349
|
+
- **Unverified MCP servers** — any MCP server in `.mcp.json` / `.claude/mcp.json` whose
|
|
350
|
+
executed package isn't a recognised first-party / well-known server. Trust is bound to
|
|
351
|
+
the package that actually runs (the `npx`/`uvx`/`dlx` target or command binary), not the
|
|
352
|
+
human-set `name`, so a server can't mark itself trusted by label. Non-npm servers (e.g.
|
|
353
|
+
`uvx`-launched Python servers) are listed separately as "source not checkable" rather
|
|
354
|
+
than flagged as unverified.
|
|
355
|
+
- **`high`/`critical` dependency advisories** — from `npm`/`pnpm`/`yarn audit` (Yarn Berry
|
|
356
|
+
uses `yarn npm audit`). Findings are sorted by severity so criticals are never dropped.
|
|
357
|
+
|
|
358
|
+
The scan is **on by default**. It runs only on a genuine fresh session start (not on
|
|
359
|
+
`resume`/`compact` re-fires, and not on subagent starts), so it never re-runs the audit
|
|
360
|
+
subprocess on the hot path. To opt out entirely:
|
|
361
|
+
|
|
362
|
+
```yaml
|
|
363
|
+
security_scan: false
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Setting this to `false` also skips the dependency-audit subprocess, so a session that has
|
|
367
|
+
nothing else to inject won't run a session-start context hook at all.
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
344
371
|
## Commands
|
|
345
372
|
|
|
346
373
|
| Command | What it does |
|
|
@@ -59,6 +59,31 @@ patterns:
|
|
|
59
59
|
changelog-files: "(^|/)CHANGELOG\\.md$"
|
|
60
60
|
|
|
61
61
|
checks:
|
|
62
|
+
# ── Coding practices (universal) ───────────────────────────────────
|
|
63
|
+
- id: karpathy-practices
|
|
64
|
+
label: "Karpathy coding practices"
|
|
65
|
+
on: session_start
|
|
66
|
+
inject:
|
|
67
|
+
text: |
|
|
68
|
+
## Coding practices (enforced by Holdpoint)
|
|
69
|
+
|
|
70
|
+
1. Read all relevant files fully before making any change.
|
|
71
|
+
2. Make the smallest change that satisfies the task. No unsolicited refactors.
|
|
72
|
+
3. Edit existing code surgically. Do not rewrite what you were not asked to rewrite.
|
|
73
|
+
4. Do not add logging, tests, types, or abstractions that were not asked for.
|
|
74
|
+
5. If a test suite exists, it must pass before you stop.
|
|
75
|
+
6. Complete exactly what was asked. Log adjacent issues separately, don't fix them.
|
|
76
|
+
|
|
77
|
+
- id: check-test-suite
|
|
78
|
+
label: "Test suite passes"
|
|
79
|
+
on: before_done
|
|
80
|
+
prompt: "If this project has a test suite (package.json test script, pytest, go test, etc.), confirm it passes. If you did not run it, run it now before finishing."
|
|
81
|
+
|
|
82
|
+
- id: check-minimal-change
|
|
83
|
+
label: "Change is minimal and scoped"
|
|
84
|
+
on: before_done
|
|
85
|
+
prompt: "Review every file you changed. Remove any addition that was not explicitly requested — unused imports, debug logs, reformatted blocks, unrequested refactors. Confirm the diff is surgical."
|
|
86
|
+
|
|
62
87
|
# ── Node / TypeScript / JavaScript ─────────────────────────────────
|
|
63
88
|
- id: node-lint
|
|
64
89
|
label: "Lint (Node) — no warnings"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holdpoint/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.22",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -46,23 +46,23 @@
|
|
|
46
46
|
],
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"chalk": "^5.3.0",
|
|
49
|
-
"commander": "^
|
|
49
|
+
"commander": "^15.0.0",
|
|
50
50
|
"ora": "^9.4.0",
|
|
51
|
-
"@holdpoint/live-daemon": "0.1.0-alpha.
|
|
52
|
-
"@holdpoint/engine-claude": "0.1.0-alpha.14",
|
|
53
|
-
"@holdpoint/engine-codex": "0.1.0-alpha.15",
|
|
54
|
-
"@holdpoint/sdk": "0.1.0-alpha.4",
|
|
51
|
+
"@holdpoint/live-daemon": "0.1.0-alpha.7",
|
|
55
52
|
"@holdpoint/live-protocol": "0.1.0-alpha.4",
|
|
56
|
-
"@holdpoint/
|
|
57
|
-
"@holdpoint/engine-
|
|
58
|
-
"@holdpoint/
|
|
59
|
-
"@holdpoint/
|
|
53
|
+
"@holdpoint/sdk": "0.1.0-alpha.4",
|
|
54
|
+
"@holdpoint/engine-claude": "0.1.0-alpha.16",
|
|
55
|
+
"@holdpoint/engine-codex": "0.1.0-alpha.17",
|
|
56
|
+
"@holdpoint/engine-copilot": "0.1.0-alpha.17",
|
|
57
|
+
"@holdpoint/engine-cursor": "0.1.0-alpha.15",
|
|
58
|
+
"@holdpoint/types": "0.1.0-alpha.11",
|
|
59
|
+
"@holdpoint/yaml-core": "0.1.0-alpha.12"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@types/node": "^25.9.
|
|
62
|
+
"@types/node": "^25.9.2",
|
|
63
63
|
"tsup": "^8.3.5",
|
|
64
64
|
"typescript": "^6.0.3",
|
|
65
|
-
"vitest": "^4.1.
|
|
65
|
+
"vitest": "^4.1.8"
|
|
66
66
|
},
|
|
67
67
|
"scripts": {
|
|
68
68
|
"build": "tsup",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/init.ts","../src/detect.ts","../src/templates.ts","../src/lib/preflight.ts","../src/claude-settings.ts","../src/cursor-hooks.ts","../src/lib/instructions-breadcrumb.ts"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { buildConfigJson, buildEngine } from \"@holdpoint/engine-copilot\";\nimport { buildEngineJson as buildClaudeEngineJson } from \"@holdpoint/engine-claude\";\nimport {\n buildCheckScript as buildCursorCheckScript,\n buildEngine as buildCursorEngine,\n buildHooksJson as buildCursorHooksJson,\n} from \"@holdpoint/engine-cursor\";\nimport {\n buildConfigToml as buildCodexConfigToml,\n buildHooksJson as buildCodexHooksJson,\n buildCheckScript as buildCodexCheckScript,\n} from \"@holdpoint/engine-codex\";\nimport { parseHoldpointYaml } from \"@holdpoint/yaml-core\";\nimport type { AgentType } from \"@holdpoint/types\";\nimport { detectPackageManager, type PackageManager } from \"../detect.js\";\nimport { ensureBundledFile } from \"../templates.js\";\nimport { runPreflight, printPreflight } from \"../lib/preflight.js\";\nimport { mergeClaudeSettings } from \"../claude-settings.js\";\nimport { mergeCursorHooks } from \"../cursor-hooks.js\";\nimport { spliceBreadcrumb } from \"../lib/instructions-breadcrumb.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nfunction getDefaultTemplatePath(): string {\n const candidates = [\n join(__dirname, \"templates\", \"default.yaml\"), // dist/templates/ (published package)\n join(__dirname, \"../../../templates\", \"default.yaml\"), // monorepo dev fallback\n join(process.cwd(), \"templates\", \"default.yaml\"), // cwd fallback\n ];\n for (const p of candidates) {\n if (existsSync(p)) return p;\n }\n return \"\";\n}\n\nconst MINIMAL_CHECKS_YAML = `version: 1\ncontext:\n guides: {}\nconditions: []\nchecks:\n - id: lint\n label: \"Lint codebase\"\n cmd: \"echo 'Add your lint command here'\"\n\n - id: jsdoc\n label: \"JSDoc on changed public functions\"\n prompt: \"Ensure all changed public functions and exports have JSDoc comments.\"\n`;\n\nconst MINIMAL_MASTER_PROMPT = `# Holdpoint\n\nRun \\`holdpoint check\\` before marking any task complete.\nSee \\`checks.yaml\\` for the full list of checks.\n`;\n\nconst MINIMAL_HOLDPOINT_REFERENCE = `# Holdpoint reference\n\nRead \\`MASTER_PROMPT.md\\` first for the mandatory workflow, then use this file for deeper project-specific Holdpoint notes.\n`;\n\nconst MINIMAL_PREREQUISITES = `# Holdpoint prerequisites\n\nHoldpoint installed repo-local engine integrations for one or more AI coding agents. Before relying on them locally, review these setup notes:\n\n- **GitHub Copilot CLI** — Holdpoint's \\`.github/extensions/holdpoint/extension.mjs\\` uses the Copilot CLI **EXTENSIONS** feature. Today that feature is gated behind experimental mode. In Copilot CLI, run \\`/experimental on\\` so **EXTENSIONS** appears in the enabled feature set before using Holdpoint locally.\n- **Cursor** — project-level hooks run in trusted workspaces. After opening the repo in Cursor, confirm the workspace is trusted and review Settings → Hooks if hooks do not fire.\n- **OpenAI Codex** — project-level hooks require trust approval. Run \\`codex trust\\` in the Codex TUI or review the hook with \\`/hooks\\`.\n- **General** — Holdpoint expects Node.js 18+ and a git repository so \\`holdpoint init\\`, \\`holdpoint update\\`, and \\`holdpoint check\\` can run normally.\n\nDocs: https://holdpoint.dev/docs\n`;\n\n/**\n * Initialise Holdpoint in the current project.\n *\n * Writes `checks.yaml` (from the unified default template), `checks.immutable.json`,\n * engine files for each target agent (Copilot, Claude, Cursor, Codex),\n * and repo-local handoff docs such as `HOLDPOINT_PREREQUISITES.md`.\n * Defaults to installing all four agents; pass `--agent` to restrict to one.\n */\nexport async function initCommand(options: { agent?: string }): Promise<void> {\n const spinner = ora(\"Initialising Holdpoint…\").start();\n\n // Default: install for all agents. Pass --agent=copilot|claude|cursor to restrict.\n const agentOpt = options.agent;\n const agents: AgentType[] =\n !agentOpt || agentOpt === \"all\"\n ? [\"copilot\", \"claude\", \"cursor\", \"codex\"]\n : [agentOpt as AgentType];\n\n spinner.text = `Installing for: ${chalk.cyan(agents.join(\", \"))}`;\n\n // Detect package manager once — used both for template substitution and devDep install.\n const pm = detectPackageManager();\n\n // 1. Read or create checks.yaml\n let yamlContent = MINIMAL_CHECKS_YAML;\n if (!existsSync(\"checks.yaml\")) {\n const templatePath = getDefaultTemplatePath();\n if (templatePath) {\n yamlContent = readFileSync(templatePath, \"utf8\");\n }\n // Substitute the package manager so checks use the right runner (npm/yarn/pnpm).\n if (pm !== \"pnpm\") {\n yamlContent = yamlContent.replace(/\\bpnpm\\b/g, pm);\n }\n writeFileSync(\"checks.yaml\", yamlContent, \"utf8\");\n } else {\n yamlContent = readFileSync(\"checks.yaml\", \"utf8\");\n }\n\n const config = parseHoldpointYaml(yamlContent);\n\n // 2. Write checks.immutable.json — read by holdpoint-check.mjs at runtime\n const generatedDir = \".github/holdpoint/generated\";\n mkdirSync(generatedDir, { recursive: true });\n writeFileSync(`${generatedDir}/checks.immutable.json`, buildConfigJson(config), \"utf8\");\n\n // 3. Install engine files for each target agent\n if (agents.includes(\"copilot\")) {\n // extension.mjs handles both session context injection (onSessionStart) and\n // check enforcement (onPreToolUse → task_complete). No separate hooks files needed.\n const extDir = \".github/extensions/holdpoint\";\n mkdirSync(extDir, { recursive: true });\n writeFileSync(join(extDir, \"extension.mjs\"), buildEngine(config), \"utf8\");\n spliceBreadcrumb(\".github/copilot-instructions.md\");\n }\n\n if (agents.includes(\"claude\")) {\n mkdirSync(\".claude\", { recursive: true });\n const settingsPath = \".claude/settings.json\";\n let existing: Record<string, unknown> = {};\n if (existsSync(settingsPath)) {\n try {\n existing = JSON.parse(readFileSync(settingsPath, \"utf8\")) as Record<string, unknown>;\n } catch {\n /* ignore */\n }\n }\n const holdpointHooks = JSON.parse(buildClaudeEngineJson(config)) as Record<string, unknown>;\n writeFileSync(\n settingsPath,\n JSON.stringify(mergeClaudeSettings(existing, holdpointHooks), null, 2),\n \"utf8\",\n );\n spliceBreadcrumb(\"CLAUDE.md\");\n }\n\n if (agents.includes(\"cursor\")) {\n mkdirSync(\".cursor\", { recursive: true });\n const cursorHooksPath = \".cursor/hooks.json\";\n let existingHooks: Record<string, unknown> = {};\n if (existsSync(cursorHooksPath)) {\n try {\n existingHooks = JSON.parse(readFileSync(cursorHooksPath, \"utf8\")) as Record<\n string,\n unknown\n >;\n } catch {\n /* ignore */\n }\n }\n const cursorHooks = JSON.parse(buildCursorHooksJson(config)) as Record<string, unknown>;\n writeFileSync(\n cursorHooksPath,\n JSON.stringify(mergeCursorHooks(existingHooks, cursorHooks), null, 2) + \"\\n\",\n \"utf8\",\n );\n writeFileSync(\".cursor/holdpoint-hook.mjs\", buildCursorCheckScript(), \"utf8\");\n\n const cursorRules = buildCursorEngine(config);\n const cursorPath = \".cursorrules\";\n if (existsSync(cursorPath)) {\n const existing = readFileSync(cursorPath, \"utf8\");\n if (!existing.includes(\"Holdpoint Rules\")) {\n writeFileSync(cursorPath, `${existing.trimEnd()}\\n\\n${cursorRules}`, \"utf8\");\n }\n } else {\n writeFileSync(cursorPath, cursorRules, \"utf8\");\n }\n spliceBreadcrumb(\".cursor/rules/holdpoint.md\");\n }\n\n if (agents.includes(\"codex\")) {\n mkdirSync(\".codex\", { recursive: true });\n writeFileSync(\".codex/hooks.json\", buildCodexHooksJson(config), \"utf8\");\n writeFileSync(\".codex/holdpoint-check.mjs\", buildCodexCheckScript(config), \"utf8\");\n writeFileSync(\".codex/config.toml\", buildCodexConfigToml(), \"utf8\");\n spliceBreadcrumb(\"AGENTS.md\");\n }\n\n // 4. Create repo-local guidance files if not present\n ensureBundledFile(\"MASTER_PROMPT.md\", \"MASTER_PROMPT.md\", MINIMAL_MASTER_PROMPT);\n ensureBundledFile(\n \"HOLDPOINT_REFERENCE.md\",\n \"HOLDPOINT_REFERENCE.md\",\n MINIMAL_HOLDPOINT_REFERENCE,\n );\n ensureBundledFile(\n \"HOLDPOINT_PREREQUISITES.md\",\n \"HOLDPOINT_PREREQUISITES.md\",\n MINIMAL_PREREQUISITES,\n );\n\n // Install holdpoint as a devDependency so hooks resolve via node_modules/.bin\n // rather than downloading on every hook fire via npx.\n spinner.text = \"Installing holdpoint as a devDependency…\";\n const installCmds: Record<PackageManager, string> = {\n pnpm: \"pnpm add -D holdpoint\",\n yarn: \"yarn add --dev holdpoint\",\n npm: \"npm install --save-dev holdpoint\",\n };\n const installCmd = installCmds[pm];\n try {\n execSync(installCmd, { stdio: \"pipe\" });\n spinner.succeed(chalk.bold.green(\"Holdpoint initialised!\"));\n } catch {\n spinner.warn(\n chalk.yellow(`Holdpoint initialised, but could not install the package automatically.`) +\n `\\n Run manually: ${chalk.yellow(installCmd)}`,\n );\n }\n\n // Per-agent preflight: surface the Copilot `/experimental on` step and Codex\n // `codex trust` step at install time.\n // instead of burying them in HOLDPOINT_PREREQUISITES.md where users\n // routinely miss them.\n const preflight = runPreflight(agents);\n printPreflight(preflight);\n\n // If `holdpoint` is already on PATH (typically because the user has the\n // global install), use the bare command. Otherwise fall back to `npx\n // holdpoint` so the suggested commands actually work for users who only\n // have the local devDep.\n let holdpointInvocation = \"npx holdpoint\";\n try {\n execSync(\"command -v holdpoint\", { stdio: \"pipe\" });\n holdpointInvocation = \"holdpoint\";\n } catch {\n // not on PATH — keep the npx fallback\n }\n\n console.log(`\n${chalk.cyan(\"Next steps:\")}\n 1. Edit ${chalk.yellow(\"checks.yaml\")} to customise your eval checkpoints\n 2. Address any ${chalk.yellow(\"→\")} items above (full notes in ${chalk.yellow(\"HOLDPOINT_PREREQUISITES.md\")})\n 3. Commit ${chalk.yellow(\"checks.yaml\")}, ${chalk.yellow(\"HOLDPOINT_PREREQUISITES.md\")}, and the generated engine files\n 4. Run ${chalk.yellow(holdpointInvocation)} ${chalk.yellow(\"check\")} at any time to validate\n\n Visual builder: ${chalk.yellow(holdpointInvocation + \" builder\")} (opens the daemon at /builder)\n Agents: ${chalk.cyan(agents.join(\", \"))}\n`);\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport type { AgentType } from \"@holdpoint/types\";\n\nexport type PackageManager = \"pnpm\" | \"yarn\" | \"npm\";\n\n/** Detect which package manager owns the current project by checking lock files. */\nexport function detectPackageManager(): PackageManager {\n if (existsSync(\"pnpm-lock.yaml\")) return \"pnpm\";\n if (existsSync(\"yarn.lock\")) return \"yarn\";\n return \"npm\";\n}\n\n/** @deprecated Use detectInstalledAgents() — single-agent detection is no longer the default. */\nexport function detectAgent(): AgentType {\n if (existsSync(\".github/extensions\")) return \"copilot\";\n if (existsSync(\".claude\")) return \"claude\";\n if (existsSync(\".cursor/hooks.json\")) return \"cursor\";\n if (existsSync(\".cursorrules\")) return \"cursor\";\n if (existsSync(\".codex\")) return \"codex\";\n return \"unknown\";\n}\n\n/**\n * Returns every agent whose Holdpoint engine files are already present in the\n * current working directory. Used by `holdpoint update` so it regenerates only\n * the engines that were previously installed.\n */\nexport function detectInstalledAgents(): AgentType[] {\n const agents: AgentType[] = [];\n if (existsSync(\".github/extensions/holdpoint/extension.mjs\")) agents.push(\"copilot\");\n if (existsSync(\".claude/settings.json\")) agents.push(\"claude\");\n if (existsSync(\".cursor/hooks.json\")) {\n try {\n if (readFileSync(\".cursor/hooks.json\", \"utf8\").includes(\"HOLDPOINT_MANAGED=cursor\")) {\n agents.push(\"cursor\");\n }\n } catch {\n /* ignore unreadable file */\n }\n }\n if (existsSync(\".cursorrules\")) {\n try {\n if (\n !agents.includes(\"cursor\") &&\n readFileSync(\".cursorrules\", \"utf8\").includes(\"Holdpoint Rules\")\n ) {\n agents.push(\"cursor\");\n }\n } catch {\n /* ignore unreadable file */\n }\n }\n // Detect Codex by the generated check script (more specific than .codex/ existence)\n if (existsSync(\".codex/holdpoint-check.mjs\")) agents.push(\"codex\");\n return agents;\n}\n","import { copyFileSync, existsSync, writeFileSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport function getBundledTemplatePath(filename: string): string {\n const candidates = [\n join(__dirname, \"templates\", filename), // dist/templates/ (published package)\n join(__dirname, \"../../../templates\", filename), // monorepo dev fallback\n join(process.cwd(), \"templates\", filename), // cwd fallback\n ];\n for (const candidate of candidates) {\n if (existsSync(candidate)) return candidate;\n }\n return \"\";\n}\n\nexport function ensureBundledFile(\n outputPath: string,\n templateFilename: string,\n fallbackContent: string,\n): boolean {\n if (existsSync(outputPath)) {\n return false;\n }\n\n const templatePath = getBundledTemplatePath(templateFilename);\n if (templatePath) {\n copyFileSync(templatePath, outputPath);\n } else {\n writeFileSync(outputPath, fallbackContent, \"utf8\");\n }\n\n return true;\n}\n","import { execSync } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport type { AgentType } from \"@holdpoint/types\";\n\n/**\n * Result of a single preflight check for one agent.\n *\n * - `ok`: the agent's toolchain is detected and ready to use.\n * - `action_required`: we can be specific about something the user must do\n * (install a tool, enable a feature, approve a hook) — `command` is set.\n * - `unknown`: detection failed but we can't be sure what the user needs.\n */\nexport type PreflightStatus = \"ok\" | \"action_required\" | \"unknown\";\n\nexport interface PreflightResult {\n agent: AgentType;\n status: PreflightStatus;\n /** One-line human-readable summary, no trailing newline. */\n message: string;\n /** When `action_required`, the exact command the user should run next. */\n command?: string;\n /** When set, points at HOLDPOINT_PREREQUISITES.md or external docs. */\n docs?: string;\n}\n\n/**\n * Run silently — used for tool detection where we expect failure to be common\n * and don't want stderr bleeding into the init spinner output.\n */\nfunction silentExec(cmd: string): { ok: boolean; stdout: string } {\n try {\n const stdout = execSync(cmd, { stdio: [\"ignore\", \"pipe\", \"ignore\"] }).toString();\n return { ok: true, stdout };\n } catch {\n return { ok: false, stdout: \"\" };\n }\n}\n\n/**\n * Copilot CLI preflight.\n *\n * We can detect `gh` and the `gh-copilot` extension reliably, but the\n * `/experimental on` requirement is runtime state inside the Copilot CLI\n * session itself — there's no clean filesystem signal. So we always remind\n * users to enable it, even when everything else looks healthy.\n */\nfunction checkCopilot(): PreflightResult {\n const gh = silentExec(\"gh --version\");\n if (!gh.ok) {\n return {\n agent: \"copilot\",\n status: \"action_required\",\n message: \"GitHub CLI not found on PATH\",\n command: \"brew install gh # or: https://cli.github.com/\",\n };\n }\n\n // `gh copilot --version` exits non-zero if the extension isn't installed.\n const copilot = silentExec(\"gh copilot --version\");\n if (!copilot.ok) {\n return {\n agent: \"copilot\",\n status: \"action_required\",\n message: \"Copilot CLI extension not installed\",\n command: \"gh extension install github/gh-copilot\",\n };\n }\n\n return {\n agent: \"copilot\",\n status: \"action_required\",\n message: \"Copilot CLI detected — experimental mode required for EXTENSIONS\",\n command: \"Inside Copilot CLI, run: /experimental on\",\n };\n}\n\n/**\n * Claude Code preflight. Settings live at `.claude/settings.json`, which we\n * write ourselves during init, so the only failure mode is the binary\n * missing from PATH (in which case the user still wants the settings file\n * written — they may be invoking Claude Code from a different machine).\n */\nfunction checkClaude(): PreflightResult {\n const claude = silentExec(\"claude --version\");\n if (!claude.ok) {\n return {\n agent: \"claude\",\n status: \"unknown\",\n message: \"Claude Code binary not on PATH (hooks still written for when it is)\",\n };\n }\n return {\n agent: \"claude\",\n status: \"ok\",\n message: \"Claude Code detected — hooks installed at .claude/settings.json\",\n };\n}\n\n/**\n * Cursor preflight. Project `.cursor/hooks.json` hooks run only in trusted\n * workspaces, which is runtime state inside Cursor and not reliably readable\n * from disk, so init prints the trust/debugging reminder every time.\n */\nfunction checkCursor(): PreflightResult {\n return {\n agent: \"cursor\",\n status: \"ok\",\n message: \"Cursor — .cursor/hooks.json gate + .cursor/rules breadcrumb installed\",\n docs: \"https://holdpoint.dev/docs#cursor\",\n };\n}\n\n/**\n * Codex preflight. Project-level hooks require trust approval inside the\n * Codex TUI, which is runtime state we can't read from disk reliably across\n * Codex versions — so this mirrors the Copilot pattern: detect the binary,\n * always remind the user about `codex trust`.\n */\nfunction checkCodex(): PreflightResult {\n const codex = silentExec(\"codex --version\");\n if (!codex.ok) {\n return {\n agent: \"codex\",\n status: \"action_required\",\n message: \"Codex CLI not found on PATH\",\n command: \"Install Codex: https://github.com/openai/codex\",\n };\n }\n return {\n agent: \"codex\",\n status: \"action_required\",\n message: \"Codex detected — project-level hooks require trust approval\",\n command: \"In the Codex TUI: codex trust (or /hooks to review)\",\n };\n}\n\n// `AgentType` includes \"unknown\" for the stack-detection fallback path, but\n// only the four real agents have a preflight to run. `Partial` keeps this\n// honest instead of forcing a no-op stub.\nconst CHECKS: Partial<Record<AgentType, () => PreflightResult>> = {\n copilot: checkCopilot,\n claude: checkClaude,\n cursor: checkCursor,\n codex: checkCodex,\n};\n\n/**\n * Run preflight for the given agents and return results in input order.\n * Agents without a registered check are silently skipped — the caller's\n * agent list is the source of truth.\n *\n * Intentionally pure apart from `execSync` so callers can decide whether\n * to print, summarise, or fail-fast on the results.\n */\nexport function runPreflight(agents: readonly AgentType[]): PreflightResult[] {\n return agents.flatMap((agent) => {\n const check = CHECKS[agent];\n return check ? [check()] : [];\n });\n}\n\n/**\n * Pretty-print preflight results to stdout in the style used by `holdpoint init`.\n * Always groups by status so action items don't get lost between OKs.\n */\nexport function printPreflight(results: readonly PreflightResult[]): void {\n if (results.length === 0) return;\n\n const ok = results.filter((r) => r.status === \"ok\");\n const unknown = results.filter((r) => r.status === \"unknown\");\n const action = results.filter((r) => r.status === \"action_required\");\n\n console.log(\"\");\n console.log(chalk.bold(\"Agent preflight:\"));\n\n for (const r of ok) {\n console.log(` ${chalk.green(\"✓\")} ${r.agent.padEnd(7)} ${chalk.dim(r.message)}`);\n }\n for (const r of unknown) {\n console.log(` ${chalk.dim(\"?\")} ${r.agent.padEnd(7)} ${chalk.dim(r.message)}`);\n }\n for (const r of action) {\n console.log(` ${chalk.yellow(\"→\")} ${chalk.bold(r.agent.padEnd(7))} ${r.message}`);\n if (r.command) console.log(` ${chalk.cyan(r.command)}`);\n }\n}\n","type JsonObject = Record<string, unknown>;\n\nconst HOLDPOINT_CLAUDE_HOOK_MARKER = \"HOLDPOINT_MANAGED=claude\";\n\nfunction isObject(value: unknown): value is JsonObject {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction asHookArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nfunction isManagedHookCommand(value: unknown): boolean {\n return (\n isObject(value) &&\n typeof value.command === \"string\" &&\n value.command.includes(HOLDPOINT_CLAUDE_HOOK_MARKER)\n );\n}\n\nfunction isLegacyManagedHookCommand(value: unknown): boolean {\n if (!isObject(value) || typeof value.command !== \"string\") return false;\n return (\n value.command === \"node_modules/.bin/holdpoint event --engine claude --from-hook || true\" ||\n value.command === \"node_modules/.bin/holdpoint check --staged\"\n );\n}\n\nfunction isManagedHookEntry(value: unknown): boolean {\n if (!isObject(value)) return false;\n const hooks = asHookArray(value.hooks);\n return (\n hooks.length > 0 &&\n (hooks.every(isManagedHookCommand) || hooks.every(isLegacyManagedHookCommand))\n );\n}\n\n/**\n * Merge generated Holdpoint hooks into .claude/settings.json without clobbering\n * user-owned hooks. Re-runs remove only entries carrying Holdpoint's marker.\n */\nexport function mergeClaudeSettings(existing: JsonObject, generated: JsonObject): JsonObject {\n const existingHooks = isObject(existing.hooks) ? existing.hooks : {};\n const generatedHooks = isObject(generated.hooks) ? generated.hooks : {};\n const mergedHooks: JsonObject = {};\n\n for (const eventName of new Set([\n ...Object.keys(existingHooks),\n ...Object.keys(generatedHooks),\n ])) {\n const preserved = asHookArray(existingHooks[eventName]).filter(\n (entry) => !isManagedHookEntry(entry),\n );\n const next = asHookArray(generatedHooks[eventName]);\n if (preserved.length > 0 || next.length > 0) {\n mergedHooks[eventName] = [...preserved, ...next];\n }\n }\n\n return { ...existing, ...generated, hooks: mergedHooks };\n}\n","type JsonObject = Record<string, unknown>;\n\nconst HOLDPOINT_CURSOR_HOOK_MARKER = \"HOLDPOINT_MANAGED=cursor\";\n\nfunction isObject(value: unknown): value is JsonObject {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction asHookArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nfunction isManagedCursorHook(value: unknown): boolean {\n return (\n isObject(value) &&\n typeof value.command === \"string\" &&\n (value.command.includes(HOLDPOINT_CURSOR_HOOK_MARKER) ||\n value.command.includes(\".cursor/holdpoint-hook.mjs\"))\n );\n}\n\n/**\n * Merge generated Holdpoint Cursor hooks into `.cursor/hooks.json` without\n * clobbering user/partner hooks. Re-runs remove only entries carrying\n * Holdpoint's marker or the generated hook script path.\n */\nexport function mergeCursorHooks(existing: JsonObject, generated: JsonObject): JsonObject {\n const existingHooks = isObject(existing.hooks) ? existing.hooks : {};\n const generatedHooks = isObject(generated.hooks) ? generated.hooks : {};\n const mergedHooks: JsonObject = {};\n\n for (const eventName of new Set([\n ...Object.keys(existingHooks),\n ...Object.keys(generatedHooks),\n ])) {\n const preserved = asHookArray(existingHooks[eventName]).filter(\n (entry) => !isManagedCursorHook(entry),\n );\n const next = asHookArray(generatedHooks[eventName]);\n if (preserved.length > 0 || next.length > 0) {\n mergedHooks[eventName] = [...preserved, ...next];\n }\n }\n\n return { ...existing, ...generated, hooks: mergedHooks };\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nconst START_MARKER =\n \"<!-- HOLDPOINT_MANAGED — content between these markers is auto-generated by holdpoint init / holdpoint update -->\";\nconst END_MARKER = \"<!-- /HOLDPOINT_MANAGED -->\";\n\n/** Canonical breadcrumb content. Same wording for every agent on purpose. */\nexport const BREADCRUMB_BODY = `## Holdpoint workflow\n\nThis repo uses [Holdpoint](https://holdpoint.dev) to gate task completion on deterministic checks.\n\nBefore marking any task done:\n\n1. Run \\`holdpoint check\\` (or it will run automatically via Stop / TaskCompleted hooks).\n2. Fix any failures. Re-run until exit 0.\n3. Never bypass with \\`--no-verify\\` or by skipping the agent's stop hook.\n\nFull workflow reference: [\\`MASTER_PROMPT.md\\`](./MASTER_PROMPT.md) (always injected at session start).\nDeep reference: [\\`HOLDPOINT_REFERENCE.md\\`](./HOLDPOINT_REFERENCE.md) (read on demand).\nActive checks: [\\`checks.yaml\\`](./checks.yaml).`;\n\n/**\n * Idempotently splice the Holdpoint breadcrumb into a markdown instructions file.\n * - If the file is missing and createIfMissing: write a new file containing only the breadcrumb block.\n * - If the file has the markers: replace content between them.\n * - If the file exists but has no markers: append the breadcrumb block separated by a blank line.\n * Content outside the markers is never touched.\n */\nexport function spliceBreadcrumb(\n filePath: string,\n body: string = BREADCRUMB_BODY,\n createIfMissing = true,\n): void {\n const block = `${START_MARKER}\\n\\n${body}\\n\\n${END_MARKER}`;\n if (!existsSync(filePath)) {\n if (!createIfMissing) return;\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, block + \"\\n\", \"utf8\");\n return;\n }\n const existing = readFileSync(filePath, \"utf8\");\n const startIdx = existing.indexOf(START_MARKER);\n const endIdx = existing.indexOf(END_MARKER);\n if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {\n const before = existing.slice(0, startIdx);\n const after = existing.slice(endIdx + END_MARKER.length);\n writeFileSync(filePath, before + block + after, \"utf8\");\n return;\n }\n const sep = existing.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n writeFileSync(filePath, existing + sep + block + \"\\n\", \"utf8\");\n}\n"],"mappings":"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","names":["execSync","existsSync","readFileSync","writeFileSync","mkdirSync","join","dirname","fileURLToPath","chalk","existsSync","isObject","asHookArray","existsSync","readFileSync","writeFileSync","dirname","__dirname","dirname","fileURLToPath","join","existsSync","chalk","readFileSync","writeFileSync","mkdirSync","execSync"]}
|
package/dist/init-FNQ5GQBD.js
DELETED
|
File without changes
|