agentsclimarketplace

Pwnote engagement file

Skill Pwnote/skills/skills/pwnote-engagement-file

AI agent skills for Pwnote Pentest Notebook

Install
npx -y skills add Pwnote/skills --skill pwnote-engagement-file

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 14 days oldThe repository was created 14 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Create or validate a pwnote engagement import/export JSON file. Use when the user wants to generate, edit, or verify a pwnote engagement file for data transfer between pwnote instances. The file bundles an entire pentest engagement — metadata, notebook documents, code/host/credential blocks, findings with CVSS/cwe/cve, attack-path boards, and activity history. Also use when the user asks how to structure such a file, needs a template, or wants to programmatically generate one from external tooling.

SKILL.md

15.6 KB, as published. Nobody here has run it

Security

This skill describes the engagement file schema for data transfer between pwnote instances. Follow these rules:

  • Never output real credential secret values anywhere — use <REDACTED> as placeholder
  • Never log, echo, or print plaintext secrets
  • Treat requestBody, requestHeaders, responseBody fields as potentially sensitive — redact before sharing externally
  • The secret field in credential blocks is populated from user-provided data, never generated by the agent

Installation

npx skills add Pwnote/skills

Pwnote Engagement File Format

Reference for creating or editing pwnote engagement import/export JSON files. A valid file contains all data for one pentest engagement and can be imported via Settings → Import or the workspace Import button.

File Structure

{
  "engagement": { ... },
  "docs": [ ... ],
  "blocks": [ ... ],
  "findings": [ ... ],
  "boards": [ ... ],
  "boardNodes": [ ... ],
  "boardEdges": [ ... ],
  "activity": [ ... ]
}

All top-level keys are required but may be empty arrays.

Field Reference

engagement (object)

FieldTypeRequiredDescription
namestringyesEngagement name, e.g. "Q4_External_2026"
clientstringyesClient name, e.g. "Acme Corp"
testTypestringyesOne of: "black-box", "grey-box", "white-box"
scopestring[]yesIPs, domains, CIDRs, app URLs
roestringnoRules of engagement as free text
startDatestringyesISO date "YYYY-MM-DD"
endDatestringyesISO date "YYYY-MM-DD"
testersstring[]yesOperator names/handles
archivedbooleanyesfalse for new engagements

Generated fields (omit — set on import): id, createdAt, updatedAt.

docs (array of objects)

FieldTypeRequiredDescription
titlestringyesDoc name, e.g. "01_Recon"
ordernumberyesSort order within engagement
parentIdstringnoParent doc ID for folder nesting
folderbooleannotrue if this doc is a folder

Generated fields: id, engagementId, createdAt, updatedAt.

blocks (array of objects)

Each block has these base fields plus type-specific fields:

Base fields (all block types):

FieldTypeRequiredDescription
typestringyesBlock type discriminator (see below)
docIdstringyesMust match a doc id in the file
ordernumberyesSort order within doc
tagsstring[]noTag labels, e.g. ["nmap", "discovery"]

Generated fields: id.

Type-specific fields:

"heading" — Section header

FieldTypeRequiredDescription
levelnumberyes1, 2, or 3
textstringyesHeading text

Use level: 1 for document titles, level: 2 for major sections, level: 3 for sub-sections. Always use a mix of levels for structure — never use only level 1.

"paragraph" — Plain text

FieldTypeRequiredDescription
textstringyesParagraph content

"markdown" — Rich text block

FieldTypeRequiredDescription
markdownstringyesMarkdown content

"code" — Code snippet

FieldTypeRequiredDescription
languagestringyese.g. "bash", "python3", "rust", "go", "javascript", "typescript", "sql", "yaml"
codestringyesCode content

"command-output" — Shell command and its output

FieldTypeRequiredDescription
commandstringyesThe command run
outputstringyesCommand output text
timestampstringnoISO timestamp

"host" — Host/asset entry

FieldTypeRequiredDescription
ipstringyesIP address
hostnamestringnoDNS name
osstringnoOperating system
portsstring[]yesPort list, e.g. ["22/tcp", "80/tcp", "443/tcp"]
notesstringnoFree-text notes

"credential" — Credential (sensitive). The secret field must use <REDACTED> when demonstrating — never output real values.

FieldTypeRequiredDescription
usernamestringyesUsername
secretstringyes<REDACTED> in examples; real values come from user-provided data only
secretTypestringyesOne of: "password", "hash", "token", "key"
sourcestringnoWhere credential was found
sensitivebooleanyesAlways true

"screenshot" — Image evidence

FieldTypeRequiredDescription
dataUrlstringnoBase64 data URL of image
captionstringnoImage caption

"checklist" — Task checklist

FieldTypeRequiredDescription
titlestringyesChecklist title
itemsarrayyesArray of { id: string, text: string, done: boolean }

