@jenz-ai/sdk 0.2.0 → 0.2.1
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/cli.js +7 -6
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -5,12 +5,13 @@ import { intro, multiselect, note, outro, isCancel, cancel, select, log } from "
|
|
|
5
5
|
import pc from "picocolors";
|
|
6
6
|
|
|
7
7
|
// src/cli/logo.ts
|
|
8
|
-
var LOGO = `
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
var LOGO = ` \u2591\u2588\u2588\u2588\u2588\u2588
|
|
9
|
+
\u2591\u2588\u2588
|
|
10
|
+
\u2591\u2588\u2588 \u2591\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2591\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2591\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588
|
|
11
|
+
\u2591\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588\u2588
|
|
12
|
+
\u2591\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588\u2588
|
|
13
|
+
\u2591\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588\u2588
|
|
14
|
+
\u2591\u2588\u2588\u2588\u2588\u2588\u2588 \u2591\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588 \u2591\u2588\u2588
|
|
14
15
|
`;
|
|
15
16
|
var TAGLINE = "observability for AI agents";
|
|
16
17
|
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/init.ts","../src/cli/logo.ts","../src/cli/detect.ts","../src/cli/skill-content.ts","../src/cli/install/claude.ts","../src/cli/install/conflict.ts","../src/cli/install/cursor.ts","../src/cli/install/agents.ts","../src/cli/install/markers.ts","../src/cli/install/codex.ts","../src/cli.ts"],"sourcesContent":["import { intro, multiselect, note, outro, isCancel, cancel, select, log } from '@clack/prompts';\nimport pc from 'picocolors';\nimport { LOGO, TAGLINE } from './logo.js';\nimport { detectTools } from './detect.js';\nimport { readSkillBody } from './skill-content.js';\nimport { installClaude } from './install/claude.js';\nimport { installCursor } from './install/cursor.js';\nimport { installAgentsMd } from './install/agents.js';\nimport { installCodex } from './install/codex.js';\nimport type { ConflictHandler } from './install/conflict.js';\nimport { diffHint } from './install/conflict.js';\n\ninterface TargetMeta {\n id: 'claude' | 'cursor' | 'agents' | 'codex';\n label: string;\n hint: string;\n detected: boolean;\n}\n\nconst clackConflict: ConflictHandler = async (filePath, existing, planned) => {\n note(\n `File exists with different content:\\n${pc.dim(filePath)}\\n\\n${diffHint(existing, planned)}`,\n 'Conflict',\n );\n const choice = await select({\n message: 'What should I do?',\n options: [\n { value: 'overwrite' as const, label: 'Overwrite', hint: 'replace the existing file' },\n { value: 'skip' as const, label: 'Skip', hint: 'leave the existing file alone' },\n { value: 'rename' as const, label: 'Rename', hint: 'write to <file>.new' },\n ],\n });\n if (isCancel(choice)) {\n cancel('Cancelled.');\n process.exit(0);\n }\n return choice as 'overwrite' | 'skip' | 'rename';\n};\n\nexport async function runInit(): Promise<void> {\n // Welcome\n intro(pc.cyan(LOGO) + '\\n ' + pc.dim(TAGLINE));\n\n // Detect\n const detected = detectTools();\n const targets: TargetMeta[] = [\n { id: 'claude', label: 'Claude Code', hint: '~/.claude/skills/jenz-setup/ + /jenz command', detected: detected.claude },\n { id: 'cursor', label: 'Cursor', hint: '.cursor/rules/jenz-setup.mdc', detected: detected.cursor },\n { id: 'agents', label: 'AGENTS.md', hint: './AGENTS.md (section)', detected: detected.agents },\n { id: 'codex', label: 'Codex', hint: '~/.codex/instructions.md (section)', detected: detected.codex },\n ];\n\n note(\n targets\n .map((t) => `${t.detected ? pc.green('✓') : pc.dim('✗')} ${t.label.padEnd(14)} ${pc.dim(t.hint)}`)\n .join('\\n'),\n 'Detected tools',\n );\n\n // Multi-select install targets\n const selected = await multiselect({\n message: 'Where should I install the Jenz setup skill?',\n options: targets.map((t) => ({\n value: t.id,\n label: t.label,\n hint: t.hint,\n })),\n initialValues: targets.filter((t) => t.detected).map((t) => t.id),\n required: false,\n });\n\n if (isCancel(selected)) {\n cancel('Cancelled.');\n process.exit(0);\n }\n\n if (!selected || selected.length === 0) {\n note(\n `No targets selected. To set up Jenz manually, tell your AI tool:\\n\\n ${pc.cyan('\"Read node_modules/@jenz-ai/sdk/SETUP.md and follow it to add Jenz observability.\"')}`,\n 'Fallback',\n );\n outro('Done.');\n return;\n }\n\n // Install\n const skillBody = readSkillBody();\n const written: string[] = [];\n\n for (const id of selected) {\n const t = targets.find((x) => x.id === id)!;\n try {\n const result = await runInstall(id as TargetMeta['id'], skillBody);\n written.push(...result.written);\n const detail = result.written.length === 0\n ? pc.dim('(skipped)')\n : result.written.map((p) => pc.dim(p)).join(', ');\n log.success(`${t.label} → ${detail}`);\n } catch (err) {\n log.error(`${t.label} — ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n // Next steps\n note(\n `1. Open your AI tool (Claude Code, Cursor, Codex, …)\\n` +\n `2. Say \"${pc.cyan('set up jenz')}\" or run ${pc.cyan('/jenz')} (Claude only)\\n` +\n `3. The skill walks you through the rest — it'll wire the SDK,\\n` +\n ` ask about your agent, and prompt for an API key.`,\n 'Next',\n );\n outro(pc.green('Setup files written. Happy shipping.'));\n}\n\nasync function runInstall(id: TargetMeta['id'], body: string): Promise<{ written: string[] }> {\n switch (id) {\n case 'claude':\n return installClaude(body, { onConflict: clackConflict });\n case 'cursor':\n return installCursor(body, { onConflict: clackConflict });\n case 'agents':\n return installAgentsMd(body);\n case 'codex':\n return installCodex(body);\n }\n}\n","// figlet \"standard\" font rendering of \"jenz.ai\".\n// Kept as a string constant so init.ts can wrap it in color\n// without depending on a runtime ASCII generator.\nexport const LOGO = `\\\n _ _ \n (_) ___ _ __ ________ __(_)\n | |/ _ \\\\ '_ \\\\|_ /\\\\ \\\\ / // _ \\\\\n | | __/ | | |/ / \\\\ V // __/\n _/ |\\\\___|_| |_/___| \\\\_(_)\\\\___|\n |__| \n`;\n\nexport const TAGLINE = 'observability for AI agents';\n","import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\n\nexport interface DetectionInputs {\n homedir: string;\n cwd: string;\n /** Colon-separated PATH; defaults to process.env.PATH ?? ''. */\n path?: string;\n}\n\nexport interface DetectionResult {\n claude: boolean;\n cursor: boolean;\n codex: boolean;\n agents: boolean;\n}\n\nconst PATH_SEP = process.platform === 'win32' ? ';' : ':';\n\nfunction isBinaryInPath(binary: string, pathEnv: string): boolean {\n if (!pathEnv) return false;\n for (const dir of pathEnv.split(PATH_SEP)) {\n if (!dir) continue;\n if (existsSync(join(dir, binary))) return true;\n }\n return false;\n}\n\nexport function detectTools(inputs?: DetectionInputs): DetectionResult {\n const home = inputs?.homedir ?? homedir();\n const cwd = inputs?.cwd ?? process.cwd();\n const pathEnv = inputs?.path ?? process.env.PATH ?? '';\n\n return {\n claude: existsSync(join(home, '.claude')),\n cursor: existsSync(join(cwd, '.cursor')) || existsSync(join(home, '.cursor')),\n codex: existsSync(join(home, '.codex')) || isBinaryInPath('codex', pathEnv),\n agents: true,\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\n\n// Read SETUP.md relative to this file. The published layout is:\n// dist/cli.js ← compiled CLI (this file at runtime)\n// SETUP.md ← package root, two levels up from dist/\n// In source layout (vitest), this file is src/cli/skill-content.ts,\n// so SETUP.md is three levels up.\nfunction findSetupMd(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n // Try packaged layout (dist/cli.js → ../SETUP.md), then source\n // layout (src/cli/skill-content.ts → ../../../SETUP.md).\n const candidates = [\n join(here, '..', 'SETUP.md'),\n join(here, '..', '..', 'SETUP.md'),\n join(here, '..', '..', '..', 'SETUP.md'),\n ];\n for (const p of candidates) {\n try {\n return readFileSync(p, 'utf8');\n } catch {\n // try next\n }\n }\n throw new Error(\n `[jenz] could not locate SETUP.md (tried: ${candidates.join(', ')})`,\n );\n}\n\nlet cached: string | undefined;\n\nexport function readSkillBody(): string {\n if (cached === undefined) cached = findSetupMd();\n return cached;\n}\n","import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport type { ConflictHandler } from './conflict.js';\nimport { renamedPath } from './conflict.js';\n\nexport interface ClaudeInstallOptions {\n homedir?: string;\n onConflict?: ConflictHandler;\n}\n\nexport interface InstallResult {\n written: string[];\n}\n\nconst SKILL_FRONTMATTER = `---\nname: jenz-setup\ndescription: Set up Jenz observability (jenz.dev) for an AI agent — detects the agent's main loop and LLM calls, asks about logging scope, wires up @jenz-ai/sdk, and prompts for an API key. Use when the user says \"set up jenz\", \"add jenz\", \"monitor my agent with jenz\", or just installed @jenz-ai/sdk.\n---\n`;\n\nconst SLASH_COMMAND = `---\ndescription: Set up Jenz observability for this project\n---\n\nActivate the jenz-setup skill and walk me through wiring up Jenz\nin this project. Use AskUserQuestion for the configuration\nquestions and TodoWrite to track the 6 setup steps.\n`;\n\nasync function writeWithConflictPolicy(\n filePath: string,\n planned: string,\n onConflict: ConflictHandler | undefined,\n): Promise<string | null> {\n mkdirSync(dirname(filePath), { recursive: true });\n if (existsSync(filePath) && onConflict) {\n const existing = readFileSync(filePath, 'utf8');\n if (existing !== planned) {\n const decision = await onConflict(filePath, existing, planned);\n if (decision === 'skip') return null;\n if (decision === 'rename') {\n const newPath = renamedPath(filePath);\n writeFileSync(newPath, planned, 'utf8');\n return newPath;\n }\n }\n }\n writeFileSync(filePath, planned, 'utf8');\n return filePath;\n}\n\nexport async function installClaude(\n skillBody: string,\n opts: ClaudeInstallOptions = {},\n): Promise<InstallResult> {\n const home = opts.homedir ?? homedir();\n const skillPath = join(home, '.claude', 'skills', 'jenz-setup', 'SKILL.md');\n const cmdPath = join(home, '.claude', 'commands', 'jenz.md');\n\n const written: string[] = [];\n const skillResult = await writeWithConflictPolicy(\n skillPath,\n `${SKILL_FRONTMATTER}\\n${skillBody}`,\n opts.onConflict,\n );\n if (skillResult) written.push(skillResult);\n\n const cmdResult = await writeWithConflictPolicy(\n cmdPath,\n SLASH_COMMAND,\n opts.onConflict,\n );\n if (cmdResult) written.push(cmdResult);\n\n return { written };\n}\n","/** Decision returned by an onConflict callback. */\nexport type ConflictDecision = 'overwrite' | 'skip' | 'rename';\n\n/**\n * Called when a target wants to write a file that already exists with\n * different content. The callback decides what to do.\n *\n * - `overwrite`: write the new content over the existing file\n * - `skip`: leave the existing file alone, do not write\n * - `rename`: write the new content to a sibling path (`<file>.new`),\n * leave the existing file alone\n */\nexport type ConflictHandler = (\n filePath: string,\n existing: string,\n planned: string,\n) => Promise<ConflictDecision>;\n\n/**\n * Insert `.new` before the file extension. If no extension, append `.new`.\n * Examples:\n * foo.md → foo.new.md\n * bar.tar.gz → bar.tar.new.gz\n * plain → plain.new\n */\nexport function renamedPath(filePath: string): string {\n const dotIdx = filePath.lastIndexOf('.');\n const slashIdx = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\\\'));\n if (dotIdx <= slashIdx) return `${filePath}.new`;\n return `${filePath.slice(0, dotIdx)}.new${filePath.slice(dotIdx)}`;\n}\n\n/**\n * Generate a human-readable 3-line diff hint between existing and planned\n * content. Used by the clack-based prompt to show users WHAT differs.\n */\nexport function diffHint(existing: string, planned: string): string {\n const exLines = existing.split('\\n');\n const plLines = planned.split('\\n');\n let firstDiff = -1;\n const max = Math.max(exLines.length, plLines.length);\n for (let i = 0; i < max; i++) {\n if (exLines[i] !== plLines[i]) {\n firstDiff = i;\n break;\n }\n }\n if (firstDiff === -1) return 'Files match (no diff).';\n const exLine = exLines[firstDiff] ?? '(end of file)';\n const plLine = plLines[firstDiff] ?? '(end of file)';\n const truncated = (s: string) => (s.length > 80 ? `${s.slice(0, 77)}...` : s);\n return [\n `existing ${exLines.length} lines, new ${plLines.length} lines (first diff at line ${firstDiff + 1})`,\n ` - ${truncated(exLine)}`,\n ` + ${truncated(plLine)}`,\n ].join('\\n');\n}\n","import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport type { ConflictHandler } from './conflict.js';\nimport { renamedPath } from './conflict.js';\n\nexport interface CursorInstallOptions {\n cwd?: string;\n onConflict?: ConflictHandler;\n}\n\nexport interface InstallResult {\n written: string[];\n}\n\nconst FRONTMATTER = `---\ndescription: Jenz observability setup playbook — wires up @jenz-ai/sdk in this project. Activate when the user asks to set up jenz, add observability, or track agent runs.\nalwaysApply: false\n---\n`;\n\nexport async function installCursor(\n skillBody: string,\n opts: CursorInstallOptions = {},\n): Promise<InstallResult> {\n const cwd = opts.cwd ?? process.cwd();\n const filePath = join(cwd, '.cursor', 'rules', 'jenz-setup.mdc');\n const planned = `${FRONTMATTER}\\n${skillBody}`;\n\n mkdirSync(dirname(filePath), { recursive: true });\n\n if (existsSync(filePath) && opts.onConflict) {\n const existing = readFileSync(filePath, 'utf8');\n if (existing !== planned) {\n const decision = await opts.onConflict(filePath, existing, planned);\n if (decision === 'skip') return { written: [] };\n if (decision === 'rename') {\n const newPath = renamedPath(filePath);\n writeFileSync(newPath, planned, 'utf8');\n return { written: [newPath] };\n }\n // 'overwrite' falls through\n }\n }\n\n writeFileSync(filePath, planned, 'utf8');\n return { written: [filePath] };\n}\n","import { readFileSync, writeFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { upsertSection } from './markers.js';\n\nexport interface InstallOptions {\n cwd?: string;\n}\n\nexport interface InstallResult {\n written: string[];\n}\n\nexport async function installAgentsMd(\n skillBody: string,\n opts: InstallOptions = {},\n): Promise<InstallResult> {\n const cwd = opts.cwd ?? process.cwd();\n const filePath = join(cwd, 'AGENTS.md');\n\n const existing = existsSync(filePath) ? readFileSync(filePath, 'utf8') : '';\n const sectionBody = `## Jenz Setup\\n\\n${skillBody}`;\n const next = upsertSection(existing, sectionBody);\n\n writeFileSync(filePath, next, 'utf8');\n return { written: [filePath] };\n}\n","const START = '<!-- jenz:start -->';\nconst END = '<!-- jenz:end -->';\n\n/**\n * Insert or replace a Jenz-owned section in `existing` content.\n *\n * - If markers exist: replace the body between them (idempotent).\n * - If markers don't exist: append a fresh section at the end.\n *\n * The returned content always ends with a single newline.\n */\nexport function upsertSection(existing: string, body: string): string {\n const section = `${START}\\n${body}\\n${END}`;\n const startIdx = existing.indexOf(START);\n const endIdx = existing.indexOf(END);\n\n if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {\n const before = existing.slice(0, startIdx);\n const after = existing.slice(endIdx + END.length);\n return ensureTrailingNewline(`${before}${section}${after}`);\n }\n\n // Append: separate from existing content with a blank line if\n // existing isn't empty and doesn't already end in a blank line.\n if (existing.length === 0) return ensureTrailingNewline(section);\n const sep = existing.endsWith('\\n\\n') ? '' : existing.endsWith('\\n') ? '\\n' : '\\n\\n';\n return ensureTrailingNewline(`${existing}${sep}${section}`);\n}\n\nfunction ensureTrailingNewline(s: string): string {\n return s.endsWith('\\n') ? s : `${s}\\n`;\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport { upsertSection } from './markers.js';\n\nexport interface CodexInstallOptions {\n homedir?: string;\n}\n\nexport interface InstallResult {\n written: string[];\n}\n\nexport async function installCodex(\n skillBody: string,\n opts: CodexInstallOptions = {},\n): Promise<InstallResult> {\n const home = opts.homedir ?? homedir();\n const filePath = join(home, '.codex', 'instructions.md');\n\n mkdirSync(dirname(filePath), { recursive: true });\n const existing = existsSync(filePath) ? readFileSync(filePath, 'utf8') : '';\n const sectionBody = `## Jenz Setup\\n\\n${skillBody}`;\n const next = upsertSection(existing, sectionBody);\n\n writeFileSync(filePath, next, 'utf8');\n return { written: [filePath] };\n}\n","import { runInit } from './cli/init.js';\n\nconst USAGE = `\\\nUsage: jenz <command>\n\nCommands:\n init Install the Jenz setup skill in your AI coding tools\n\nExamples:\n npx @jenz-ai/sdk init\n npx jenz init\n`;\n\nasync function main(): Promise<void> {\n const [, , cmd, ...rest] = process.argv;\n\n if (!cmd || cmd === '--help' || cmd === '-h' || cmd === 'help') {\n console.log(USAGE);\n process.exit(0);\n }\n\n if (rest.length > 0) {\n console.error(`jenz: unexpected arguments: ${rest.join(' ')}`);\n console.error(USAGE);\n process.exit(2);\n }\n\n switch (cmd) {\n case 'init':\n await runInit();\n return;\n default:\n console.error(`jenz: unknown command \"${cmd}\"`);\n console.error(USAGE);\n process.exit(2);\n }\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n"],"mappings":"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","names":["join","existsSync","readFileSync","join","dirname","homedir","dirname","existsSync","readFileSync","homedir","join","writeFileSync","mkdirSync","existsSync","readFileSync","join","dirname","join","mkdirSync","dirname","existsSync","readFileSync","writeFileSync","readFileSync","writeFileSync","existsSync","join","join","existsSync","readFileSync","writeFileSync","readFileSync","writeFileSync","existsSync","mkdirSync","join","dirname","homedir","homedir","join","mkdirSync","dirname","existsSync","readFileSync","writeFileSync"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/init.ts","../src/cli/logo.ts","../src/cli/detect.ts","../src/cli/skill-content.ts","../src/cli/install/claude.ts","../src/cli/install/conflict.ts","../src/cli/install/cursor.ts","../src/cli/install/agents.ts","../src/cli/install/markers.ts","../src/cli/install/codex.ts","../src/cli.ts"],"sourcesContent":["import { intro, multiselect, note, outro, isCancel, cancel, select, log } from '@clack/prompts';\nimport pc from 'picocolors';\nimport { LOGO, TAGLINE } from './logo.js';\nimport { detectTools } from './detect.js';\nimport { readSkillBody } from './skill-content.js';\nimport { installClaude } from './install/claude.js';\nimport { installCursor } from './install/cursor.js';\nimport { installAgentsMd } from './install/agents.js';\nimport { installCodex } from './install/codex.js';\nimport type { ConflictHandler } from './install/conflict.js';\nimport { diffHint } from './install/conflict.js';\n\ninterface TargetMeta {\n id: 'claude' | 'cursor' | 'agents' | 'codex';\n label: string;\n hint: string;\n detected: boolean;\n}\n\nconst clackConflict: ConflictHandler = async (filePath, existing, planned) => {\n note(\n `File exists with different content:\\n${pc.dim(filePath)}\\n\\n${diffHint(existing, planned)}`,\n 'Conflict',\n );\n const choice = await select({\n message: 'What should I do?',\n options: [\n { value: 'overwrite' as const, label: 'Overwrite', hint: 'replace the existing file' },\n { value: 'skip' as const, label: 'Skip', hint: 'leave the existing file alone' },\n { value: 'rename' as const, label: 'Rename', hint: 'write to <file>.new' },\n ],\n });\n if (isCancel(choice)) {\n cancel('Cancelled.');\n process.exit(0);\n }\n return choice as 'overwrite' | 'skip' | 'rename';\n};\n\nexport async function runInit(): Promise<void> {\n // Welcome\n intro(pc.cyan(LOGO) + '\\n ' + pc.dim(TAGLINE));\n\n // Detect\n const detected = detectTools();\n const targets: TargetMeta[] = [\n { id: 'claude', label: 'Claude Code', hint: '~/.claude/skills/jenz-setup/ + /jenz command', detected: detected.claude },\n { id: 'cursor', label: 'Cursor', hint: '.cursor/rules/jenz-setup.mdc', detected: detected.cursor },\n { id: 'agents', label: 'AGENTS.md', hint: './AGENTS.md (section)', detected: detected.agents },\n { id: 'codex', label: 'Codex', hint: '~/.codex/instructions.md (section)', detected: detected.codex },\n ];\n\n note(\n targets\n .map((t) => `${t.detected ? pc.green('✓') : pc.dim('✗')} ${t.label.padEnd(14)} ${pc.dim(t.hint)}`)\n .join('\\n'),\n 'Detected tools',\n );\n\n // Multi-select install targets\n const selected = await multiselect({\n message: 'Where should I install the Jenz setup skill?',\n options: targets.map((t) => ({\n value: t.id,\n label: t.label,\n hint: t.hint,\n })),\n initialValues: targets.filter((t) => t.detected).map((t) => t.id),\n required: false,\n });\n\n if (isCancel(selected)) {\n cancel('Cancelled.');\n process.exit(0);\n }\n\n if (!selected || selected.length === 0) {\n note(\n `No targets selected. To set up Jenz manually, tell your AI tool:\\n\\n ${pc.cyan('\"Read node_modules/@jenz-ai/sdk/SETUP.md and follow it to add Jenz observability.\"')}`,\n 'Fallback',\n );\n outro('Done.');\n return;\n }\n\n // Install\n const skillBody = readSkillBody();\n const written: string[] = [];\n\n for (const id of selected) {\n const t = targets.find((x) => x.id === id)!;\n try {\n const result = await runInstall(id as TargetMeta['id'], skillBody);\n written.push(...result.written);\n const detail = result.written.length === 0\n ? pc.dim('(skipped)')\n : result.written.map((p) => pc.dim(p)).join(', ');\n log.success(`${t.label} → ${detail}`);\n } catch (err) {\n log.error(`${t.label} — ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n // Next steps\n note(\n `1. Open your AI tool (Claude Code, Cursor, Codex, …)\\n` +\n `2. Say \"${pc.cyan('set up jenz')}\" or run ${pc.cyan('/jenz')} (Claude only)\\n` +\n `3. The skill walks you through the rest — it'll wire the SDK,\\n` +\n ` ask about your agent, and prompt for an API key.`,\n 'Next',\n );\n outro(pc.green('Setup files written. Happy shipping.'));\n}\n\nasync function runInstall(id: TargetMeta['id'], body: string): Promise<{ written: string[] }> {\n switch (id) {\n case 'claude':\n return installClaude(body, { onConflict: clackConflict });\n case 'cursor':\n return installCursor(body, { onConflict: clackConflict });\n case 'agents':\n return installAgentsMd(body);\n case 'codex':\n return installCodex(body);\n }\n}\n","// Block-shaded ASCII rendering of \"jenz.ai\".\n// Kept as a string constant so init.ts can wrap it in color\n// without depending on a runtime ASCII generator.\nexport const LOGO = `\\\n ░█████\n ░██\n ░██ ░███████ ░████████ ░█████████\n ░██ ░██ ░██ ░██ ░██ ░███\n░██ ░██ ░█████████ ░██ ░██ ░███\n░██ ░██ ░██ ░██ ░██ ░███\n ░██████ ░███████ ░██ ░██ ░█████████ ░██ ░██ ░██ ░██\n`;\n\nexport const TAGLINE = 'observability for AI agents';\n","import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\n\nexport interface DetectionInputs {\n homedir: string;\n cwd: string;\n /** Colon-separated PATH; defaults to process.env.PATH ?? ''. */\n path?: string;\n}\n\nexport interface DetectionResult {\n claude: boolean;\n cursor: boolean;\n codex: boolean;\n agents: boolean;\n}\n\nconst PATH_SEP = process.platform === 'win32' ? ';' : ':';\n\nfunction isBinaryInPath(binary: string, pathEnv: string): boolean {\n if (!pathEnv) return false;\n for (const dir of pathEnv.split(PATH_SEP)) {\n if (!dir) continue;\n if (existsSync(join(dir, binary))) return true;\n }\n return false;\n}\n\nexport function detectTools(inputs?: DetectionInputs): DetectionResult {\n const home = inputs?.homedir ?? homedir();\n const cwd = inputs?.cwd ?? process.cwd();\n const pathEnv = inputs?.path ?? process.env.PATH ?? '';\n\n return {\n claude: existsSync(join(home, '.claude')),\n cursor: existsSync(join(cwd, '.cursor')) || existsSync(join(home, '.cursor')),\n codex: existsSync(join(home, '.codex')) || isBinaryInPath('codex', pathEnv),\n agents: true,\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\n\n// Read SETUP.md relative to this file. The published layout is:\n// dist/cli.js ← compiled CLI (this file at runtime)\n// SETUP.md ← package root, two levels up from dist/\n// In source layout (vitest), this file is src/cli/skill-content.ts,\n// so SETUP.md is three levels up.\nfunction findSetupMd(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n // Try packaged layout (dist/cli.js → ../SETUP.md), then source\n // layout (src/cli/skill-content.ts → ../../../SETUP.md).\n const candidates = [\n join(here, '..', 'SETUP.md'),\n join(here, '..', '..', 'SETUP.md'),\n join(here, '..', '..', '..', 'SETUP.md'),\n ];\n for (const p of candidates) {\n try {\n return readFileSync(p, 'utf8');\n } catch {\n // try next\n }\n }\n throw new Error(\n `[jenz] could not locate SETUP.md (tried: ${candidates.join(', ')})`,\n );\n}\n\nlet cached: string | undefined;\n\nexport function readSkillBody(): string {\n if (cached === undefined) cached = findSetupMd();\n return cached;\n}\n","import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport type { ConflictHandler } from './conflict.js';\nimport { renamedPath } from './conflict.js';\n\nexport interface ClaudeInstallOptions {\n homedir?: string;\n onConflict?: ConflictHandler;\n}\n\nexport interface InstallResult {\n written: string[];\n}\n\nconst SKILL_FRONTMATTER = `---\nname: jenz-setup\ndescription: Set up Jenz observability (jenz.dev) for an AI agent — detects the agent's main loop and LLM calls, asks about logging scope, wires up @jenz-ai/sdk, and prompts for an API key. Use when the user says \"set up jenz\", \"add jenz\", \"monitor my agent with jenz\", or just installed @jenz-ai/sdk.\n---\n`;\n\nconst SLASH_COMMAND = `---\ndescription: Set up Jenz observability for this project\n---\n\nActivate the jenz-setup skill and walk me through wiring up Jenz\nin this project. Use AskUserQuestion for the configuration\nquestions and TodoWrite to track the 6 setup steps.\n`;\n\nasync function writeWithConflictPolicy(\n filePath: string,\n planned: string,\n onConflict: ConflictHandler | undefined,\n): Promise<string | null> {\n mkdirSync(dirname(filePath), { recursive: true });\n if (existsSync(filePath) && onConflict) {\n const existing = readFileSync(filePath, 'utf8');\n if (existing !== planned) {\n const decision = await onConflict(filePath, existing, planned);\n if (decision === 'skip') return null;\n if (decision === 'rename') {\n const newPath = renamedPath(filePath);\n writeFileSync(newPath, planned, 'utf8');\n return newPath;\n }\n }\n }\n writeFileSync(filePath, planned, 'utf8');\n return filePath;\n}\n\nexport async function installClaude(\n skillBody: string,\n opts: ClaudeInstallOptions = {},\n): Promise<InstallResult> {\n const home = opts.homedir ?? homedir();\n const skillPath = join(home, '.claude', 'skills', 'jenz-setup', 'SKILL.md');\n const cmdPath = join(home, '.claude', 'commands', 'jenz.md');\n\n const written: string[] = [];\n const skillResult = await writeWithConflictPolicy(\n skillPath,\n `${SKILL_FRONTMATTER}\\n${skillBody}`,\n opts.onConflict,\n );\n if (skillResult) written.push(skillResult);\n\n const cmdResult = await writeWithConflictPolicy(\n cmdPath,\n SLASH_COMMAND,\n opts.onConflict,\n );\n if (cmdResult) written.push(cmdResult);\n\n return { written };\n}\n","/** Decision returned by an onConflict callback. */\nexport type ConflictDecision = 'overwrite' | 'skip' | 'rename';\n\n/**\n * Called when a target wants to write a file that already exists with\n * different content. The callback decides what to do.\n *\n * - `overwrite`: write the new content over the existing file\n * - `skip`: leave the existing file alone, do not write\n * - `rename`: write the new content to a sibling path (`<file>.new`),\n * leave the existing file alone\n */\nexport type ConflictHandler = (\n filePath: string,\n existing: string,\n planned: string,\n) => Promise<ConflictDecision>;\n\n/**\n * Insert `.new` before the file extension. If no extension, append `.new`.\n * Examples:\n * foo.md → foo.new.md\n * bar.tar.gz → bar.tar.new.gz\n * plain → plain.new\n */\nexport function renamedPath(filePath: string): string {\n const dotIdx = filePath.lastIndexOf('.');\n const slashIdx = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\\\'));\n if (dotIdx <= slashIdx) return `${filePath}.new`;\n return `${filePath.slice(0, dotIdx)}.new${filePath.slice(dotIdx)}`;\n}\n\n/**\n * Generate a human-readable 3-line diff hint between existing and planned\n * content. Used by the clack-based prompt to show users WHAT differs.\n */\nexport function diffHint(existing: string, planned: string): string {\n const exLines = existing.split('\\n');\n const plLines = planned.split('\\n');\n let firstDiff = -1;\n const max = Math.max(exLines.length, plLines.length);\n for (let i = 0; i < max; i++) {\n if (exLines[i] !== plLines[i]) {\n firstDiff = i;\n break;\n }\n }\n if (firstDiff === -1) return 'Files match (no diff).';\n const exLine = exLines[firstDiff] ?? '(end of file)';\n const plLine = plLines[firstDiff] ?? '(end of file)';\n const truncated = (s: string) => (s.length > 80 ? `${s.slice(0, 77)}...` : s);\n return [\n `existing ${exLines.length} lines, new ${plLines.length} lines (first diff at line ${firstDiff + 1})`,\n ` - ${truncated(exLine)}`,\n ` + ${truncated(plLine)}`,\n ].join('\\n');\n}\n","import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport type { ConflictHandler } from './conflict.js';\nimport { renamedPath } from './conflict.js';\n\nexport interface CursorInstallOptions {\n cwd?: string;\n onConflict?: ConflictHandler;\n}\n\nexport interface InstallResult {\n written: string[];\n}\n\nconst FRONTMATTER = `---\ndescription: Jenz observability setup playbook — wires up @jenz-ai/sdk in this project. Activate when the user asks to set up jenz, add observability, or track agent runs.\nalwaysApply: false\n---\n`;\n\nexport async function installCursor(\n skillBody: string,\n opts: CursorInstallOptions = {},\n): Promise<InstallResult> {\n const cwd = opts.cwd ?? process.cwd();\n const filePath = join(cwd, '.cursor', 'rules', 'jenz-setup.mdc');\n const planned = `${FRONTMATTER}\\n${skillBody}`;\n\n mkdirSync(dirname(filePath), { recursive: true });\n\n if (existsSync(filePath) && opts.onConflict) {\n const existing = readFileSync(filePath, 'utf8');\n if (existing !== planned) {\n const decision = await opts.onConflict(filePath, existing, planned);\n if (decision === 'skip') return { written: [] };\n if (decision === 'rename') {\n const newPath = renamedPath(filePath);\n writeFileSync(newPath, planned, 'utf8');\n return { written: [newPath] };\n }\n // 'overwrite' falls through\n }\n }\n\n writeFileSync(filePath, planned, 'utf8');\n return { written: [filePath] };\n}\n","import { readFileSync, writeFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { upsertSection } from './markers.js';\n\nexport interface InstallOptions {\n cwd?: string;\n}\n\nexport interface InstallResult {\n written: string[];\n}\n\nexport async function installAgentsMd(\n skillBody: string,\n opts: InstallOptions = {},\n): Promise<InstallResult> {\n const cwd = opts.cwd ?? process.cwd();\n const filePath = join(cwd, 'AGENTS.md');\n\n const existing = existsSync(filePath) ? readFileSync(filePath, 'utf8') : '';\n const sectionBody = `## Jenz Setup\\n\\n${skillBody}`;\n const next = upsertSection(existing, sectionBody);\n\n writeFileSync(filePath, next, 'utf8');\n return { written: [filePath] };\n}\n","const START = '<!-- jenz:start -->';\nconst END = '<!-- jenz:end -->';\n\n/**\n * Insert or replace a Jenz-owned section in `existing` content.\n *\n * - If markers exist: replace the body between them (idempotent).\n * - If markers don't exist: append a fresh section at the end.\n *\n * The returned content always ends with a single newline.\n */\nexport function upsertSection(existing: string, body: string): string {\n const section = `${START}\\n${body}\\n${END}`;\n const startIdx = existing.indexOf(START);\n const endIdx = existing.indexOf(END);\n\n if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {\n const before = existing.slice(0, startIdx);\n const after = existing.slice(endIdx + END.length);\n return ensureTrailingNewline(`${before}${section}${after}`);\n }\n\n // Append: separate from existing content with a blank line if\n // existing isn't empty and doesn't already end in a blank line.\n if (existing.length === 0) return ensureTrailingNewline(section);\n const sep = existing.endsWith('\\n\\n') ? '' : existing.endsWith('\\n') ? '\\n' : '\\n\\n';\n return ensureTrailingNewline(`${existing}${sep}${section}`);\n}\n\nfunction ensureTrailingNewline(s: string): string {\n return s.endsWith('\\n') ? s : `${s}\\n`;\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport { upsertSection } from './markers.js';\n\nexport interface CodexInstallOptions {\n homedir?: string;\n}\n\nexport interface InstallResult {\n written: string[];\n}\n\nexport async function installCodex(\n skillBody: string,\n opts: CodexInstallOptions = {},\n): Promise<InstallResult> {\n const home = opts.homedir ?? homedir();\n const filePath = join(home, '.codex', 'instructions.md');\n\n mkdirSync(dirname(filePath), { recursive: true });\n const existing = existsSync(filePath) ? readFileSync(filePath, 'utf8') : '';\n const sectionBody = `## Jenz Setup\\n\\n${skillBody}`;\n const next = upsertSection(existing, sectionBody);\n\n writeFileSync(filePath, next, 'utf8');\n return { written: [filePath] };\n}\n","import { runInit } from './cli/init.js';\n\nconst USAGE = `\\\nUsage: jenz <command>\n\nCommands:\n init Install the Jenz setup skill in your AI coding tools\n\nExamples:\n npx @jenz-ai/sdk init\n npx jenz init\n`;\n\nasync function main(): Promise<void> {\n const [, , cmd, ...rest] = process.argv;\n\n if (!cmd || cmd === '--help' || cmd === '-h' || cmd === 'help') {\n console.log(USAGE);\n process.exit(0);\n }\n\n if (rest.length > 0) {\n console.error(`jenz: unexpected arguments: ${rest.join(' ')}`);\n console.error(USAGE);\n process.exit(2);\n }\n\n switch (cmd) {\n case 'init':\n await runInit();\n return;\n default:\n console.error(`jenz: unknown command \"${cmd}\"`);\n console.error(USAGE);\n process.exit(2);\n }\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n"],"mappings":"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","names":["join","existsSync","readFileSync","join","dirname","homedir","dirname","existsSync","readFileSync","homedir","join","writeFileSync","mkdirSync","existsSync","readFileSync","join","dirname","join","mkdirSync","dirname","existsSync","readFileSync","writeFileSync","readFileSync","writeFileSync","existsSync","join","join","existsSync","readFileSync","writeFileSync","readFileSync","writeFileSync","existsSync","mkdirSync","join","dirname","homedir","homedir","join","mkdirSync","dirname","existsSync","readFileSync","writeFileSync"]}
|