create-agentmark 1.0.0 → 1.0.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/index.js +13 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import fs3 from "fs-extra";
|
|
5
5
|
import path3 from "path";
|
|
6
6
|
import prompts from "prompts";
|
|
7
|
-
import { pathToFileURL } from "url";
|
|
7
|
+
import { pathToFileURL, fileURLToPath } from "url";
|
|
8
8
|
|
|
9
9
|
// src/utils/examples/mcp-config.ts
|
|
10
10
|
import fs from "fs-extra";
|
|
@@ -209,7 +209,11 @@ var AGENTMARK_JSON = {
|
|
|
209
209
|
$schema: "https://raw.githubusercontent.com/agentmark-ai/agentmark/refs/heads/main/packages/cli/agentmark.schema.json",
|
|
210
210
|
version: "2.0.0",
|
|
211
211
|
mdxVersion: "1.0",
|
|
212
|
-
agentmarkPath: "."
|
|
212
|
+
agentmarkPath: ".",
|
|
213
|
+
// Seed one model so the dashboard prompt editor isn't an empty dropdown on
|
|
214
|
+
// first run. Add more with `npx agentmark pull-models` (writes provider/model
|
|
215
|
+
// entries here) — see https://docs.agentmark.co/configure/model-schemas.
|
|
216
|
+
builtInModels: ["openai/gpt-5.5"]
|
|
213
217
|
};
|
|
214
218
|
var parseArgs = (argv = process.argv.slice(2)) => {
|
|
215
219
|
const result = {};
|
|
@@ -349,7 +353,13 @@ var main = async () => {
|
|
|
349
353
|
var isDirectlyInvoked = () => {
|
|
350
354
|
const entry = process.argv[1];
|
|
351
355
|
if (!entry) return false;
|
|
352
|
-
|
|
356
|
+
try {
|
|
357
|
+
const entryReal = pathToFileURL(fs3.realpathSync(entry)).href;
|
|
358
|
+
const selfReal = pathToFileURL(fs3.realpathSync(fileURLToPath(import.meta.url))).href;
|
|
359
|
+
return entryReal === selfReal;
|
|
360
|
+
} catch {
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
353
363
|
};
|
|
354
364
|
if (isDirectlyInvoked()) {
|
|
355
365
|
main().catch((error) => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils/examples/mcp-config.ts","../src/utils/install-skill.ts","../src/utils/git-init.ts","../src/utils/project-detection.ts"],"sourcesContent":["import fs from \"fs-extra\";\nimport path from \"path\";\nimport prompts from \"prompts\";\nimport { pathToFileURL } from \"url\";\nimport { writeMcpConfig, type McpClient } from \"./utils/examples/mcp-config.js\";\nimport { installAgentmarkSkill } from \"./utils/install-skill.js\";\nimport { initGitRepo } from \"./utils/git-init.js\";\nimport { detectProjectInfo, isCurrentDirectory } from \"./utils/project-detection.js\";\n\n/**\n * `npm create agentmark` — minimal init.\n *\n * Scope is deliberately small. The CLI does NOT scaffold example code,\n * pick an LLM adapter, or handle login. Its job is:\n *\n * 1. Write `agentmark.json` (the SDK loader's config root)\n * 2. Create an empty `agentmark/` directory (where prompts go)\n * 3. Wire MCP configs for any IDE clients the user selects\n * 4. Install the AgentMark agent skill (`npx skills add agentmark-ai/skills`)\n * 5. Hand off to the AI tool: \"Open Claude Code / Cursor and say:\n * Set up AgentMark in this project.\"\n *\n * Everything else — framework detection, package install, code wiring,\n * first prompt — is the job of the `setup-and-integration` skill workflow,\n * which runs inside the user's IDE agent. That keeps integration adaptive\n * to whatever stack the user already has, instead of forcing a template.\n */\n\nexport interface CliArgs {\n path?: string;\n clients?: McpClient[];\n /**\n * Undocumented escape hatch for internal staging\n * (`https://api-stg.agentmark.co`) and rare self-hosters. Defaults to\n * `https://api.agentmark.co`. The `agentmark-local` MCP entry always\n * points at `http://localhost:9418` regardless of this flag.\n */\n apiUrl?: string;\n overwrite?: boolean;\n}\n\nexport const ALL_CLIENTS: readonly McpClient[] = [\"claude-code\", \"cursor\", \"vscode\", \"zed\"];\n\nexport const AGENTMARK_JSON: Record<string, unknown> = {\n $schema:\n \"https://raw.githubusercontent.com/agentmark-ai/agentmark/refs/heads/main/packages/cli/agentmark.schema.json\",\n version: \"2.0.0\",\n mdxVersion: \"1.0\",\n agentmarkPath: \".\",\n};\n\nexport const parseArgs = (argv: string[] = process.argv.slice(2)): CliArgs => {\n const result: CliArgs = {};\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === \"--path\") {\n result.path = argv[++i];\n } else if (arg === \"--client\") {\n const value = argv[++i];\n if (!value) throw new Error(\"--client requires a value\");\n const ids = value === \"all\"\n ? [...ALL_CLIENTS]\n : value.split(\",\").map((s) => s.trim()).filter(Boolean) as McpClient[];\n result.clients = [...(result.clients ?? []), ...ids];\n } else if (arg === \"--overwrite\") {\n result.overwrite = true;\n } else if (arg === \"--api-url\") {\n const value = argv[++i];\n if (!value || !/^https?:\\/\\//.test(value)) {\n throw new Error(`--api-url requires a full http(s) URL (got \"${value}\")`);\n }\n result.apiUrl = value;\n } else if (arg && !arg.startsWith(\"--\") && !result.path) {\n // Positional: folder name, matches `npx create-next-app my-app` shape.\n result.path = arg;\n }\n }\n\n return result;\n};\n\nexport const clientLabel = (id: string): string =>\n id === \"vscode\" ? \"VS Code\"\n : id === \"zed\" ? \"Zed\"\n : id === \"cursor\" ? \"Cursor\"\n : id === \"claude-code\" ? \"Claude Code\"\n : id;\n\n/**\n * Resolves the target folder via positional/flag arg or interactive prompt.\n * Default to \".\" when cwd looks like an existing project (the common case\n * for \"wire AgentMark into my repo\"); fall back to a fresh folder name when\n * cwd is empty (the greenfield case).\n */\nexport const resolveTargetPath = async (\n cliPath: string | undefined,\n): Promise<{ targetPath: string; isCurrentDir: boolean } | null> => {\n let folderName = cliPath;\n if (!folderName) {\n const cwd = process.cwd();\n const cwdHasProject =\n fs.existsSync(path.join(cwd, \"package.json\")) ||\n fs.existsSync(path.join(cwd, \"pyproject.toml\"));\n const response = await prompts({\n name: \"folderName\",\n type: \"text\",\n message: \"Where would you like to set up AgentMark?\",\n initial: cwdHasProject ? \".\" : \"my-agentmark-app\",\n });\n folderName = response.folderName;\n }\n if (!folderName) return null; // Ctrl+C / empty input\n\n const isCurrentDir = isCurrentDirectory(folderName);\n const targetPath = isCurrentDir ? process.cwd() : path.resolve(folderName);\n if (!isCurrentDir) fs.ensureDirSync(targetPath);\n return { targetPath, isCurrentDir };\n};\n\n/**\n * Resolves which IDE clients to wire MCP into. All 4 are pre-selected on\n * the prompt so the typical \"I use everything\" case is one keystroke\n * (Enter). Empty selection is equivalent to the old \"Skip\" option — the\n * caller just writes nothing.\n */\nexport const resolveClients = async (cliClients: McpClient[] | undefined): Promise<McpClient[]> => {\n if (cliClients && cliClients.length > 0) {\n for (const c of cliClients) {\n if (!ALL_CLIENTS.includes(c)) {\n throw new Error(`Invalid client \"${c}\". Valid: ${ALL_CLIENTS.join(\", \")}`);\n }\n }\n return cliClients;\n }\n const response = await prompts({\n name: \"clients\",\n type: \"multiselect\",\n message: \"Wire AgentMark MCP into which IDE clients?\",\n instructions: false,\n hint: \"Space to toggle. Enter to submit. Skip all = empty selection.\",\n choices: ALL_CLIENTS.map((id) => ({\n title: clientLabel(id),\n value: id,\n selected: true,\n })),\n });\n return (response.clients ?? []) as McpClient[];\n};\n\n/**\n * agentmark.json is the only file we conflict on (the others — MCP config\n * dirs, agentmark/, .gitkeep — are either additive or no-ops if present).\n * Default to \"skip\" so we never silently clobber an existing project's\n * config; `--overwrite` is the explicit opt-in for re-init scripts.\n */\nexport const shouldWriteAgentmarkJson = async (\n filePath: string,\n overwrite: boolean | undefined,\n): Promise<boolean> => {\n if (!fs.existsSync(filePath)) return true;\n if (overwrite) return true;\n const { action } = await prompts({\n type: \"select\",\n name: \"action\",\n message: \"agentmark.json already exists. What would you like to do?\",\n choices: [\n { title: \"Skip (keep existing)\", value: \"skip\" },\n { title: \"Overwrite with default config\", value: \"overwrite\" },\n ],\n initial: 0,\n });\n return action === \"overwrite\";\n};\n\nexport const main = async (): Promise<void> => {\n const cliArgs = parseArgs();\n\n const target = await resolveTargetPath(cliArgs.path);\n if (!target) {\n console.log(\"Aborted.\");\n return;\n }\n const { targetPath } = target;\n\n const projectInfo = detectProjectInfo(targetPath);\n const clients = await resolveClients(cliArgs.clients);\n\n console.log(\"\");\n\n // 1. agentmark.json — the SDK loader's config root\n const agentmarkJsonPath = path.join(targetPath, \"agentmark.json\");\n if (await shouldWriteAgentmarkJson(agentmarkJsonPath, cliArgs.overwrite)) {\n fs.writeJsonSync(agentmarkJsonPath, AGENTMARK_JSON, { spaces: 2 });\n console.log(\"✅ agentmark.json\");\n } else {\n console.log(\"⏭️ agentmark.json (kept existing)\");\n }\n\n // 2. agentmark/ — where prompts go. Empty + .gitkeep so the folder is\n // discoverable and version-controlled before the user adds anything.\n // Matches agentmarkPath: \".\" in agentmark.json.\n const agentmarkDirPath = path.join(targetPath, \"agentmark\");\n if (!fs.existsSync(agentmarkDirPath)) {\n fs.ensureDirSync(agentmarkDirPath);\n fs.writeFileSync(path.join(agentmarkDirPath, \".gitkeep\"), \"\");\n console.log(\"✅ agentmark/ (empty, ready for your .prompt.mdx files)\");\n } else {\n console.log(\"⏭️ agentmark/ (kept existing)\");\n }\n\n // 3. MCP wiring — one config file per selected IDE client\n for (const client of clients) {\n try {\n const result = writeMcpConfig(client, targetPath, { customApiUrl: cliArgs.apiUrl });\n if (result) {\n const rel = path.relative(targetPath, result.configPath) || result.configPath;\n console.log(`✅ MCP wired (${clientLabel(client)}): ${rel}`);\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.warn(`⚠️ Could not write MCP config for ${clientLabel(client)}: ${message}`);\n }\n }\n\n // 4. AgentMark agent skill (best-effort; logs its own status)\n installAgentmarkSkill(targetPath);\n\n // 5. git init — only if this is a greenfield folder\n if (!projectInfo.isExistingProject) {\n initGitRepo(targetPath);\n }\n\n // 6. Handoff to the AI tool. The integration logic lives in the skill\n // workflow (`setup-and-integration.md`), not here, so the rest of\n // onboarding adapts to whatever stack the user already has.\n console.log(\"\");\n console.log(\"✨ AgentMark is wired up.\");\n console.log(\"\");\n console.log(\" Next: open this project in Claude Code, Cursor, VS Code, or Zed and say:\");\n console.log(\"\");\n console.log(\" \\\"Set up AgentMark in this project.\\\"\");\n console.log(\"\");\n console.log(\" The AgentMark skill will detect your stack, propose the wiring against\");\n console.log(\" the docs MCP (https://docs.agentmark.co/mcp), and integrate adaptively.\");\n};\n\n/**\n * Run main() only when this module is invoked directly as the CLI entry —\n * NOT when imported by a test or another module. The pathToFileURL/url\n * comparison is the canonical ESM-friendly \"is this the entry script?\" check.\n */\nconst isDirectlyInvoked = (): boolean => {\n const entry = process.argv[1];\n if (!entry) return false;\n return import.meta.url === pathToFileURL(entry).href;\n};\n\nif (isDirectlyInvoked()) {\n main().catch((error) => {\n console.error(\"Error:\", error);\n process.exit(1);\n });\n}\n","/**\n * Shared MCP-config builder for the scaffolders.\n *\n * Writes the project-local IDE config (mcp.json / settings.json) for\n * the four supported clients. Every scaffolded project gets THREE\n * MCP servers wired up by default:\n *\n * 1. `agentmark-docs` (remote HTTP) — read-only docs / reference,\n * hosted at `https://docs.agentmark.co/mcp`.\n *\n * 2. `agentmark` (stdio, `@agentmark-ai/mcp-server`) — AgentMark\n * Cloud surface. Defaults to `https://api.agentmark.co`; pass a\n * custom URL via `customApiUrl` (the undocumented `--api-url`\n * flag on the CLI) to point at a non-prod gateway (staging,\n * self-hosted).\n *\n * 3. `agentmark-local` (stdio, `@agentmark-ai/mcp-server`) — the\n * same MCP binary, pointed at the local `agentmark dev` server\n * (`http://localhost:9418`). The local dev server serves the\n * same OpenAPI contract under `/v1/openapi.json`, so the same\n * tool surface (`list_traces`, `get_trace`, …) is available\n * against local SQLite traces.\n *\n * Why both `agentmark` and `agentmark-local`: workflows like \"pull\n * failing traces from AgentMark Cloud, fix locally, re-verify against\n * `agentmark dev` traces\" need BOTH endpoints reachable in the same\n * conversation. MCP clients namespace tools by server name, so the\n * agent calls `agentmark/list_traces` for cloud and\n * `agentmark-local/list_traces` for local — same tool, explicit\n * destination.\n *\n * Auth chain is endpoint-agnostic:\n *\n * - `AGENTMARK_API_KEY` env (CI / dedicated agents) wins\n * - falls back to `~/.agentmark/auth.json` from\n * `agentmark login [--base-url <matching-endpoint>]`\n * - local dev calls are unauthenticated by design (the local dev\n * server doesn't validate auth headers)\n *\n * Shell `export AGENTMARK_API_URL=…` still wins at runtime when the\n * IDE inherits the shell — what we write here is the default for\n * cold-launched IDEs.\n */\n\nimport fs from \"fs-extra\";\nimport * as path from \"path\";\n\nexport type McpClient = \"vscode\" | \"zed\" | \"cursor\" | \"claude-code\" | \"skip\";\n\n/** URL the cloud-pointing `agentmark` MCP entry talks to by default. */\nconst CLOUD_API_URL = \"https://api.agentmark.co\";\n\n/** Local `agentmark dev` server URL — matches AGENTMARK_PORT default. */\nconst LOCAL_DEV_URL = \"http://localhost:9418\";\n\n/** The npm package id of the stdio MCP server (used for both entries). */\nconst MCP_SERVER_PACKAGE = \"@agentmark-ai/mcp-server\";\n\ninterface StdioServerEntry {\n command: string;\n args: string[];\n env?: Record<string, string>;\n type?: \"stdio\";\n}\n\ninterface RemoteServerEntry {\n url: string;\n type?: \"http\";\n}\n\n/**\n * Builds an stdio MCP server entry pointed at the given URL.\n *\n * - When the URL matches the MCP server's built-in default\n * (`https://api.agentmark.co`), the `env` block is omitted so a\n * future change to that default cleanly propagates to existing\n * scaffolded projects.\n * - For any other URL (custom `--api-url`, or the local dev URL),\n * we write `env: { AGENTMARK_API_URL: <url> }` explicitly.\n */\nfunction stdioEntry(apiUrl: string, includeType: boolean): StdioServerEntry {\n const entry: StdioServerEntry = {\n command: \"npx\",\n args: [\"-y\", MCP_SERVER_PACKAGE],\n };\n if (apiUrl !== CLOUD_API_URL) {\n entry.env = { AGENTMARK_API_URL: apiUrl };\n }\n if (includeType) entry.type = \"stdio\";\n return entry;\n}\n\ninterface WriteResult {\n /** Absolute or relative path to the file that was written. */\n configPath: string;\n}\n\nexport interface WriteMcpConfigOptions {\n /**\n * Arbitrary AgentMark gateway URL for the cloud-side `agentmark` MCP\n * entry. Defaults to `https://api.agentmark.co`. Escape hatch for\n * internal AgentMark engineers (staging) and self-hosters — NOT a\n * customer-facing option.\n */\n customApiUrl?: string;\n}\n\n/**\n * Writes the IDE-specific MCP config file with three servers wired up.\n * Idempotent: caller passes a fresh target dir per scaffold.\n */\nexport function writeMcpConfig(\n client: McpClient,\n targetPath: string,\n opts: WriteMcpConfigOptions = {},\n): WriteResult | null {\n if (client === \"skip\") return null;\n\n const cloudUrl = opts.customApiUrl ?? CLOUD_API_URL;\n const docsEntry: RemoteServerEntry = { url: \"https://docs.agentmark.co/mcp\" };\n\n if (client === \"vscode\") {\n const vscodeDir = path.join(targetPath, \".vscode\");\n fs.ensureDirSync(vscodeDir);\n const configPath = path.join(vscodeDir, \"mcp.json\");\n const config = {\n servers: {\n \"agentmark-docs\": docsEntry,\n \"agentmark\": stdioEntry(cloudUrl, /* includeType */ false),\n \"agentmark-local\": stdioEntry(LOCAL_DEV_URL, /* includeType */ false),\n },\n };\n fs.writeJsonSync(configPath, config, { spaces: 2 });\n return { configPath };\n }\n\n if (client === \"zed\") {\n const zedDir = path.join(targetPath, \".zed\");\n fs.ensureDirSync(zedDir);\n const configPath = path.join(zedDir, \"settings.json\");\n const config = {\n context_servers: {\n \"agentmark-docs\": docsEntry,\n \"agentmark\": stdioEntry(cloudUrl, /* includeType */ false),\n \"agentmark-local\": stdioEntry(LOCAL_DEV_URL, /* includeType */ false),\n },\n };\n fs.writeJsonSync(configPath, config, { spaces: 2 });\n return { configPath };\n }\n\n if (client === \"cursor\") {\n const cursorDir = path.join(targetPath, \".cursor\");\n fs.ensureDirSync(cursorDir);\n const configPath = path.join(cursorDir, \"mcp.json\");\n const config = {\n mcpServers: {\n \"agentmark-docs\": docsEntry,\n \"agentmark\": stdioEntry(cloudUrl, /* includeType */ false),\n \"agentmark-local\": stdioEntry(LOCAL_DEV_URL, /* includeType */ false),\n },\n };\n fs.writeJsonSync(configPath, config, { spaces: 2 });\n return { configPath };\n }\n\n if (client === \"claude-code\") {\n const configPath = path.join(targetPath, \".mcp.json\");\n const config = {\n mcpServers: {\n \"agentmark-docs\": { type: \"http\" as const, ...docsEntry },\n \"agentmark\": stdioEntry(cloudUrl, /* includeType */ true),\n \"agentmark-local\": stdioEntry(LOCAL_DEV_URL, /* includeType */ true),\n },\n };\n fs.writeJsonSync(configPath, config, { spaces: 2 });\n return { configPath };\n }\n\n return null;\n}\n","import { execFileSync } from \"child_process\";\n\n/**\n * Installs the AgentMark agent skill (https://github.com/agentmark-ai/skills)\n * into the freshly-scaffolded project. The vercel-labs/skills tool puts files\n * at `./.agents/skills/agentmark/` and symlinks them into per-tool paths\n * (Claude Code, Codex, Cursor, GitHub Copilot, +others) per the\n * agentskills.io 0.0.2 spec.\n *\n * Uses execFileSync (no shell) for safety. All arguments are hardcoded\n * literals; no user input is interpolated.\n *\n * Best-effort: if the install fails (no network, npx unavailable, etc.) we\n * log a warning and keep going. The skill is a nice-to-have on top of a\n * working AgentMark project, not a hard requirement.\n */\n/**\n * True when the helper should skip the network install. Set in test runs\n * so the OSS Parity CI suite doesn't hit `npx skills add` per scaffolder\n * test (each call clones the public skills repo, adding 10-30s/test).\n *\n * Detected via:\n * - VITEST=true (Vitest sets this automatically)\n * - NODE_ENV=test (broad convention; many runners set this)\n * - AGENTMARK_SKIP_SKILL_INSTALL=1 (explicit opt-out for any other context)\n */\nconst shouldSkip = (): boolean =>\n process.env.VITEST === \"true\" ||\n process.env.NODE_ENV === \"test\" ||\n process.env.AGENTMARK_SKIP_SKILL_INSTALL === \"1\";\n\nexport const installAgentmarkSkill = (targetPath: string): void => {\n if (shouldSkip()) {\n console.log(\"\\n⏭️ Skipping agent skill install (test environment detected).\");\n return;\n }\n try {\n console.log(\"\\n📚 Installing AgentMark agent skill...\");\n console.log(\" (teaches Claude Code / Codex / Cursor / Copilot how to use AgentMark)\");\n execFileSync(\n \"npx\",\n [\"--yes\", \"skills\", \"add\", \"agentmark-ai/skills\"],\n {\n cwd: targetPath,\n stdio: \"inherit\",\n },\n );\n console.log(\"✅ Agent skill installed at ./.agents/skills/agentmark/\");\n } catch (error) {\n console.warn(\n \"\\n⚠️ Could not install the AgentMark agent skill automatically.\",\n );\n console.warn(\" You can install it later with:\");\n console.warn(\" cd \" + targetPath);\n console.warn(\" npx skills add agentmark-ai/skills\");\n if (error instanceof Error) {\n console.warn(` Reason: ${error.message.split(\"\\n\")[0]}`);\n }\n }\n};\n","import { execSync } from \"child_process\";\n\n/**\n * Initialize a git repository and create an initial commit.\n *\n * Skips silently when:\n * - The target path is already inside a git repository\n * - git is not installed\n * - Any git command fails (non-fatal)\n */\nexport function initGitRepo(targetPath: string): boolean {\n try {\n // Check if git is available\n try {\n execSync(\"git --version\", { stdio: \"ignore\" });\n } catch {\n console.log(\"⚠️ git not found — skipping repository initialization\");\n return false;\n }\n\n // Check if already inside a git repo\n try {\n execSync(\"git rev-parse --is-inside-work-tree\", {\n cwd: targetPath,\n stdio: \"ignore\",\n });\n // Already in a git repo — skip\n return false;\n } catch {\n // Not in a git repo — proceed\n }\n\n execSync(\"git init\", { cwd: targetPath, stdio: \"ignore\" });\n execSync(\"git add -A\", { cwd: targetPath, stdio: \"ignore\" });\n execSync(\n 'git -c user.name=\"create-agentmark\" -c user.email=\"noreply\" commit -m \"Initial commit from create-agentmark\"',\n { cwd: targetPath, stdio: \"ignore\" },\n );\n\n console.log(\"✅ Initialized git repository with initial commit\");\n return true;\n } catch {\n console.log(\"⚠️ Could not initialize git repository\");\n return false;\n }\n}\n","/**\n * Project detection for the minimal `npm create agentmark` init flow.\n *\n * Two questions only: \"is this an existing project?\" (drives whether we\n * run `git init`) and \"does AgentMark already exist here?\" (drives the\n * `agentmark.json` conflict prompt). Everything else — language, package\n * manager, Python venv, conflict file inventory — lives in the skill\n * workflow now, which can ask the docs MCP for current guidance instead\n * of encoding heuristics into the CLI.\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport type { ProjectInfo } from './types.js';\n\nconst TYPESCRIPT_INDICATORS = ['package.json', 'tsconfig.json', 'node_modules'] as const;\nconst PYTHON_INDICATORS = ['pyproject.toml', 'requirements.txt', 'setup.py', '.venv', 'venv'] as const;\n\n/** Any TypeScript/Node.js project marker present in the target directory. */\nexport function detectTypeScriptProject(targetPath: string): boolean {\n return TYPESCRIPT_INDICATORS.some((file) => fs.existsSync(path.join(targetPath, file)));\n}\n\n/** Any Python project marker present in the target directory. */\nexport function detectPythonProject(targetPath: string): boolean {\n return PYTHON_INDICATORS.some((file) => fs.existsSync(path.join(targetPath, file)));\n}\n\n/**\n * Combined detection. `isExistingProject` is true if either language's\n * markers are present; the init flow uses it only to decide whether to\n * run `git init`.\n */\nexport function detectProjectInfo(targetPath: string): ProjectInfo {\n return {\n isExistingProject: detectTypeScriptProject(targetPath) || detectPythonProject(targetPath),\n hasAgentmarkJson: fs.existsSync(path.join(targetPath, 'agentmark.json')),\n hasAgentmarkDir: fs.existsSync(path.join(targetPath, 'agentmark')),\n };\n}\n\n/**\n * True for any spelling of \"current directory\" the user might type at the\n * folder prompt. Used to skip mkdir/cd noise when the user wants to wire\n * AgentMark into the directory they're already in.\n */\nexport function isCurrentDirectory(folderName: string): boolean {\n return folderName === '.' || folderName === './' || folderName === '.\\\\';\n}\n"],"mappings":"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","names":["fs","path","fs","path","fs","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/utils/examples/mcp-config.ts","../src/utils/install-skill.ts","../src/utils/git-init.ts","../src/utils/project-detection.ts"],"sourcesContent":["import fs from \"fs-extra\";\nimport path from \"path\";\nimport prompts from \"prompts\";\nimport { pathToFileURL, fileURLToPath } from \"url\";\nimport { writeMcpConfig, type McpClient } from \"./utils/examples/mcp-config.js\";\nimport { installAgentmarkSkill } from \"./utils/install-skill.js\";\nimport { initGitRepo } from \"./utils/git-init.js\";\nimport { detectProjectInfo, isCurrentDirectory } from \"./utils/project-detection.js\";\n\n/**\n * `npm create agentmark` — minimal init.\n *\n * Scope is deliberately small. The CLI does NOT scaffold example code,\n * pick an LLM adapter, or handle login. Its job is:\n *\n * 1. Write `agentmark.json` (the SDK loader's config root)\n * 2. Create an empty `agentmark/` directory (where prompts go)\n * 3. Wire MCP configs for any IDE clients the user selects\n * 4. Install the AgentMark agent skill (`npx skills add agentmark-ai/skills`)\n * 5. Hand off to the AI tool: \"Open Claude Code / Cursor and say:\n * Set up AgentMark in this project.\"\n *\n * Everything else — framework detection, package install, code wiring,\n * first prompt — is the job of the `setup-and-integration` skill workflow,\n * which runs inside the user's IDE agent. That keeps integration adaptive\n * to whatever stack the user already has, instead of forcing a template.\n */\n\nexport interface CliArgs {\n path?: string;\n clients?: McpClient[];\n /**\n * Undocumented escape hatch for internal staging\n * (`https://api-stg.agentmark.co`) and rare self-hosters. Defaults to\n * `https://api.agentmark.co`. The `agentmark-local` MCP entry always\n * points at `http://localhost:9418` regardless of this flag.\n */\n apiUrl?: string;\n overwrite?: boolean;\n}\n\nexport const ALL_CLIENTS: readonly McpClient[] = [\"claude-code\", \"cursor\", \"vscode\", \"zed\"];\n\nexport const AGENTMARK_JSON: Record<string, unknown> = {\n $schema:\n \"https://raw.githubusercontent.com/agentmark-ai/agentmark/refs/heads/main/packages/cli/agentmark.schema.json\",\n version: \"2.0.0\",\n mdxVersion: \"1.0\",\n agentmarkPath: \".\",\n // Seed one model so the dashboard prompt editor isn't an empty dropdown on\n // first run. Add more with `npx agentmark pull-models` (writes provider/model\n // entries here) — see https://docs.agentmark.co/configure/model-schemas.\n builtInModels: [\"openai/gpt-5.5\"],\n};\n\nexport const parseArgs = (argv: string[] = process.argv.slice(2)): CliArgs => {\n const result: CliArgs = {};\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === \"--path\") {\n result.path = argv[++i];\n } else if (arg === \"--client\") {\n const value = argv[++i];\n if (!value) throw new Error(\"--client requires a value\");\n const ids = value === \"all\"\n ? [...ALL_CLIENTS]\n : value.split(\",\").map((s) => s.trim()).filter(Boolean) as McpClient[];\n result.clients = [...(result.clients ?? []), ...ids];\n } else if (arg === \"--overwrite\") {\n result.overwrite = true;\n } else if (arg === \"--api-url\") {\n const value = argv[++i];\n if (!value || !/^https?:\\/\\//.test(value)) {\n throw new Error(`--api-url requires a full http(s) URL (got \"${value}\")`);\n }\n result.apiUrl = value;\n } else if (arg && !arg.startsWith(\"--\") && !result.path) {\n // Positional: folder name, matches `npx create-next-app my-app` shape.\n result.path = arg;\n }\n }\n\n return result;\n};\n\nexport const clientLabel = (id: string): string =>\n id === \"vscode\" ? \"VS Code\"\n : id === \"zed\" ? \"Zed\"\n : id === \"cursor\" ? \"Cursor\"\n : id === \"claude-code\" ? \"Claude Code\"\n : id;\n\n/**\n * Resolves the target folder via positional/flag arg or interactive prompt.\n * Default to \".\" when cwd looks like an existing project (the common case\n * for \"wire AgentMark into my repo\"); fall back to a fresh folder name when\n * cwd is empty (the greenfield case).\n */\nexport const resolveTargetPath = async (\n cliPath: string | undefined,\n): Promise<{ targetPath: string; isCurrentDir: boolean } | null> => {\n let folderName = cliPath;\n if (!folderName) {\n const cwd = process.cwd();\n const cwdHasProject =\n fs.existsSync(path.join(cwd, \"package.json\")) ||\n fs.existsSync(path.join(cwd, \"pyproject.toml\"));\n const response = await prompts({\n name: \"folderName\",\n type: \"text\",\n message: \"Where would you like to set up AgentMark?\",\n initial: cwdHasProject ? \".\" : \"my-agentmark-app\",\n });\n folderName = response.folderName;\n }\n if (!folderName) return null; // Ctrl+C / empty input\n\n const isCurrentDir = isCurrentDirectory(folderName);\n const targetPath = isCurrentDir ? process.cwd() : path.resolve(folderName);\n if (!isCurrentDir) fs.ensureDirSync(targetPath);\n return { targetPath, isCurrentDir };\n};\n\n/**\n * Resolves which IDE clients to wire MCP into. All 4 are pre-selected on\n * the prompt so the typical \"I use everything\" case is one keystroke\n * (Enter). Empty selection is equivalent to the old \"Skip\" option — the\n * caller just writes nothing.\n */\nexport const resolveClients = async (cliClients: McpClient[] | undefined): Promise<McpClient[]> => {\n if (cliClients && cliClients.length > 0) {\n for (const c of cliClients) {\n if (!ALL_CLIENTS.includes(c)) {\n throw new Error(`Invalid client \"${c}\". Valid: ${ALL_CLIENTS.join(\", \")}`);\n }\n }\n return cliClients;\n }\n const response = await prompts({\n name: \"clients\",\n type: \"multiselect\",\n message: \"Wire AgentMark MCP into which IDE clients?\",\n instructions: false,\n hint: \"Space to toggle. Enter to submit. Skip all = empty selection.\",\n choices: ALL_CLIENTS.map((id) => ({\n title: clientLabel(id),\n value: id,\n selected: true,\n })),\n });\n return (response.clients ?? []) as McpClient[];\n};\n\n/**\n * agentmark.json is the only file we conflict on (the others — MCP config\n * dirs, agentmark/, .gitkeep — are either additive or no-ops if present).\n * Default to \"skip\" so we never silently clobber an existing project's\n * config; `--overwrite` is the explicit opt-in for re-init scripts.\n */\nexport const shouldWriteAgentmarkJson = async (\n filePath: string,\n overwrite: boolean | undefined,\n): Promise<boolean> => {\n if (!fs.existsSync(filePath)) return true;\n if (overwrite) return true;\n const { action } = await prompts({\n type: \"select\",\n name: \"action\",\n message: \"agentmark.json already exists. What would you like to do?\",\n choices: [\n { title: \"Skip (keep existing)\", value: \"skip\" },\n { title: \"Overwrite with default config\", value: \"overwrite\" },\n ],\n initial: 0,\n });\n return action === \"overwrite\";\n};\n\nexport const main = async (): Promise<void> => {\n const cliArgs = parseArgs();\n\n const target = await resolveTargetPath(cliArgs.path);\n if (!target) {\n console.log(\"Aborted.\");\n return;\n }\n const { targetPath } = target;\n\n const projectInfo = detectProjectInfo(targetPath);\n const clients = await resolveClients(cliArgs.clients);\n\n console.log(\"\");\n\n // 1. agentmark.json — the SDK loader's config root\n const agentmarkJsonPath = path.join(targetPath, \"agentmark.json\");\n if (await shouldWriteAgentmarkJson(agentmarkJsonPath, cliArgs.overwrite)) {\n fs.writeJsonSync(agentmarkJsonPath, AGENTMARK_JSON, { spaces: 2 });\n console.log(\"✅ agentmark.json\");\n } else {\n console.log(\"⏭️ agentmark.json (kept existing)\");\n }\n\n // 2. agentmark/ — where prompts go. Empty + .gitkeep so the folder is\n // discoverable and version-controlled before the user adds anything.\n // Matches agentmarkPath: \".\" in agentmark.json.\n const agentmarkDirPath = path.join(targetPath, \"agentmark\");\n if (!fs.existsSync(agentmarkDirPath)) {\n fs.ensureDirSync(agentmarkDirPath);\n fs.writeFileSync(path.join(agentmarkDirPath, \".gitkeep\"), \"\");\n console.log(\"✅ agentmark/ (empty, ready for your .prompt.mdx files)\");\n } else {\n console.log(\"⏭️ agentmark/ (kept existing)\");\n }\n\n // 3. MCP wiring — one config file per selected IDE client\n for (const client of clients) {\n try {\n const result = writeMcpConfig(client, targetPath, { customApiUrl: cliArgs.apiUrl });\n if (result) {\n const rel = path.relative(targetPath, result.configPath) || result.configPath;\n console.log(`✅ MCP wired (${clientLabel(client)}): ${rel}`);\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.warn(`⚠️ Could not write MCP config for ${clientLabel(client)}: ${message}`);\n }\n }\n\n // 4. AgentMark agent skill (best-effort; logs its own status)\n installAgentmarkSkill(targetPath);\n\n // 5. git init — only if this is a greenfield folder\n if (!projectInfo.isExistingProject) {\n initGitRepo(targetPath);\n }\n\n // 6. Handoff to the AI tool. The integration logic lives in the skill\n // workflow (`setup-and-integration.md`), not here, so the rest of\n // onboarding adapts to whatever stack the user already has.\n console.log(\"\");\n console.log(\"✨ AgentMark is wired up.\");\n console.log(\"\");\n console.log(\" Next: open this project in Claude Code, Cursor, VS Code, or Zed and say:\");\n console.log(\"\");\n console.log(\" \\\"Set up AgentMark in this project.\\\"\");\n console.log(\"\");\n console.log(\" The AgentMark skill will detect your stack, propose the wiring against\");\n console.log(\" the docs MCP (https://docs.agentmark.co/mcp), and integrate adaptively.\");\n};\n\n/**\n * Run main() only when this module is invoked directly as the CLI entry —\n * NOT when imported by a test or another module.\n *\n * Both sides MUST be realpath'd before comparing. npm/npx invoke bins\n * through a `node_modules/.bin` SYMLINK, so `process.argv[1]` is the\n * symlink path while `import.meta.url` is the resolved real path — a naive\n * URL comparison never matches and the CLI exits 0 having done nothing.\n * That exact bug shipped in 1.0.0 and made `npm create agentmark` a silent\n * no-op for every user (macOS additionally symlinks /tmp, which is why\n * even \"direct\" invocations failed in temp dirs). Regression-pinned by\n * test/bin-invocation.test.ts, which runs the built bin through a symlink.\n */\nconst isDirectlyInvoked = (): boolean => {\n const entry = process.argv[1];\n if (!entry) return false;\n try {\n const entryReal = pathToFileURL(fs.realpathSync(entry)).href;\n const selfReal = pathToFileURL(fs.realpathSync(fileURLToPath(import.meta.url))).href;\n return entryReal === selfReal;\n } catch {\n // realpath can throw on exotic entries (deleted cwd, permissions);\n // treat as \"not the CLI entry\" rather than crashing an import.\n return false;\n }\n};\n\nif (isDirectlyInvoked()) {\n main().catch((error) => {\n console.error(\"Error:\", error);\n process.exit(1);\n });\n}\n","/**\n * Shared MCP-config builder for the scaffolders.\n *\n * Writes the project-local IDE config (mcp.json / settings.json) for\n * the four supported clients. Every scaffolded project gets THREE\n * MCP servers wired up by default:\n *\n * 1. `agentmark-docs` (remote HTTP) — read-only docs / reference,\n * hosted at `https://docs.agentmark.co/mcp`.\n *\n * 2. `agentmark` (stdio, `@agentmark-ai/mcp-server`) — AgentMark\n * Cloud surface. Defaults to `https://api.agentmark.co`; pass a\n * custom URL via `customApiUrl` (the undocumented `--api-url`\n * flag on the CLI) to point at a non-prod gateway (staging,\n * self-hosted).\n *\n * 3. `agentmark-local` (stdio, `@agentmark-ai/mcp-server`) — the\n * same MCP binary, pointed at the local `agentmark dev` server\n * (`http://localhost:9418`). The local dev server serves the\n * same OpenAPI contract under `/v1/openapi.json`, so the same\n * tool surface (`list_traces`, `get_trace`, …) is available\n * against local SQLite traces.\n *\n * Why both `agentmark` and `agentmark-local`: workflows like \"pull\n * failing traces from AgentMark Cloud, fix locally, re-verify against\n * `agentmark dev` traces\" need BOTH endpoints reachable in the same\n * conversation. MCP clients namespace tools by server name, so the\n * agent calls `agentmark/list_traces` for cloud and\n * `agentmark-local/list_traces` for local — same tool, explicit\n * destination.\n *\n * Auth chain is endpoint-agnostic:\n *\n * - `AGENTMARK_API_KEY` env (CI / dedicated agents) wins\n * - falls back to `~/.agentmark/auth.json` from\n * `agentmark login [--base-url <matching-endpoint>]`\n * - local dev calls are unauthenticated by design (the local dev\n * server doesn't validate auth headers)\n *\n * Shell `export AGENTMARK_API_URL=…` still wins at runtime when the\n * IDE inherits the shell — what we write here is the default for\n * cold-launched IDEs.\n */\n\nimport fs from \"fs-extra\";\nimport * as path from \"path\";\n\nexport type McpClient = \"vscode\" | \"zed\" | \"cursor\" | \"claude-code\" | \"skip\";\n\n/** URL the cloud-pointing `agentmark` MCP entry talks to by default. */\nconst CLOUD_API_URL = \"https://api.agentmark.co\";\n\n/** Local `agentmark dev` server URL — matches AGENTMARK_PORT default. */\nconst LOCAL_DEV_URL = \"http://localhost:9418\";\n\n/** The npm package id of the stdio MCP server (used for both entries). */\nconst MCP_SERVER_PACKAGE = \"@agentmark-ai/mcp-server\";\n\ninterface StdioServerEntry {\n command: string;\n args: string[];\n env?: Record<string, string>;\n type?: \"stdio\";\n}\n\ninterface RemoteServerEntry {\n url: string;\n type?: \"http\";\n}\n\n/**\n * Builds an stdio MCP server entry pointed at the given URL.\n *\n * - When the URL matches the MCP server's built-in default\n * (`https://api.agentmark.co`), the `env` block is omitted so a\n * future change to that default cleanly propagates to existing\n * scaffolded projects.\n * - For any other URL (custom `--api-url`, or the local dev URL),\n * we write `env: { AGENTMARK_API_URL: <url> }` explicitly.\n */\nfunction stdioEntry(apiUrl: string, includeType: boolean): StdioServerEntry {\n const entry: StdioServerEntry = {\n command: \"npx\",\n args: [\"-y\", MCP_SERVER_PACKAGE],\n };\n if (apiUrl !== CLOUD_API_URL) {\n entry.env = { AGENTMARK_API_URL: apiUrl };\n }\n if (includeType) entry.type = \"stdio\";\n return entry;\n}\n\ninterface WriteResult {\n /** Absolute or relative path to the file that was written. */\n configPath: string;\n}\n\nexport interface WriteMcpConfigOptions {\n /**\n * Arbitrary AgentMark gateway URL for the cloud-side `agentmark` MCP\n * entry. Defaults to `https://api.agentmark.co`. Escape hatch for\n * internal AgentMark engineers (staging) and self-hosters — NOT a\n * customer-facing option.\n */\n customApiUrl?: string;\n}\n\n/**\n * Writes the IDE-specific MCP config file with three servers wired up.\n * Idempotent: caller passes a fresh target dir per scaffold.\n */\nexport function writeMcpConfig(\n client: McpClient,\n targetPath: string,\n opts: WriteMcpConfigOptions = {},\n): WriteResult | null {\n if (client === \"skip\") return null;\n\n const cloudUrl = opts.customApiUrl ?? CLOUD_API_URL;\n const docsEntry: RemoteServerEntry = { url: \"https://docs.agentmark.co/mcp\" };\n\n if (client === \"vscode\") {\n const vscodeDir = path.join(targetPath, \".vscode\");\n fs.ensureDirSync(vscodeDir);\n const configPath = path.join(vscodeDir, \"mcp.json\");\n const config = {\n servers: {\n \"agentmark-docs\": docsEntry,\n \"agentmark\": stdioEntry(cloudUrl, /* includeType */ false),\n \"agentmark-local\": stdioEntry(LOCAL_DEV_URL, /* includeType */ false),\n },\n };\n fs.writeJsonSync(configPath, config, { spaces: 2 });\n return { configPath };\n }\n\n if (client === \"zed\") {\n const zedDir = path.join(targetPath, \".zed\");\n fs.ensureDirSync(zedDir);\n const configPath = path.join(zedDir, \"settings.json\");\n const config = {\n context_servers: {\n \"agentmark-docs\": docsEntry,\n \"agentmark\": stdioEntry(cloudUrl, /* includeType */ false),\n \"agentmark-local\": stdioEntry(LOCAL_DEV_URL, /* includeType */ false),\n },\n };\n fs.writeJsonSync(configPath, config, { spaces: 2 });\n return { configPath };\n }\n\n if (client === \"cursor\") {\n const cursorDir = path.join(targetPath, \".cursor\");\n fs.ensureDirSync(cursorDir);\n const configPath = path.join(cursorDir, \"mcp.json\");\n const config = {\n mcpServers: {\n \"agentmark-docs\": docsEntry,\n \"agentmark\": stdioEntry(cloudUrl, /* includeType */ false),\n \"agentmark-local\": stdioEntry(LOCAL_DEV_URL, /* includeType */ false),\n },\n };\n fs.writeJsonSync(configPath, config, { spaces: 2 });\n return { configPath };\n }\n\n if (client === \"claude-code\") {\n const configPath = path.join(targetPath, \".mcp.json\");\n const config = {\n mcpServers: {\n \"agentmark-docs\": { type: \"http\" as const, ...docsEntry },\n \"agentmark\": stdioEntry(cloudUrl, /* includeType */ true),\n \"agentmark-local\": stdioEntry(LOCAL_DEV_URL, /* includeType */ true),\n },\n };\n fs.writeJsonSync(configPath, config, { spaces: 2 });\n return { configPath };\n }\n\n return null;\n}\n","import { execFileSync } from \"child_process\";\n\n/**\n * Installs the AgentMark agent skill (https://github.com/agentmark-ai/skills)\n * into the freshly-scaffolded project. The vercel-labs/skills tool puts files\n * at `./.agents/skills/agentmark/` and symlinks them into per-tool paths\n * (Claude Code, Codex, Cursor, GitHub Copilot, +others) per the\n * agentskills.io 0.0.2 spec.\n *\n * Uses execFileSync (no shell) for safety. All arguments are hardcoded\n * literals; no user input is interpolated.\n *\n * Best-effort: if the install fails (no network, npx unavailable, etc.) we\n * log a warning and keep going. The skill is a nice-to-have on top of a\n * working AgentMark project, not a hard requirement.\n */\n/**\n * True when the helper should skip the network install. Set in test runs\n * so the OSS Parity CI suite doesn't hit `npx skills add` per scaffolder\n * test (each call clones the public skills repo, adding 10-30s/test).\n *\n * Detected via:\n * - VITEST=true (Vitest sets this automatically)\n * - NODE_ENV=test (broad convention; many runners set this)\n * - AGENTMARK_SKIP_SKILL_INSTALL=1 (explicit opt-out for any other context)\n */\nconst shouldSkip = (): boolean =>\n process.env.VITEST === \"true\" ||\n process.env.NODE_ENV === \"test\" ||\n process.env.AGENTMARK_SKIP_SKILL_INSTALL === \"1\";\n\nexport const installAgentmarkSkill = (targetPath: string): void => {\n if (shouldSkip()) {\n console.log(\"\\n⏭️ Skipping agent skill install (test environment detected).\");\n return;\n }\n try {\n console.log(\"\\n📚 Installing AgentMark agent skill...\");\n console.log(\" (teaches Claude Code / Codex / Cursor / Copilot how to use AgentMark)\");\n execFileSync(\n \"npx\",\n [\"--yes\", \"skills\", \"add\", \"agentmark-ai/skills\"],\n {\n cwd: targetPath,\n stdio: \"inherit\",\n },\n );\n console.log(\"✅ Agent skill installed at ./.agents/skills/agentmark/\");\n } catch (error) {\n console.warn(\n \"\\n⚠️ Could not install the AgentMark agent skill automatically.\",\n );\n console.warn(\" You can install it later with:\");\n console.warn(\" cd \" + targetPath);\n console.warn(\" npx skills add agentmark-ai/skills\");\n if (error instanceof Error) {\n console.warn(` Reason: ${error.message.split(\"\\n\")[0]}`);\n }\n }\n};\n","import { execSync } from \"child_process\";\n\n/**\n * Initialize a git repository and create an initial commit.\n *\n * Skips silently when:\n * - The target path is already inside a git repository\n * - git is not installed\n * - Any git command fails (non-fatal)\n */\nexport function initGitRepo(targetPath: string): boolean {\n try {\n // Check if git is available\n try {\n execSync(\"git --version\", { stdio: \"ignore\" });\n } catch {\n console.log(\"⚠️ git not found — skipping repository initialization\");\n return false;\n }\n\n // Check if already inside a git repo\n try {\n execSync(\"git rev-parse --is-inside-work-tree\", {\n cwd: targetPath,\n stdio: \"ignore\",\n });\n // Already in a git repo — skip\n return false;\n } catch {\n // Not in a git repo — proceed\n }\n\n execSync(\"git init\", { cwd: targetPath, stdio: \"ignore\" });\n execSync(\"git add -A\", { cwd: targetPath, stdio: \"ignore\" });\n execSync(\n 'git -c user.name=\"create-agentmark\" -c user.email=\"noreply\" commit -m \"Initial commit from create-agentmark\"',\n { cwd: targetPath, stdio: \"ignore\" },\n );\n\n console.log(\"✅ Initialized git repository with initial commit\");\n return true;\n } catch {\n console.log(\"⚠️ Could not initialize git repository\");\n return false;\n }\n}\n","/**\n * Project detection for the minimal `npm create agentmark` init flow.\n *\n * Two questions only: \"is this an existing project?\" (drives whether we\n * run `git init`) and \"does AgentMark already exist here?\" (drives the\n * `agentmark.json` conflict prompt). Everything else — language, package\n * manager, Python venv, conflict file inventory — lives in the skill\n * workflow now, which can ask the docs MCP for current guidance instead\n * of encoding heuristics into the CLI.\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport type { ProjectInfo } from './types.js';\n\nconst TYPESCRIPT_INDICATORS = ['package.json', 'tsconfig.json', 'node_modules'] as const;\nconst PYTHON_INDICATORS = ['pyproject.toml', 'requirements.txt', 'setup.py', '.venv', 'venv'] as const;\n\n/** Any TypeScript/Node.js project marker present in the target directory. */\nexport function detectTypeScriptProject(targetPath: string): boolean {\n return TYPESCRIPT_INDICATORS.some((file) => fs.existsSync(path.join(targetPath, file)));\n}\n\n/** Any Python project marker present in the target directory. */\nexport function detectPythonProject(targetPath: string): boolean {\n return PYTHON_INDICATORS.some((file) => fs.existsSync(path.join(targetPath, file)));\n}\n\n/**\n * Combined detection. `isExistingProject` is true if either language's\n * markers are present; the init flow uses it only to decide whether to\n * run `git init`.\n */\nexport function detectProjectInfo(targetPath: string): ProjectInfo {\n return {\n isExistingProject: detectTypeScriptProject(targetPath) || detectPythonProject(targetPath),\n hasAgentmarkJson: fs.existsSync(path.join(targetPath, 'agentmark.json')),\n hasAgentmarkDir: fs.existsSync(path.join(targetPath, 'agentmark')),\n };\n}\n\n/**\n * True for any spelling of \"current directory\" the user might type at the\n * folder prompt. Used to skip mkdir/cd noise when the user wants to wire\n * AgentMark into the directory they're already in.\n */\nexport function isCurrentDirectory(folderName: string): boolean {\n return folderName === '.' || folderName === './' || folderName === '.\\\\';\n}\n"],"mappings":"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","names":["fs","path","fs","path","fs","path"]}
|