@thinkingpatterns/cli 0.2.0 → 0.2.2

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 CHANGED
@@ -216,7 +216,7 @@ function resolveProjectId(explicit) {
216
216
  // src/commands/findings.ts
217
217
  function registerFindingCommands(program2) {
218
218
  const findings = program2.command("findings").description("Manage security findings");
219
- findings.command("list").description("List findings for a project").option("-p, --project <id>", "Project ID").option("--severity <severity>", "Filter by severity, comma-separated (critical,high,medium,low,info)").option("--status <status>", "Filter by status, comma-separated (open,triaged,completed,dismissed)").option("--category <category>", "Filter by category").option("--source-tool <tool>", "Filter by source tool").option("--module-path <path>", "Filter by module path prefix").option("--branch <branch>", "Filter by branch").option("--limit <n>", "Max results", parseInt).option("--offset <n>", "Result offset", parseInt).action(async (opts) => {
219
+ findings.command("list").description("List findings for a project").option("-p, --project <id>", "Project ID").option("--severity <severity>", "Filter by severity, comma-separated (critical,high,medium,low,info)").option("--status <status>", "Filter by status, comma-separated (open,triaged,completed,dismissed)").option("--category <category>", "Filter by category").option("--source-tool <tool>", "Filter by source tool").option("--module-path <path>", "Filter by module path prefix").option("--branch <branch>", "Filter by branch").option("--limit <n>", "Max results", parseInt).option("--offset <n>", "Result offset", parseInt).option("--verbose", "Show all fields (default: summary only)").action(async (opts) => {
220
220
  try {
221
221
  const projectId = resolveProjectId(opts.project);
222
222
  const result = await getClient().listFindings({
@@ -230,6 +230,18 @@ function registerFindingCommands(program2) {
230
230
  limit: opts.limit,
231
231
  offset: opts.offset
232
232
  });
233
+ if (!opts.verbose) {
234
+ result.data = result.data.map((f) => ({
235
+ id: f.id,
236
+ title: f.title,
237
+ severity: f.severity,
238
+ status: f.status,
239
+ category: f.category,
240
+ code_location_file: f.code_location_file,
241
+ code_location_line_start: f.code_location_line_start,
242
+ first_seen_at: f.first_seen_at
243
+ }));
244
+ }
233
245
  printJson(result);
234
246
  } catch (err) {
235
247
  printError(err);
@@ -326,16 +338,26 @@ function registerRunCommands(program2) {
326
338
  import { readFileSync as readFileSync3 } from "fs";
327
339
  function registerIngestCommands(program2) {
328
340
  const ingest = program2.command("ingest").description("Ingest scan results");
329
- ingest.command("sarif").description("Ingest a SARIF file").option("-p, --project <id>", "Project ID").option("-b, --branch <name>", "Branch name for scoping findings").requiredOption("--file <path>", "Path to SARIF file").action(async (opts) => {
341
+ ingest.command("sarif").description("Ingest a SARIF file").option("-p, --project <id>", "Project ID").option("-b, --branch <name>", "Branch name for scoping findings").option("--run-id <id>", "Associate with an existing run (skips auto-run creation)").requiredOption("--file <path>", "Path to SARIF file").action(async (opts) => {
330
342
  try {
331
343
  const projectId = resolveProjectId(opts.project);
332
344
  const content = readFileSync3(opts.file, "utf-8");
333
- const result = await getClient().ingestSarifChunked(
334
- projectId,
335
- content,
336
- opts.branch
337
- );
338
- printJson(result);
345
+ if (opts.runId) {
346
+ const result = await getClient().ingestSarif(
347
+ projectId,
348
+ content,
349
+ opts.branch,
350
+ opts.runId
351
+ );
352
+ printJson(result);
353
+ } else {
354
+ const result = await getClient().ingestSarifChunked(
355
+ projectId,
356
+ content,
357
+ opts.branch
358
+ );
359
+ printJson(result);
360
+ }
339
361
  } catch (err) {
340
362
  printError(err);
341
363
  }
@@ -382,7 +404,7 @@ function registerAgentCommands(program2) {
382
404
  printError(err);
383
405
  }
384
406
  });
385
- agents.command("run <id>").description("Run an agent against a project").option("-p, --project <id>", "Project ID").action(async (id, opts) => {
407
+ agents.command("run <id>").description("Run an agent against a project").option("-p, --project <id>", "Project ID").option("-b, --branch <name>", "Branch name").action(async (id, opts) => {
386
408
  try {
387
409
  const projectId = resolveProjectId(opts.project);
388
410
  const client = getClient();
@@ -396,11 +418,21 @@ function registerAgentCommands(program2) {
396
418
  `);
397
419
  process.exit(3);
398
420
  }
421
+ const branch = opts.branch ?? project.default_branch ?? "main";
422
+ const run = await client.createRun({
423
+ project_id: projectId,
424
+ agent_definition_id: agent.slug,
425
+ trigger_type: "mcp",
426
+ scope_type: "full",
427
+ branch
428
+ });
429
+ await client.updateRunStatus(run.id, "running");
399
430
  printJson({
400
431
  agent: { id: agent.id, name: agent.name, slug: agent.slug },
401
432
  project: { id: project.id, name: project.name },
433
+ run: { id: run.id, status: "running" },
402
434
  skill_md: agent.skill_md,
403
- instruction: "Follow the SKILL.md workflow above. When done, ingest results with: tp ingest sarif --project " + projectId + " --file results.sarif"
435
+ instruction: "Follow the SKILL.md workflow above. When done, ingest results with: tp ingest sarif --project " + projectId + " --run-id " + run.id + " --file results.sarif --branch " + branch
404
436
  });
405
437
  } catch (err) {
406
438
  printError(err);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/lib/client.ts","../src/lib/credentials.ts","../src/commands/login.ts","../src/lib/output.ts","../src/commands/auth.ts","../src/commands/projects.ts","../src/lib/config.ts","../src/commands/findings.ts","../src/commands/metrics.ts","../src/commands/risk-modules.ts","../src/commands/runs.ts","../src/commands/ingest.ts","../src/commands/agents.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { setGlobalOpts, resolveApiKey } from \"./lib/client.js\";\nimport { registerLoginCommands } from \"./commands/login.js\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerProjectCommands } from \"./commands/projects.js\";\nimport { registerFindingCommands } from \"./commands/findings.js\";\nimport { registerMetricsCommands } from \"./commands/metrics.js\";\nimport { registerRiskModulesCommands } from \"./commands/risk-modules.js\";\nimport { registerRunCommands } from \"./commands/runs.js\";\nimport { registerIngestCommands } from \"./commands/ingest.js\";\nimport { registerAgentCommands } from \"./commands/agents.js\";\n\n/** Commands that work without authentication. */\nconst NO_AUTH_COMMANDS = new Set([\"login\", \"logout\", \"help\"]);\n\nconst program = new Command();\n\nprogram\n .name(\"tp\")\n .description(\"ThinkingPatterns CLI — security findings management\")\n .version(\"0.1.0\")\n .option(\"--api-key <key>\", \"API key (overrides TP_API_KEY env)\")\n .option(\"--api-url <url>\", \"API URL (overrides TP_API_URL env)\")\n .option(\"--quiet\", \"Suppress non-data output\")\n .hook(\"preAction\", (thisCommand) => {\n const commandName = thisCommand.args?.[0] ?? thisCommand.name();\n if (NO_AUTH_COMMANDS.has(commandName)) return;\n\n const opts = program.opts();\n setGlobalOpts({ apiKey: opts.apiKey, apiUrl: opts.apiUrl });\n\n if (!resolveApiKey()) {\n process.stderr.write(\n \"Error: Not authenticated. Run `tp login` or set TP_API_KEY.\\n\"\n );\n process.exit(2);\n }\n });\n\nregisterLoginCommands(program);\nregisterAuthCommands(program);\nregisterProjectCommands(program);\nregisterFindingCommands(program);\nregisterMetricsCommands(program);\nregisterRiskModulesCommands(program);\nregisterRunCommands(program);\nregisterIngestCommands(program);\nregisterAgentCommands(program);\n\nprogram.parse();\n","import { ThinkingPatternsClient } from \"@thinkingpatterns/core\";\nimport { loadCredentials } from \"./credentials.js\";\n\nconst DEFAULT_API_URL = \"https://thinkingpatterns.ai\";\n\nlet _client: ThinkingPatternsClient | null = null;\nlet _opts: { apiKey?: string; apiUrl?: string } = {};\n\n/** Call once from index.ts to pass through global CLI options. */\nexport function setGlobalOpts(opts: { apiKey?: string; apiUrl?: string }): void {\n _opts = opts;\n _client = null; // reset if options change\n}\n\n/**\n * Resolve the API key from (in priority order):\n * 1. --api-key flag\n * 2. TP_API_KEY env var\n * 3. ~/.thinkingpatterns/credentials.json (saved by `tp login`)\n */\nexport function resolveApiKey(): string | undefined {\n if (_opts.apiKey) return _opts.apiKey;\n if (process.env.TP_API_KEY) return process.env.TP_API_KEY;\n return loadCredentials()?.api_key;\n}\n\n/** Resolve the API URL from flag, env, saved credentials, or default. */\nfunction resolveApiUrl(): string {\n return _opts.apiUrl || process.env.TP_API_URL || loadCredentials()?.api_url || DEFAULT_API_URL;\n}\n\n/** Get the shared client instance (created lazily). */\nexport function getClient(): ThinkingPatternsClient {\n if (!_client) {\n const apiKey = resolveApiKey() || \"\";\n const apiUrl = resolveApiUrl();\n _client = new ThinkingPatternsClient({ apiKey, apiUrl });\n }\n return _client;\n}\n","import { readFileSync, writeFileSync, mkdirSync, rmSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nconst CONFIG_DIR = join(homedir(), \".thinkingpatterns\");\nconst CREDENTIALS_FILE = join(CONFIG_DIR, \"credentials.json\");\n\ninterface StoredCredentials {\n api_key: string;\n api_url?: string;\n}\n\n/** Read persisted credentials, or null if none saved. */\nexport function loadCredentials(): StoredCredentials | null {\n if (!existsSync(CREDENTIALS_FILE)) return null;\n try {\n const content = readFileSync(CREDENTIALS_FILE, \"utf-8\");\n return JSON.parse(content) as StoredCredentials;\n } catch {\n return null;\n }\n}\n\n/** Persist credentials to ~/.thinkingpatterns/credentials.json. */\nexport function saveCredentials(apiKey: string, apiUrl?: string): void {\n mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n const data: StoredCredentials = { api_key: apiKey };\n if (apiUrl) data.api_url = apiUrl;\n writeFileSync(CREDENTIALS_FILE, JSON.stringify(data, null, 2) + \"\\n\", {\n mode: 0o600,\n });\n}\n\n/** Remove persisted credentials. Returns true if a file was deleted. */\nexport function clearCredentials(): boolean {\n if (!existsSync(CREDENTIALS_FILE)) return false;\n rmSync(CREDENTIALS_FILE);\n return true;\n}\n","import type { Command } from \"commander\";\nimport { createInterface } from \"node:readline\";\nimport { ThinkingPatternsClient } from \"@thinkingpatterns/core\";\nimport { saveCredentials, clearCredentials, loadCredentials } from \"../lib/credentials.js\";\n\nconst DEFAULT_API_URL = \"https://thinkingpatterns.ai\";\n\nfunction prompt(question: string): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stderr });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nexport function registerLoginCommands(program: Command): void {\n program\n .command(\"login\")\n .description(\"Authenticate and save credentials\")\n .option(\"--api-url <url>\", \"API URL (default: https://thinkingpatterns.ai)\")\n .action(async (opts) => {\n const apiUrl = opts.apiUrl || DEFAULT_API_URL;\n\n process.stderr.write(\n `\\nPaste your API key from ${apiUrl}/settings/api-keys\\n\\n`\n );\n\n const apiKey = await prompt(\"API key: \");\n if (!apiKey) {\n process.stderr.write(\"Aborted — no key provided.\\n\");\n process.exit(1);\n }\n\n // Validate the key\n process.stderr.write(\"Verifying...\");\n try {\n const client = new ThinkingPatternsClient({ apiKey, apiUrl });\n const me = await client.whoami();\n saveCredentials(apiKey, apiUrl !== DEFAULT_API_URL ? apiUrl : undefined);\n const identity = me.profile?.email ?? me.profile?.display_name ?? me.org?.name ?? \"authenticated user\";\n process.stderr.write(\n ` logged in as ${identity}.\\n\\n` +\n `Credentials saved to ~/.thinkingpatterns/credentials.json\\n`\n );\n } catch {\n process.stderr.write(\" failed.\\n\\nError: Invalid API key.\\n\");\n process.exit(2);\n }\n });\n\n program\n .command(\"logout\")\n .description(\"Remove saved credentials\")\n .action(() => {\n const had = loadCredentials();\n clearCredentials();\n if (had) {\n process.stderr.write(\"Credentials removed.\\n\");\n } else {\n process.stderr.write(\"No saved credentials found.\\n\");\n }\n });\n}\n","import { TPError, TPAuthError, TPNotFoundError } from \"@thinkingpatterns/core\";\n\n/* ─── Exit codes ─── */\n\nexport const EXIT_OK = 0;\nexport const EXIT_CLIENT_ERROR = 1;\nexport const EXIT_AUTH_ERROR = 2;\nexport const EXIT_NOT_FOUND = 3;\nexport const EXIT_UNEXPECTED = 10;\n\n/* ─── Output helpers ─── */\n\nexport function printJson(data: unknown): void {\n process.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n}\n\nexport function printError(err: unknown): never {\n if (err instanceof TPAuthError) {\n process.stderr.write(`Error: ${err.message}\\nHint: Run \\`tp login\\` or check your --api-key value.\\n`);\n process.exit(EXIT_AUTH_ERROR);\n }\n if (err instanceof TPNotFoundError) {\n process.stderr.write(`Error: ${err.message}\\n`);\n process.exit(EXIT_NOT_FOUND);\n }\n if (err instanceof TPError) {\n process.stderr.write(`Error: ${err.message}\\n`);\n if (err.details) {\n process.stderr.write(`Details: ${JSON.stringify(err.details, null, 2)}\\n`);\n }\n process.exit(EXIT_CLIENT_ERROR);\n }\n if (err instanceof Error) {\n process.stderr.write(`Error: ${err.message}\\n`);\n } else {\n process.stderr.write(`Error: ${String(err)}\\n`);\n }\n process.exit(EXIT_UNEXPECTED);\n}\n","import type { Command } from \"commander\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\n\nexport function registerAuthCommands(program: Command): void {\n program\n .command(\"whoami\")\n .description(\"Show current authentication context\")\n .action(async () => {\n try {\n const result = await getClient().whoami();\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\n\nexport function registerProjectCommands(program: Command): void {\n const projects = program\n .command(\"projects\")\n .description(\"Manage projects\");\n\n projects\n .command(\"list\")\n .description(\"List all projects\")\n .action(async () => {\n try {\n const result = await getClient().listProjects();\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n}\n","import { readFileSync, existsSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\n\nconst CONFIG_FILE = \".thinkingpatterns.json\";\n\ninterface ProjectConfig {\n project_id?: string;\n}\n\n/**\n * Walk up from cwd looking for .thinkingpatterns.json.\n * Returns the parsed config or null if not found.\n */\nexport function loadProjectConfig(): ProjectConfig | null {\n let dir = process.cwd();\n const root = dirname(dir) === dir ? dir : \"/\";\n\n while (true) {\n const filePath = join(dir, CONFIG_FILE);\n if (existsSync(filePath)) {\n try {\n const content = readFileSync(filePath, \"utf-8\");\n return JSON.parse(content) as ProjectConfig;\n } catch {\n return null;\n }\n }\n const parent = dirname(dir);\n if (parent === dir || dir === root) break;\n dir = parent;\n }\n return null;\n}\n\n/**\n * Resolve project ID from explicit option, falling back to config file.\n * Exits with error if neither is available.\n */\nexport function resolveProjectId(explicit?: string): string {\n if (explicit) return explicit;\n const config = loadProjectConfig();\n if (config?.project_id) return config.project_id;\n process.stderr.write(\n \"Error: --project is required (or set project_id in .thinkingpatterns.json)\\n\"\n );\n process.exit(1);\n}\n","import type { Command } from \"commander\";\nimport type { TriageAction } from \"@thinkingpatterns/core\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\nimport { resolveProjectId } from \"../lib/config.js\";\n\nexport function registerFindingCommands(program: Command): void {\n const findings = program\n .command(\"findings\")\n .description(\"Manage security findings\");\n\n findings\n .command(\"list\")\n .description(\"List findings for a project\")\n .option(\"-p, --project <id>\", \"Project ID\")\n .option(\"--severity <severity>\", \"Filter by severity, comma-separated (critical,high,medium,low,info)\")\n .option(\"--status <status>\", \"Filter by status, comma-separated (open,triaged,completed,dismissed)\")\n .option(\"--category <category>\", \"Filter by category\")\n .option(\"--source-tool <tool>\", \"Filter by source tool\")\n .option(\"--module-path <path>\", \"Filter by module path prefix\")\n .option(\"--branch <branch>\", \"Filter by branch\")\n .option(\"--limit <n>\", \"Max results\", parseInt)\n .option(\"--offset <n>\", \"Result offset\", parseInt)\n .action(async (opts) => {\n try {\n const projectId = resolveProjectId(opts.project);\n const result = await getClient().listFindings({\n project_id: projectId,\n severity: opts.severity?.includes(\",\") ? opts.severity.split(\",\").map((s: string) => s.trim()) : opts.severity,\n status: opts.status?.includes(\",\") ? opts.status.split(\",\").map((s: string) => s.trim()) : opts.status,\n category: opts.category,\n source_tool: opts.sourceTool,\n module_path: opts.modulePath,\n branch: opts.branch,\n limit: opts.limit,\n offset: opts.offset,\n });\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n\n findings\n .command(\"get <id>\")\n .description(\"Get finding details\")\n .action(async (id: string) => {\n try {\n const result = await getClient().getFinding(id);\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n\n findings\n .command(\"triage <id>\")\n .description(\"Triage a finding\")\n .requiredOption(\"--action <action>\", \"Triage action (accept|dismiss|defer|complete|reopen)\")\n .option(\"--reason <reason>\", \"Reason for the triage decision\")\n .action(async (id: string, opts) => {\n try {\n const result = await getClient().triageFinding(\n id,\n opts.action as TriageAction,\n opts.reason\n );\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n\n findings\n .command(\"bulk-triage\")\n .description(\"Triage multiple findings at once\")\n .requiredOption(\"--ids <ids>\", \"Comma-separated finding IDs\")\n .requiredOption(\"--action <action>\", \"Triage action (accept|dismiss|defer|complete|reopen)\")\n .option(\"--reason <reason>\", \"Reason for the triage decision\")\n .action(async (opts) => {\n try {\n const findingIds = opts.ids.split(\",\").map((s: string) => s.trim());\n const result = await getClient().bulkTriage({\n finding_ids: findingIds,\n action: opts.action as TriageAction,\n reason: opts.reason,\n });\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n\n findings\n .command(\"comment <id>\")\n .description(\"Add a comment to a finding\")\n .requiredOption(\"--body <text>\", \"Comment text\")\n .action(async (id: string, opts) => {\n try {\n const result = await getClient().addComment(id, opts.body);\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\nimport { resolveProjectId } from \"../lib/config.js\";\n\nexport function registerMetricsCommands(program: Command): void {\n program\n .command(\"metrics\")\n .description(\"Get project metrics (MTTR, fix rate, open count)\")\n .option(\"-p, --project <id>\", \"Project ID\")\n .action(async (opts) => {\n try {\n const projectId = resolveProjectId(opts.project);\n const result = await getClient().getProjectMetrics(projectId);\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\nimport { resolveProjectId } from \"../lib/config.js\";\n\nexport function registerRiskModulesCommands(program: Command): void {\n program\n .command(\"risk-modules\")\n .description(\"Get top risk modules for a project\")\n .option(\"-p, --project <id>\", \"Project ID\")\n .option(\"--limit <n>\", \"Max results\", parseInt)\n .action(async (opts) => {\n try {\n const projectId = resolveProjectId(opts.project);\n const result = await getClient().getTopRiskModules(projectId, opts.limit);\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\nimport { resolveProjectId } from \"../lib/config.js\";\n\nexport function registerRunCommands(program: Command): void {\n const runs = program\n .command(\"runs\")\n .description(\"Manage scan runs\");\n\n runs\n .command(\"list\")\n .description(\"List runs for a project\")\n .option(\"-p, --project <id>\", \"Project ID\")\n .option(\"--status <status>\", \"Filter by status\")\n .option(\"--limit <n>\", \"Max results\", parseInt)\n .option(\"--offset <n>\", \"Result offset\", parseInt)\n .action(async (opts) => {\n try {\n const projectId = resolveProjectId(opts.project);\n const result = await getClient().listRuns(projectId, {\n status: opts.status,\n limit: opts.limit,\n offset: opts.offset,\n });\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n}\n","import { readFileSync } from \"node:fs\";\nimport type { Command } from \"commander\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\nimport { resolveProjectId } from \"../lib/config.js\";\n\nexport function registerIngestCommands(program: Command): void {\n const ingest = program\n .command(\"ingest\")\n .description(\"Ingest scan results\");\n\n ingest\n .command(\"sarif\")\n .description(\"Ingest a SARIF file\")\n .option(\"-p, --project <id>\", \"Project ID\")\n .option(\"-b, --branch <name>\", \"Branch name for scoping findings\")\n .requiredOption(\"--file <path>\", \"Path to SARIF file\")\n .action(async (opts) => {\n try {\n const projectId = resolveProjectId(opts.project);\n const content = readFileSync(opts.file, \"utf-8\");\n const result = await getClient().ingestSarifChunked(\n projectId,\n content,\n opts.branch\n );\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n}\n","import { readFileSync } from \"node:fs\";\nimport type { Command } from \"commander\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\nimport { resolveProjectId } from \"../lib/config.js\";\n\nexport function registerAgentCommands(program: Command): void {\n const agents = program\n .command(\"agents\")\n .description(\"Manage analysis agents\");\n\n agents\n .command(\"list\")\n .description(\"List available agents\")\n .option(\"--category <category>\", \"Filter by category\")\n .option(\"--status <status>\", \"Filter by status (draft|active|archived)\")\n .option(\"--limit <n>\", \"Max results\", parseInt)\n .option(\"--offset <n>\", \"Result offset\", parseInt)\n .action(async (opts) => {\n try {\n const result = await getClient().listAgents({\n category: opts.category,\n status: opts.status,\n limit: opts.limit,\n offset: opts.offset,\n });\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n\n agents\n .command(\"get <id>\")\n .description(\"Get agent details\")\n .action(async (id: string) => {\n try {\n const result = await getClient().getAgent(id);\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n\n agents\n .command(\"create\")\n .description(\"Create a new agent\")\n .requiredOption(\"--name <name>\", \"Agent name\")\n .requiredOption(\"--slug <slug>\", \"Agent slug (URL-safe identifier)\")\n .requiredOption(\"--skill-md <path>\", \"Path to SKILL.md file\")\n .option(\"--description <desc>\", \"Agent description\")\n .option(\"--category <category>\", \"Agent category\")\n .action(async (opts) => {\n try {\n const skillMd = readFileSync(opts.skillMd, \"utf-8\");\n const result = await getClient().createAgent({\n name: opts.name,\n slug: opts.slug,\n skill_md: skillMd,\n description: opts.description,\n category: opts.category,\n });\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n\n agents\n .command(\"run <id>\")\n .description(\"Run an agent against a project\")\n .option(\"-p, --project <id>\", \"Project ID\")\n .action(async (id: string, opts) => {\n try {\n const projectId = resolveProjectId(opts.project);\n const client = getClient();\n const [agent, projects] = await Promise.all([\n client.getAgent(id),\n client.listProjects(),\n ]);\n const project = projects.find((p) => p.id === projectId);\n if (!project) {\n process.stderr.write(`Error: Project ${projectId} not found\\n`);\n process.exit(3);\n }\n printJson({\n agent: { id: agent.id, name: agent.name, slug: agent.slug },\n project: { id: project.id, name: project.name },\n skill_md: agent.skill_md,\n instruction:\n \"Follow the SKILL.md workflow above. When done, ingest results with: tp ingest sarif --project \" +\n projectId +\n \" --file results.sarif\",\n });\n } catch (err) {\n printError(err);\n }\n });\n}\n"],"mappings":"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","names":["ThinkingPatternsClient","DEFAULT_API_URL","program","ThinkingPatternsClient","program","program","readFileSync","existsSync","join","program","program","program","program","readFileSync","program","readFileSync","readFileSync","program","readFileSync"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/lib/client.ts","../src/lib/credentials.ts","../src/commands/login.ts","../src/lib/output.ts","../src/commands/auth.ts","../src/commands/projects.ts","../src/lib/config.ts","../src/commands/findings.ts","../src/commands/metrics.ts","../src/commands/risk-modules.ts","../src/commands/runs.ts","../src/commands/ingest.ts","../src/commands/agents.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { setGlobalOpts, resolveApiKey } from \"./lib/client.js\";\nimport { registerLoginCommands } from \"./commands/login.js\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerProjectCommands } from \"./commands/projects.js\";\nimport { registerFindingCommands } from \"./commands/findings.js\";\nimport { registerMetricsCommands } from \"./commands/metrics.js\";\nimport { registerRiskModulesCommands } from \"./commands/risk-modules.js\";\nimport { registerRunCommands } from \"./commands/runs.js\";\nimport { registerIngestCommands } from \"./commands/ingest.js\";\nimport { registerAgentCommands } from \"./commands/agents.js\";\n\n/** Commands that work without authentication. */\nconst NO_AUTH_COMMANDS = new Set([\"login\", \"logout\", \"help\"]);\n\nconst program = new Command();\n\nprogram\n .name(\"tp\")\n .description(\"ThinkingPatterns CLI — security findings management\")\n .version(\"0.1.0\")\n .option(\"--api-key <key>\", \"API key (overrides TP_API_KEY env)\")\n .option(\"--api-url <url>\", \"API URL (overrides TP_API_URL env)\")\n .option(\"--quiet\", \"Suppress non-data output\")\n .hook(\"preAction\", (thisCommand) => {\n const commandName = thisCommand.args?.[0] ?? thisCommand.name();\n if (NO_AUTH_COMMANDS.has(commandName)) return;\n\n const opts = program.opts();\n setGlobalOpts({ apiKey: opts.apiKey, apiUrl: opts.apiUrl });\n\n if (!resolveApiKey()) {\n process.stderr.write(\n \"Error: Not authenticated. Run `tp login` or set TP_API_KEY.\\n\"\n );\n process.exit(2);\n }\n });\n\nregisterLoginCommands(program);\nregisterAuthCommands(program);\nregisterProjectCommands(program);\nregisterFindingCommands(program);\nregisterMetricsCommands(program);\nregisterRiskModulesCommands(program);\nregisterRunCommands(program);\nregisterIngestCommands(program);\nregisterAgentCommands(program);\n\nprogram.parse();\n","import { ThinkingPatternsClient } from \"@thinkingpatterns/core\";\nimport { loadCredentials } from \"./credentials.js\";\n\nconst DEFAULT_API_URL = \"https://thinkingpatterns.ai\";\n\nlet _client: ThinkingPatternsClient | null = null;\nlet _opts: { apiKey?: string; apiUrl?: string } = {};\n\n/** Call once from index.ts to pass through global CLI options. */\nexport function setGlobalOpts(opts: { apiKey?: string; apiUrl?: string }): void {\n _opts = opts;\n _client = null; // reset if options change\n}\n\n/**\n * Resolve the API key from (in priority order):\n * 1. --api-key flag\n * 2. TP_API_KEY env var\n * 3. ~/.thinkingpatterns/credentials.json (saved by `tp login`)\n */\nexport function resolveApiKey(): string | undefined {\n if (_opts.apiKey) return _opts.apiKey;\n if (process.env.TP_API_KEY) return process.env.TP_API_KEY;\n return loadCredentials()?.api_key;\n}\n\n/** Resolve the API URL from flag, env, saved credentials, or default. */\nfunction resolveApiUrl(): string {\n return _opts.apiUrl || process.env.TP_API_URL || loadCredentials()?.api_url || DEFAULT_API_URL;\n}\n\n/** Get the shared client instance (created lazily). */\nexport function getClient(): ThinkingPatternsClient {\n if (!_client) {\n const apiKey = resolveApiKey() || \"\";\n const apiUrl = resolveApiUrl();\n _client = new ThinkingPatternsClient({ apiKey, apiUrl });\n }\n return _client;\n}\n","import { readFileSync, writeFileSync, mkdirSync, rmSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nconst CONFIG_DIR = join(homedir(), \".thinkingpatterns\");\nconst CREDENTIALS_FILE = join(CONFIG_DIR, \"credentials.json\");\n\ninterface StoredCredentials {\n api_key: string;\n api_url?: string;\n}\n\n/** Read persisted credentials, or null if none saved. */\nexport function loadCredentials(): StoredCredentials | null {\n if (!existsSync(CREDENTIALS_FILE)) return null;\n try {\n const content = readFileSync(CREDENTIALS_FILE, \"utf-8\");\n return JSON.parse(content) as StoredCredentials;\n } catch {\n return null;\n }\n}\n\n/** Persist credentials to ~/.thinkingpatterns/credentials.json. */\nexport function saveCredentials(apiKey: string, apiUrl?: string): void {\n mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n const data: StoredCredentials = { api_key: apiKey };\n if (apiUrl) data.api_url = apiUrl;\n writeFileSync(CREDENTIALS_FILE, JSON.stringify(data, null, 2) + \"\\n\", {\n mode: 0o600,\n });\n}\n\n/** Remove persisted credentials. Returns true if a file was deleted. */\nexport function clearCredentials(): boolean {\n if (!existsSync(CREDENTIALS_FILE)) return false;\n rmSync(CREDENTIALS_FILE);\n return true;\n}\n","import type { Command } from \"commander\";\nimport { createInterface } from \"node:readline\";\nimport { ThinkingPatternsClient } from \"@thinkingpatterns/core\";\nimport { saveCredentials, clearCredentials, loadCredentials } from \"../lib/credentials.js\";\n\nconst DEFAULT_API_URL = \"https://thinkingpatterns.ai\";\n\nfunction prompt(question: string): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stderr });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nexport function registerLoginCommands(program: Command): void {\n program\n .command(\"login\")\n .description(\"Authenticate and save credentials\")\n .option(\"--api-url <url>\", \"API URL (default: https://thinkingpatterns.ai)\")\n .action(async (opts) => {\n const apiUrl = opts.apiUrl || DEFAULT_API_URL;\n\n process.stderr.write(\n `\\nPaste your API key from ${apiUrl}/settings/api-keys\\n\\n`\n );\n\n const apiKey = await prompt(\"API key: \");\n if (!apiKey) {\n process.stderr.write(\"Aborted — no key provided.\\n\");\n process.exit(1);\n }\n\n // Validate the key\n process.stderr.write(\"Verifying...\");\n try {\n const client = new ThinkingPatternsClient({ apiKey, apiUrl });\n const me = await client.whoami();\n saveCredentials(apiKey, apiUrl !== DEFAULT_API_URL ? apiUrl : undefined);\n const identity = me.profile?.email ?? me.profile?.display_name ?? me.org?.name ?? \"authenticated user\";\n process.stderr.write(\n ` logged in as ${identity}.\\n\\n` +\n `Credentials saved to ~/.thinkingpatterns/credentials.json\\n`\n );\n } catch {\n process.stderr.write(\" failed.\\n\\nError: Invalid API key.\\n\");\n process.exit(2);\n }\n });\n\n program\n .command(\"logout\")\n .description(\"Remove saved credentials\")\n .action(() => {\n const had = loadCredentials();\n clearCredentials();\n if (had) {\n process.stderr.write(\"Credentials removed.\\n\");\n } else {\n process.stderr.write(\"No saved credentials found.\\n\");\n }\n });\n}\n","import { TPError, TPAuthError, TPNotFoundError } from \"@thinkingpatterns/core\";\n\n/* ─── Exit codes ─── */\n\nexport const EXIT_OK = 0;\nexport const EXIT_CLIENT_ERROR = 1;\nexport const EXIT_AUTH_ERROR = 2;\nexport const EXIT_NOT_FOUND = 3;\nexport const EXIT_UNEXPECTED = 10;\n\n/* ─── Output helpers ─── */\n\nexport function printJson(data: unknown): void {\n process.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n}\n\nexport function printError(err: unknown): never {\n if (err instanceof TPAuthError) {\n process.stderr.write(`Error: ${err.message}\\nHint: Run \\`tp login\\` or check your --api-key value.\\n`);\n process.exit(EXIT_AUTH_ERROR);\n }\n if (err instanceof TPNotFoundError) {\n process.stderr.write(`Error: ${err.message}\\n`);\n process.exit(EXIT_NOT_FOUND);\n }\n if (err instanceof TPError) {\n process.stderr.write(`Error: ${err.message}\\n`);\n if (err.details) {\n process.stderr.write(`Details: ${JSON.stringify(err.details, null, 2)}\\n`);\n }\n process.exit(EXIT_CLIENT_ERROR);\n }\n if (err instanceof Error) {\n process.stderr.write(`Error: ${err.message}\\n`);\n } else {\n process.stderr.write(`Error: ${String(err)}\\n`);\n }\n process.exit(EXIT_UNEXPECTED);\n}\n","import type { Command } from \"commander\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\n\nexport function registerAuthCommands(program: Command): void {\n program\n .command(\"whoami\")\n .description(\"Show current authentication context\")\n .action(async () => {\n try {\n const result = await getClient().whoami();\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\n\nexport function registerProjectCommands(program: Command): void {\n const projects = program\n .command(\"projects\")\n .description(\"Manage projects\");\n\n projects\n .command(\"list\")\n .description(\"List all projects\")\n .action(async () => {\n try {\n const result = await getClient().listProjects();\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n}\n","import { readFileSync, existsSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\n\nconst CONFIG_FILE = \".thinkingpatterns.json\";\n\ninterface ProjectConfig {\n project_id?: string;\n}\n\n/**\n * Walk up from cwd looking for .thinkingpatterns.json.\n * Returns the parsed config or null if not found.\n */\nexport function loadProjectConfig(): ProjectConfig | null {\n let dir = process.cwd();\n const root = dirname(dir) === dir ? dir : \"/\";\n\n while (true) {\n const filePath = join(dir, CONFIG_FILE);\n if (existsSync(filePath)) {\n try {\n const content = readFileSync(filePath, \"utf-8\");\n return JSON.parse(content) as ProjectConfig;\n } catch {\n return null;\n }\n }\n const parent = dirname(dir);\n if (parent === dir || dir === root) break;\n dir = parent;\n }\n return null;\n}\n\n/**\n * Resolve project ID from explicit option, falling back to config file.\n * Exits with error if neither is available.\n */\nexport function resolveProjectId(explicit?: string): string {\n if (explicit) return explicit;\n const config = loadProjectConfig();\n if (config?.project_id) return config.project_id;\n process.stderr.write(\n \"Error: --project is required (or set project_id in .thinkingpatterns.json)\\n\"\n );\n process.exit(1);\n}\n","import type { Command } from \"commander\";\nimport type { TriageAction } from \"@thinkingpatterns/core\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\nimport { resolveProjectId } from \"../lib/config.js\";\n\nexport function registerFindingCommands(program: Command): void {\n const findings = program\n .command(\"findings\")\n .description(\"Manage security findings\");\n\n findings\n .command(\"list\")\n .description(\"List findings for a project\")\n .option(\"-p, --project <id>\", \"Project ID\")\n .option(\"--severity <severity>\", \"Filter by severity, comma-separated (critical,high,medium,low,info)\")\n .option(\"--status <status>\", \"Filter by status, comma-separated (open,triaged,completed,dismissed)\")\n .option(\"--category <category>\", \"Filter by category\")\n .option(\"--source-tool <tool>\", \"Filter by source tool\")\n .option(\"--module-path <path>\", \"Filter by module path prefix\")\n .option(\"--branch <branch>\", \"Filter by branch\")\n .option(\"--limit <n>\", \"Max results\", parseInt)\n .option(\"--offset <n>\", \"Result offset\", parseInt)\n .option(\"--verbose\", \"Show all fields (default: summary only)\")\n .action(async (opts) => {\n try {\n const projectId = resolveProjectId(opts.project);\n const result = await getClient().listFindings({\n project_id: projectId,\n severity: opts.severity?.includes(\",\") ? opts.severity.split(\",\").map((s: string) => s.trim()) : opts.severity,\n status: opts.status?.includes(\",\") ? opts.status.split(\",\").map((s: string) => s.trim()) : opts.status,\n category: opts.category,\n source_tool: opts.sourceTool,\n module_path: opts.modulePath,\n branch: opts.branch,\n limit: opts.limit,\n offset: opts.offset,\n });\n if (!opts.verbose) {\n result.data = result.data.map((f: Record<string, unknown>) => ({\n id: f.id,\n title: f.title,\n severity: f.severity,\n status: f.status,\n category: f.category,\n code_location_file: f.code_location_file,\n code_location_line_start: f.code_location_line_start,\n first_seen_at: f.first_seen_at,\n }));\n }\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n\n findings\n .command(\"get <id>\")\n .description(\"Get finding details\")\n .action(async (id: string) => {\n try {\n const result = await getClient().getFinding(id);\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n\n findings\n .command(\"triage <id>\")\n .description(\"Triage a finding\")\n .requiredOption(\"--action <action>\", \"Triage action (accept|dismiss|defer|complete|reopen)\")\n .option(\"--reason <reason>\", \"Reason for the triage decision\")\n .action(async (id: string, opts) => {\n try {\n const result = await getClient().triageFinding(\n id,\n opts.action as TriageAction,\n opts.reason\n );\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n\n findings\n .command(\"bulk-triage\")\n .description(\"Triage multiple findings at once\")\n .requiredOption(\"--ids <ids>\", \"Comma-separated finding IDs\")\n .requiredOption(\"--action <action>\", \"Triage action (accept|dismiss|defer|complete|reopen)\")\n .option(\"--reason <reason>\", \"Reason for the triage decision\")\n .action(async (opts) => {\n try {\n const findingIds = opts.ids.split(\",\").map((s: string) => s.trim());\n const result = await getClient().bulkTriage({\n finding_ids: findingIds,\n action: opts.action as TriageAction,\n reason: opts.reason,\n });\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n\n findings\n .command(\"comment <id>\")\n .description(\"Add a comment to a finding\")\n .requiredOption(\"--body <text>\", \"Comment text\")\n .action(async (id: string, opts) => {\n try {\n const result = await getClient().addComment(id, opts.body);\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\nimport { resolveProjectId } from \"../lib/config.js\";\n\nexport function registerMetricsCommands(program: Command): void {\n program\n .command(\"metrics\")\n .description(\"Get project metrics (MTTR, fix rate, open count)\")\n .option(\"-p, --project <id>\", \"Project ID\")\n .action(async (opts) => {\n try {\n const projectId = resolveProjectId(opts.project);\n const result = await getClient().getProjectMetrics(projectId);\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\nimport { resolveProjectId } from \"../lib/config.js\";\n\nexport function registerRiskModulesCommands(program: Command): void {\n program\n .command(\"risk-modules\")\n .description(\"Get top risk modules for a project\")\n .option(\"-p, --project <id>\", \"Project ID\")\n .option(\"--limit <n>\", \"Max results\", parseInt)\n .action(async (opts) => {\n try {\n const projectId = resolveProjectId(opts.project);\n const result = await getClient().getTopRiskModules(projectId, opts.limit);\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\nimport { resolveProjectId } from \"../lib/config.js\";\n\nexport function registerRunCommands(program: Command): void {\n const runs = program\n .command(\"runs\")\n .description(\"Manage scan runs\");\n\n runs\n .command(\"list\")\n .description(\"List runs for a project\")\n .option(\"-p, --project <id>\", \"Project ID\")\n .option(\"--status <status>\", \"Filter by status\")\n .option(\"--limit <n>\", \"Max results\", parseInt)\n .option(\"--offset <n>\", \"Result offset\", parseInt)\n .action(async (opts) => {\n try {\n const projectId = resolveProjectId(opts.project);\n const result = await getClient().listRuns(projectId, {\n status: opts.status,\n limit: opts.limit,\n offset: opts.offset,\n });\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n}\n","import { readFileSync } from \"node:fs\";\nimport type { Command } from \"commander\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\nimport { resolveProjectId } from \"../lib/config.js\";\n\nexport function registerIngestCommands(program: Command): void {\n const ingest = program\n .command(\"ingest\")\n .description(\"Ingest scan results\");\n\n ingest\n .command(\"sarif\")\n .description(\"Ingest a SARIF file\")\n .option(\"-p, --project <id>\", \"Project ID\")\n .option(\"-b, --branch <name>\", \"Branch name for scoping findings\")\n .option(\"--run-id <id>\", \"Associate with an existing run (skips auto-run creation)\")\n .requiredOption(\"--file <path>\", \"Path to SARIF file\")\n .action(async (opts) => {\n try {\n const projectId = resolveProjectId(opts.project);\n const content = readFileSync(opts.file, \"utf-8\");\n if (opts.runId) {\n // Use direct SARIF upload to attach to the existing run\n const result = await getClient().ingestSarif(\n projectId,\n content,\n opts.branch,\n opts.runId\n );\n printJson(result);\n } else {\n // Chunked path — auto-creates a run\n const result = await getClient().ingestSarifChunked(\n projectId,\n content,\n opts.branch\n );\n printJson(result);\n }\n } catch (err) {\n printError(err);\n }\n });\n}\n","import { readFileSync } from \"node:fs\";\nimport type { Command } from \"commander\";\nimport { getClient } from \"../lib/client.js\";\nimport { printJson, printError } from \"../lib/output.js\";\nimport { resolveProjectId } from \"../lib/config.js\";\n\nexport function registerAgentCommands(program: Command): void {\n const agents = program\n .command(\"agents\")\n .description(\"Manage analysis agents\");\n\n agents\n .command(\"list\")\n .description(\"List available agents\")\n .option(\"--category <category>\", \"Filter by category\")\n .option(\"--status <status>\", \"Filter by status (draft|active|archived)\")\n .option(\"--limit <n>\", \"Max results\", parseInt)\n .option(\"--offset <n>\", \"Result offset\", parseInt)\n .action(async (opts) => {\n try {\n const result = await getClient().listAgents({\n category: opts.category,\n status: opts.status,\n limit: opts.limit,\n offset: opts.offset,\n });\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n\n agents\n .command(\"get <id>\")\n .description(\"Get agent details\")\n .action(async (id: string) => {\n try {\n const result = await getClient().getAgent(id);\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n\n agents\n .command(\"create\")\n .description(\"Create a new agent\")\n .requiredOption(\"--name <name>\", \"Agent name\")\n .requiredOption(\"--slug <slug>\", \"Agent slug (URL-safe identifier)\")\n .requiredOption(\"--skill-md <path>\", \"Path to SKILL.md file\")\n .option(\"--description <desc>\", \"Agent description\")\n .option(\"--category <category>\", \"Agent category\")\n .action(async (opts) => {\n try {\n const skillMd = readFileSync(opts.skillMd, \"utf-8\");\n const result = await getClient().createAgent({\n name: opts.name,\n slug: opts.slug,\n skill_md: skillMd,\n description: opts.description,\n category: opts.category,\n });\n printJson(result);\n } catch (err) {\n printError(err);\n }\n });\n\n agents\n .command(\"run <id>\")\n .description(\"Run an agent against a project\")\n .option(\"-p, --project <id>\", \"Project ID\")\n .option(\"-b, --branch <name>\", \"Branch name\")\n .action(async (id: string, opts) => {\n try {\n const projectId = resolveProjectId(opts.project);\n const client = getClient();\n const [agent, projects] = await Promise.all([\n client.getAgent(id),\n client.listProjects(),\n ]);\n const project = projects.find((p) => p.id === projectId);\n if (!project) {\n process.stderr.write(`Error: Project ${projectId} not found\\n`);\n process.exit(3);\n }\n\n const branch = opts.branch ?? project.default_branch ?? \"main\";\n\n // Create a run record upfront so it appears on the runs page\n const run = await client.createRun({\n project_id: projectId,\n agent_definition_id: agent.slug,\n trigger_type: \"mcp\",\n scope_type: \"full\",\n branch,\n });\n await client.updateRunStatus(run.id, \"running\");\n\n printJson({\n agent: { id: agent.id, name: agent.name, slug: agent.slug },\n project: { id: project.id, name: project.name },\n run: { id: run.id, status: \"running\" },\n skill_md: agent.skill_md,\n instruction:\n \"Follow the SKILL.md workflow above. When done, ingest results with: tp ingest sarif --project \" +\n projectId +\n \" --run-id \" +\n run.id +\n \" --file results.sarif --branch \" +\n branch,\n });\n } catch (err) {\n printError(err);\n }\n });\n}\n"],"mappings":"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","names":["ThinkingPatternsClient","DEFAULT_API_URL","program","ThinkingPatternsClient","program","program","readFileSync","existsSync","join","program","program","program","program","readFileSync","program","readFileSync","readFileSync","program","readFileSync"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thinkingpatterns/cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "ThinkingPatterns CLI for security findings management",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",