@gpzhang2001/sharpkit-analysis 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +24 -0
- package/THIRD_PARTY_NOTICES.md +48 -0
- package/lib/index.d.ts +125 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +1231 -0
- package/lib/index.js.map +1 -0
- package/package.json +48 -0
- package/src/index.ts +815 -0
- package/src/stores.ts +97 -0
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["args","result"],"sources":["../src/stores.ts","../src/index.ts"],"sourcesContent":["/**\n * Run-scoped JSON mirror stores (strix .state/ mirrors): atomic writes\n * (temp-in-dir + rename), hydrate-on-start, per-store in-memory maps.\n * One instance per scan, owned by the analysis service.\n * @module @gpzhang2001/sharpkit-analysis/stores\n */\n\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\n\n/** A JSON file mirror with atomic write and hydrate. */\nexport class JsonMirrorStore {\n private readonly path: string | null\n private readonly map = new Map<string, Record<string, unknown>>()\n\n constructor(path: string | null) {\n this.path = path\n }\n\n /** Load the mirror file; corrupt JSON is tolerated as empty on hydrate (resume aid only). */\n async hydrate(): Promise<void> {\n if (this.path === null) return\n try {\n const raw = await readFile(this.path, 'utf8')\n const parsed = JSON.parse(raw) as unknown\n if (typeof parsed !== 'object' || parsed === null) return\n for (const [key, value] of Object.entries(parsed as Record<string, unknown>)) {\n if (typeof value === 'object' && value !== null) this.map.set(key, value as Record<string, unknown>)\n }\n } catch {\n // Missing or unreadable mirror: start empty.\n }\n }\n\n /** Persist the whole map atomically (strix `_persist_locked`). */\n async persist(): Promise<void> {\n if (this.path === null) return\n const payload = JSON.stringify(Object.fromEntries(this.map), null, 2)\n await mkdir(dirname(this.path), { recursive: true })\n const temp = `${dirname(this.path)}/.${join('', this.path.split('/').pop() ?? 'store')}.${process.pid}.tmp`\n await writeFile(temp, payload, 'utf8')\n await rename(temp, this.path)\n }\n\n get(key: string): Record<string, unknown> | undefined {\n return this.map.get(key)\n }\n\n set(key: string, value: Record<string, unknown>): void {\n this.map.set(key, value)\n }\n\n delete(key: string): boolean {\n return this.map.delete(key)\n }\n\n values(): Record<string, unknown>[] {\n return [...this.map.values()]\n }\n\n get size(): number {\n return this.map.size\n }\n}\n\n/** Generate a 6-hex id with bounded collision retries (strix parity). */\nexport function generateId(existing: ReadonlySet<string>): string | null {\n for (let attempt = 0; attempt < 1024; attempt++) {\n const id = Math.random().toString(16).slice(2, 8).padEnd(6, '0')\n if (!existing.has(id)) return id\n }\n return null\n}\n\n/**\n * Normalize a remote target to its identity (threat_model/tools.py\n * `_normalize_remote_target` + `_normalize_git_remote`): scp-style and\n * scheme'd git remotes map to https URLs, `.git` stripped, trailing slash\n * stripped, host lowercased with default ports collapsed.\n * @param target - the raw target string.\n */\nexport function normalizeTargetIdentity(target: string): string {\n const trimmed = target.trim()\n const scp = /^git@([^:]+):(.+?)(?:\\.git)?$/.exec(trimmed)\n if (scp !== null) return `https://${scp[1]?.toLowerCase()}/${scp[2]}`\n const withScheme = /^([a-z][a-z0-9+.-]*):\\/\\/([^/?#]+)([^#]*)/i.exec(trimmed)\n if (withScheme !== null) {\n const scheme = withScheme[1] ?? ''\n const authority = withScheme[2] ?? ''\n const path = withScheme[3] ?? ''\n const defaultPort = scheme.toLowerCase() === 'https' ? '443' : scheme.toLowerCase() === 'http' ? '80' : null\n let host = authority.toLowerCase()\n if (defaultPort !== null && host.endsWith(`:${defaultPort}`)) host = host.slice(0, -defaultPort.length - 1)\n return `https://${host}${path.replace(/\\/$/, '')}`.replace(/\\.git$/, '')\n }\n return trimmed.replace(/\\/$/, '').replace(/\\.git$/, '')\n}\n","/**\n * Analysis tools — port of strix tools/{threat_model,coverage,notes,\n * thinking}/ + finish_scan: get/save/amend_threat_model (validated\n * sections, size gates, append-only amendments), record/update/\n * list_coverage (duplicate guard, evidence requirements, history),\n * create/list/get/update/delete_note, think, and finish_scan (root-only,\n * four required sections, coverage summary, final artifacts). State lives\n * in per-scan mirror stores under the run dir (.state parity) and is\n * provided as `pentestAnalysis` for the reporting package's coverage\n * document and SARIF bridge.\n * @module @gpzhang2001/sharpkit-analysis\n */\n\nimport { join } from 'node:path'\nimport type { Context } from '@deepseek-ai/cordis'\nimport { defineTool } from '@deepseek-ai/dsh-tools'\nimport { JsonMirrorStore, generateId, normalizeTargetIdentity } from './stores.ts'\n\nexport { normalizeTargetIdentity } from './stores.ts'\n\n/** Coverage outcome values (strix VALID_OUTCOMES). */\nexport const VALID_OUTCOMES = ['reported', 'no_issue_found', 'ruled_out', 'not_applicable', 'needs_follow_up'] as const\n\n/** Outcomes that require evidence text (strix `_OUTCOMES_REQUIRING_EVIDENCE`). */\nconst OUTCOMES_REQUIRING_EVIDENCE = new Set(['ruled_out', 'not_applicable', 'needs_follow_up'])\n\n/** Note categories (strix `_VALID_NOTE_CATEGORIES`). */\nexport const VALID_NOTE_CATEGORIES = ['general', 'findings', 'methodology', 'questions', 'plan', 'wiki'] as const\n\n/** Required threat-model sections, matched as lowercase substrings (strix parity). */\nconst REQUIRED_SECTIONS = ['overview', 'trust boundaries', 'attack surface', 'severity calibration'] as const\n\n/** Threat model gates (strix constants). */\nconst MAX_MODEL_BYTES = 512 * 1024\nconst MIN_MODEL_CHARS = 400\nconst MIN_AMENDMENT_CHARS = 80\nconst MAX_AMENDMENTS = 40\n\n/** Display timestamp in the coverage format. */\nfunction displayTimestamp(date: Date): string {\n const pad = (value: number): string => String(value).padStart(2, '0')\n return `${date.getUTCFullYear()}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())} ${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:${pad(date.getUTCSeconds())} UTC`\n}\n\n/** Deployment-tunable configuration. */\nexport interface Config {\n /** Sandbox session cache key shared with the other tool packages. */\n readonly scanId?: string\n /** Scan targets (threat-model identity snapping). */\n readonly scanTargets?: readonly string[]\n /** Run directory for the .state mirrors (default sharpkit_runs/<scanId>/.state). */\n readonly runDir?: string\n /** Whether this composition's agent may call finish_scan (root guard). */\n readonly allowFinish?: boolean\n}\n\nexport const name = 'pentest-tool-analysis'\n\nexport const inject = ['tools', 'pentestReporting']\n\n/** The per-scan analysis stores exposed to other packages. */\nexport interface AnalysisHandle {\n readonly coverage: JsonMirrorStore\n readonly threatModels: JsonMirrorStore\n readonly notes: JsonMirrorStore\n /** Coverage entries in list order with ids (reporting package consumes). */\n coverageEntries(): Array<Record<string, unknown> & { entry_id: string }>\n outcomeCounts(): Record<string, number>\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n pentestAnalysis: AnalysisHandle\n }\n}\n\n/** ISO-8601 timestamp (threat model + notes stores). */\nfunction isoNow(): string {\n return new Date().toISOString().replace('Z', '+00:00')\n}\n\nexport function apply(ctx: Context, config: Config = {}): AnalysisHandle {\n const scanId = config.scanId ?? 'pentest'\n const runDir = config.runDir ?? join('sharpkit_runs', scanId)\n const stateDir = join(runDir, '.state')\n const coverage = new JsonMirrorStore(join(stateDir, 'coverage.json'))\n const threatModels = new JsonMirrorStore(join(stateDir, 'threat_models.json'))\n const notes = new JsonMirrorStore(join(stateDir, 'notes.json'))\n void coverage.hydrate()\n void threatModels.hydrate()\n void notes.hydrate()\n\n const coverageEntries = (): Array<Record<string, unknown> & { entry_id: string }> =>\n coverage.values().map(entry => ({ ...entry, entry_id: String(entry['id'] ?? '') })) as Array<Record<string, unknown> & { entry_id: string }>\n\n const outcomeCounts = (): Record<string, number> => {\n const counts: Record<string, number> = {}\n for (const outcome of VALID_OUTCOMES) {\n const count = coverage.values().filter(entry => entry['outcome'] === outcome).length\n if (count > 0) counts[outcome] = count\n }\n return counts\n }\n\n const handle: AnalysisHandle = { coverage, threatModels, notes, coverageEntries, outcomeCounts }\n ctx.provide('pentestAnalysis', handle)\n\n const resolveTarget = (target: string | undefined): { readonly identity: string } | { readonly error: string } => {\n const cleaned = target?.trim() ?? ''\n if (cleaned === '') {\n const targets = config.scanTargets ?? []\n if (targets.length === 1) return { identity: normalizeTargetIdentity(targets[0] ?? '') }\n return { error: 'target cannot be empty - name the target this threat model describes' }\n }\n return { identity: normalizeTargetIdentity(cleaned) }\n }\n\n ctx.tools.register(defineTool({\n name: 'get_threat_model',\n description: 'Fetch the threat model shared for a target in this scan (found=false when none exists yet). Read-only.',\n parameters: {\n target: { type: 'string', description: 'Target the model describes; omit when the scan has exactly one target.' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n found: { type: 'boolean' },\n target: { type: 'string' },\n content: { type: 'string' },\n amendments: { type: 'array', items: { type: 'object', properties: {}, additionalProperties: true } },\n amendments_note: { type: 'string' },\n message: { type: 'string' },\n error: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; found?: boolean; error?: string }\n if (!result.success) return [{ type: 'text', text: `get_threat_model failed: ${result.error ?? 'unknown'}` }]\n return [{ type: 'text', text: result.found === true ? 'threat model found' : 'no threat model yet' }]\n },\n },\n execute: (async (rawArgs: never) => {\n const args = rawArgs as never as { target?: string }\n const resolved = resolveTarget(args.target)\n if ('error' in resolved) return { success: false, error: resolved.error }\n const model = threatModels.get(resolved.identity)\n if (model === undefined || String(model['content'] ?? '').trim() === '') {\n return { success: true, found: false, target: resolved.identity, message: 'No threat model exists for this target yet. Save one with save_threat_model.' }\n }\n const amendments = model['amendments'] as unknown[] | undefined\n return {\n success: true,\n found: true,\n target: resolved.identity,\n content: String(model['content']),\n ...(amendments !== undefined && amendments.length > 0 ? { amendments, amendments_note: 'Addenda recorded by agents after the model was saved.' } : {}),\n }\n }) as never,\n }))\n\n ctx.tools.register(defineTool({\n name: 'save_threat_model',\n description: `Share your threat model for a target with the whole scan team (full replace; clears amendments). Must cover Overview, Trust Boundaries, Attack Surface, and Severity Calibration; minimum ${String(MIN_MODEL_CHARS)} characters, maximum 512KB.`,\n parameters: {\n target: { type: 'string', description: 'Target the model describes; omit when the scan has exactly one target.' },\n content: { type: 'string', required: true, description: 'The full markdown threat model.' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n target: { type: 'string' },\n amendments_cleared: { type: 'integer' },\n message: { type: 'string' },\n error: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; error?: string }\n return [{ type: 'text', text: result.success ? 'threat model saved' : `save_threat_model failed: ${result.error ?? 'unknown'}` }]\n },\n },\n execute: (async (rawArgs: never) => {\n const args = rawArgs as never as { target?: string; content: string }\n const resolved = resolveTarget(args.target)\n if ('error' in resolved) return { success: false, error: resolved.error }\n const content = args.content.trim()\n if (content.length < MIN_MODEL_CHARS) {\n return { success: false, error: `Threat model is too thin (${String(content.length)} chars). It has to be usable by every agent in this scan.` }\n }\n if (Buffer.byteLength(content, 'utf8') > MAX_MODEL_BYTES) return { success: false, error: 'Threat model exceeds 512KB; tighten it.' }\n const lower = content.toLowerCase()\n const missing = REQUIRED_SECTIONS.filter(section => !lower.includes(section))\n if (missing.length > 0) {\n return { success: false, error: `Threat model is missing required section(s): ${missing.join(', ')}. Cover Overview, Trust Boundaries, Attack Surface, and Severity Calibration.` }\n }\n const previous = threatModels.get(resolved.identity)\n const previousAmendments = previous?.['amendments']\n const amendmentsCleared = Array.isArray(previousAmendments) ? previousAmendments.length : 0\n threatModels.set(resolved.identity, {\n target: resolved.identity,\n written_at: isoNow(),\n written_by: null,\n content,\n })\n await threatModels.persist()\n return {\n success: true,\n target: resolved.identity,\n amendments_cleared: amendmentsCleared,\n message: amendmentsCleared > 0\n ? `Threat model shared with this scan. It replaced a previous model, folding ${String(amendmentsCleared)} amendment(s) into the full rewrite.`\n : 'Threat model shared with this scan.',\n }\n }) as never,\n }))\n\n ctx.tools.register(defineTool({\n name: 'amend_threat_model',\n description: `Append an addendum to the existing threat model without rewriting it (minimum ${String(MIN_AMENDMENT_CHARS)} characters). Use save_threat_model for a full rewrite that folds amendments.`,\n parameters: {\n target: { type: 'string', description: 'Target the model describes; omit when the scan has exactly one target.' },\n addendum: { type: 'string', required: true, description: 'The markdown addendum.' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n target: { type: 'string' },\n amendment_count: { type: 'integer' },\n message: { type: 'string' },\n error: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; error?: string }\n return [{ type: 'text', text: result.success ? 'amendment recorded' : `amend_threat_model failed: ${result.error ?? 'unknown'}` }]\n },\n },\n execute: (async (rawArgs: never) => {\n const args = rawArgs as never as { target?: string; addendum: string }\n const resolved = resolveTarget(args.target)\n if ('error' in resolved) return { success: false, error: resolved.error }\n const addendum = args.addendum.trim()\n if (addendum.length < MIN_AMENDMENT_CHARS) {\n return { success: false, error: `Amendment is too thin (${String(addendum.length)} chars). Give the new knowledge in full.` }\n }\n const model = threatModels.get(resolved.identity)\n if (model === undefined) return { success: false, error: 'No threat model exists for this target yet. Save the full model with save_threat_model first.' }\n const amendments = (model['amendments'] as unknown[] | undefined) ?? []\n if (amendments.length >= MAX_AMENDMENTS) {\n return { success: false, error: `This threat model already carries ${String(amendments.length)} amendments. Fold them into a full save_threat_model rewrite.` }\n }\n if (Buffer.byteLength(String(model['content']) + addendum, 'utf8') > MAX_MODEL_BYTES) {\n return { success: false, error: 'Combined threat model exceeds 512KB; fold amendments with save_threat_model.' }\n }\n amendments.push({ at: isoNow(), by: null, content: addendum })\n model['amendments'] = amendments\n await threatModels.persist()\n return { success: true, target: resolved.identity, amendment_count: amendments.length, message: 'Amendment recorded. Every agent reading the threat model will see it.' }\n }) as never,\n }))\n\n // ---- coverage ----\n\n interface CoverageValidateInput {\n readonly surface: string\n readonly riskArea: string\n readonly outcome: string\n readonly evidence: string\n }\n\n /** strix coverage `_validate`: normalization + per-field errors. */\n function validateCoverage(input: CoverageValidateInput): { readonly outcome: string } | { readonly errors: string[] } {\n const errors: string[] = []\n if (input.surface === '') errors.push('surface cannot be empty - name the endpoint, route, file, or component')\n if (input.riskArea === '') errors.push('risk_area cannot be empty - name what you were testing for')\n const outcome = input.outcome.trim().toLowerCase().replaceAll('-', '_').replaceAll(' ', '_')\n if (!(VALID_OUTCOMES as readonly string[]).includes(outcome)) {\n errors.push(`Invalid outcome: '${input.outcome}'. Must be one of: [${VALID_OUTCOMES.join(', ')}]`)\n }\n if (OUTCOMES_REQUIRING_EVIDENCE.has(outcome) && input.evidence === '') {\n errors.push(`evidence is required for outcome '${outcome}' - name the specific control, response, or observation that justifies it`)\n }\n return errors.length > 0 ? { errors } : { outcome }\n }\n\n const findCoverageDuplicate = (surface: string, riskArea: string): Record<string, unknown> | undefined =>\n coverage.values().find(entry => String(entry['surface']).toLowerCase() === surface.toLowerCase() && String(entry['risk_area']).toLowerCase() === riskArea.toLowerCase())\n\n ctx.tools.register(defineTool({\n name: 'record_coverage',\n description: \"Record that you exercised an attack surface for a risk area, with an outcome. Outcomes: reported / no_issue_found / ruled_out / not_applicable / needs_follow_up. ruled_out, not_applicable, and needs_follow_up REQUIRE evidence. One entry per (surface, risk_area).\",\n parameters: {\n surface: { type: 'string', required: true, description: 'The endpoint, route, file, or component you exercised.' },\n risk_area: { type: 'string', required: true, description: 'What you were testing for (e.g. \"SQL injection in login\").' },\n outcome: { type: 'string', required: true, enum: [...VALID_OUTCOMES], description: 'The testing outcome.' },\n evidence: { type: 'string', description: 'Concrete observation justifying the outcome (required for some outcomes).' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n entry_id: { type: 'string' },\n outcome: { type: 'string' },\n message: { type: 'string' },\n error: { type: 'string' },\n errors: { type: 'array', items: { type: 'string' } },\n existing_entry_id: { type: 'string' },\n existing_outcome: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; error?: string; errors?: string[] }\n const reason = result.error ?? result.errors?.join('; ') ?? 'unknown'\n return [{ type: 'text', text: result.success ? 'coverage recorded' : `record_coverage failed: ${reason}` }]\n },\n },\n execute: (async (rawArgs: never) => {\n const args = rawArgs as never as { surface?: string; risk_area?: string; outcome?: string; evidence?: string }\n const surface = (args.surface ?? '').trim()\n const riskArea = (args.risk_area ?? '').trim()\n const evidence = (args.evidence ?? '').trim()\n const checked = validateCoverage({ surface, riskArea, outcome: args.outcome ?? '', evidence })\n if ('errors' in checked) return { success: false, error: 'Validation failed', errors: checked.errors }\n const duplicate = findCoverageDuplicate(surface, riskArea)\n if (duplicate !== undefined) {\n return {\n success: false,\n error: `'${surface}' (${riskArea}) already has coverage entry ${String(duplicate['id'])}, recorded by ${String(duplicate['agent_name'] ?? 'an agent')} as '${String(duplicate['outcome'])}'. Two rows for the same surface and risk area are never allowed; update_coverage to change the outcome.`,\n existing_entry_id: String(duplicate['id']),\n existing_outcome: String(duplicate['outcome']),\n }\n }\n const id = generateId(new Set(coverage.values().map(entry => String(entry['id'] ?? ''))))\n if (id === null) return { success: false, error: 'could not allocate a coverage entry id' }\n coverage.set(id, {\n id,\n surface,\n risk_area: riskArea,\n outcome: checked.outcome,\n created_at: displayTimestamp(new Date()),\n ...(evidence !== '' ? { evidence } : {}),\n })\n await coverage.persist()\n return { success: true, entry_id: id, outcome: checked.outcome, message: `Coverage recorded for '${surface}' (${checked.outcome})` }\n }) as never,\n }))\n\n ctx.tools.register(defineTool({\n name: 'update_coverage',\n description: \"Move an existing coverage entry to a new outcome (surface and risk_area are never editable). The previous state is kept as history.\",\n parameters: {\n entry_id: { type: 'string', required: true, description: 'Id from record_coverage or list_coverage.' },\n outcome: { type: 'string', required: true, enum: [...VALID_OUTCOMES], description: 'The new outcome.' },\n evidence: { type: 'string', description: 'Evidence for the new outcome (required for some outcomes).' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n entry_id: { type: 'string' },\n previous_outcome: { type: 'string' },\n outcome: { type: 'string' },\n message: { type: 'string' },\n error: { type: 'string' },\n errors: { type: 'array', items: { type: 'string' } },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; error?: string; errors?: string[] }\n const reason = result.error ?? result.errors?.join('; ') ?? 'unknown'\n return [{ type: 'text', text: result.success ? 'coverage updated' : `update_coverage failed: ${reason}` }]\n },\n },\n execute: (async (rawArgs: never) => {\n const args = rawArgs as never as { entry_id?: string; outcome?: string; evidence?: string }\n const entryId = (args.entry_id ?? '').trim()\n const entry = coverage.get(entryId)\n if (entry === undefined) return { success: false, error: `No coverage entry '${entryId}'. Call list_coverage to see recorded entries.` }\n const surface = String(entry['surface'] ?? '')\n const riskArea = String(entry['risk_area'] ?? '')\n const evidence = (args.evidence ?? '').trim()\n const checked = validateCoverage({ surface, riskArea, outcome: args.outcome ?? '', evidence })\n if ('errors' in checked) return { success: false, error: 'Validation failed', errors: checked.errors }\n const previousOutcome = String(entry['outcome'])\n const history = (entry['history'] as Array<Record<string, unknown>> | undefined) ?? []\n const prior: Record<string, unknown> = { outcome: previousOutcome, recorded_at: String(entry['created_at']) }\n if (entry['evidence'] !== undefined) prior['evidence'] = entry['evidence']\n history.push(prior)\n entry['history'] = history\n entry['outcome'] = checked.outcome\n entry['updated_at'] = displayTimestamp(new Date())\n if (evidence !== '') entry['evidence'] = evidence\n await coverage.persist()\n return {\n success: true,\n entry_id: entryId,\n previous_outcome: previousOutcome,\n outcome: checked.outcome,\n message: `'${surface}' (${riskArea}) moved from ${previousOutcome} to ${checked.outcome}. The previous state is kept as history.`,\n }\n }) as never,\n }))\n\n ctx.tools.register(defineTool({\n name: 'list_coverage',\n description: 'List coverage entries recorded in this scan (filters compose; outcome counts are over all entries).',\n parameters: {\n outcome: { type: 'string', description: 'Filter to one outcome.' },\n surface: { type: 'string', description: 'Case-insensitive substring match on the surface.' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n entries: { type: 'array', items: { type: 'object', properties: {}, additionalProperties: true }, required: true },\n filtered_count: { type: 'integer', required: true },\n total_count: { type: 'integer', required: true },\n outcome_counts: { type: 'object', properties: {}, additionalProperties: true, required: true },\n error: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { entries?: unknown[]; error?: string }\n if (result.error !== undefined) return [{ type: 'text', text: `list_coverage failed: ${result.error}` }]\n return [{ type: 'text', text: `${String(result.entries?.length ?? 0)} coverage entry(ies)` }]\n },\n },\n execute: (async (rawArgs: never) => {\n const args = rawArgs as never as { outcome?: string; surface?: string }\n let outcomeFilter: string | undefined\n if (args.outcome !== undefined && args.outcome !== '') {\n outcomeFilter = args.outcome.trim().toLowerCase().replaceAll('-', '_').replaceAll(' ', '_')\n if (outcomeFilter !== undefined && !(VALID_OUTCOMES as readonly string[]).includes(outcomeFilter)) {\n return {\n success: false,\n error: `Invalid outcome: '${args.outcome}'. Must be one of: [${VALID_OUTCOMES.join(', ')}]`,\n entries: [],\n filtered_count: 0,\n total_count: coverage.size,\n outcome_counts: {},\n }\n }\n }\n const surfaceFilter = args.surface?.toLowerCase() ?? ''\n const entries = coverageEntries()\n .filter(entry => (outcomeFilter === undefined || entry['outcome'] === outcomeFilter))\n .filter(entry => surfaceFilter === '' || String(entry['surface']).toLowerCase().includes(surfaceFilter))\n .sort((a, b) => String(a['created_at']).localeCompare(String(b['created_at'])))\n .map(entry => {\n const listing: Record<string, unknown> = {\n entry_id: entry.entry_id,\n surface: entry['surface'],\n risk_area: entry['risk_area'],\n outcome: entry['outcome'],\n created_at: entry['created_at'],\n }\n const evidence = entry['evidence']\n if (typeof evidence === 'string' && evidence !== '') {\n listing['evidence'] = evidence.length > 240 ? `${evidence.slice(0, 240)}...` : evidence\n }\n const history = entry['history'] as Array<Record<string, unknown>> | undefined\n if (history !== undefined && history.length > 0) {\n listing['previous_outcomes'] = history.map(item => item['outcome'])\n }\n return listing\n })\n return {\n success: true,\n entries,\n filtered_count: entries.length,\n total_count: coverage.size,\n outcome_counts: outcomeCounts(),\n }\n }) as never,\n }))\n\n // ---- notes ----\n\n const noteList = (): Array<Record<string, unknown> & { id: string }> =>\n notes.values().map(entry => ({ ...entry, id: String(entry['id'] ?? '') })) as Array<Record<string, unknown> & { id: string }>\n\n ctx.tools.register(defineTool({\n name: 'create_note',\n description: 'Create a persistent note shared across the scan team (categories: general/findings/methodology/questions/plan/wiki).',\n parameters: {\n title: { type: 'string', required: true, description: 'Short note title.' },\n content: { type: 'string', required: true, description: 'The note body.' },\n category: { type: 'string', enum: [...VALID_NOTE_CATEGORIES], description: 'Note category (default general).' },\n tags: { type: 'array', items: { type: 'string' }, description: 'Optional tags.' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n note_id: { type: 'string' },\n message: { type: 'string' },\n total_count: { type: 'integer' },\n error: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; error?: string }\n return [{ type: 'text', text: result.success ? 'note created' : `create_note failed: ${result.error ?? 'unknown'}` }]\n },\n },\n execute: (async (rawArgs: never) => {\n const args = rawArgs as never as { title?: string; content?: string; category?: string; tags?: string[] }\n const title = (args.title ?? '').trim()\n const content = (args.content ?? '').trim()\n const category = (args.category ?? 'general').trim()\n if (title === '') return { success: false, error: 'Title cannot be empty' }\n if (content === '') return { success: false, error: 'Content cannot be empty' }\n if (!(VALID_NOTE_CATEGORIES as readonly string[]).includes(category)) {\n return { success: false, error: `Invalid category. Must be one of: ${VALID_NOTE_CATEGORIES.join(', ')}` }\n }\n const id = generateId(new Set(noteList().map(note => note.id)))\n if (id === null) return { success: false, error: 'could not allocate a note id' }\n const now = isoNow()\n notes.set(id, {\n id,\n title,\n content,\n category,\n tags: args.tags ?? [],\n created_at: now,\n updated_at: now,\n })\n await notes.persist()\n return { success: true, note_id: id, message: `Note '${title}' created successfully`, total_count: notes.size }\n }) as never,\n }))\n\n ctx.tools.register(defineTool({\n name: 'list_notes',\n description: 'List notes (filters compose; newest first).',\n parameters: {\n category: { type: 'string', description: 'Exact category filter.' },\n tags: { type: 'array', items: { type: 'string' }, description: 'ANY-match tag filter.' },\n search: { type: 'string', description: 'Substring match on title or content.' },\n include_content: { type: 'boolean', description: 'Full content instead of a 280-char preview.' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n notes: { type: 'array', items: { type: 'object', properties: {}, additionalProperties: true }, required: true },\n filtered_count: { type: 'integer', required: true },\n total_count: { type: 'integer', required: true },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { notes?: unknown[] }\n return [{ type: 'text', text: `${String(result.notes?.length ?? 0)} note(s)` }]\n },\n },\n execute: (async (rawArgs: never) => {\n const args = rawArgs as never as { category?: string; tags?: string[]; search?: string; include_content?: boolean }\n const category = args.category?.trim() ?? ''\n const search = args.search?.toLowerCase() ?? ''\n const tags = args.tags ?? []\n const entries = noteList()\n .filter(note => category === '' || note['category'] === category)\n .filter(note => tags.length === 0 || tags.some(tag => (note['tags'] as string[] | undefined)?.includes(tag) === true))\n .filter(note => search === '' || String(note['title']).toLowerCase().includes(search) || String(note['content']).toLowerCase().includes(search))\n .sort((a, b) => String(b['created_at']).localeCompare(String(a['created_at'])))\n .map(note => {\n const listing: Record<string, unknown> = {\n note_id: note.id,\n title: note['title'],\n category: note['category'],\n tags: note['tags'],\n created_at: note['created_at'],\n updated_at: note['updated_at'],\n }\n const content = String(note['content'] ?? '')\n listing[args.include_content === true ? 'content' : 'content_preview'] = args.include_content === true ? content : content.length > 280 ? `${content.slice(0, 280)}...` : content\n return listing\n })\n return { success: true, notes: entries, filtered_count: entries.length, total_count: notes.size }\n }) as never,\n }))\n\n ctx.tools.register(defineTool({\n name: 'get_note',\n description: 'Fetch one note by id.',\n parameters: {\n note_id: { type: 'string', required: true, description: 'Note id from list_notes or create_note.' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n note: { type: 'object', properties: {}, additionalProperties: true },\n error: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; error?: string }\n return [{ type: 'text', text: result.success ? 'note returned' : `get_note failed: ${result.error ?? 'unknown'}` }]\n },\n },\n execute: (async (rawArgs: never) => {\n const args = rawArgs as never as { note_id?: string }\n const noteId = (args.note_id ?? '').trim()\n if (noteId === '') return { success: false, error: 'Note ID cannot be empty' }\n const note = notes.get(noteId)\n if (note === undefined) return { success: false, error: `Note with ID '${noteId}' not found` }\n return { success: true, note: { ...note, note_id: noteId } }\n }) as never,\n }))\n\n ctx.tools.register(defineTool({\n name: 'update_note',\n description: 'Revise a note (only the fields you pass change; updated_at always bumps).',\n parameters: {\n note_id: { type: 'string', required: true, description: 'Note id.' },\n title: { type: 'string', description: 'Replacement title.' },\n content: { type: 'string', description: 'Replacement content.' },\n tags: { type: 'array', items: { type: 'string' }, description: 'Replacement tags (full replace).' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n note_id: { type: 'string' },\n message: { type: 'string' },\n total_count: { type: 'integer' },\n error: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; error?: string }\n return [{ type: 'text', text: result.success ? 'note updated' : `update_note failed: ${result.error ?? 'unknown'}` }]\n },\n },\n execute: (async (rawArgs: never) => {\n const args = rawArgs as never as { note_id?: string; title?: string; content?: string; tags?: string[] }\n const noteId = (args.note_id ?? '').trim()\n const note = notes.get(noteId)\n if (note === undefined) return { success: false, error: `Note with ID '${noteId}' not found` }\n if (args.title !== undefined && args.title.trim() === '') return { success: false, error: 'Title cannot be empty' }\n if (args.content !== undefined && args.content.trim() === '') return { success: false, error: 'Content cannot be empty' }\n if (args.title !== undefined) note['title'] = args.title.trim()\n if (args.content !== undefined) note['content'] = args.content.trim()\n if (args.tags !== undefined) note['tags'] = args.tags\n note['updated_at'] = isoNow()\n await notes.persist()\n return { success: true, note_id: noteId, message: `Note '${String(note['title'])}' updated successfully`, total_count: notes.size }\n }) as never,\n }))\n\n ctx.tools.register(defineTool({\n name: 'delete_note',\n description: 'Delete a note by id.',\n parameters: {\n note_id: { type: 'string', required: true, description: 'Note id.' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n note_id: { type: 'string' },\n message: { type: 'string' },\n total_count: { type: 'integer' },\n error: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; error?: string }\n return [{ type: 'text', text: result.success ? 'note deleted' : `delete_note failed: ${result.error ?? 'unknown'}` }]\n },\n },\n execute: (async (rawArgs: never) => {\n const args = rawArgs as never as { note_id?: string }\n const noteId = (args.note_id ?? '').trim()\n const note = notes.get(noteId)\n if (note === undefined) return { success: false, error: `Note with ID '${noteId}' not found` }\n notes.delete(noteId)\n await notes.persist()\n return { success: true, note_id: noteId, message: `Note '${String(note['title'])}' deleted successfully`, total_count: notes.size }\n }) as never,\n }))\n\n ctx.tools.register(defineTool({\n name: 'think',\n description: 'Record a private reasoning step (no storage; use notes for persistent knowledge).',\n parameters: {\n thought: { type: 'string', required: true, description: 'The reasoning step.' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n message: { type: 'string' },\n error: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; error?: string }\n return [{ type: 'text', text: result.success ? 'recorded' : `think failed: ${result.error ?? 'unknown'}` }]\n },\n },\n execute: (async (rawArgs: never) => {\n const args = rawArgs as never as { thought?: string }\n if ((args.thought ?? '').trim() === '') return { success: false, error: 'Thought cannot be empty' }\n return { success: true, message: 'Thought recorded' }\n }) as never,\n }))\n\n // ---- finish_scan ----\n\n ctx.tools.register(defineTool({\n name: 'finish_scan',\n description: 'Complete the scan: validates the four report sections, records the coverage summary, writes the final artifacts, and marks the scan completed. Root agent only.',\n parameters: {\n executive_summary: { type: 'string', required: true, description: 'Non-technical summary for stakeholders.' },\n methodology: { type: 'string', required: true, description: 'How the scan was conducted.' },\n technical_analysis: { type: 'string', required: true, description: 'Technical findings analysis.' },\n recommendations: { type: 'string', required: true, description: 'Prioritized remediation recommendations.' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n scan_completed: { type: 'boolean' },\n message: { type: 'string' },\n vulnerabilities_found: { type: 'integer' },\n coverage_recorded: { type: 'integer' },\n coverage_outcomes: { type: 'object', properties: {}, additionalProperties: true },\n coverage_warning: { type: 'string' },\n unresolved_surfaces: { type: 'array', items: { type: 'object', properties: {}, additionalProperties: true } },\n warning: { type: 'string' },\n error: { type: 'string' },\n errors: { type: 'array', items: { type: 'string' } },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; error?: string; errors?: string[] }\n const reason = result.error ?? result.errors?.join('; ') ?? 'unknown'\n return [{ type: 'text', text: result.success ? 'scan completed' : `finish_scan failed: ${reason}` }]\n },\n },\n execute: (async (rawArgs: never) => {\n const args = rawArgs as never as { executive_summary?: string; methodology?: string; technical_analysis?: string; recommendations?: string }\n if (config.allowFinish === false) {\n return { success: false, scan_completed: false, error: 'This tool can only be used by the root/main agent. If you are a subagent, use agent_finish instead' }\n }\n const sections = {\n executiveSummary: (args.executive_summary ?? '').trim(),\n methodology: (args.methodology ?? '').trim(),\n technicalAnalysis: (args.technical_analysis ?? '').trim(),\n recommendations: (args.recommendations ?? '').trim(),\n }\n const errors: string[] = []\n if (sections.executiveSummary === '') errors.push('Executive summary cannot be empty')\n if (sections.methodology === '') errors.push('Methodology cannot be empty')\n if (sections.technicalAnalysis === '') errors.push('Technical analysis cannot be empty')\n if (sections.recommendations === '') errors.push('Recommendations cannot be empty')\n if (errors.length > 0) return { success: false, error: 'Validation failed', errors }\n const summary: Record<string, unknown> = {\n coverage_recorded: coverage.size,\n coverage_outcomes: outcomeCounts(),\n }\n if (coverage.size === 0) {\n summary['coverage_warning'] = 'No coverage was recorded for this scan. The report cannot state what was and was not tested; record coverage with record_coverage in future scans.'\n } else {\n const unresolved = coverageEntries()\n .filter(entry => entry['outcome'] === 'needs_follow_up')\n .map(entry => ({ surface: entry['surface'], risk_area: entry['risk_area'] }))\n if (unresolved.length > 0) {\n summary['coverage_warning'] = `${String(unresolved.length)} surface(s) still need follow-up; they are listed in unresolved_surfaces.`\n summary['unresolved_surfaces'] = unresolved\n }\n }\n const reporting = (ctx as unknown as { pentestReporting?: { finishScan(sections: { executiveSummary: string; methodology: string; technicalAnalysis: string; recommendations: string }, status?: string): Promise<void>; state: { vulnerabilityReports: unknown[] } } }).pentestReporting\n if (reporting === undefined) {\n return { success: true, scan_completed: true, message: 'Scan completed (not persisted)', warning: 'Results could not be persisted - report state unavailable', ...summary }\n }\n await reporting.finishScan(sections)\n return { success: true, scan_completed: true, message: 'Scan completed successfully', vulnerabilities_found: reporting.state.vulnerabilityReports.length, ...summary }\n }) as never,\n }))\n\n return handle\n}\n\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gpzhang2001/sharpkit-analysis",
|
|
3
|
+
"description": "Threat model / coverage / notes / think tools + finish_scan over per-scan mirror stores",
|
|
4
|
+
"version": "0.2.1",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/gpzhang2001/sharpkit.git",
|
|
11
|
+
"directory": "packages/tool-analysis"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"license": "Apache-2.0",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./lib/index.d.ts",
|
|
18
|
+
"default": "./lib/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./src/*": "./src/*",
|
|
21
|
+
"./package.json": "./package.json"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"lib",
|
|
25
|
+
"src",
|
|
26
|
+
"LICENSE",
|
|
27
|
+
"THIRD_PARTY_NOTICES.md"
|
|
28
|
+
],
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@deepseek-ai/schemastery": "3.18.2",
|
|
31
|
+
"@gpzhang2001/sharpkit-reporting": "^0.2.1"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
35
|
+
"@deepseek-ai/dsh-tools": "^0.1.2-rc.1",
|
|
36
|
+
"@gpzhang2001/sharpkit-reporting": "^0.1.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@deepseek-ai/cordis": "4.0.2",
|
|
40
|
+
"@deepseek-ai/dsh-tools": "0.1.2-rc.1",
|
|
41
|
+
"@gpzhang2001/sharpkit-reporting": "^0.2.1"
|
|
42
|
+
},
|
|
43
|
+
"main": "lib/index.js",
|
|
44
|
+
"types": "lib/index.d.ts",
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "cp ../../LICENSE ../../THIRD_PARTY_NOTICES.md . && tsdown && mv -f lib/index.ts lib/index.d.ts && mv -f lib/index.ts.map lib/index.d.ts.map"
|
|
47
|
+
}
|
|
48
|
+
}
|