"timeline" — Timeline event

FieldTypeRequiredDescription
timestampstringyesISO datetime
eventstringyesEvent description
actorstringnoWho performed the action

"table" — Data table

FieldTypeRequiredDescription
headersstring[]yesColumn headers
rowsarrayyesArray of string arrays (cells)

"separator" — Visual divider No extra fields beyond base.

"http-request" — HTTP request/response pair

FieldTypeRequiredDescription
methodstringyesHTTP method: "GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"
urlstringyesRequest URL
requestHeadersstringyesRaw request headers (one per line)
requestBodystringyesRequest body
responseStatusnumberyesHTTP status code (0 if no response)
responseHeadersstringyesRaw response headers (one per line)
responseBodystringyesResponse body

"finding" — Linked finding (references a finding by ID)

FieldTypeRequiredDescription
findingIdstringyesMust match a finding id in the file

findings (array of objects)

FieldTypeRequiredDescription
titlestringyesFinding title
severitystringyesOne of: "critical", "high", "medium", "low", "info"
cvssScorenumberno0.0–10.0
cvssVectorstringnoCVSS vector string
cwestringnoCWE identifier, e.g. "CWE-79"
cvestringnoCVE identifier, e.g. "CVE-2024-12345"
affectedAssetsstring[]yesAffected hosts/URLs
descriptionstringyesVulnerability description
pocstringyesProof of concept
remediationstringyesFix guidance
referencesstring[]yesURLs to references
statusstringyesOne of: "draft", "confirmed", "fixed", "accepted-risk", "needs-retest"
retestResultstringnoOutcome of retest
tagsstring[]yesTag labels

Generated fields: id, engagementId, createdAt, updatedAt.

boards (array of objects)

FieldTypeRequiredDescription
namestringyesBoard name, e.g. "Topology"
kindstringyesOne of: "topology", "killchain", "planning", "forensics", "retest", "post-exploitation", "custom"
lockedbooleannotrue to lock board from edits

Generated fields: id, engagementId, createdAt, updatedAt.

boardNodes (array of objects)

FieldTypeRequiredDescription
refTypestringyesOne of: "host", "finding", "credential", "freeform"
refIdstringnoLinks to block/finding ID (null for freeform)
xnumberyesFlow canvas X position
ynumberyesFlow canvas Y position
dataobjectnoExtra node data (label for freeform, ip/ports for host, etc.)
boardIdstringyesMust match a board id in the file

Generated fields: id.

boardEdges (array of objects)

FieldTypeRequiredDescription
sourcestringyesSource boardNode id
targetstringyesTarget boardNode id
labelstringnoEdge label (e.g. "credential" for cred edges)
boardIdstringyesMust match a board id in the file

Generated fields: id.

activity (array of objects)

FieldTypeRequiredDescription
actorstringyesWho performed the action
kindstringyesActivity kind, e.g. "engagement.create", "block.create", "finding.status"
messagestringyesHuman-readable description
metaobjectnoExtra metadata

Generated fields: id, engagementId, timestamp.

ID Linking Rules

IDs in export files are local references. The import process regenerates all IDs but preserves the relationship graph by remapping foreign keys automatically. Use any ID pattern you like (e.g. tmp_doc_recon, tmp_f_xss, tmp_bn_host1).

All cross-references MUST point to IDs defined within the same JSON file. The import remaps them to the newly generated IDs so links survive the import intact.

Foreign KeyPoints ToField Location
block.docIddoc idevery block
block.findingIdfinding idfinding-type blocks only
boardNode.boardIdboard idevery boardNode
boardNode.refIdblock id or finding idhost/finding/credential nodes
boardEdge.sourceboardNode idevery boardEdge
boardEdge.targetboardNode idevery boardEdge
boardEdge.boardIdboard idevery boardEdge

Freeform nodes have refId: null (no link to any block/finding).

Node Linking Example

To display a host and linked finding on a topology board:

{
  "docs": [{ "id": "tmp_doc_recon", "title": "01_Recon", "order": 0 }],
  "blocks": [
    {
      "id": "tmp_b_host1", "docId": "tmp_doc_recon", "order": 0, "tags": [],
      "type": "host", "ip": "10.0.0.1", "hostname": "web.example.com",
      "os": "Ubuntu 22.04", "ports": ["22/tcp", "80/tcp", "443/tcp"]
    },
    {
      "id": "tmp_b_finding1", "docId": "tmp_doc_recon", "order": 1, "tags": ["web"],
      "type": "finding", "findingId": "tmp_f_xss"
    }
  ],
  "findings": [
    {
      "id": "tmp_f_xss", "title": "Reflected XSS",
      "severity": "high", "cvssScore": 6.1, "...": "..."
    }
  ],
  "boards": [
    { "id": "tmp_brd_topology", "name": "Topology", "kind": "topology" }
  ],
  "boardNodes": [
    {
      "id": "tmp_bn_host1", "boardId": "tmp_brd_topology",
      "refType": "host", "refId": "tmp_b_host1",
      "x": 100, "y": 100,
      "data": { "ip": "10.0.0.1", "hostname": "web.example.com", "ports": ["22/tcp", "80/tcp", "443/tcp"] }
    },
    {
      "id": "tmp_bn_finding1", "boardId": "tmp_brd_topology",
      "refType": "finding", "refId": "tmp_f_xss",
      "x": 350, "y": 100,
      "data": { "title": "Reflected XSS", "severity": "high", "cvssScore": 6.1 }
    }
  ],
  "boardEdges": [
    {
      "id": "tmp_be_1", "boardId": "tmp_brd_topology",
      "source": "tmp_bn_host1", "target": "tmp_bn_finding1",
      "label": "exploits"
    }
  ]
}

Key rules for node data:

  • host nodes: data must include ip, hostname, ports
  • finding nodes: data must include title, severity, cvssScore
  • credential nodes: data must include username, secretType
  • freeform nodes: data must include label (display text)
  • Edges between credential and host nodes should use label: "credential" for visual styling

Example: Minimal Engagement

{
  "engagement": {
    "name": "External Pentest Q4",
    "client": "Example Corp",
    "testType": "grey-box",
    "scope": ["10.0.0.0/24", "app.example.com"],
    "roe": "Testing window: 09-18 local.\nExclusions: production DB.",
    "startDate": "2026-07-21",
    "endDate": "2026-08-04",
    "testers": ["operator"],
    "archived": false
  },
  "docs": [
    { "id": "tmp_doc_recon", "title": "01_Recon", "order": 0, "engagementId": "tmp_eng" },
    { "id": "tmp_doc_exploit", "title": "02_Exploitation", "order": 1, "engagementId": "tmp_eng" }
  ],
  "blocks": [
    {
      "id": "tmp_b_host1", "docId": "tmp_doc_recon", "order": 0, "tags": [],
      "type": "host", "ip": "10.0.0.1", "hostname": "web.example.com", "os": "Ubuntu 22.04",
      "ports": ["22/tcp", "80/tcp", "443/tcp"]
    },
    {
      "id": "tmp_b_finding1", "docId": "tmp_doc_exploit", "order": 0, "tags": ["web"],
      "type": "finding", "findingId": "tmp_f_xss"
    },
    {
      "id": "tmp_b_sep1", "docId": "tmp_doc_recon", "order": 1, "tags": [],
      "type": "separator"
    },
    {
      "id": "tmp_b_code1", "docId": "tmp_doc_exploit", "order": 1, "tags": [],
      "type": "code", "language": "python3", "code": "print('hello')"
    }
  ],
  "findings": [
    {
      "id": "tmp_f_xss",
      "title": "Reflected XSS in search endpoint",
      "severity": "high",
      "cvssScore": 6.1,
      "affectedAssets": ["app.example.com/search"],
      "description": "The search parameter is reflected without sanitization.",
      "poc": "<script>alert(1)</script>",
      "remediation": "Encode HTML entities in the response.",
      "references": ["https://owasp.org/www-community/attacks/xss/"],
      "status": "confirmed",
      "tags": ["xss", "web"]
    }
  ],
  "boards": [
    {
      "id": "tmp_brd_topology",
      "name": "Topology", "kind": "topology", "locked": false,
      "engagementId": "tmp_eng", "createdAt": 0, "updatedAt": 0
    }
  ],
  "boardNodes": [
    {
      "id": "tmp_bn_host1", "boardId": "tmp_brd_topology",
      "refType": "host", "refId": "tmp_b_host1",
      "x": 100, "y": 100,
      "data": { "ip": "10.0.0.1", "hostname": "web.example.com", "ports": ["22/tcp", "80/tcp", "443/tcp"] }
    },
    {
      "id": "tmp_bn_finding1", "boardId": "tmp_brd_topology",
      "refType": "finding", "refId": "tmp_f_xss",
      "x": 300, "y": 100,
      "data": { "title": "Reflected XSS in search endpoint", "severity": "high", "cvssScore": 6.1 }
    }
  ],
  "boardEdges": [
    {
      "id": "tmp_be_1", "boardId": "tmp_brd_topology",
      "source": "tmp_bn_host1", "target": "tmp_bn_finding1",
      "label": "exploits"
    }
  ],
  "activity": [
    {
      "id": "tmp_act_1", "engagementId": "tmp_eng",
      "timestamp": 0, "actor": "operator",
      "kind": "engagement.create", "message": "Engagement created"
    }
  ]
}

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.